From b4e3fab85fcd9f5b1502ec991c81302b910492d3 Mon Sep 17 00:00:00 2001 From: Leo C Date: Tue, 3 Apr 2018 13:43:51 +0200 Subject: Remove STM32 variant (and submodule libopencm3) Make spi_wait() and spi_write() allways inline. --- stm32/z180-stamp-stm32.c | 766 ----------------------------------------------- 1 file changed, 766 deletions(-) delete mode 100644 stm32/z180-stamp-stm32.c (limited to 'stm32/z180-stamp-stm32.c') diff --git a/stm32/z180-stamp-stm32.c b/stm32/z180-stamp-stm32.c deleted file mode 100644 index 888494d..0000000 --- a/stm32/z180-stamp-stm32.c +++ /dev/null @@ -1,766 +0,0 @@ -/* - * (C) Copyright 2014 Leo C. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#define ODR 0x0c -#define IDR 0x08 - - -#include "debug.h" -#include "serial.h" -#include "z80-if.h" -#include "../z180/hdrom.h" - -#define ESCCHAR ('^'-0x40) - -#define S_10MS_TO (1<<0) - -/* - * LED Connections - */ - -#define LED_PORT GPIOC -#define LED_BLUE_PIN GPIO8 -#define BLUE 8 -#define LED_GREEN_PIN GPIO9 -#define GREEN 9 - - -#define LED_BLUE_ON() BBIO_PERIPH(LED_PORT+ODR, BLUE) = 1 -#define LED_BLUE_OFF() BBIO_PERIPH(LED_PORT+ODR, BLUE) = 0 -#define LED_BLUE_TOGGLE() BBIO_PERIPH(LED_PORT+ODR, BLUE) = !BBIO_PERIPH(LED_PORT+ODR, BLUE) - -#define LED_GREEN_ON() BBIO_PERIPH(LED_PORT+ODR, GREEN) = 1 -#define LED_GREEN_OFF() BBIO_PERIPH(LED_PORT+ODR, GREEN) = 0 -#define LED_GREEN_TOGGLE() BBIO_PERIPH(LED_PORT+ODR, GREEN) = !BBIO_PERIPH(LED_PORT+ODR, GREEN) - - -/* - * Button connections - */ - -//BBIO_PERIPH(GPIOA+IDR, 0); - -#define KEY_PORT GPIOA_IDR -#define KEY0 GPIO0 -//#define KEY1 GPIO1 -//#define KEY2 GPIO2 - -#define REPEAT_MASK KEY0 // repeat: key0 -#define REPEAT_START 100 // after 1s -#define REPEAT_NEXT 20 // every 200ms - - -typedef enum { - NOTHING, PULSE, BLINK1, BLINK2 -} LED_MODE; - -typedef struct { - uint8_t mode; - uint8_t ontime, offtime; -} led_stat_t; - -volatile uint8_t led_timer[2]; -led_stat_t led_stat[2]; - -volatile int timeout_1s; -volatile uint32_t Stat; - - -/*--------------------------------------------------------------------------*/ - - -static void clock_setup(void) -{ - //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 (IOCS1) - */ - rcc_peripheral_enable_clock(&RCC_APB2ENR, - RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN - | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN - | RCC_APB2ENR_USART1EN | RCC_APB2ENR_AFIOEN - | RCC_APB2ENR_TIM1EN | RCC_APB2ENR_TIM16EN); - /* Enable clocks for: - TIM3 - */ - rcc_peripheral_enable_clock(&RCC_APB1ENR, - RCC_APB1ENR_TIM3EN); - - /* Enable clocks for: - DMA1 - */ - rcc_peripheral_enable_clock(&RCC_AHBENR, - RCC_AHBENR_DMA1EN); -} - -static void systick_setup(void) -{ - /* SysTick interrupt every N clock pulses: set reload to N-1 */ - STK_RVR = 24000000/1000 - 1; - - /* Set source to core clock, enable int and start counting. */ - STK_CSR = STK_CSR_CLKSOURCE_AHB | STK_CSR_TICKINT | STK_CSR_ENABLE; -} - -#if 0 -static void nvic_setup(void) -{ -// nvic_enable_irq(NVIC_RTC_IRQ); -// nvic_set_priority(NVIC_RTC_IRQ, 1); -} -#endif - -static void tim3_setup(void) -{ - TIM3_CR1 = TIM_CR1_CMS_EDGE | TIM_CR1_DIR_UP; - - TIM3_CCMR2 = 0 - | TIM_CCMR2_OC4M_FORCE_LOW - /* | TIM_CCMR2_OC4M_FORCE_HIGH */ - /* | TIM_CCMR2_OC4M_PWM2 */ - - /* | TIM_CCMR2_OC4PE */ - /* | TIM_CCMR2_OC4FE */ - | TIM_CCMR2_CC4S_OUT; - - TIM3_CCER = TIM_CCER_CC4E - | TIM_CCER_CC4P; - - TIM3_ARR = 48; /* default */ - TIM3_CCR4 = 1; /* */ -} - -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_PD01_REMAP); - - /* LEDs and User Button. */ - gpio_set_mode(LED_PORT, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, LED_BLUE_PIN); - gpio_set_mode(LED_PORT, GPIO_MODE_OUTPUT_10_MHZ, - GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, LED_GREEN_PIN); - gpio_set_mode(GPIOA, GPIO_MODE_INPUT, - GPIO_CNF_INPUT_FLOAT, GPIO0); -} - - -/*--------------------------------------------------------------------------*/ - -void delay_systicks(int ticks) -{ - int start, stop, now; - - start = STK_CVR; - stop = start - ticks; - if (stop < 0) { - stop += STK_RVR; - do { - now = STK_CVR; - } while ((now > stop) || (now <= start)); - } else { - do { - now = STK_CVR; - } while ((now > stop) && (now <= start)); - } -} - - -/*--------------------------------------------------------------------------*/ - -static void led_toggle(uint8_t lednr) { - if (lednr == 0) - LED_BLUE_TOGGLE(); - else if (lednr == 1) - LED_GREEN_TOGGLE(); -} - -static void led_on(uint8_t lednr) { - if (lednr == 0) - LED_BLUE_ON(); - else if (lednr == 1) - LED_GREEN_ON(); -} - -static void led_off(uint8_t lednr) { - if (lednr == 0) - LED_BLUE_OFF(); - else if (lednr == 1) - LED_GREEN_OFF(); -} - -static uint8_t led_is_on(uint8_t lednr) { - if (lednr == 0) - return BBIO_PERIPH(LED_PORT+ODR, BLUE); - else if (lednr == 1) - return BBIO_PERIPH(LED_PORT+ODR, GREEN); - else - return 0; -} - -static void ledset(uint8_t lednr, uint8_t what, uint8_t len) { - - led_stat[lednr].mode = what; - switch (what) { - case PULSE: - led_stat[lednr].ontime = len; - led_stat[lednr].offtime = 0; - led_timer[lednr] = len; - led_on(lednr); - break; - case BLINK1: - case BLINK2: - if (what == BLINK1) - led_stat[lednr].offtime = 100 - len; - else - led_stat[lednr].offtime = 200 - len; - led_stat[lednr].ontime = len; - led_timer[lednr] = len; - led_on(lednr); - break; - default: - break; - } -} - -/*--------------------------------------------------------------------------*/ - -static volatile uint16_t key_state, - key_press, // key press detect - key_rpt; // key long press and repeat - - -static uint16_t get_key_press(uint16_t key_mask) { - __disable_irq(); - // read and clear atomic ! - key_mask &= key_press; // read key(s) - key_press ^= key_mask; // clear key(s) - __enable_irq(); - return key_mask; -} - -/* -static uint16_t get_key_rpt(uint16_t key_mask) { - __disable_irq(); - // read and clear atomic ! - key_mask &= key_rpt; // read key(s) - key_rpt ^= key_mask; // clear key(s) - __enable_irq(); - return key_mask; -} -*/ - -static uint16_t get_key_short(uint16_t key_mask) { - __disable_irq(); - // read key state and key press atomic ! - return get_key_press(key_state & key_mask); -} - -/* -static uint16_t get_key_long(uint16_t key_mask) { - return get_key_press(get_key_rpt(key_mask)); -} -*/ - -static void key_timerproc() { - static uint16_t key_in_last, rpt; - uint16_t key_in, c; - - key_in = KEY_PORT; - - c = key_in_last & key_in & ~key_state; - -// key_state = key_state & key_in_last | (key_state | key_in_last) & key_in; -// key_state = key_state & key_in | (key_state | key_in) & key_in_last; - - key_state = c | ((key_in_last | key_in) & key_state); - -// key_state = (key_state&key_in_last) | (key_state&key_in) | (key_in_last&key_in); - - key_press |= c; - - key_in_last = key_in; - - - if ((key_state & REPEAT_MASK) == 0) // check repeat function - rpt = REPEAT_START; - if (--rpt == 0) { - rpt = REPEAT_NEXT; // repeat delay - key_rpt |= key_state & REPEAT_MASK; - } - -} - -/*--------------------------------------------------------------------------*/ - -void sys_tick_handler(void) -{ - static int_fast8_t tick_10ms = 0; - static int_fast16_t count_ms = 0; - - int_fast8_t i; - - ++tick_10ms; - if (tick_10ms == 10) - { - Stat |= S_10MS_TO; - - tick_10ms = 0; - - i = led_timer[0]; - if (i) - led_timer[0] = i - 1; - i = led_timer[1]; - if (i) - led_timer[1] = i - 1; - - key_timerproc(); - - /* Drive timer procedure of low level disk I/O module */ - //disk_timerproc(); - } - - count_ms++; - if (count_ms == 1000) { - count_ms = 0; - - i = timeout_1s; - if (i) - timeout_1s = i - 1; - } -} - -void rtc_isr(void) -{ - /* The interrupt flag isn't cleared by hardware, we have to do it. */ - rtc_clear_flag(RTC_SEC); - -} - -/*--------------------------------------------------------------------------*/ - -void tim3_set(int mode) -{ - uint16_t cc_mode; - - cc_mode = TIM_CCMR2_CC4S_OUT; - - TIM3_CR1 = TIM_CR1_CMS_EDGE | TIM_CR1_DIR_UP /*| TIM_CR1_OPM */ ; - - if (mode < 0) - cc_mode |= TIM_CCMR2_OC4M_FORCE_LOW; - else if (mode == 0) - cc_mode |= TIM_CCMR2_OC4M_FORCE_HIGH; - else { - TIM3_ARR = mode; - TIM3_CCR4 = mode/2; - cc_mode |= TIM_CCMR2_OC4M_PWM2; - } - - TIM3_CCMR2 = cc_mode; - - if (mode > 0) - TIM3_CR1 |= TIM_CR1_CEN; -} - -/*--------------------------------------------------------------------------*/ - -static uint32_t z80_sram_cmp(uint32_t addr, uint32_t length, uint8_t wval, int inc) -{ - uint8_t rval; - int_fast8_t errors = 0; - - DBG_P(1, "SRAM: Check %#.5x byte... ", length); - while (length--) { - if ((rval = z80_read(addr)) != wval) { - if (errors == 0) { - printf("\nSRAM: Address W R\n" \ - " -------------\n"); -// 12345 00 11 - } - printf(" %.5lx %.2x %.2x\n", addr, wval, rval); - - if (++errors > 16 ) - break; - } - addr++; - wval += inc; - } - DBG_P(1, "Done.\n"); - - return addr; -} - -#if 0 -static void z80_sram_fill(uint32_t addr, int length, uint8_t startval, int inc) -{ - printf("SRAM: Write %#.5x byte... ", length); //fflush(stdout); - while (length--) { - z80_write(addr, startval); - ++addr; - startval += inc; - } - printf("Done.\n"); -} - - -void z80_sram_fill_string(uint32_t addr, int length, const char *text) -{ - char c; - const char *p = text; - - while (length--) { - z80_write(addr++, c = *p++); - if (c == 0) - p = text; - } -} - - -uint32_t z80_sram_cmp_string(uint32_t addr, int length, const char *text) -{ - char c; - const char *p = text; - - while (length--) { - c = *p++; - if (z80_read(addr) != c) - break; - ++addr; - if (c == 0) - p = text; - } - return addr; -} - -const char * const qbfox = "Zhe quick brown fox jumps over the lazy dog!"; -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_request_bus(); - data = z80_read(adr), - z80_release_bus(); - - return data; -} - - -/*--------------------------------------------------------------------------*/ - -static void do_10ms(void) -{ - for (uint_fast8_t i = 0; i < 2; i++) { - switch (led_stat[i].mode) { - case PULSE: - if (led_timer[i] == 0) { - led_off(i); - led_stat[i].mode = NOTHING; - } - break; - case BLINK1: - case BLINK2: - if (led_timer[i] == 0) { - if (led_is_on(i)) - led_timer[i] = led_stat[i].offtime; - else - led_timer[i] = led_stat[i].ontime; - led_toggle(i); - } - break; - default: - break; - } - } -} - -struct msg_item { - uint8_t fct; - uint8_t sub_min, sub_max; - void (*func)(uint8_t, int, uint8_t *); -}; - -uint32_t msg_to_addr(uint8_t *msg) -{ - uint32_t addr = msg[0] | (msg[1] << 8) | ((uint32_t)msg[2] << 16); - - return addr; - -} - -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)); -} - - -void do_msg_ini_memfifo(uint8_t subf, int len, uint8_t * msg) -{ - (void)len; - - z80_memfifo_init(subf - 1, msg_to_addr(msg)); -} - - -void do_msg_char_out(uint8_t subf, int len, uint8_t * msg) -{ - (void)subf; - - while (len--) - putchar(*msg++); -} - - -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}, - -}; - - - - -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 - -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) -{ - int_fast8_t state = 0; - int ch; - - clock_setup(); - gpio_setup(); - tim3_setup(); - setvbuf(stdout, NULL, _IONBF, 0); - serial_setup(); - printf("\n(STM32F100+HD64180)_stamp Tester\n"); - - DBG_P(1, "z80_setup_bus... "); - z80_setup_msg_fifo(); - z80_setup_bus(); - DBG_P(1, "done.\n"); - - /* - * If the RTC is pre-configured just allow access, don't reconfigure. - * Otherwise enable it with the LSE as clock source and 0x7fff as - * prescale value. - */ - rtc_auto_awake(RCC_LSE, 0x7fff); - - systick_setup(); - - DBG_P(1, "Get bus... "); - z80_busreq(LOW); - z80_reset(HIGH); - 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, (uint32_t)512 * 1024, 0x76, 0); - - z80_load_mem(); - z80_reset(LOW); - DBG_P(1, "Bus released!\n"); - z80_release_bus(); - z80_reset(HIGH); - DBG_P(1, "Reset released!\n"); - - - ledset(0, BLINK1, 50); - - while (1) { - - if (Stat & S_10MS_TO) { - Stat &= ~S_10MS_TO; - do_10ms(); - } - - if (get_key_short(KEY0)) { - z80_reset_pulse(); - } - - if ((ch = serial_getc()) >= 0) { - switch (state) { - case 0: - if (ch == ESCCHAR) { - state = 1; - /* TODO: Timer starten */ - } else - z80_memfifo_putc(fifo_out, ch); - break; - case 1: - switch (ch) { - - case 'h': /* test: green led on */ - tim3_set(-1); - break; - case 'l': /* test: green led off */ - tim3_set(0); - break; - 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_memfifo_putc(fifo_out, ch); - } - state = 0; - break; - } - } - - check_msg_fifo(); - } - - return 0; -} -- cgit v1.2.3