X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/e64eba003f92992057c5a1c8b5eff902e4ddaaa5..64045ba0916623ab9e7c2f1eed837a2aae081e63:/stm32/z180-stamp-stm32.c diff --git a/stm32/z180-stamp-stm32.c b/stm32/z180-stamp-stm32.c index 6751fe1..96d724c 100644 --- a/stm32/z180-stamp-stm32.c +++ b/stm32/z180-stamp-stm32.c @@ -1,46 +1,27 @@ /* */ -#include -#include -#include #include #include #include #include -#include #include #include #include +#include + #define ODR 0x0c #define IDR 0x08 -/* -#define __ASM __asm -#define __STATIC_INLINE static inline - -__attribute__((always_inline)) __STATIC_INLINE void __enable_irq(void) -{ - __ASM volatile ("cpsie i"); -} - -__attribute__((always_inline)) __STATIC_INLINE void __disable_irq(void) -{ - __ASM volatile ("cpsid i"); -} -*/ - - - +#include "debug.h" +#include "serial.h" #include "z80-if.h" -#include "hdrom.h" - -#define USART_CONSOLE USART1 +#include "../z180/hdrom.h" -int _write(int fd, char *ptr, int len) __attribute__((used)); +#define ESCCHAR ('^'-0x40) #define S_10MS_TO (1<<0) @@ -101,15 +82,15 @@ volatile uint32_t Stat; static void clock_setup(void) { - rcc_clock_setup_in_hse_8mhz_out_24mhz(); + //rcc_clock_setup_in_hse_8mhz_out_24mhz(); + rcc_clock_setup_in_hsi_out_24mhz(); /* Enable clocks for: GPIO port A (for GPIO_USART1_TX and Button) GPIO port C (LEDs) USART1 TIM16 (RST-Pin) - TIM1 (IOE) - TODO: USART1 --> USART_CONSOLE + TIM1 (IOCS1) */ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN @@ -123,7 +104,7 @@ static void clock_setup(void) RCC_APB1ENR_TIM3EN); /* Enable clocks for: - TIM3 + DMA1 */ rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_DMA1EN); @@ -172,9 +153,12 @@ static void gpio_setup(void) /* Disable JTAG-DP, but leave SW-DP Enabled. (free PA15, PB3, PB4) Remap SPI1 to PB3, PB4, PB5 and PA15. Remap TIM3 (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9) + Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON, - AFIO_MAPR_SPI1_REMAP | AFIO_MAPR_TIM3_REMAP_FULL_REMAP); + AFIO_MAPR_SPI1_REMAP + | AFIO_MAPR_TIM3_REMAP_FULL_REMAP + | AFIO_MAPR_PD01_REMAP); /* LEDs and User Button. */ gpio_set_mode(LED_PORT, GPIO_MODE_OUTPUT_2_MHZ, @@ -186,55 +170,6 @@ static void gpio_setup(void) } -static void usart_setup(void) -{ - /* Setup GPIO pin GPIO_USART1_TX/LED_GREEN_PIN on GPIO port A for transmit. */ - /* TODO: USART1 --> USART_CONSOLE */ - - gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, - GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX); - - /* Setup UART parameters. */ -// usart_set_baudrate(USART_CONSOLE, 38400); - usart_set_baudrate(USART_CONSOLE, 115200); - usart_set_databits(USART_CONSOLE, 8); - usart_set_stopbits(USART_CONSOLE, USART_STOPBITS_1); - usart_set_mode(USART_CONSOLE, USART_MODE_TX_RX); - usart_set_parity(USART_CONSOLE, USART_PARITY_NONE); - usart_set_flow_control(USART_CONSOLE, USART_FLOWCONTROL_NONE); - - /* Finally enable the USART. */ - usart_enable(USART_CONSOLE); -} - -/*--------------------------------------------------------------------------*/ - -/** - * Use USART_CONSOLE as a console. - * This is a syscall for newlib - * @param fd - * @param ptr - * @param len - * @return - */ -int _write(int fd, char *ptr, int len) -{ - int i; - - if (fd == STDOUT_FILENO || fd == STDERR_FILENO) { - for (i = 0; i < len; i++) { - if (ptr[i] == '\n') { - usart_send_blocking(USART_CONSOLE, '\r'); - } - usart_send_blocking(USART_CONSOLE, ptr[i]); - } - return i; - } - errno = EIO; - return -1; -} - - /*--------------------------------------------------------------------------*/ void delay_systicks(int ticks) @@ -329,6 +264,7 @@ static uint16_t get_key_press(uint16_t key_mask) { return key_mask; } +/* static uint16_t get_key_rpt(uint16_t key_mask) { __disable_irq(); // read and clear atomic ! @@ -337,6 +273,7 @@ static uint16_t get_key_rpt(uint16_t key_mask) { __enable_irq(); return key_mask; } +*/ static uint16_t get_key_short(uint16_t key_mask) { __disable_irq(); @@ -377,36 +314,16 @@ static void key_timerproc() { key_rpt |= key_state & REPEAT_MASK; } - -#if 0 - -static char ds[30]; -int dsi = 0; - -ds[dsi++] = key_state & 1 ? '1' : '0'; -ds[dsi++] = key_in_last & 1 ? '1' : '0'; -ds[dsi++] = key_in & 1 ? '1' : '0'; -ds[dsi++] = ' '; - -//ds[dsi++] = key_state & 1 ? '1' : '0'; -//ds[dsi++] = key_in_last & 1 ? '1' : '0'; - -//ds[dsi++] = ' '; -//ds[dsi++] = ' '; -ds[dsi++] = 0; -puts(ds); -#endif - } /*--------------------------------------------------------------------------*/ void sys_tick_handler(void) { - static int tick_10ms = 0; - static int count_ms = 0; + static int_fast8_t tick_10ms = 0; + static int_fast16_t count_ms = 0; - int i; + int_fast8_t i; ++tick_10ms; if (tick_10ms == 10) @@ -432,8 +349,9 @@ void sys_tick_handler(void) if (count_ms == 1000) { count_ms = 0; - if (timeout_1s) - --timeout_1s; + i = timeout_1s; + if (i) + timeout_1s = i - 1; } } @@ -452,7 +370,7 @@ void tim3_set(int mode) cc_mode = TIM_CCMR2_CC4S_OUT; - TIM3_CR1 = TIM_CR1_CMS_EDGE | TIM_CR1_DIR_UP | TIM_CR1_OPM; + TIM3_CR1 = TIM_CR1_CMS_EDGE | TIM_CR1_DIR_UP /*| TIM_CR1_OPM */ ; if (mode < 0) cc_mode |= TIM_CCMR2_OC4M_FORCE_LOW; @@ -460,6 +378,7 @@ void tim3_set(int mode) cc_mode |= TIM_CCMR2_OC4M_FORCE_HIGH; else { TIM3_ARR = mode; + TIM3_CCR4 = mode/2; cc_mode |= TIM_CCMR2_OC4M_PWM2; } @@ -471,12 +390,12 @@ void tim3_set(int mode) /*--------------------------------------------------------------------------*/ -static uint32_t z80_sram_cmp(uint32_t addr, int length, uint8_t wval, int inc) +static uint32_t z80_sram_cmp(uint32_t addr, uint32_t length, uint8_t wval, int inc) { uint8_t rval; - int errors = 0; + int_fast8_t errors = 0; - printf("SRAM: Check %#.5x byte... ", length); //fflush(stdout); + DBG_P(1, "SRAM: Check 0x%.5lX byte... ", length); while (length--) { if ((rval = z80_read(addr)) != wval) { if (errors == 0) { @@ -492,7 +411,7 @@ static uint32_t z80_sram_cmp(uint32_t addr, int length, uint8_t wval, int inc) addr++; wval += inc; } - printf("Done.\n"); + DBG_P(1, "Done.\n"); return addr; } @@ -544,11 +463,13 @@ const char * const qbcat = "Zhe quick brown fox jumps over the lazy cat!"; #endif +/*--------------------------------------------------------------------------*/ + uint8_t z80_get_byte(uint32_t adr) { uint8_t data; - z80_get_bus(); + z80_request_bus(); data = z80_read(adr), z80_release_bus(); @@ -560,7 +481,7 @@ uint8_t z80_get_byte(uint32_t adr) static void do_10ms(void) { - for (uint8_t i = 0; i < 2; i++) { + for (uint_fast8_t i = 0; i < 2; i++) { switch (led_stat[i].mode) { case PULSE: if (led_timer[i] == 0) { @@ -584,26 +505,192 @@ static void do_10ms(void) } } +struct msg_item { + uint8_t fct; + uint8_t sub_min, sub_max; + void (*func)(uint8_t, int, uint8_t *); +}; + +static +uint32_t msg_to_addr(uint8_t *msg) +{ + uint32_t addr = msg[0] | (msg[1] << 8) | ((uint32_t)msg[2] << 16); + + return addr; + +} + +static +void do_msg_ini_msgfifo(uint8_t subf, int len, uint8_t * msg) +{ + (void)subf; (void)len; + + z80_init_msg_fifo(msg_to_addr(msg)); +} + + +static +void do_msg_ini_memfifo(uint8_t subf, int len, uint8_t * msg) +{ + (void)len; + + z80_memfifo_init(subf - 1, msg_to_addr(msg)); +} + + +static +void do_msg_char_out(uint8_t subf, int len, uint8_t * msg) +{ + (void)subf; + + while (len--) + putchar(*msg++); +} + + +static +const struct msg_item z80_messages[] = +{ + { 0, /* fct nr. */ + 0, 0, /* sub fct nr. from, to */ + &do_msg_ini_msgfifo}, + { 0, + 1, 2, + &do_msg_ini_memfifo}, + { 1, + 1, 1, + &do_msg_char_out}, + { 0xff, /* end mark */ + 0, 0, + 0}, + +}; + + + + +static +void do_message(int len, uint8_t *msg) +{ + uint8_t fct, sub_fct; + int_fast8_t i = 0; + + if (len >= 2) { + fct = *msg++; + sub_fct = *msg++; + len -= 2; + + while (fct != z80_messages[i].fct) + ++i; + + if (z80_messages[i].fct == 0xff) { + DBG_P(1, "do_message: Unknown function: %i, %i\n", + fct, sub_fct); + return; /* TODO: unknown message # */ + } + + while (fct == z80_messages[i].fct) { + if (sub_fct >= z80_messages[i].sub_min && sub_fct <= z80_messages[i].sub_max ) + break; + ++i; + } + + if (z80_messages[i].fct != fct) { + DBG_P(1, "do_message: Unknown sub function: %i, %i\n", + fct, sub_fct); + return; /* TODO: unknown message sub# */ + } + + (z80_messages[i].func)(sub_fct, len, msg); + + + } else { + /* TODO: error */ + DBG_P(1, "do_message: to few arguments (%i); this shouldn't happen!\n", len); + } +} + + + +#define CTRBUF_LEN 256 + +static +void check_msg_fifo(void) +{ + int ch; + static int_fast8_t state; + static int msglen,idx; + static uint8_t buffer[CTRBUF_LEN]; + + while (state != 3 && (ch = z80_msg_fifo_getc()) >= 0) { + switch (state) { + case 0: /* wait for start of message */ + if (ch == 0x81) { + msglen = 0; + idx = 0; + state = 1; + } + break; + case 1: /* get msg len */ + if (ch > 0 && ch <= CTRBUF_LEN) { + msglen = ch; + state = 2; + } else + state = 0; + break; + case 2: /* get message */ + buffer[idx++] = ch; + if (idx == msglen) + state = 3; + break; + } + } + + if (state == 3) { + do_message(msglen, buffer); + state = 0; + } +} + + +void z80_load_mem(void) +{ + unsigned sec = 0; + uint32_t sec_base = hdrom_start; + + DBG_P(1, "Loading z80 memory... \n"); + + while (sec < hdrom_sections) { + DBG_P(2, " From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n", + hdrom_address[sec], + hdrom_address[sec]+hdrom_length_of_sections[sec] - 1, + hdrom_length_of_sections[sec]); + + z80_write_block((unsigned char *) &hdrom[sec_base], /* src */ + hdrom_address[sec], /* dest */ + hdrom_length_of_sections[sec]); /* len */ + sec_base+=hdrom_length_of_sections[sec]; + sec++; + } +} /*--------------------------------------------------------------------------*/ int main(void) { - //uint32_t led_state = LED_BLUE_PIN; - //uint32_t rc; - //uint8_t startval = 0; - //int count; - int stat, ch; - uint8_t c; + int_fast8_t state = 0; + int ch; clock_setup(); gpio_setup(); tim3_setup(); setvbuf(stdout, NULL, _IONBF, 0); - usart_setup(); - printf("Hello World!\n"); + serial_setup(); + printf("\n(STM32F100+HD64180)_stamp Tester\n"); + DBG_P(1, "z80_setup_bus... "); + z80_setup_msg_fifo(); z80_setup_bus(); - printf("z80_setup_bus done.\n"); + DBG_P(1, "done.\n"); /* * If the RTC is pre-configured just allow access, don't reconfigure. @@ -613,166 +700,74 @@ int main(void) rtc_auto_awake(LSE, 0x7fff); systick_setup(); - ///* Setup the RTC interrupt. */ - //nvic_setup(); - - /* Enable the RTC interrupt to occur off the SEC flag. */ - //rtc_interrupt_enable(RTC_SEC); - printf("get bus..."); + DBG_P(1, "Get bus... "); z80_busreq(LOW); z80_reset(HIGH); - z80_get_bus(); - printf(" got it!\n"); + z80_request_bus(); + DBG_P(1, "got it!\n"); z80_memset(0, 0x76, 0x80000); //z80_sram_fill(0, 512 * 1024, 0x76, 0); - z80_sram_cmp(0, 512 * 1024, 0x76, 0); + z80_sram_cmp(0, (uint32_t)512 * 1024, 0x76, 0); - z80_write_block((unsigned char *) hdrom, 0, hdrom_length); + z80_load_mem(); z80_reset(LOW); - printf("bus released! "); + DBG_P(1, "Bus released!\n"); z80_release_bus(); z80_reset(HIGH); - printf(" reset released!\n"); + DBG_P(1, "Reset released!\n"); - timeout_1s = 6; - while (timeout_1s) { - static int to=0; - uint8_t b, rc, tc, m; - if (to != timeout_1s) { - b = z80_get_byte(tx_fifo-0), - rc = z80_get_byte(tx_fifo-1), - tc = z80_get_byte(tx_fifo-2), - m =z80_get_byte(tx_fifo-3); - printf(" %.2x %.2x %.2x %.2x\n", - b, rc, tc, m); - to = timeout_1s; - - if ((rc==0) && (m==0x7f)) - break; - } - } - - z80_fifo_init(); ledset(0, BLINK1, 50); while (1) { -// static int tickstat = 0; - + if (Stat & S_10MS_TO) { Stat &= ~S_10MS_TO; do_10ms(); } - -// if (get_key_long(KEY0)) -// ledset(1, PULSE, 100); - - if (get_key_short(KEY0)) + if (get_key_short(KEY0)) { z80_reset_pulse(); + } - -/* - switch (tickstat) { - + if ((ch = serial_getc()) >= 0) { + switch (state) { case 0: - if (BBIO_PERIPH(GPIOA+IDR, 0)) - { - tickstat = 1; - - LED_GREEN_ON(); - LED_GREEN_OFF(); - LED_GREEN_ON(); - delay_systicks(12); - LED_GREEN_OFF(); - } + if (ch == ESCCHAR) { + state = 1; + /* TODO: Timer starten */ + } else + z80_memfifo_putc(fifo_out, ch); break; - default: - if (!BBIO_PERIPH(GPIOA+IDR, 0)) - tickstat = 0; - } -*/ + case 1: + switch (ch) { - //BBIO_PERIPH(LED_PORT+0x0C, 9) = BBIO_PERIPH(GPIOA+0x08, 0); - - //BBIO_PERIPH(LED_PORT+0x0C, 9) = !z80_stat_halt(); - - //BBIO_PERIPH(LED_PORT+0x0C, 9) = (~key_state & KEY0) != 0; - - -/* - stat = z80_fifo_is_not_full(rx_fifo); - if(stat) { - z80_fifo_putc(rx_fifo, 'y'); - if (++count == 154) { - putchar('\n'); - putchar('\r'); - count = 0; - } - - } -*/ - - stat = usart_get_flag(USART_CONSOLE, USART_SR_RXNE); - if (stat) { - c = usart_recv(USART_CONSOLE) & 0xff; - switch (c) { - case 'H': + case 'h': /* test: green led on */ tim3_set(-1); break; - case 'L': + case 'l': /* test: green led off */ tim3_set(0); break; - case 'P': - tim3_set(24000000/1000000 * 5); /* 5 us */ + case 'p': /* test: pulse on led pin */ + tim3_set(24000000 / 1000000 * 5); /* 5 us */ break; + case 'r': + z80_reset_pulse(); + break; + + case ESCCHAR: default: - z80_fifo_putc(fifo_out, c); + z80_memfifo_putc(fifo_out, ch); + } + state = 0; + break; } } - if (timeout_1s == 0) { - - while (z80_fifo_is_not_empty(fifo_in)) { -// LED_GREEN_ON(); - c = z80_fifo_getc(fifo_in); - putchar(c); -// LED_GREEN_OFF(); - } - - timeout_1s = 1; - } - - while ((ch = z80_inbuf_getc()) >= 0) - printf(" 0x%.2X ", ch); + check_msg_fifo(); } return 0; } - -#if 0 - -static char ds[30]; -int dsi = 0; - -ds[dsi++] = key_state1 & 1 ? '1' : '0'; -ds[dsi++] = key_in_last & 1 ? '1' : '0'; -ds[dsi++] = key_in & 1 ? '1' : '0'; -ds[dsi++] = ' '; -ds[dsi++] = key_state1 & 1 ? '1' : '0'; -ds[dsi++] = key_in_last & 1 ? '1' : '0'; - -ds[dsi++] = ' '; -ds[dsi++] = ' '; -ds[dsi++] = key_state & 1 ? '1' : '0'; -ds[dsi++] = ct1 & 1 ? '0' : '1'; -ds[dsi++] = ct0 & 1 ? '0' : '1'; -ds[dsi++] = ' '; -ds[dsi++] = key_state & 1 ? '1' : '0'; -//ds[dsi++] = '\r'; -//ds[dsi++] = '\n'; -ds[dsi++] = 0; -puts(ds); -#endif