diff --git a/Library/SPL/stm8s.h b/Library/SPL/stm8s.h index 7bb8a49..a7baaa3 100644 --- a/Library/SPL/stm8s.h +++ b/Library/SPL/stm8s.h @@ -240,6 +240,9 @@ typedef uint8_t u8; typedef enum { FALSE = 0, TRUE = !FALSE } bool; +//#include +//#define TRUE true +//#define FALSE false typedef enum { RESET = 0, SET = !RESET diff --git a/User/bootstrap.c b/User/bootstrap.c new file mode 100644 index 0000000..da8d7d8 --- /dev/null +++ b/User/bootstrap.c @@ -0,0 +1,85 @@ +// +// Created by MightyPork on 2017/02/10. +// + +#include +#include "bootstrap.h" + +/** Global time base */ +volatile uint32_t time_ms; + +/** + * Putchar for printf + * @param c - char to print + */ +void putchar(char c) +{ + while ((UART1->SR & UART1_SR_TXE) == 0); + UART1->DR = (u8)c; +} + +/** + * Init for the chinese STM8 board + * - enable LED + * - enable UART @ 115200 + * - set up UART rx irq + */ +void SimpleInit(void) +{ + // Disable default div/8 HSI prescaller + CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); + + // LED + GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_FAST); + + // UART init & enable IRQ + UART_SimpleInit(UART_BAUD_115200); + UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE); + + // Timebase generation counter + TIM4_UpdateRequestConfig(TIM4_UPDATESOURCE_REGULAR); + TIM4_PrescalerConfig(TIM4_PRESCALER_128, TIM4_PSCRELOADMODE_IMMEDIATE); + TIM4_SetAutoreload(0xFF); + TIM4_ARRPreloadConfig(ENABLE); + TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE); + TIM4_Cmd(ENABLE); + + enableInterrupts(); +} + +/** + * @brief Timer4 Update/Overflow Interrupt routine. + * @param None + * @retval None + */ +INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23) +{ + time_ms++; + TIM4_ClearITPendingBit(TIM4_IT_UPDATE); +} + +/** Delay ms */ +void Delay(uint16_t ms) +{ + uint32_t start = time_ms; + while ((time_ms - start) < ms); +} + +/** + * UART1 RX Interrupt routine. + */ +INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18) +{ + if (UART1->SR & UART1_SR_RXNE) { + UART_HandleRx(UART1->DR); + } +} + +// Comment out if custom rx handler is added +#if 1 +void UART_HandleRx(char c) +{ + // echo + putchar(c); +} +#endif diff --git a/User/bootstrap.h b/User/bootstrap.h new file mode 100644 index 0000000..e579c47 --- /dev/null +++ b/User/bootstrap.h @@ -0,0 +1,58 @@ +// +// Created by MightyPork on 2017/02/10. +// + +#ifndef STM8S_STDINIT_H +#define STM8S_STDINIT_H + +/** Global timebase */ +extern volatile uint32_t time_ms; + +/** Uart IRQ handler */ +void UART1_RX_IRQHandler(void) INTERRUPT(18); + +/** SysTick handler */ +void TIM4_UPD_OVF_IRQHandler(void) INTERRUPT(23); + +/** putchar, used by the SDCC stdlib */ +void putchar(char c); + +/** + * Simple init (UART, LED, timebase) + */ +void SimpleInit(void); + +/** + * Millisecond delay + * + * @param ms - nr of milliseconds + */ +void Delay(uint16_t ms); + +/** + * User UART rx handler + * + * If adding custom handler, comment out the defualt echo impl in bootstrap.c + * + * @param c + */ +extern void UART_HandleRx(char c); + +/** Toggle indicator LED */ +inline void LED_Toggle(void) +{ + GPIOB->ODR ^= GPIO_PIN_5; +} + +/** Set indicator LED */ +inline void LED_Set(bool state) +{ + if (state) { + GPIOB->ODR &= ~GPIO_PIN_5; + } else { + GPIOB->ODR |= GPIO_PIN_5; + } +} + + +#endif //STM8S_DEBUG_H diff --git a/User/main.c b/User/main.c index dc7f1a6..8eae033 100644 --- a/User/main.c +++ b/User/main.c @@ -1,70 +1,17 @@ #include "stm8s.h" -#include - -void Delay(uint16_t nCount) { - uint8_t i; - for (; nCount != 0; nCount--) { - for (i = 255; i != 0; i--) {} - } -} - -void putchar(char c) { - while ((UART1->SR & UART1_SR_TXE) == 0); - UART1->DR = (u8)c; -} - -void puts(const char *ch) { - char c; - while ((c = *ch++) != 0) - putchar(c); -} - -void puts_itoa(int32_t n, unsigned char radix) { - char s[10], i, c; - _ltoa(n, s, radix); - i = 0; - while((c = s[i++]) != 0) { - putchar(c); - } -} +#include +#include "bootstrap.h" void main(void) { - // Disable div8 - CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); - - // LED for blinking - GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_FAST); - - // minimal uart init - UART_SimpleInit(UART_BAUD_115200); - - // irq conf - UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE); - enableInterrupts(); + SimpleInit(); - // Clear screen & print system frequency - puts("\033c\033[?25lClock freq = "); // cls - puts_itoa(CLK_GetClockFreq(), 10); - puts(" Hz"); // cls + // clear screen, hide cursor + printf("\033c\033[?25lClock freq = \033[32m%lu Hz\033[0m\r\n", CLK_GetClockFreq()); - // echo & blinking while (1) { - Delay(2000); - GPIOB->ODR ^= GPIO_PIN_5; + LED_Toggle(); + printf("Time = %lu ms\r", time_ms); + Delay(500); } } - -/** - * @brief UART1 RX Interrupt routine. - * @param None - * @retval None - */ -INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18) -{ - if (UART1->SR & UART1_SR_RXNE) - UART1->DR = (u8) (UART1->DR); // echo - - if (UART1->SR & UART1_SR_OR) - UART1->SR &= ~UART1_SR_OR; // clear OR flag -}