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