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