From 406617a2a470021d9412e9280feda0d28bdb653b Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Fri, 4 Feb 2011 20:23:52 +1300 Subject: Import of working source tree. --- src/stm32/platform.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 src/stm32/platform.c (limited to 'src/stm32/platform.c') diff --git a/src/stm32/platform.c b/src/stm32/platform.c new file mode 100644 index 0000000..bdf2b33 --- /dev/null +++ b/src/stm32/platform.c @@ -0,0 +1,179 @@ +/* + * This file is part of the Black Magic Debug project. + * + * Copyright (C) 2011 Black Sphere Technologies Ltd. + * Written by Gareth McMullin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* This file implements the platform specific functions for the STM32 + * implementation. + */ + +#include +#include +#include +#include +#include + +#include "platform.h" + +#include + +uint8_t running_status; +volatile uint32_t timeout_counter; + +jmp_buf fatal_error_jmpbuf; + +void morse(const char *msg, char repeat); +static void morse_update(void); + +int +platform_init(void) +{ +#ifndef LIGHT + rcc_clock_setup_in_hse_8mhz_out_72mhz(); +#else + rcc_clock_setup_in_hsi_out_48mhz(); +#endif + + /* Enable peripherals */ + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USBEN); + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM2EN); + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPDEN); + + /* Setup GPIO ports */ +#ifdef LIGHT + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); + AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON; +#endif + gpio_clear(USB_PU_PORT, USB_PU_PIN); + gpio_set_mode(USB_PU_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, + USB_PU_PIN); + + gpio_set_mode(JTAG_PORT, GPIO_MODE_OUTPUT_10_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, + TMS_PIN | TCK_PIN | TDO_PIN); + + gpio_set_mode(LED_PORT, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, + LED_RUN | LED_IDLE | LED_ERROR); + + /* Setup heartbeat timer */ + systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8); + systick_set_reload(900000); /* Interrupt us at 10 Hz */ + systick_interrupt_enable(); + systick_counter_enable(); + +#ifndef LIGHT + SCB_VTOR = 0x2000; // Relocate interrupt vector table here +#endif + /* Enable IRQs */ + nvic_enable_irq(NVIC_TIM2_IRQ); + + return 0; +} + +void sys_tick_handler(void) +{ + if(running_status) + gpio_toggle(LED_PORT, LED_RUN); + else + gpio_clear(LED_PORT, LED_RUN); + + if(timeout_counter) + timeout_counter--; + + morse_update(); +} + + +/* Morse code patterns and lengths */ +static const struct { + uint16_t code; + uint8_t bits; +} morse_letter[] = { + { 0b00011101, 8}, // 'A' .- + { 0b000101010111, 12}, // 'B' -... + { 0b00010111010111, 14}, // 'C' -.-. + { 0b0001010111, 10}, // 'D' -.. + { 0b0001, 4}, // 'E' . + { 0b000101110101, 12}, // 'F' ..-. + { 0b000101110111, 12}, // 'G' --. + { 0b0001010101, 10}, // 'H' .... + { 0b000101, 6}, // 'I' .. + {0b0001110111011101, 16}, // 'J' .--- + { 0b000111010111, 12}, // 'K' -.- + { 0b000101011101, 12}, // 'L' .-.. + { 0b0001110111, 10}, // 'M' -- + { 0b00010111, 8}, // 'N' -. + { 0b00011101110111, 14}, // 'O' --- + { 0b00010111011101, 14}, // 'P' .--. + {0b0001110101110111, 16}, // 'Q' --.- + { 0b0001011101, 10}, // 'R' .-. + { 0b00010101, 8}, // 'S' ... + { 0b000111, 6}, // 'T' - + { 0b0001110101, 10}, // 'U' ..- + { 0b000111010101, 12}, // 'V' ...- + { 0b000111011101, 12}, // 'W' .-- + { 0b00011101010111, 14}, // 'X' -..- + {0b0001110111010111, 16}, // 'Y' -.-- + { 0b00010101110111, 14}, // 'Z' --.. +}; + + +const char *morse_msg; +static const char * volatile morse_ptr; +static char morse_repeat; + +void morse(const char *msg, char repeat) +{ + morse_msg = morse_ptr = msg; + morse_repeat = repeat; + SET_ERROR_STATE(0); +} + +static void morse_update(void) +{ + static uint16_t code; + static uint8_t bits; + + if(!morse_ptr) return; + + if(!bits) { + char c = *morse_ptr++; + if(!c) { + if(morse_repeat) { + morse_ptr = morse_msg; + c = *morse_ptr++; + } else { + morse_ptr = 0; + return; + } + } + if((c >= 'A') && (c <= 'Z')) { + c -= 'A'; + code = morse_letter[c].code; + bits = morse_letter[c].bits; + } else { + code = 0; bits = 4; + } + } + SET_ERROR_STATE(code & 1); + code >>= 1; bits--; +} + -- cgit v1.2.3