]> cloudbase.mooo.com Git - z180-stamp.git/blame - stm32/z80-if.c
Swap pins for IOSEL1 and /BUSACK. IOSEL --> TIM3_CH4 (DMA-REQ)
[z180-stamp.git] / stm32 / z80-if.c
CommitLineData
acd9bdaf
L
1/**
2 *
3 * Pin assignments
4 *
5 * | Z180-Sig | STM32-Port | Buffer | Dir |Special Function |
6 * | -------- | ---------- | ------ | --- | --------------- |
7 * | A0 |A 1 |P |O | |
8 * | A1 |A 2 |P |O | |
9 * | A2 |A 3 |P |O | |
10 * | A3 |A 4 |P |O | |
11 * | A4 |A 5 |P |O | |
12 * | A5 |A 6 |P |O | |
13 * | A6 |A 7 |P |O | |
14 * | A7 |A 8 | |O | |
15 * | A8 |C 0 |P |O | |
16 * | A9 |C 1 |P |O | |
17 * | A10 |C 2 |P |O | |
18 * | A11 |C 3 |P |O | |
19 * | A12 |C 4 |P |O | |
20 * | A13 |C 5 |P |O | |
21 * | A14 |C 6 | |O | |
22 * | A15 |C 7 | |O | |
23 * | A16 |C 10 | |O | |
24 * | A17 |C 11 | |O | |
25 * | A18 |C 12 | |O | |
26 * | D0 |B 8 | |I/O | |
27 * | D1 |B 9 | |I/O | |
28 * | D2 |B 10 | |I/O | |
29 * | D3 |B 11 | |I/O | |
30 * | D4 |B 12 | |I/O | |
31 * | D5 |B 13 | |I/O | |
32 * | D6 |B 14 | |I/O | |
33 * | D7 |B 15 | |I/O | |
34 * | ME |C 13 |P |O | |
35 * | RD |B 0 |P |O | |
36 * | WR |B 1 |P |O | |
37 * | BUSREQ |D 2 | |O | |
38 * | IOCS1 |A 11 | |I |TIM1_CH4 |
39 * | BUSACK |A 12 | |I | |
40 * | HALT |A 12 | |I | |
41 * | NMI |B 7 | |O | |
42 * | RST |B 6 | |O |TIM16_CH1N |
43 * | | | | | |
44 * | |A 9 | | |af1 USART1_TX |
45 * | |A 10 | | |af1 USART1_RX |
46 * | |A 15 | |JTDI | remap SPI1_NSS' |
47 * | |B 3 | |JTDO |remap SPI1_SCK' |
48 * | |B 4 | |NJTRST |remap SPI1_MISO' |
49 * | |B 5 | | |remap SPI1_MOSI' |
50 * | |C 14 | | |af1 OSC32 |
51 * | |C 15 | | |af1 OSC32 |
e64eba00 52
e64eba00
L
53
54AFIO_MAPR2 =
55AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON (frees
56AFIO_MAPR_SPI1_REMAP
57
acd9bdaf
L
58 */
59
e64eba00
L
60
61#include <libopencm3/stm32/gpio.h>
62#include <libopencm3/stm32/rcc.h>
63#include <libopencm3/stm32/timer.h>
64#include <libopencm3/stm32/dma.h>
65#include "z80-if.h"
66
67/* Number of array elements */
68#define NELEMS(x) (sizeof x/sizeof *x)
69
70#define ODR 0x0c
71#define IDR 0x08
72
73#define CONCAT(x,y) x ## y
74#define EVALUATOR(x,y) CONCAT(x,y)
75
76#define GPIO_(X) CONCAT(GPIO, X)
77
e64eba00 78
e64eba00 79
e64eba00
L
80
81#define P_ME GPIOC
82#define ME 13
83#define P_RD GPIOB
84#define RD 0
85#define P_WR GPIOB
86#define WR 1
87#define P_BUSREQ GPIOD
88#define BUSREQ 2
89#define P_BUSACK GPIOA
acd9bdaf 90#define BUSACK 12
e64eba00
L
91//#define P_HALT GPIOA
92//#define HALT 12
acd9bdaf
L
93#define P_IOCS1 GPIOA
94#define IOCS1 11
e64eba00
L
95#define P_NMI GPIOB
96#define NMI 7
97#define P_RST GPIOB
98#define RST 6
99
100#define ADp1_OFS 0
101#define ADp1_WIDTH 8
102#define ADp1_SHIFT 1
103#define ADp1_PORT GPIOA
104
105#define ADp2_OFS ADp1_WIDTH
106#define ADp2_WIDTH 8
107#define ADp2_SHIFT 0
108#define ADp2_PORT GPIOC
109
110#define ADp3_OFS (ADp2_OFS+ADp2_WIDTH)
111#define ADp3_WIDTH 3
112#define ADp3_SHIFT 10
113#define ADp3_PORT GPIOC
114
115#define ADunbuff1_WIDTH 1
116#define ADunbuff1_SHIFT 8
117#define ADunbuff1_PORT GPIOA
118
119#define ADunbuff2_WIDTH 2
120#define ADunbuff2_SHIFT 6
121#define ADunbuff2_PORT GPIOC
122
123#define ADunbuff3_WIDTH 3
124#define ADunbuff3_SHIFT 10
125#define ADunbuff3_PORT GPIOC
126
127#define DB_OFS 0
128#define DB_WIDTH 8
129#define DB_SHIFT 8
130#define DB_PORT GPIOB
131
132#define GPIO_ME GPIO_(ME)
133#define GPIO_RD GPIO_(RD)
134#define GPIO_WR GPIO_(WR)
135#define GPIO_BUSREQ GPIO_(BUSREQ)
136#define GPIO_BUSACK GPIO_(BUSACK)
137//#define GPIO_HALT GPIO_(HALT)
acd9bdaf 138#define GPIO_IOCS1 GPIO_(IOCS1)
e64eba00
L
139#define GPIO_NMI GPIO_(NMI)
140#define GPIO_RST GPIO_(RST)
141
142#define Z80_O_ME BBIO_PERIPH(P_ME+ODR, ME)
143#define Z80_O_RD BBIO_PERIPH(P_RD+ODR, RD)
144#define Z80_O_WR BBIO_PERIPH(P_WR+ODR, WR)
145#define Z80_O_BUSREQ BBIO_PERIPH(P_BUSREQ+ODR, BUSREQ)
146#define Z80_O_NMI BBIO_PERIPH(P_NMI+ODR, NMI)
147#define Z80_O_RST BBIO_PERIPH(P_RST+ODR, RST)
148
149#define Z80_I_BUSACK BBIO_PERIPH(P_BUSACK+IDR, BUSACK)
150//#define Z80_I_HALT BBIO_PERIPH(P_HALT+IDR, HALT)
151
152
153#define MASK(n) ((1<<n)-1)
154
155#define IOFIELD_SET(src, ofs, width, shift) \
156 ((((src>>ofs) & MASK(width)) << shift) | ((((~src>>ofs) & MASK(width)) << shift) << 16))
157
158#define IOFIELD_GET(src, width, shift) \
159 ((src>>shift) & MASK(width))
160
161#define CNF_MODE_I_F (GPIO_CNF_INPUT_FLOAT<<2 |GPIO_MODE_INPUT)
162#define CNF_MODE_O_PP (GPIO_CNF_OUTPUT_PUSHPULL<<2 | GPIO_MODE_OUTPUT_10_MHZ)
163
164#define DB_MODE_INPUT ( (CNF_MODE_I_F << (4 * 0)) \
165 | (CNF_MODE_I_F << (4 * 1)) \
166 | (CNF_MODE_I_F << (4 * 2)) \
167 | (CNF_MODE_I_F << (4 * 3)) \
168 | (CNF_MODE_I_F << (4 * 4)) \
169 | (CNF_MODE_I_F << (4 * 5)) \
170 | (CNF_MODE_I_F << (4 * 6)) \
171 | (CNF_MODE_I_F << (4 * 7)))
172
173#define DB_MODE_OUTPUT ( (CNF_MODE_O_PP << (4 * 0)) \
174 | (CNF_MODE_O_PP << (4 * 1)) \
175 | (CNF_MODE_O_PP << (4 * 2)) \
176 | (CNF_MODE_O_PP << (4 * 3)) \
177 | (CNF_MODE_O_PP << (4 * 4)) \
178 | (CNF_MODE_O_PP << (4 * 5)) \
179 | (CNF_MODE_O_PP << (4 * 6)) \
180 | (CNF_MODE_O_PP << (4 * 7)))
181
182
183/*--------------------------------------------------------------------------*/
184
e64eba00
L
185static void tim16_setup(void)
186{
acd9bdaf
L
187 RCC_APB2RSTR |= RCC_APB2RSTR_TIM16RST;
188 RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM16RST;
e64eba00
L
189
190 TIM16_BDTR = TIM_BDTR_MOE;
191
192 TIM16_CCMR1 = 0
193 | TIM_CCMR1_OC1M_FORCE_LOW
e64eba00
L
194 | TIM_CCMR1_CC1S_OUT;
195
196 TIM16_CCER = TIM_CCER_CC1NE
197 | TIM_CCER_CC1NP;
198
199 TIM16_ARR = 48; /* default */
200 TIM16_CCR1 = 1; /* */
201}
202
203/*--------------------------------------------------------------------------*/
204
acd9bdaf 205static void tim16_set(int mode)
e64eba00
L
206{
207 uint16_t cc_mode;
208
209 cc_mode = TIM_CCMR1_CC1S_OUT;
210
211 TIM16_CR1 = TIM_CR1_OPM;
212
213 if (mode < 0)
214 cc_mode |= TIM_CCMR1_OC1M_FORCE_LOW;
215 else if (mode == 0)
216 cc_mode |= TIM_CCMR1_OC1M_FORCE_HIGH;
217 else {
218 TIM16_ARR = mode;
219 cc_mode |= TIM_CCMR1_OC1M_PWM2;
220 }
221
222 TIM16_CCMR1 = cc_mode;
223
224 if (mode > 0)
225 TIM16_CR1 |= TIM_CR1_CEN;
226}
227
228/*--------------------------------------------------------------------------*/
229
230
231
232/*
233 * A0..A6, A8..A13 are buffered. No need to disable.
234 * A7, A14..A18: set to input.
235 */
236
237static void z80_setup_adrbus_tristate(void)
238{
239#if 0
240 gpio_set_mode(ADunbuff1_PORT, GPIO_MODE_INPUT,
241 GPIO_CNF_INPUT_FLOAT, MASK(ADunbuff1_WIDTH) << ADunbuff1_SHIFT);
242 gpio_set_mode(ADunbuff2_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT,
243 (MASK(ADunbuff2_WIDTH) << ADunbuff2_SHIFT) | (MASK(ADunbuff3_WIDTH) << ADunbuff3_SHIFT));
244#else
245 GPIO_CRH(GPIOA) = (GPIO_CRH(GPIOA) & ~(0x0f << (4 * 0)))
246 | (CNF_MODE_I_F << (4 * 0));
247 GPIO_CRL(GPIOC) = (GPIO_CRL(GPIOC) & ~((0x0f << (4 * 6)) | (0x0f << (4 * 7))))
248 | ((CNF_MODE_I_F << (4 * 6)) | (CNF_MODE_I_F << (4 * 7)));
249 GPIO_CRH(GPIOC) = (GPIO_CRH(GPIOC) & ~((0x0f << (4*2)) | (0x0f << (4*3)) | (0x0f << (4*4))))
250 | ((CNF_MODE_I_F << (4*2)) | (CNF_MODE_I_F << (4*3)) | (CNF_MODE_I_F << (4*4)));
251#endif
252}
253
254
255static void z80_setup_adrbus_active(void)
256{
257#if 0
258 gpio_set_mode(ADunbuff1_PORT, GPIO_MODE_OUTPUT_10_MHZ,
259 GPIO_CNF_OUTPUT_PUSHPULL, MASK(ADunbuff1_WIDTH) << ADunbuff1_SHIFT);
260 gpio_set_mode(ADunbuff2_PORT, GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_PUSHPULL,
261 (MASK(ADunbuff2_WIDTH) << ADunbuff2_SHIFT) | (MASK(ADunbuff3_WIDTH) << ADunbuff3_SHIFT));
262#else
263 GPIO_CRH(GPIOA) = (GPIO_CRH(GPIOA) & ~(0x0f << (4 * 0)))
264 | (CNF_MODE_O_PP << (4 * 0));
265 GPIO_CRL(GPIOC) = (GPIO_CRL(GPIOC) & ~((0x0f << (4 * 6)) | (0x0f << (4 * 7))))
266 | ((CNF_MODE_O_PP << (4 * 6)) | (CNF_MODE_O_PP << (4 * 7)));
267 GPIO_CRH(GPIOC) = (GPIO_CRH(GPIOC) & ~((0x0f << (4*2)) | (0x0f << (4*3)) | (0x0f << (4*4))))
268 | ((CNF_MODE_O_PP << (4*2)) | (CNF_MODE_O_PP << (4*3)) | (CNF_MODE_O_PP << (4*4)));
269#endif
270}
271
272
273static void z80_setup_dbus_in(void)
274{
275 GPIO_CRH(DB_PORT) = DB_MODE_INPUT;
276}
277
278static void z80_setup_dbus_out(void)
279{
280 GPIO_CRH(DB_PORT) = DB_MODE_OUTPUT;
281}
282
283
284static void z80_setaddress(uint32_t addr)
285{
286 GPIO_BSRR(ADp1_PORT) = IOFIELD_SET(addr, ADp1_OFS, ADp1_WIDTH, ADp1_SHIFT);
287 GPIO_BSRR(ADp2_PORT) = IOFIELD_SET(addr, ADp2_OFS, ADp2_WIDTH, ADp2_SHIFT);
288 GPIO_BSRR(ADp3_PORT) = IOFIELD_SET(addr, ADp3_OFS, ADp3_WIDTH, ADp3_SHIFT);
289}
290
291void z80_setup_bus(void)
292{
293 tim16_setup();
acd9bdaf 294
e64eba00
L
295 gpio_set_mode(P_RST, GPIO_MODE_OUTPUT_10_MHZ,
296 GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_RST);
297 Z80_O_BUSREQ = 1;
298 gpio_set_mode(P_BUSREQ, GPIO_MODE_OUTPUT_10_MHZ,
299 GPIO_CNF_OUTPUT_PUSHPULL, GPIO_BUSREQ);
300 Z80_O_NMI = 1;
301 gpio_set_mode(P_NMI, GPIO_MODE_OUTPUT_10_MHZ,
302 GPIO_CNF_OUTPUT_PUSHPULL, GPIO_NMI);
303 Z80_O_ME = 1;
304 Z80_O_RD = 1;
305 Z80_O_WR = 1;
306 gpio_set_mode(P_ME, GPIO_MODE_OUTPUT_2_MHZ,
307 GPIO_CNF_OUTPUT_PUSHPULL, GPIO_ME);
308 gpio_set_mode(P_RD, GPIO_MODE_OUTPUT_10_MHZ,
309 GPIO_CNF_OUTPUT_PUSHPULL, GPIO_RD | GPIO_WR);
310
e64eba00
L
311 //Z80_O_BUSREQ = 0;
312 //while(Z80_I_BUSACK == 1);
313
314 gpio_set_mode(ADp1_PORT, GPIO_MODE_OUTPUT_10_MHZ,
315 GPIO_CNF_OUTPUT_PUSHPULL, MASK(ADp1_WIDTH) << ADp1_SHIFT);
316 gpio_set_mode(ADp2_PORT, GPIO_MODE_OUTPUT_10_MHZ,
317 GPIO_CNF_OUTPUT_PUSHPULL, MASK(ADp2_WIDTH) << ADp2_SHIFT);
318 gpio_set_mode(ADp3_PORT, GPIO_MODE_OUTPUT_10_MHZ,
319 GPIO_CNF_OUTPUT_PUSHPULL, MASK(ADp3_WIDTH) << ADp3_SHIFT);
320
321 z80_setup_dbus_in();
322}
323
acd9bdaf 324void z80_request_bus(void)
e64eba00
L
325{
326 Z80_O_BUSREQ = 0;
327 while(Z80_I_BUSACK == 1);
328 z80_setup_adrbus_active();
329}
330
331void z80_release_bus(void)
332{
333 z80_setup_dbus_in();
334 z80_setup_adrbus_tristate();
335 Z80_O_BUSREQ = 1;
336 while(Z80_I_BUSACK == 0);
337}
338
339void z80_reset(level_t level)
340{
341 int x = level ? -1 : 0;
342
343 tim16_set(x);
344
345// Z80_O_RST = level;
346}
347
348void z80_reset_pulse(void)
349{
350 tim16_set(48);
351}
352
353void z80_busreq(level_t level)
354{
355 Z80_O_BUSREQ = level;
356}
357
358#if 0
359int z80_stat_halt(void)
360{
361 return Z80_I_HALT;
362}
363#endif
364
365void z80_write(uint32_t addr, uint8_t data)
366{
367 z80_setaddress(addr);
368 Z80_O_ME = 0;
369 GPIO_BSRR(DB_PORT) = IOFIELD_SET(data, DB_OFS, DB_WIDTH, DB_SHIFT);
370 z80_setup_dbus_out();
371 Z80_O_WR = 0;
372 Z80_O_WR = 1;
373 Z80_O_ME = 1;
374}
375
376uint8_t z80_read(uint32_t addr)
377{
378 uint8_t data;
379
380 z80_setaddress(addr);
381 Z80_O_ME = 0;
382 z80_setup_dbus_in();
383 Z80_O_RD = 0;
384 Z80_O_RD = 0;
385 data = IOFIELD_GET(GPIO_IDR(DB_PORT),DB_WIDTH, DB_SHIFT);
386 Z80_O_RD = 1;
387 Z80_O_ME = 1;
388
389 return data;
390}
391
392
393void z80_memset(uint32_t addr, uint8_t data, int length)
394{
395 z80_setup_dbus_out();
396 Z80_O_ME = 0;
397 while(length--) {
398 z80_setaddress(addr++);
399 GPIO_BSRR(DB_PORT) = IOFIELD_SET(data, DB_OFS, DB_WIDTH, DB_SHIFT);
400 Z80_O_WR = 0;
401 Z80_O_WR = 1;
402 }
403 Z80_O_ME = 1;
404}
405
406void z80_write_block(uint8_t *src, uint32_t dest, uint32_t length)
407{
408 uint8_t data;
409
410 z80_setup_dbus_out();
411 Z80_O_ME = 0;
412 while(length--) {
413 z80_setaddress(dest++);
414 data = *src++;
415 GPIO_BSRR(DB_PORT) = IOFIELD_SET(data, DB_OFS, DB_WIDTH, DB_SHIFT);
416 Z80_O_WR = 0;
417 Z80_O_WR = 1;
418 }
419 Z80_O_ME = 1;
420}
421
422/*
423 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
424 017A' rx.in_idx: ds 1 ;
425 017B' rx.out_idx: ds 1 ;
426 017C' rx.buf: ds rx.buf_len ;
427 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
428
429 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
430 018D' tx.in_idx: ds 1 ;
431 018E' tx.out_idx: ds 1 ;
432 018F' tx.buf: ds tx.buf_len ;
433 019E' tx.buf_end equ $-1 ; last byte
434*/
435
436#define fifo_bufsize_mask -3
437#define fifo_index_in -2
438#define fifo_index_out -1
439
440#if 1
441
442static struct {
443 uint32_t base;
444 uint8_t idx_out,
445 idx_in,
446 mask;
acd9bdaf 447 } fifo_dsc[2];
e64eba00 448
acd9bdaf 449void z80_memfifo_init(void)
e64eba00 450{
acd9bdaf
L
451 z80_request_bus();
452 fifo_dsc[fifo_in].base = tx_fifo;
453 fifo_dsc[fifo_in].idx_out = z80_read(tx_fifo+fifo_index_out);
454 fifo_dsc[fifo_in].idx_in = z80_read(tx_fifo+fifo_index_in);
455 fifo_dsc[fifo_in].mask = z80_read(tx_fifo+fifo_bufsize_mask);
456
457 fifo_dsc[fifo_out].base = rx_fifo;
458 fifo_dsc[fifo_out].idx_out = z80_read(rx_fifo+fifo_index_out);
459 fifo_dsc[fifo_out].idx_in = z80_read(rx_fifo+fifo_index_in);
460 fifo_dsc[fifo_out].mask = z80_read(rx_fifo+fifo_bufsize_mask);
e64eba00
L
461 z80_release_bus();
462}
463#endif
464
acd9bdaf 465int z80_memfifo_is_empty(fifo_t f)
e64eba00 466{
acd9bdaf 467 uint32_t adr = fifo_dsc[f].base+fifo_index_in;
e64eba00
L
468 uint8_t idx;
469
acd9bdaf 470 z80_request_bus();
e64eba00
L
471 idx = z80_read(adr);
472 z80_release_bus();
473
acd9bdaf 474 return idx == fifo_dsc[f].idx_out;
e64eba00
L
475}
476
acd9bdaf 477int z80_memfifo_is_full(fifo_t f)
e64eba00
L
478{
479 int rc;
480
acd9bdaf
L
481 z80_request_bus();
482 rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
483 == z80_read(fifo_dsc[f].base+fifo_index_out);
e64eba00
L
484 z80_release_bus();
485
486 return rc;
487}
488
acd9bdaf 489uint8_t z80_memfifo_getc(fifo_t f)
e64eba00
L
490{
491 uint8_t rc, idx;
492
acd9bdaf 493 while (z80_memfifo_is_empty(f))
e64eba00
L
494 ;
495
acd9bdaf
L
496 z80_request_bus();
497 idx = fifo_dsc[f].idx_out;
498 rc = z80_read(fifo_dsc[f].base+idx);
499 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
500 z80_write(fifo_dsc[f].base+fifo_index_out, fifo_dsc[f].idx_out);
e64eba00
L
501 z80_release_bus();
502
503 return rc;
504}
505
506
acd9bdaf 507void z80_memfifo_putc(fifo_t f, uint8_t val)
e64eba00
L
508{
509 int idx;
510
acd9bdaf 511 while (z80_memfifo_is_full(f))
e64eba00
L
512 ;
513
acd9bdaf
L
514 z80_request_bus();
515 idx = fifo_dsc[f].idx_in;
516 z80_write(fifo_dsc[f].base+idx, val);
517 fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
518 z80_write(fifo_dsc[f].base+fifo_index_in, fifo_dsc[f].idx_in);
e64eba00
L
519 z80_release_bus();
520}
521
acd9bdaf
L
522/*--------------------------------------------------------------------------*/
523
524//volatile uint8_t io_infifo[256];
525
526static struct {
527 uint8_t idx_out,
528 idx_in;
529 uint16_t count;
530 uint8_t buf[256];
531 } io_infifo;
532
533/*--------------------------------------------------------------------------*/
534
535static void tim1_setup(void)
536{
537 RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST;
538 RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM1RST;
539
540 TIM1_CR1 = 0;
541
542 TIM1_SMCR = 0
543 /* | TIM_SMCR_ETP */
544 /* | TIM_SMCR_ETF_CK_INT_N_2 */
545 | TIM_SMCR_TS_ETRF
546 | TIM_SMCR_SMS_OFF
547 ;
548
549 TIM1_DIER = TIM_DIER_TDE;
550
551
552 TIM1_CCMR1 = 0
553 | TIM_CCMR1_OC1M_FORCE_LOW
554 | TIM_CCMR1_CC1S_OUT;
555
556 TIM1_SMCR |= TIM_SMCR_SMS_TM;
557}
558
559/*--------------------------------------------------------------------------*/
560
561static void tim1_ch4_setup(void)
562{
563 /* Reset Timer 1 */
564 RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST;
565 RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM1RST;
566
567 TIM1_CCMR2 = 0
568 | TIM_CCMR2_CC4S_IN_TI2
569 | TIM_CCMR2_IC4F_OFF
570 | TIM_CCMR2_IC4PSC_OFF;
571
572 TIM1_CCER = 0
573 /* | TIM_CCER_CC4P */
574 | TIM_CCER_CC4E;
575
576 /* Enable DMA for channel 4 */
577 TIM1_DIER = TIM_DIER_CC4DE;
578}
579
580/*--------------------------------------------------------------------------*/
581
582static void dma1_ch4_setup(void)
583{
584 DMA1_CCR4 =
585 DMA_CCR_PL_VERY_HIGH
586 | DMA_CCR_MSIZE_8BIT
587 | DMA_CCR_PSIZE_8BIT
588 | DMA_CCR_MINC
589 | DMA_CCR_CIRC;
590
591 DMA1_CMAR4 = (uint32_t) io_infifo.buf;
592
593#if (DB_SHIFT == 0) || (DB_SHIFT == 8)
594 DMA1_CPAR4 = DB_PORT + IDR + DB_SHIFT/8;
595#else
596 #error "Databus not byte aligned!"
597#endif
598
599 DMA1_CNDTR4 = io_infifo.count = NELEMS(io_infifo.buf);
600
601 DMA1_CCR4 |= DMA_CCR_EN;
602}
603
604/*--------------------------------------------------------------------------*/
605
606void z80_setup_io_infifo(void)
607{
608 gpio_set_mode(P_BUSACK, GPIO_MODE_INPUT,
609 GPIO_CNF_INPUT_FLOAT, GPIO_BUSACK | GPIO_IOCS1);
610
611 tim1_ch4_setup();
612 dma1_ch4_setup();
613}
614
615
616int z80_io_infifo_getc(void)
e64eba00
L
617{
618 int c = -1;
619
acd9bdaf
L
620 if (io_infifo.count != DMA1_CNDTR4) {
621 c = io_infifo.buf[NELEMS(io_infifo.buf) - io_infifo.count--];
622 if (io_infifo.count == 0)
623 io_infifo.count = NELEMS(io_infifo.buf);
e64eba00
L
624 }
625
626 return c;
627}
628