2 * (C) Copyright 2014 Leo C. <erbl259-lmu@yahoo.de>
4 * SPDX-License-Identifier: GPL-2.0+
9 #include <libopencmsis/core_cm3.h>
10 #include <libopencm3/cm3/nvic.h>
11 #include <libopencm3/cm3/systick.h>
12 #include <libopencm3/stm32/rtc.h>
13 #include <libopencm3/stm32/rcc.h>
14 #include <libopencm3/stm32/gpio.h>
15 #include <libopencm3/stm32/timer.h>
24 #include "../z180/hdrom.h"
26 #define ESCCHAR ('^'-0x40)
28 #define S_10MS_TO (1<<0)
34 #define LED_PORT GPIOC
35 #define LED_BLUE_PIN GPIO8
37 #define LED_GREEN_PIN GPIO9
41 #define LED_BLUE_ON() BBIO_PERIPH(LED_PORT+ODR, BLUE) = 1
42 #define LED_BLUE_OFF() BBIO_PERIPH(LED_PORT+ODR, BLUE) = 0
43 #define LED_BLUE_TOGGLE() BBIO_PERIPH(LED_PORT+ODR, BLUE) = !BBIO_PERIPH(LED_PORT+ODR, BLUE)
45 #define LED_GREEN_ON() BBIO_PERIPH(LED_PORT+ODR, GREEN) = 1
46 #define LED_GREEN_OFF() BBIO_PERIPH(LED_PORT+ODR, GREEN) = 0
47 #define LED_GREEN_TOGGLE() BBIO_PERIPH(LED_PORT+ODR, GREEN) = !BBIO_PERIPH(LED_PORT+ODR, GREEN)
54 //BBIO_PERIPH(GPIOA+IDR, 0);
56 #define KEY_PORT GPIOA_IDR
61 #define REPEAT_MASK KEY0 // repeat: key0
62 #define REPEAT_START 100 // after 1s
63 #define REPEAT_NEXT 20 // every 200ms
67 NOTHING
, PULSE
, BLINK1
, BLINK2
72 uint8_t ontime
, offtime
;
75 volatile uint8_t led_timer
[2];
76 led_stat_t led_stat
[2];
78 volatile int timeout_1s
;
79 volatile uint32_t Stat
;
82 /*--------------------------------------------------------------------------*/
85 static void clock_setup(void)
87 //rcc_clock_setup_in_hse_8mhz_out_24mhz();
88 rcc_clock_setup_in_hsi_out_24mhz();
91 GPIO port A (for GPIO_USART1_TX and Button)
97 rcc_peripheral_enable_clock(&RCC_APB2ENR
,
98 RCC_APB2ENR_IOPAEN
| RCC_APB2ENR_IOPBEN
99 | RCC_APB2ENR_IOPCEN
| RCC_APB2ENR_IOPDEN
100 | RCC_APB2ENR_USART1EN
| RCC_APB2ENR_AFIOEN
101 | RCC_APB2ENR_TIM1EN
| RCC_APB2ENR_TIM16EN
);
102 /* Enable clocks for:
105 rcc_peripheral_enable_clock(&RCC_APB1ENR
,
108 /* Enable clocks for:
111 rcc_peripheral_enable_clock(&RCC_AHBENR
,
115 static void systick_setup(void)
117 /* SysTick interrupt every N clock pulses: set reload to N-1 */
118 STK_RVR
= 24000000/1000 - 1;
120 /* Set source to core clock, enable int and start counting. */
121 STK_CSR
= STK_CSR_CLKSOURCE_AHB
| STK_CSR_TICKINT
| STK_CSR_ENABLE
;
125 static void nvic_setup(void)
127 // nvic_enable_irq(NVIC_RTC_IRQ);
128 // nvic_set_priority(NVIC_RTC_IRQ, 1);
132 static void tim3_setup(void)
134 TIM3_CR1
= TIM_CR1_CMS_EDGE
| TIM_CR1_DIR_UP
;
137 | TIM_CCMR2_OC4M_FORCE_LOW
138 /* | TIM_CCMR2_OC4M_FORCE_HIGH */
139 /* | TIM_CCMR2_OC4M_PWM2 */
141 /* | TIM_CCMR2_OC4PE */
142 /* | TIM_CCMR2_OC4FE */
143 | TIM_CCMR2_CC4S_OUT
;
145 TIM3_CCER
= TIM_CCER_CC4E
148 TIM3_ARR
= 48; /* default */
152 static void gpio_setup(void)
155 /* Disable JTAG-DP, but leave SW-DP Enabled. (free PA15, PB3, PB4)
156 Remap SPI1 to PB3, PB4, PB5 and PA15.
157 Remap TIM3 (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9)
158 Port D0/Port D1 mapping on OSC_IN/OSC_OUT
160 gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON
,
162 | AFIO_MAPR_TIM3_REMAP_FULL_REMAP
163 | AFIO_MAPR_PD01_REMAP
);
165 /* LEDs and User Button. */
166 gpio_set_mode(LED_PORT
, GPIO_MODE_OUTPUT_2_MHZ
,
167 GPIO_CNF_OUTPUT_PUSHPULL
, LED_BLUE_PIN
);
168 gpio_set_mode(LED_PORT
, GPIO_MODE_OUTPUT_10_MHZ
,
169 GPIO_CNF_OUTPUT_ALTFN_PUSHPULL
, LED_GREEN_PIN
);
170 gpio_set_mode(GPIOA
, GPIO_MODE_INPUT
,
171 GPIO_CNF_INPUT_FLOAT
, GPIO0
);
175 /*--------------------------------------------------------------------------*/
177 void delay_systicks(int ticks
)
179 int start
, stop
, now
;
182 stop
= start
- ticks
;
187 } while ((now
> stop
) || (now
<= start
));
191 } while ((now
> stop
) && (now
<= start
));
196 /*--------------------------------------------------------------------------*/
198 static void led_toggle(uint8_t lednr
) {
205 static void led_on(uint8_t lednr
) {
212 static void led_off(uint8_t lednr
) {
219 static uint8_t led_is_on(uint8_t lednr
) {
221 return BBIO_PERIPH(LED_PORT
+ODR
, BLUE
);
223 return BBIO_PERIPH(LED_PORT
+ODR
, GREEN
);
228 static void ledset(uint8_t lednr
, uint8_t what
, uint8_t len
) {
230 led_stat
[lednr
].mode
= what
;
233 led_stat
[lednr
].ontime
= len
;
234 led_stat
[lednr
].offtime
= 0;
235 led_timer
[lednr
] = len
;
241 led_stat
[lednr
].offtime
= 100 - len
;
243 led_stat
[lednr
].offtime
= 200 - len
;
244 led_stat
[lednr
].ontime
= len
;
245 led_timer
[lednr
] = len
;
253 /*--------------------------------------------------------------------------*/
255 static volatile uint16_t key_state
,
256 key_press
, // key press detect
257 key_rpt
; // key long press and repeat
260 static uint16_t get_key_press(uint16_t key_mask
) {
262 // read and clear atomic !
263 key_mask
&= key_press
; // read key(s)
264 key_press
^= key_mask
; // clear key(s)
270 static uint16_t get_key_rpt(uint16_t key_mask) {
272 // read and clear atomic !
273 key_mask &= key_rpt; // read key(s)
274 key_rpt ^= key_mask; // clear key(s)
280 static uint16_t get_key_short(uint16_t key_mask
) {
282 // read key state and key press atomic !
283 return get_key_press(key_state
& key_mask
);
287 static uint16_t get_key_long(uint16_t key_mask) {
288 return get_key_press(get_key_rpt(key_mask));
292 static void key_timerproc() {
293 static uint16_t key_in_last
, rpt
;
298 c
= key_in_last
& key_in
& ~key_state
;
300 // key_state = key_state & key_in_last | (key_state | key_in_last) & key_in;
301 // key_state = key_state & key_in | (key_state | key_in) & key_in_last;
303 key_state
= c
| ((key_in_last
| key_in
) & key_state
);
305 // key_state = (key_state&key_in_last) | (key_state&key_in) | (key_in_last&key_in);
309 key_in_last
= key_in
;
312 if ((key_state
& REPEAT_MASK
) == 0) // check repeat function
315 rpt
= REPEAT_NEXT
; // repeat delay
316 key_rpt
|= key_state
& REPEAT_MASK
;
321 /*--------------------------------------------------------------------------*/
323 void sys_tick_handler(void)
325 static int_fast8_t tick_10ms
= 0;
326 static int_fast16_t count_ms
= 0;
339 led_timer
[0] = i
- 1;
342 led_timer
[1] = i
- 1;
346 /* Drive timer procedure of low level disk I/O module */
351 if (count_ms
== 1000) {
362 /* The interrupt flag isn't cleared by hardware, we have to do it. */
363 rtc_clear_flag(RTC_SEC
);
367 /*--------------------------------------------------------------------------*/
369 void tim3_set(int mode
)
373 cc_mode
= TIM_CCMR2_CC4S_OUT
;
375 TIM3_CR1
= TIM_CR1_CMS_EDGE
| TIM_CR1_DIR_UP
/*| TIM_CR1_OPM */ ;
378 cc_mode
|= TIM_CCMR2_OC4M_FORCE_LOW
;
380 cc_mode
|= TIM_CCMR2_OC4M_FORCE_HIGH
;
384 cc_mode
|= TIM_CCMR2_OC4M_PWM2
;
387 TIM3_CCMR2
= cc_mode
;
390 TIM3_CR1
|= TIM_CR1_CEN
;
393 /*--------------------------------------------------------------------------*/
395 static uint32_t z80_sram_cmp(uint32_t addr
, uint32_t length
, uint8_t wval
, int inc
)
398 int_fast8_t errors
= 0;
400 DBG_P(1, "SRAM: Check %#.5x byte... ", length
);
402 if ((rval
= z80_read(addr
)) != wval
) {
404 printf("\nSRAM: Address W R\n" \
408 printf(" %.5lx %.2x %.2x\n", addr
, wval
, rval
);
422 static void z80_sram_fill(uint32_t addr
, int length
, uint8_t startval
, int inc
)
424 printf("SRAM: Write %#.5x byte... ", length
); //fflush(stdout);
426 z80_write(addr
, startval
);
434 void z80_sram_fill_string(uint32_t addr
, int length
, const char *text
)
437 const char *p
= text
;
440 z80_write(addr
++, c
= *p
++);
447 uint32_t z80_sram_cmp_string(uint32_t addr
, int length
, const char *text
)
450 const char *p
= text
;
454 if (z80_read(addr
) != c
)
463 const char * const qbfox
= "Zhe quick brown fox jumps over the lazy dog!";
464 const char * const qbcat
= "Zhe quick brown fox jumps over the lazy cat!";
468 uint8_t z80_get_byte(uint32_t adr
)
473 data
= z80_read(adr
),
480 /*--------------------------------------------------------------------------*/
482 static void do_10ms(void)
484 for (uint_fast8_t i
= 0; i
< 2; i
++) {
485 switch (led_stat
[i
].mode
) {
487 if (led_timer
[i
] == 0) {
489 led_stat
[i
].mode
= NOTHING
;
494 if (led_timer
[i
] == 0) {
496 led_timer
[i
] = led_stat
[i
].offtime
;
498 led_timer
[i
] = led_stat
[i
].ontime
;
510 uint8_t sub_min
, sub_max
;
511 void (*func
)(uint8_t, int, uint8_t *);
514 uint32_t msg_to_addr(uint8_t *msg
)
516 uint32_t addr
= msg
[0] | (msg
[1] << 8) | ((uint32_t)msg
[2] << 16);
522 void do_msg_ini_msgfifo(uint8_t subf
, int len
, uint8_t * msg
)
524 (void)subf
; (void)len
;
526 z80_init_msg_fifo(msg_to_addr(msg
));
530 void do_msg_ini_memfifo(uint8_t subf
, int len
, uint8_t * msg
)
534 z80_memfifo_init(subf
- 1, msg_to_addr(msg
));
538 void do_msg_char_out(uint8_t subf
, int len
, uint8_t * msg
)
547 const struct msg_item z80_messages
[] =
550 0, 0, /* sub fct nr. from, to */
551 &do_msg_ini_msgfifo
},
554 &do_msg_ini_memfifo
},
558 { 0xff, /* end mark */
567 void do_message(int len
, uint8_t *msg
)
569 uint8_t fct
, sub_fct
;
577 while (fct
!= z80_messages
[i
].fct
)
580 if (z80_messages
[i
].fct
== 0xff) {
581 DBG_P(1, "do_message: Unknown function: %i, %i\n",
583 return; /* TODO: unknown message # */
586 while (fct
== z80_messages
[i
].fct
) {
587 if (sub_fct
>= z80_messages
[i
].sub_min
&& sub_fct
<= z80_messages
[i
].sub_max
)
592 if (z80_messages
[i
].fct
!= fct
) {
593 DBG_P(1, "do_message: Unknown sub function: %i, %i\n",
595 return; /* TODO: unknown message sub# */
598 (z80_messages
[i
].func
)(sub_fct
, len
, msg
);
603 DBG_P(1, "do_message: to few arguments (%i); this shouldn't happen!\n", len
);
609 #define CTRBUF_LEN 256
611 void check_msg_fifo(void)
614 static int_fast8_t state
;
615 static int msglen
,idx
;
616 static uint8_t buffer
[CTRBUF_LEN
];
618 while (state
!= 3 && (ch
= z80_msg_fifo_getc()) >= 0) {
620 case 0: /* wait for start of message */
627 case 1: /* get msg len */
628 if (ch
> 0 && ch
<= CTRBUF_LEN
) {
634 case 2: /* get message */
643 do_message(msglen
, buffer
);
649 void z80_load_mem(void)
652 uint32_t sec_base
= hdrom_start
;
654 DBG_P(1, "Loading z80 memory... \n");
656 while (sec
< hdrom_sections
) {
657 DBG_P(2, " From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n",
659 hdrom_address
[sec
]+hdrom_length_of_sections
[sec
] - 1,
660 hdrom_length_of_sections
[sec
]);
662 z80_write_block((unsigned char *) &hdrom
[sec_base
], /* src */
663 hdrom_address
[sec
], /* dest */
664 hdrom_length_of_sections
[sec
]); /* len */
665 sec_base
+=hdrom_length_of_sections
[sec
];
669 /*--------------------------------------------------------------------------*/
673 int_fast8_t state
= 0;
679 setvbuf(stdout
, NULL
, _IONBF
, 0);
681 printf("\n(STM32F100+HD64180)_stamp Tester\n");
683 DBG_P(1, "z80_setup_bus... ");
684 z80_setup_msg_fifo();
689 * If the RTC is pre-configured just allow access, don't reconfigure.
690 * Otherwise enable it with the LSE as clock source and 0x7fff as
693 rtc_auto_awake(RCC_LSE
, 0x7fff);
697 DBG_P(1, "Get bus... ");
701 DBG_P(1, "got it!\n");
703 z80_memset(0, 0x76, 0x80000);
704 //z80_sram_fill(0, 512 * 1024, 0x76, 0);
705 z80_sram_cmp(0, (uint32_t)512 * 1024, 0x76, 0);
709 DBG_P(1, "Bus released!\n");
712 DBG_P(1, "Reset released!\n");
715 ledset(0, BLINK1
, 50);
719 if (Stat
& S_10MS_TO
) {
724 if (get_key_short(KEY0
)) {
728 if ((ch
= serial_getc()) >= 0) {
733 /* TODO: Timer starten */
735 z80_memfifo_putc(fifo_out
, ch
);
740 case 'h': /* test: green led on */
743 case 'l': /* test: green led off */
746 case 'p': /* test: pulse on led pin */
747 tim3_set(24000000 / 1000000 * 5); /* 5 us */
755 z80_memfifo_putc(fifo_out
, ch
);