6 #include <libopencmsis/core_cm3.h>
7 #include <libopencm3/cm3/nvic.h>
8 #include <libopencm3/cm3/systick.h>
9 #include <libopencm3/stm32/rtc.h>
10 #include <libopencm3/stm32/rcc.h>
11 #include <libopencm3/stm32/gpio.h>
12 #include <libopencm3/stm32/timer.h>
21 #include "../z180/hdrom.h"
23 #define ESCCHAR ('^'-0x40)
25 #define S_10MS_TO (1<<0)
31 #define LED_PORT GPIOC
32 #define LED_BLUE_PIN GPIO8
34 #define LED_GREEN_PIN GPIO9
38 #define LED_BLUE_ON() BBIO_PERIPH(LED_PORT+ODR, BLUE) = 1
39 #define LED_BLUE_OFF() BBIO_PERIPH(LED_PORT+ODR, BLUE) = 0
40 #define LED_BLUE_TOGGLE() BBIO_PERIPH(LED_PORT+ODR, BLUE) = !BBIO_PERIPH(LED_PORT+ODR, BLUE)
42 #define LED_GREEN_ON() BBIO_PERIPH(LED_PORT+ODR, GREEN) = 1
43 #define LED_GREEN_OFF() BBIO_PERIPH(LED_PORT+ODR, GREEN) = 0
44 #define LED_GREEN_TOGGLE() BBIO_PERIPH(LED_PORT+ODR, GREEN) = !BBIO_PERIPH(LED_PORT+ODR, GREEN)
51 //BBIO_PERIPH(GPIOA+IDR, 0);
53 #define KEY_PORT GPIOA_IDR
58 #define REPEAT_MASK KEY0 // repeat: key0
59 #define REPEAT_START 100 // after 1s
60 #define REPEAT_NEXT 20 // every 200ms
64 NOTHING
, PULSE
, BLINK1
, BLINK2
69 uint8_t ontime
, offtime
;
72 volatile uint8_t led_timer
[2];
73 led_stat_t led_stat
[2];
75 volatile int timeout_1s
;
76 volatile uint32_t Stat
;
79 /*--------------------------------------------------------------------------*/
82 static void clock_setup(void)
84 //rcc_clock_setup_in_hse_8mhz_out_24mhz();
85 rcc_clock_setup_in_hsi_out_24mhz();
88 GPIO port A (for GPIO_USART1_TX and Button)
94 rcc_peripheral_enable_clock(&RCC_APB2ENR
,
95 RCC_APB2ENR_IOPAEN
| RCC_APB2ENR_IOPBEN
96 | RCC_APB2ENR_IOPCEN
| RCC_APB2ENR_IOPDEN
97 | RCC_APB2ENR_USART1EN
| RCC_APB2ENR_AFIOEN
98 | RCC_APB2ENR_TIM1EN
| RCC_APB2ENR_TIM16EN
);
102 rcc_peripheral_enable_clock(&RCC_APB1ENR
,
105 /* Enable clocks for:
108 rcc_peripheral_enable_clock(&RCC_AHBENR
,
112 static void systick_setup(void)
114 /* SysTick interrupt every N clock pulses: set reload to N-1 */
115 STK_RVR
= 24000000/1000 - 1;
117 /* Set source to core clock, enable int and start counting. */
118 STK_CSR
= STK_CSR_CLKSOURCE_AHB
| STK_CSR_TICKINT
| STK_CSR_ENABLE
;
122 static void nvic_setup(void)
124 // nvic_enable_irq(NVIC_RTC_IRQ);
125 // nvic_set_priority(NVIC_RTC_IRQ, 1);
129 static void tim3_setup(void)
131 TIM3_CR1
= TIM_CR1_CMS_EDGE
| TIM_CR1_DIR_UP
;
134 | TIM_CCMR2_OC4M_FORCE_LOW
135 /* | TIM_CCMR2_OC4M_FORCE_HIGH */
136 /* | TIM_CCMR2_OC4M_PWM2 */
138 /* | TIM_CCMR2_OC4PE */
139 /* | TIM_CCMR2_OC4FE */
140 | TIM_CCMR2_CC4S_OUT
;
142 TIM3_CCER
= TIM_CCER_CC4E
145 TIM3_ARR
= 48; /* default */
149 static void gpio_setup(void)
152 /* Disable JTAG-DP, but leave SW-DP Enabled. (free PA15, PB3, PB4)
153 Remap SPI1 to PB3, PB4, PB5 and PA15.
154 Remap TIM3 (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9)
155 Port D0/Port D1 mapping on OSC_IN/OSC_OUT
157 gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON
,
159 | AFIO_MAPR_TIM3_REMAP_FULL_REMAP
160 | AFIO_MAPR_PD01_REMAP
);
162 /* LEDs and User Button. */
163 gpio_set_mode(LED_PORT
, GPIO_MODE_OUTPUT_2_MHZ
,
164 GPIO_CNF_OUTPUT_PUSHPULL
, LED_BLUE_PIN
);
165 gpio_set_mode(LED_PORT
, GPIO_MODE_OUTPUT_10_MHZ
,
166 GPIO_CNF_OUTPUT_ALTFN_PUSHPULL
, LED_GREEN_PIN
);
167 gpio_set_mode(GPIOA
, GPIO_MODE_INPUT
,
168 GPIO_CNF_INPUT_FLOAT
, GPIO0
);
172 /*--------------------------------------------------------------------------*/
174 void delay_systicks(int ticks
)
176 int start
, stop
, now
;
179 stop
= start
- ticks
;
184 } while ((now
> stop
) || (now
<= start
));
188 } while ((now
> stop
) && (now
<= start
));
193 /*--------------------------------------------------------------------------*/
195 static void led_toggle(uint8_t lednr
) {
202 static void led_on(uint8_t lednr
) {
209 static void led_off(uint8_t lednr
) {
216 static uint8_t led_is_on(uint8_t lednr
) {
218 return BBIO_PERIPH(LED_PORT
+ODR
, BLUE
);
220 return BBIO_PERIPH(LED_PORT
+ODR
, GREEN
);
225 static void ledset(uint8_t lednr
, uint8_t what
, uint8_t len
) {
227 led_stat
[lednr
].mode
= what
;
230 led_stat
[lednr
].ontime
= len
;
231 led_stat
[lednr
].offtime
= 0;
232 led_timer
[lednr
] = len
;
238 led_stat
[lednr
].offtime
= 100 - len
;
240 led_stat
[lednr
].offtime
= 200 - len
;
241 led_stat
[lednr
].ontime
= len
;
242 led_timer
[lednr
] = len
;
250 /*--------------------------------------------------------------------------*/
252 static volatile uint16_t key_state
,
253 key_press
, // key press detect
254 key_rpt
; // key long press and repeat
257 static uint16_t get_key_press(uint16_t key_mask
) {
259 // read and clear atomic !
260 key_mask
&= key_press
; // read key(s)
261 key_press
^= key_mask
; // clear key(s)
267 static uint16_t get_key_rpt(uint16_t key_mask) {
269 // read and clear atomic !
270 key_mask &= key_rpt; // read key(s)
271 key_rpt ^= key_mask; // clear key(s)
277 static uint16_t get_key_short(uint16_t key_mask
) {
279 // read key state and key press atomic !
280 return get_key_press(key_state
& key_mask
);
284 static uint16_t get_key_long(uint16_t key_mask) {
285 return get_key_press(get_key_rpt(key_mask));
289 static void key_timerproc() {
290 static uint16_t key_in_last
, rpt
;
295 c
= key_in_last
& key_in
& ~key_state
;
297 // key_state = key_state & key_in_last | (key_state | key_in_last) & key_in;
298 // key_state = key_state & key_in | (key_state | key_in) & key_in_last;
300 key_state
= c
| ((key_in_last
| key_in
) & key_state
);
302 // key_state = (key_state&key_in_last) | (key_state&key_in) | (key_in_last&key_in);
306 key_in_last
= key_in
;
309 if ((key_state
& REPEAT_MASK
) == 0) // check repeat function
312 rpt
= REPEAT_NEXT
; // repeat delay
313 key_rpt
|= key_state
& REPEAT_MASK
;
318 /*--------------------------------------------------------------------------*/
320 void sys_tick_handler(void)
322 static int tick_10ms
= 0;
323 static int count_ms
= 0;
336 led_timer
[0] = i
- 1;
339 led_timer
[1] = i
- 1;
343 /* Drive timer procedure of low level disk I/O module */
348 if (count_ms
== 1000) {
359 /* The interrupt flag isn't cleared by hardware, we have to do it. */
360 rtc_clear_flag(RTC_SEC
);
364 /*--------------------------------------------------------------------------*/
366 void tim3_set(int mode
)
370 cc_mode
= TIM_CCMR2_CC4S_OUT
;
372 TIM3_CR1
= TIM_CR1_CMS_EDGE
| TIM_CR1_DIR_UP
/*| TIM_CR1_OPM */ ;
375 cc_mode
|= TIM_CCMR2_OC4M_FORCE_LOW
;
377 cc_mode
|= TIM_CCMR2_OC4M_FORCE_HIGH
;
381 cc_mode
|= TIM_CCMR2_OC4M_PWM2
;
384 TIM3_CCMR2
= cc_mode
;
387 TIM3_CR1
|= TIM_CR1_CEN
;
390 /*--------------------------------------------------------------------------*/
392 static uint32_t z80_sram_cmp(uint32_t addr
, int length
, uint8_t wval
, int inc
)
397 DBG_P(1, "SRAM: Check %#.5x byte... ", length
);
399 if ((rval
= z80_read(addr
)) != wval
) {
401 printf("\nSRAM: Address W R\n" \
405 printf(" %.5lx %.2x %.2x\n", addr
, wval
, rval
);
419 static void z80_sram_fill(uint32_t addr
, int length
, uint8_t startval
, int inc
)
421 printf("SRAM: Write %#.5x byte... ", length
); //fflush(stdout);
423 z80_write(addr
, startval
);
431 void z80_sram_fill_string(uint32_t addr
, int length
, const char *text
)
434 const char *p
= text
;
437 z80_write(addr
++, c
= *p
++);
444 uint32_t z80_sram_cmp_string(uint32_t addr
, int length
, const char *text
)
447 const char *p
= text
;
451 if (z80_read(addr
) != c
)
460 const char * const qbfox
= "Zhe quick brown fox jumps over the lazy dog!";
461 const char * const qbcat
= "Zhe quick brown fox jumps over the lazy cat!";
465 uint8_t z80_get_byte(uint32_t adr
)
470 data
= z80_read(adr
),
477 /*--------------------------------------------------------------------------*/
479 static void do_10ms(void)
481 for (uint_fast8_t i
= 0; i
< 2; i
++) {
482 switch (led_stat
[i
].mode
) {
484 if (led_timer
[i
] == 0) {
486 led_stat
[i
].mode
= NOTHING
;
491 if (led_timer
[i
] == 0) {
493 led_timer
[i
] = led_stat
[i
].offtime
;
495 led_timer
[i
] = led_stat
[i
].ontime
;
507 uint8_t sub_min
, sub_max
;
508 void (*func
)(uint8_t, int, uint8_t *);
511 uint32_t msg_to_addr(uint8_t *msg
)
513 uint32_t addr
= msg
[0] + (msg
[1] << 8) + (msg
[2] << 16);
519 void do_msg_ini_msgfifo(uint8_t subf
, int len
, uint8_t * msg
)
521 (void)subf
; (void)len
;
523 z80_init_msg_fifo(msg_to_addr(msg
));
527 void do_msg_ini_memfifo(uint8_t subf
, int len
, uint8_t * msg
)
531 z80_memfifo_init(subf
- 1, msg_to_addr(msg
));
535 void do_msg_char_out(uint8_t subf
, int len
, uint8_t * msg
)
544 const struct msg_item z80_messages
[] =
548 &do_msg_ini_msgfifo
},
551 &do_msg_ini_memfifo
},
555 { 0xff, /* end mark */
564 void do_message(int len
, uint8_t *msg
)
566 uint8_t fct
, sub_fct
;
574 while (fct
!= z80_messages
[i
].fct
)
577 if (z80_messages
[i
].fct
== 0xff) {
578 DBG_P(1, "do_message: Unknown function: %i, %i\n",
580 return; /* TODO: unknown message # */
583 while (fct
== z80_messages
[i
].fct
) {
584 if (sub_fct
>= z80_messages
[i
].sub_min
&& sub_fct
<= z80_messages
[i
].sub_max
)
589 if (z80_messages
[i
].fct
!= fct
) {
590 DBG_P(1, "do_message: Unknown sub function: %i, %i\n",
592 return; /* TODO: unknown message sub# */
595 (z80_messages
[i
].func
)(sub_fct
, len
, msg
);
600 DBG_P(1, "do_message: to few arguments (%i); this shouldn't happen!\n", len
);
606 #define CTRBUF_LEN 256
608 void check_msg_fifo(void)
612 static int msglen
,idx
;
613 static uint8_t buffer
[CTRBUF_LEN
];
615 while (state
!= 3 && (ch
= z80_msg_fifo_getc()) >= 0) {
617 case 0: /* wait for start of message */
624 case 1: /* get msg len */
625 if (ch
> 0 && ch
<= CTRBUF_LEN
) {
631 case 2: /* get message */
640 do_message(msglen
, buffer
);
646 void z80_load_mem(void)
649 DBG_P(1, "Loading z80 memory... \n");
652 uint32_t sec_base
= hdrom_start
;
654 while (sec
< hdrom_sections
) {
655 DBG_P(2, " From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n",
657 hdrom_address
[sec
]+hdrom_length_of_sections
[sec
] - 1,
658 hdrom_length_of_sections
[sec
]);
660 z80_write_block((unsigned char *) &hdrom
[sec_base
], /* src */
661 hdrom_address
[sec
], /* dest */
662 hdrom_length_of_sections
[sec
]); /* len */
663 sec_base
+=hdrom_length_of_sections
[sec
];
667 /*--------------------------------------------------------------------------*/
671 //uint32_t led_state = LED_BLUE_PIN;
673 //uint8_t startval = 0;
681 setvbuf(stdout
, NULL
, _IONBF
, 0);
683 printf("\n(STM32F100+HD64180)_stamp Tester\n");
685 DBG_P(1, "z80_setup_bus... ");
686 z80_setup_msg_fifo();
691 * If the RTC is pre-configured just allow access, don't reconfigure.
692 * Otherwise enable it with the LSE as clock source and 0x7fff as
695 rtc_auto_awake(LSE
, 0x7fff);
699 DBG_P(1, "Get bus... ");
703 DBG_P(1, "got it!\n");
705 z80_memset(0, 0x76, 0x80000);
706 //z80_sram_fill(0, 512 * 1024, 0x76, 0);
707 z80_sram_cmp(0, 512 * 1024, 0x76, 0);
711 DBG_P(1, "Bus released!\n");
714 DBG_P(1, "Reset released!\n");
717 ledset(0, BLINK1
, 50);
721 if (Stat
& S_10MS_TO
) {
726 if (get_key_short(KEY0
)) {
730 if ((ch
= serial_getc()) >= 0) {
735 /* TODO: Timer starten */
737 z80_memfifo_putc(fifo_out
, ch
);
742 case 'h': /* test: green led on */
745 case 'l': /* test: green led off */
748 case 'p': /* test: pulse on led pin */
749 tim3_set(24000000 / 1000000 * 5); /* 5 us */
757 z80_memfifo_putc(fifo_out
, ch
);