]> cloudbase.mooo.com Git - z180-stamp.git/blob - stm32/z80-if.c
a8083c8ca5fa9d5eccca97490bc442da8cca1036
[z180-stamp.git] / stm32 / z80-if.c
1 /*
2
3 PC14 af1 OSC32
4 PC15 " "
5 PA9 af1 USART1_TX
6 PA10 af1 USART1_RX
7
8
9 JTDO remap PB3, SPI1_SCK'
10 NJTRST remap PB4, SPI1_MISO'
11 PB5 remap SPI1_MOSI'
12 JTDI remap PA15, SPI1_NSS'
13
14 AFIO_MAPR2 =
15 AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON (frees
16 AFIO_MAPR_SPI1_REMAP
17
18 */
19
20 #include <libopencm3/stm32/gpio.h>
21 #include <libopencm3/stm32/rcc.h>
22 #include <libopencm3/stm32/timer.h>
23 #include <libopencm3/stm32/dma.h>
24 #include "z80-if.h"
25
26 /* Number of array elements */
27 #define NELEMS(x) (sizeof x/sizeof *x)
28
29 #define ODR 0x0c
30 #define IDR 0x08
31
32 #define CONCAT(x,y) x ## y
33 #define EVALUATOR(x,y) CONCAT(x,y)
34
35 #define GPIO_(X) CONCAT(GPIO, X)
36
37 /*
38
39 A0 A 1 P O
40 A1 A 2 P O
41 A2 A 3 P O
42 A3 A 4 P O
43 A4 A 5 P O
44 A5 A 6 P O
45 A6 A 7 P O
46 A7 A 8 O
47 A8 C 0 P O
48 A9 C 1 P O
49 A10 C 2 P O
50 A11 C 3 P O
51 A12 C 4 P O
52 A13 C 5 P O
53 A14 C 6 O
54 A15 C 7 O
55 A16 C 10 O
56 A17 C 11 O
57 A18 C 12 O
58
59 D0 B 8 I/O
60 D1 B 9 I/O
61 D2 B 10 I/O
62 D3 B 11 I/O
63 D4 B 12 I/O
64 D5 B 13 I/O
65 D6 B 14 I/O
66 D7 B 15 I/O
67
68 ME C 13 P O
69 RD B 0 P O
70 WR B 1 P O
71
72 BUSREQ D 2 O
73 BUSACK A 11 I
74 // HALT A 12 I
75 IOE A 12 I TIM1_ETR
76 NMI B 7 O
77 RST B 6 O TIM16_CH1N
78
79 */
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
90 #define BUSACK 11
91 //#define P_HALT GPIOA
92 //#define HALT 12
93 #define P_IOE GPIOA
94 #define IOE 12
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)
138 #define GPIO_IOE GPIO_(IOE)
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
185 volatile uint8_t z80_inbuf[256];
186 static uint32_t inbuf_ndt;
187
188 /*--------------------------------------------------------------------------*/
189
190 #define TIM16_BDTR TIM_BDTR(TIM16)
191
192 static void tim16_setup(void)
193 {
194 RCC_APB2RSTR |= (1<<17);
195 RCC_APB2RSTR &= ~(1<<17);
196
197 TIM16_BDTR = TIM_BDTR_MOE;
198
199 TIM16_CCMR1 = 0
200 | TIM_CCMR1_OC1M_FORCE_LOW
201 /* | TIM_CCMR1_OC1M_FORCE_HIGH */
202 /* | TIM_CCMR1_OC1M_PWM2 */
203
204 /* | TIM_CCMR1_OC1PE */
205 /* | TIM_CCMR1_OC1FE */
206 | TIM_CCMR1_CC1S_OUT;
207
208 TIM16_CCER = TIM_CCER_CC1NE
209 | TIM_CCER_CC1NP;
210
211 TIM16_ARR = 48; /* default */
212 TIM16_CCR1 = 1; /* */
213 }
214
215 /*--------------------------------------------------------------------------*/
216
217 static void tim1_setup(void)
218 {
219 RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST;
220 RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM1RST;
221
222 TIM1_CR1 = 0;
223
224 TIM1_SMCR = 0
225 /* | TIM_SMCR_ETP */
226 /* | TIM_SMCR_ETF_CK_INT_N_2 */
227 | TIM_SMCR_TS_ETRF
228 | TIM_SMCR_SMS_OFF
229 ;
230
231 TIM1_DIER = TIM_DIER_TDE;
232
233
234 TIM1_CCMR1 = 0
235 | TIM_CCMR1_OC1M_FORCE_LOW
236 /* | TIM_CCMR1_OC1M_FORCE_HIGH */
237 /* | TIM_CCMR1_OC1M_PWM2 */
238
239 /* | TIM_CCMR1_OC1PE */
240 /* | TIM_CCMR1_OC1FE */
241 | TIM_CCMR1_CC1S_OUT;
242
243 TIM1_SMCR |= TIM_SMCR_SMS_TM;
244 /* | TIM_SMCR_SMS_ECM1 */
245 }
246
247 /*--------------------------------------------------------------------------*/
248
249 static void dma4_setup(void)
250 {
251 DMA1_CCR4 =
252 DMA_CCR_PL_VERY_HIGH
253 | DMA_CCR_MSIZE_8BIT
254 | DMA_CCR_PSIZE_8BIT
255 | DMA_CCR_MINC
256 | DMA_CCR_CIRC;
257
258 DMA1_CMAR4 = (uint32_t) &z80_inbuf[0];
259
260 #if (DB_SHIFT == 0) || (DB_SHIFT == 8)
261 DMA1_CPAR4 = DB_PORT + IDR + DB_SHIFT/8;
262 #else
263 #error "Databus not byte aligned!"
264 #endif
265
266 DMA1_CNDTR4 = inbuf_ndt = NELEMS(z80_inbuf);
267
268 DMA1_CCR4 |= DMA_CCR_EN;
269 }
270
271 /*--------------------------------------------------------------------------*/
272
273 void tim16_set(int mode)
274 {
275 uint16_t cc_mode;
276
277 cc_mode = TIM_CCMR1_CC1S_OUT;
278
279 TIM16_CR1 = TIM_CR1_OPM;
280
281 if (mode < 0)
282 cc_mode |= TIM_CCMR1_OC1M_FORCE_LOW;
283 else if (mode == 0)
284 cc_mode |= TIM_CCMR1_OC1M_FORCE_HIGH;
285 else {
286 TIM16_ARR = mode;
287 cc_mode |= TIM_CCMR1_OC1M_PWM2;
288 }
289
290 TIM16_CCMR1 = cc_mode;
291
292 if (mode > 0)
293 TIM16_CR1 |= TIM_CR1_CEN;
294 }
295
296 /*--------------------------------------------------------------------------*/
297
298
299
300 /*
301 * A0..A6, A8..A13 are buffered. No need to disable.
302 * A7, A14..A18: set to input.
303 */
304
305 static void z80_setup_adrbus_tristate(void)
306 {
307 #if 0
308 gpio_set_mode(ADunbuff1_PORT, GPIO_MODE_INPUT,
309 GPIO_CNF_INPUT_FLOAT, MASK(ADunbuff1_WIDTH) << ADunbuff1_SHIFT);
310 gpio_set_mode(ADunbuff2_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT,
311 (MASK(ADunbuff2_WIDTH) << ADunbuff2_SHIFT) | (MASK(ADunbuff3_WIDTH) << ADunbuff3_SHIFT));
312 #else
313 GPIO_CRH(GPIOA) = (GPIO_CRH(GPIOA) & ~(0x0f << (4 * 0)))
314 | (CNF_MODE_I_F << (4 * 0));
315 GPIO_CRL(GPIOC) = (GPIO_CRL(GPIOC) & ~((0x0f << (4 * 6)) | (0x0f << (4 * 7))))
316 | ((CNF_MODE_I_F << (4 * 6)) | (CNF_MODE_I_F << (4 * 7)));
317 GPIO_CRH(GPIOC) = (GPIO_CRH(GPIOC) & ~((0x0f << (4*2)) | (0x0f << (4*3)) | (0x0f << (4*4))))
318 | ((CNF_MODE_I_F << (4*2)) | (CNF_MODE_I_F << (4*3)) | (CNF_MODE_I_F << (4*4)));
319 #endif
320 }
321
322
323 static void z80_setup_adrbus_active(void)
324 {
325 #if 0
326 gpio_set_mode(ADunbuff1_PORT, GPIO_MODE_OUTPUT_10_MHZ,
327 GPIO_CNF_OUTPUT_PUSHPULL, MASK(ADunbuff1_WIDTH) << ADunbuff1_SHIFT);
328 gpio_set_mode(ADunbuff2_PORT, GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_PUSHPULL,
329 (MASK(ADunbuff2_WIDTH) << ADunbuff2_SHIFT) | (MASK(ADunbuff3_WIDTH) << ADunbuff3_SHIFT));
330 #else
331 GPIO_CRH(GPIOA) = (GPIO_CRH(GPIOA) & ~(0x0f << (4 * 0)))
332 | (CNF_MODE_O_PP << (4 * 0));
333 GPIO_CRL(GPIOC) = (GPIO_CRL(GPIOC) & ~((0x0f << (4 * 6)) | (0x0f << (4 * 7))))
334 | ((CNF_MODE_O_PP << (4 * 6)) | (CNF_MODE_O_PP << (4 * 7)));
335 GPIO_CRH(GPIOC) = (GPIO_CRH(GPIOC) & ~((0x0f << (4*2)) | (0x0f << (4*3)) | (0x0f << (4*4))))
336 | ((CNF_MODE_O_PP << (4*2)) | (CNF_MODE_O_PP << (4*3)) | (CNF_MODE_O_PP << (4*4)));
337 #endif
338 }
339
340
341 static void z80_setup_dbus_in(void)
342 {
343 GPIO_CRH(DB_PORT) = DB_MODE_INPUT;
344 }
345
346 static void z80_setup_dbus_out(void)
347 {
348 GPIO_CRH(DB_PORT) = DB_MODE_OUTPUT;
349 }
350
351
352 static void z80_setaddress(uint32_t addr)
353 {
354 GPIO_BSRR(ADp1_PORT) = IOFIELD_SET(addr, ADp1_OFS, ADp1_WIDTH, ADp1_SHIFT);
355 GPIO_BSRR(ADp2_PORT) = IOFIELD_SET(addr, ADp2_OFS, ADp2_WIDTH, ADp2_SHIFT);
356 GPIO_BSRR(ADp3_PORT) = IOFIELD_SET(addr, ADp3_OFS, ADp3_WIDTH, ADp3_SHIFT);
357 }
358
359 void z80_setup_bus(void)
360 {
361 tim16_setup();
362 tim1_setup();
363 dma4_setup();
364
365 gpio_set_mode(P_RST, GPIO_MODE_OUTPUT_10_MHZ,
366 GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_RST);
367 Z80_O_BUSREQ = 1;
368 gpio_set_mode(P_BUSREQ, GPIO_MODE_OUTPUT_10_MHZ,
369 GPIO_CNF_OUTPUT_PUSHPULL, GPIO_BUSREQ);
370 Z80_O_NMI = 1;
371 gpio_set_mode(P_NMI, GPIO_MODE_OUTPUT_10_MHZ,
372 GPIO_CNF_OUTPUT_PUSHPULL, GPIO_NMI);
373 Z80_O_ME = 1;
374 Z80_O_RD = 1;
375 Z80_O_WR = 1;
376 gpio_set_mode(P_ME, GPIO_MODE_OUTPUT_2_MHZ,
377 GPIO_CNF_OUTPUT_PUSHPULL, GPIO_ME);
378 gpio_set_mode(P_RD, GPIO_MODE_OUTPUT_10_MHZ,
379 GPIO_CNF_OUTPUT_PUSHPULL, GPIO_RD | GPIO_WR);
380
381 gpio_set_mode(P_BUSACK, GPIO_MODE_INPUT,
382 GPIO_CNF_INPUT_FLOAT, GPIO_BUSACK | GPIO_IOE);
383
384 //Z80_O_BUSREQ = 0;
385 //while(Z80_I_BUSACK == 1);
386
387 gpio_set_mode(ADp1_PORT, GPIO_MODE_OUTPUT_10_MHZ,
388 GPIO_CNF_OUTPUT_PUSHPULL, MASK(ADp1_WIDTH) << ADp1_SHIFT);
389 gpio_set_mode(ADp2_PORT, GPIO_MODE_OUTPUT_10_MHZ,
390 GPIO_CNF_OUTPUT_PUSHPULL, MASK(ADp2_WIDTH) << ADp2_SHIFT);
391 gpio_set_mode(ADp3_PORT, GPIO_MODE_OUTPUT_10_MHZ,
392 GPIO_CNF_OUTPUT_PUSHPULL, MASK(ADp3_WIDTH) << ADp3_SHIFT);
393
394 z80_setup_dbus_in();
395 }
396
397 void z80_get_bus(void)
398 {
399 Z80_O_BUSREQ = 0;
400 while(Z80_I_BUSACK == 1);
401 z80_setup_adrbus_active();
402 }
403
404 void z80_release_bus(void)
405 {
406 z80_setup_dbus_in();
407 z80_setup_adrbus_tristate();
408 Z80_O_BUSREQ = 1;
409 while(Z80_I_BUSACK == 0);
410 }
411
412 void z80_reset(level_t level)
413 {
414 int x = level ? -1 : 0;
415
416 tim16_set(x);
417
418 // Z80_O_RST = level;
419 }
420
421 void z80_reset_pulse(void)
422 {
423 tim16_set(48);
424 }
425
426 void z80_busreq(level_t level)
427 {
428 Z80_O_BUSREQ = level;
429 }
430
431 #if 0
432 int z80_stat_halt(void)
433 {
434 return Z80_I_HALT;
435 }
436 #endif
437
438 void z80_write(uint32_t addr, uint8_t data)
439 {
440 z80_setaddress(addr);
441 Z80_O_ME = 0;
442 GPIO_BSRR(DB_PORT) = IOFIELD_SET(data, DB_OFS, DB_WIDTH, DB_SHIFT);
443 z80_setup_dbus_out();
444 Z80_O_WR = 0;
445 Z80_O_WR = 1;
446 Z80_O_ME = 1;
447 }
448
449 uint8_t z80_read(uint32_t addr)
450 {
451 uint8_t data;
452
453 z80_setaddress(addr);
454 Z80_O_ME = 0;
455 z80_setup_dbus_in();
456 Z80_O_RD = 0;
457 Z80_O_RD = 0;
458 data = IOFIELD_GET(GPIO_IDR(DB_PORT),DB_WIDTH, DB_SHIFT);
459 Z80_O_RD = 1;
460 Z80_O_ME = 1;
461
462 return data;
463 }
464
465
466 void z80_memset(uint32_t addr, uint8_t data, int length)
467 {
468 z80_setup_dbus_out();
469 Z80_O_ME = 0;
470 while(length--) {
471 z80_setaddress(addr++);
472 GPIO_BSRR(DB_PORT) = IOFIELD_SET(data, DB_OFS, DB_WIDTH, DB_SHIFT);
473 Z80_O_WR = 0;
474 Z80_O_WR = 1;
475 }
476 Z80_O_ME = 1;
477 }
478
479 void z80_write_block(uint8_t *src, uint32_t dest, uint32_t length)
480 {
481 uint8_t data;
482
483 z80_setup_dbus_out();
484 Z80_O_ME = 0;
485 while(length--) {
486 z80_setaddress(dest++);
487 data = *src++;
488 GPIO_BSRR(DB_PORT) = IOFIELD_SET(data, DB_OFS, DB_WIDTH, DB_SHIFT);
489 Z80_O_WR = 0;
490 Z80_O_WR = 1;
491 }
492 Z80_O_ME = 1;
493 }
494
495 /*
496 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
497 017A' rx.in_idx: ds 1 ;
498 017B' rx.out_idx: ds 1 ;
499 017C' rx.buf: ds rx.buf_len ;
500 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
501
502 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
503 018D' tx.in_idx: ds 1 ;
504 018E' tx.out_idx: ds 1 ;
505 018F' tx.buf: ds tx.buf_len ;
506 019E' tx.buf_end equ $-1 ; last byte
507 */
508
509 #define fifo_bufsize_mask -3
510 #define fifo_index_in -2
511 #define fifo_index_out -1
512
513 #if 1
514
515 static struct {
516 uint32_t base;
517 uint8_t idx_out,
518 idx_in,
519 mask;
520 } fifos[2];
521
522 void z80_fifo_init(void)
523 {
524 z80_get_bus();
525 fifos[fifo_in].base = tx_fifo;
526 fifos[fifo_in].idx_out = z80_read(tx_fifo+fifo_index_out);
527 fifos[fifo_in].idx_in = z80_read(tx_fifo+fifo_index_in);
528 fifos[fifo_in].mask = z80_read(tx_fifo+fifo_bufsize_mask);
529
530 fifos[fifo_out].base = rx_fifo;
531 fifos[fifo_out].idx_out = z80_read(rx_fifo+fifo_index_out);
532 fifos[fifo_out].idx_in = z80_read(rx_fifo+fifo_index_in);
533 fifos[fifo_out].mask = z80_read(rx_fifo+fifo_bufsize_mask);
534 z80_release_bus();
535 }
536 #endif
537
538 int z80_fifo_is_not_empty(fifo_t f)
539 {
540 uint32_t adr = fifos[f].base+fifo_index_in;
541 uint8_t idx;
542
543 z80_get_bus();
544 idx = z80_read(adr);
545 z80_release_bus();
546
547 return idx != fifos[f].idx_out;
548 }
549
550 int z80_fifo_is_not_full(fifo_t f)
551 {
552 int rc;
553
554 z80_get_bus();
555 rc = ((fifos[f].idx_in + 1) & fifos[f].mask)
556 != z80_read(fifos[f].base+fifo_index_out);
557 z80_release_bus();
558
559 return rc;
560 }
561
562 uint8_t z80_fifo_getc(fifo_t f)
563 {
564 uint8_t rc, idx;
565
566 while (!z80_fifo_is_not_empty(f))
567 ;
568
569 z80_get_bus();
570 idx = fifos[f].idx_out;
571 rc = z80_read(fifos[f].base+idx);
572 fifos[f].idx_out = ++idx & fifos[f].mask;
573 z80_write(fifos[f].base+fifo_index_out, fifos[f].idx_out);
574 z80_release_bus();
575
576 return rc;
577 }
578
579
580 void z80_fifo_putc(fifo_t f, uint8_t val)
581 {
582 int idx;
583
584 while (!z80_fifo_is_not_full(f))
585 ;
586
587 z80_get_bus();
588 idx = fifos[f].idx_in;
589 z80_write(fifos[f].base+idx, val);
590 fifos[f].idx_in = ++idx & fifos[f].mask;
591 z80_write(fifos[f].base+fifo_index_in, fifos[f].idx_in);
592 z80_release_bus();
593 }
594
595 int z80_inbuf_getc(void)
596 {
597 int c = -1;
598
599 if (inbuf_ndt != DMA1_CNDTR4) {
600 c = z80_inbuf[NELEMS(z80_inbuf) - inbuf_ndt--];
601 if (inbuf_ndt == 0)
602 inbuf_ndt = NELEMS(z80_inbuf);
603 }
604
605 return c;
606 }
607