8 #include <libopencmsis/core_cm3.h>
9 #include <libopencm3/cm3/nvic.h>
10 #include <libopencm3/cm3/systick.h>
11 #include <libopencm3/stm32/rtc.h>
12 #include <libopencm3/stm32/usart.h>
13 #include <libopencm3/stm32/rcc.h>
14 #include <libopencm3/stm32/gpio.h>
15 #include <libopencm3/stm32/timer.h>
23 #define __STATIC_INLINE static inline
25 __attribute__((always_inline)) __STATIC_INLINE void __enable_irq(void)
27 __ASM volatile ("cpsie i");
30 __attribute__((always_inline)) __STATIC_INLINE void __disable_irq(void)
32 __ASM volatile ("cpsid i");
41 #define USART_CONSOLE USART1
43 int _write(int fd
, char *ptr
, int len
) __attribute__((used
));
45 #define S_10MS_TO (1<<0)
51 #define LED_PORT GPIOC
52 #define LED_BLUE_PIN GPIO8
54 #define LED_GREEN_PIN GPIO9
58 #define LED_BLUE_ON() BBIO_PERIPH(LED_PORT+ODR, BLUE) = 1
59 #define LED_BLUE_OFF() BBIO_PERIPH(LED_PORT+ODR, BLUE) = 0
60 #define LED_BLUE_TOGGLE() BBIO_PERIPH(LED_PORT+ODR, BLUE) = !BBIO_PERIPH(LED_PORT+ODR, BLUE)
62 #define LED_GREEN_ON() BBIO_PERIPH(LED_PORT+ODR, GREEN) = 1
63 #define LED_GREEN_OFF() BBIO_PERIPH(LED_PORT+ODR, GREEN) = 0
64 #define LED_GREEN_TOGGLE() BBIO_PERIPH(LED_PORT+ODR, GREEN) = !BBIO_PERIPH(LED_PORT+ODR, GREEN)
71 //BBIO_PERIPH(GPIOA+IDR, 0);
73 #define KEY_PORT GPIOA_IDR
78 #define REPEAT_MASK KEY0 // repeat: key0
79 #define REPEAT_START 100 // after 1s
80 #define REPEAT_NEXT 20 // every 200ms
84 NOTHING
, PULSE
, BLINK1
, BLINK2
89 uint8_t ontime
, offtime
;
92 volatile uint8_t led_timer
[2];
93 led_stat_t led_stat
[2];
95 volatile int timeout_1s
;
96 volatile uint32_t Stat
;
99 /*--------------------------------------------------------------------------*/
102 static void clock_setup(void)
104 rcc_clock_setup_in_hse_8mhz_out_24mhz();
106 /* Enable clocks for:
107 GPIO port A (for GPIO_USART1_TX and Button)
112 TODO: USART1 --> USART_CONSOLE
114 rcc_peripheral_enable_clock(&RCC_APB2ENR
,
115 RCC_APB2ENR_IOPAEN
| RCC_APB2ENR_IOPBEN
116 | RCC_APB2ENR_IOPCEN
| RCC_APB2ENR_IOPDEN
117 | RCC_APB2ENR_USART1EN
| RCC_APB2ENR_AFIOEN
118 | RCC_APB2ENR_TIM1EN
| RCC_APB2ENR_TIM16EN
);
119 /* Enable clocks for:
122 rcc_peripheral_enable_clock(&RCC_APB1ENR
,
125 /* Enable clocks for:
128 rcc_peripheral_enable_clock(&RCC_AHBENR
,
132 static void systick_setup(void)
134 /* SysTick interrupt every N clock pulses: set reload to N-1 */
135 STK_RVR
= 24000000/1000 - 1;
137 /* Set source to core clock, enable int and start counting. */
138 STK_CSR
= STK_CSR_CLKSOURCE_AHB
| STK_CSR_TICKINT
| STK_CSR_ENABLE
;
142 static void nvic_setup(void)
144 // nvic_enable_irq(NVIC_RTC_IRQ);
145 // nvic_set_priority(NVIC_RTC_IRQ, 1);
149 static void tim3_setup(void)
151 TIM3_CR1
= TIM_CR1_CMS_EDGE
| TIM_CR1_DIR_UP
;
154 | TIM_CCMR2_OC4M_FORCE_LOW
155 /* | TIM_CCMR2_OC4M_FORCE_HIGH */
156 /* | TIM_CCMR2_OC4M_PWM2 */
158 /* | TIM_CCMR2_OC4PE */
159 /* | TIM_CCMR2_OC4FE */
160 | TIM_CCMR2_CC4S_OUT
;
162 TIM3_CCER
= TIM_CCER_CC4E
165 TIM3_ARR
= 48; /* default */
169 static void gpio_setup(void)
172 /* Disable JTAG-DP, but leave SW-DP Enabled. (free PA15, PB3, PB4)
173 Remap SPI1 to PB3, PB4, PB5 and PA15.
174 Remap TIM3 (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9)
176 gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON
,
177 AFIO_MAPR_SPI1_REMAP
| AFIO_MAPR_TIM3_REMAP_FULL_REMAP
);
179 /* LEDs and User Button. */
180 gpio_set_mode(LED_PORT
, GPIO_MODE_OUTPUT_2_MHZ
,
181 GPIO_CNF_OUTPUT_PUSHPULL
, LED_BLUE_PIN
);
182 gpio_set_mode(LED_PORT
, GPIO_MODE_OUTPUT_10_MHZ
,
183 GPIO_CNF_OUTPUT_ALTFN_PUSHPULL
, LED_GREEN_PIN
);
184 gpio_set_mode(GPIOA
, GPIO_MODE_INPUT
,
185 GPIO_CNF_INPUT_FLOAT
, GPIO0
);
189 static void usart_setup(void)
191 /* Setup GPIO pin GPIO_USART1_TX/LED_GREEN_PIN on GPIO port A for transmit. */
192 /* TODO: USART1 --> USART_CONSOLE */
194 gpio_set_mode(GPIOA
, GPIO_MODE_OUTPUT_50_MHZ
,
195 GPIO_CNF_OUTPUT_ALTFN_PUSHPULL
, GPIO_USART1_TX
);
197 /* Setup UART parameters. */
198 // usart_set_baudrate(USART_CONSOLE, 38400);
199 usart_set_baudrate(USART_CONSOLE
, 115200);
200 usart_set_databits(USART_CONSOLE
, 8);
201 usart_set_stopbits(USART_CONSOLE
, USART_STOPBITS_1
);
202 usart_set_mode(USART_CONSOLE
, USART_MODE_TX_RX
);
203 usart_set_parity(USART_CONSOLE
, USART_PARITY_NONE
);
204 usart_set_flow_control(USART_CONSOLE
, USART_FLOWCONTROL_NONE
);
206 /* Finally enable the USART. */
207 usart_enable(USART_CONSOLE
);
210 /*--------------------------------------------------------------------------*/
213 * Use USART_CONSOLE as a console.
214 * This is a syscall for newlib
220 int _write(int fd
, char *ptr
, int len
)
224 if (fd
== STDOUT_FILENO
|| fd
== STDERR_FILENO
) {
225 for (i
= 0; i
< len
; i
++) {
226 if (ptr
[i
] == '\n') {
227 usart_send_blocking(USART_CONSOLE
, '\r');
229 usart_send_blocking(USART_CONSOLE
, ptr
[i
]);
238 /*--------------------------------------------------------------------------*/
240 void delay_systicks(int ticks
)
242 int start
, stop
, now
;
245 stop
= start
- ticks
;
250 } while ((now
> stop
) || (now
<= start
));
254 } while ((now
> stop
) && (now
<= start
));
259 /*--------------------------------------------------------------------------*/
261 static void led_toggle(uint8_t lednr
) {
268 static void led_on(uint8_t lednr
) {
275 static void led_off(uint8_t lednr
) {
282 static uint8_t led_is_on(uint8_t lednr
) {
284 return BBIO_PERIPH(LED_PORT
+ODR
, BLUE
);
286 return BBIO_PERIPH(LED_PORT
+ODR
, GREEN
);
291 static void ledset(uint8_t lednr
, uint8_t what
, uint8_t len
) {
293 led_stat
[lednr
].mode
= what
;
296 led_stat
[lednr
].ontime
= len
;
297 led_stat
[lednr
].offtime
= 0;
298 led_timer
[lednr
] = len
;
304 led_stat
[lednr
].offtime
= 100 - len
;
306 led_stat
[lednr
].offtime
= 200 - len
;
307 led_stat
[lednr
].ontime
= len
;
308 led_timer
[lednr
] = len
;
316 /*--------------------------------------------------------------------------*/
318 static volatile uint16_t key_state
,
319 key_press
, // key press detect
320 key_rpt
; // key long press and repeat
323 static uint16_t get_key_press(uint16_t key_mask
) {
325 // read and clear atomic !
326 key_mask
&= key_press
; // read key(s)
327 key_press
^= key_mask
; // clear key(s)
332 static uint16_t get_key_rpt(uint16_t key_mask
) {
334 // read and clear atomic !
335 key_mask
&= key_rpt
; // read key(s)
336 key_rpt
^= key_mask
; // clear key(s)
341 static uint16_t get_key_short(uint16_t key_mask
) {
343 // read key state and key press atomic !
344 return get_key_press(key_state
& key_mask
);
348 static uint16_t get_key_long(uint16_t key_mask) {
349 return get_key_press(get_key_rpt(key_mask));
353 static void key_timerproc() {
354 static uint16_t key_in_last
, rpt
;
359 c
= key_in_last
& key_in
& ~key_state
;
361 // key_state = key_state & key_in_last | (key_state | key_in_last) & key_in;
362 // key_state = key_state & key_in | (key_state | key_in) & key_in_last;
364 key_state
= c
| ((key_in_last
| key_in
) & key_state
);
366 // key_state = (key_state&key_in_last) | (key_state&key_in) | (key_in_last&key_in);
370 key_in_last
= key_in
;
373 if ((key_state
& REPEAT_MASK
) == 0) // check repeat function
376 rpt
= REPEAT_NEXT
; // repeat delay
377 key_rpt
|= key_state
& REPEAT_MASK
;
386 ds
[dsi
++] = key_state
& 1 ? '1' : '0';
387 ds
[dsi
++] = key_in_last
& 1 ? '1' : '0';
388 ds
[dsi
++] = key_in
& 1 ? '1' : '0';
391 //ds[dsi++] = key_state & 1 ? '1' : '0';
392 //ds[dsi++] = key_in_last & 1 ? '1' : '0';
402 /*--------------------------------------------------------------------------*/
404 void sys_tick_handler(void)
406 static int tick_10ms
= 0;
407 static int count_ms
= 0;
420 led_timer
[0] = i
- 1;
423 led_timer
[1] = i
- 1;
427 /* Drive timer procedure of low level disk I/O module */
432 if (count_ms
== 1000) {
442 /* The interrupt flag isn't cleared by hardware, we have to do it. */
443 rtc_clear_flag(RTC_SEC
);
447 /*--------------------------------------------------------------------------*/
449 void tim3_set(int mode
)
453 cc_mode
= TIM_CCMR2_CC4S_OUT
;
455 TIM3_CR1
= TIM_CR1_CMS_EDGE
| TIM_CR1_DIR_UP
| TIM_CR1_OPM
;
458 cc_mode
|= TIM_CCMR2_OC4M_FORCE_LOW
;
460 cc_mode
|= TIM_CCMR2_OC4M_FORCE_HIGH
;
463 cc_mode
|= TIM_CCMR2_OC4M_PWM2
;
466 TIM3_CCMR2
= cc_mode
;
469 TIM3_CR1
|= TIM_CR1_CEN
;
472 /*--------------------------------------------------------------------------*/
474 static uint32_t z80_sram_cmp(uint32_t addr
, int length
, uint8_t wval
, int inc
)
479 printf("SRAM: Check %#.5x byte... ", length
); //fflush(stdout);
481 if ((rval
= z80_read(addr
)) != wval
) {
483 printf("\nSRAM: Address W R\n" \
487 printf(" %.5lx %.2x %.2x\n", addr
, wval
, rval
);
501 static void z80_sram_fill(uint32_t addr
, int length
, uint8_t startval
, int inc
)
503 printf("SRAM: Write %#.5x byte... ", length
); //fflush(stdout);
505 z80_write(addr
, startval
);
513 void z80_sram_fill_string(uint32_t addr
, int length
, const char *text
)
516 const char *p
= text
;
519 z80_write(addr
++, c
= *p
++);
526 uint32_t z80_sram_cmp_string(uint32_t addr
, int length
, const char *text
)
529 const char *p
= text
;
533 if (z80_read(addr
) != c
)
542 const char * const qbfox
= "Zhe quick brown fox jumps over the lazy dog!";
543 const char * const qbcat
= "Zhe quick brown fox jumps over the lazy cat!";
547 uint8_t z80_get_byte(uint32_t adr
)
552 data
= z80_read(adr
),
559 /*--------------------------------------------------------------------------*/
561 static void do_10ms(void)
563 for (uint8_t i
= 0; i
< 2; i
++) {
564 switch (led_stat
[i
].mode
) {
566 if (led_timer
[i
] == 0) {
568 led_stat
[i
].mode
= NOTHING
;
573 if (led_timer
[i
] == 0) {
575 led_timer
[i
] = led_stat
[i
].offtime
;
577 led_timer
[i
] = led_stat
[i
].ontime
;
587 /*--------------------------------------------------------------------------*/
591 //uint32_t led_state = LED_BLUE_PIN;
593 //uint8_t startval = 0;
601 setvbuf(stdout
, NULL
, _IONBF
, 0);
603 printf("Hello World!\n");
606 printf("z80_setup_bus done.\n");
609 * If the RTC is pre-configured just allow access, don't reconfigure.
610 * Otherwise enable it with the LSE as clock source and 0x7fff as
613 rtc_auto_awake(LSE
, 0x7fff);
616 ///* Setup the RTC interrupt. */
619 /* Enable the RTC interrupt to occur off the SEC flag. */
620 //rtc_interrupt_enable(RTC_SEC);
622 printf("get bus...");
626 printf(" got it!\n");
628 z80_memset(0, 0x76, 0x80000);
629 //z80_sram_fill(0, 512 * 1024, 0x76, 0);
630 z80_sram_cmp(0, 512 * 1024, 0x76, 0);
632 z80_write_block((unsigned char *) hdrom
, 0, hdrom_length
);
634 printf("bus released! ");
637 printf(" reset released!\n");
642 uint8_t b
, rc
, tc
, m
;
643 if (to
!= timeout_1s
) {
644 b
= z80_get_byte(tx_fifo
-0),
645 rc
= z80_get_byte(tx_fifo
-1),
646 tc
= z80_get_byte(tx_fifo
-2),
647 m
=z80_get_byte(tx_fifo
-3);
648 printf(" %.2x %.2x %.2x %.2x\n",
652 if ((rc
==0) && (m
==0x7f))
659 ledset(0, BLINK1
, 50);
662 // static int tickstat = 0;
664 if (Stat
& S_10MS_TO
) {
670 // if (get_key_long(KEY0))
671 // ledset(1, PULSE, 100);
673 if (get_key_short(KEY0
))
681 if (BBIO_PERIPH(GPIOA+IDR, 0))
693 if (!BBIO_PERIPH(GPIOA+IDR, 0))
698 //BBIO_PERIPH(LED_PORT+0x0C, 9) = BBIO_PERIPH(GPIOA+0x08, 0);
700 //BBIO_PERIPH(LED_PORT+0x0C, 9) = !z80_stat_halt();
702 //BBIO_PERIPH(LED_PORT+0x0C, 9) = (~key_state & KEY0) != 0;
706 stat = z80_fifo_is_not_full(rx_fifo);
708 z80_fifo_putc(rx_fifo, 'y');
709 if (++count == 154) {
718 stat
= usart_get_flag(USART_CONSOLE
, USART_SR_RXNE
);
720 c
= usart_recv(USART_CONSOLE
) & 0xff;
729 tim3_set(24000000/1000000 * 5); /* 5 us */
732 z80_fifo_putc(fifo_out
, c
);
736 if (timeout_1s
== 0) {
738 while (z80_fifo_is_not_empty(fifo_in
)) {
740 c
= z80_fifo_getc(fifo_in
);
748 while ((ch
= z80_inbuf_getc()) >= 0)
749 printf(" 0x%.2X ", ch
);
760 ds
[dsi
++] = key_state1
& 1 ? '1' : '0';
761 ds
[dsi
++] = key_in_last
& 1 ? '1' : '0';
762 ds
[dsi
++] = key_in
& 1 ? '1' : '0';
764 ds
[dsi
++] = key_state1
& 1 ? '1' : '0';
765 ds
[dsi
++] = key_in_last
& 1 ? '1' : '0';
769 ds
[dsi
++] = key_state
& 1 ? '1' : '0';
770 ds
[dsi
++] = ct1
& 1 ? '0' : '1';
771 ds
[dsi
++] = ct0
& 1 ? '0' : '1';
773 ds
[dsi
++] = key_state
& 1 ? '1' : '0';