From 9894dd2c3a530cf89e5f8011b88a5c18be836e1b Mon Sep 17 00:00:00 2001 From: arighi Date: Wed, 12 May 2010 12:15:36 +0000 Subject: [PATCH] STM32: add basic kdebug support. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@3661 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cpu/cortex-m3/drv/kdebug_cm3.c | 2 + bertos/cpu/cortex-m3/drv/kdebug_stm32.c | 195 ++++++++++++++++++++++++ bertos/cpu/cortex-m3/drv/kdebug_stm32.h | 53 +++++++ bertos/cpu/cortex-m3/drv/timer_cm3.h | 2 +- bertos/cpu/cortex-m3/io/stm32_memmap.h | 2 +- examples/stm32p103/cfg/cfg_debug.h | 2 +- examples/stm32p103/cfg/cfg_proc.h | 6 +- 7 files changed, 256 insertions(+), 6 deletions(-) create mode 100644 bertos/cpu/cortex-m3/drv/kdebug_stm32.c create mode 100644 bertos/cpu/cortex-m3/drv/kdebug_stm32.h diff --git a/bertos/cpu/cortex-m3/drv/kdebug_cm3.c b/bertos/cpu/cortex-m3/drv/kdebug_cm3.c index 2e76f7dd..c236ca6b 100644 --- a/bertos/cpu/cortex-m3/drv/kdebug_cm3.c +++ b/bertos/cpu/cortex-m3/drv/kdebug_cm3.c @@ -39,6 +39,8 @@ #if CPU_CM3_LM3S #include "kdebug_lm3s.c" +#elif CPU_CM3_STM32 + #include "kdebug_stm32.c" /*#elif Add other families here */ #else #error Unknown CPU diff --git a/bertos/cpu/cortex-m3/drv/kdebug_stm32.c b/bertos/cpu/cortex-m3/drv/kdebug_stm32.c new file mode 100644 index 00000000..722e3e20 --- /dev/null +++ b/bertos/cpu/cortex-m3/drv/kdebug_stm32.c @@ -0,0 +1,195 @@ +/** + * \file + * + * + * \brief STM32 debug support (implementation). + * + * \author Andrea Righi + */ + +#include /* for BV() */ +#include +#include +#include /* RCC */ +#include +#include "kdebug_stm32.h" + +#define CR1_RUN_SET ((uint16_t)0x2000) /* USART Enable MASK */ +#define CR1_RUN_RESET ((uint16_t)0xDFFF) /* USART Disable MASK */ +#define CR1_RWU_SET ((uint16_t)0x0002) /* USART mute mode Enable MASK */ +#define CR1_RWU_RESET ((uint16_t)0xFFFD) /* USART mute mode Enable MASK */ +#define CR1_SBK_SET ((uint16_t)0x0001) /* USART Break Character send MASK */ +#define CR1_CLEAR_MASK ((uint16_t)0xE9F3) /* USART CR1 MASK */ + +#define CR2_MASK ((uint16_t)0xFFF0) /* USART address MASK */ +#define CR2_LINE_SET ((uint16_t)0x4000) /* USART LIN Enable MASK */ +#define CR2_LINE_RESET ((uint16_t)0xBFFF) /* USART LIN Disable MASK */ +#define CR2_CLEAR_MASK ((uint16_t)0xC0FF) /* USART CR2 MASK */ + +#define CR3_SCEN_SET ((uint16_t)0x0020) /* USART SC Enable MASK */ +#define CR3_SCEN_RESET ((uint16_t)0xFFDF) /* USART SC Disable MASK */ +#define CR3_NACK_SET ((uint16_t)0x0010) /* USART SC NACK Enable MASK */ +#define CR3_NACK_RESET ((uint16_t)0xFFEF) /* USART SC NACK Disable MASK */ +#define CR3_HDSEL_SET ((uint16_t)0x0008) /* USART Half-Duplex Enable MASK */ +#define CR3_HDSEL_RESET ((uint16_t)0xFFF7) /* USART Half-Duplex Disable MASK */ +#define CR3_IRLP_MASK ((uint16_t)0xFFFB) /* USART IrDA LowPower mode MASK */ +#define CR3_LBDL_MASK ((uint16_t)0xFFDF) /* USART LIN Break detection MASK */ +#define CR3_WAKE_MASK ((uint16_t)0xF7FF) /* USART WakeUp Method MASK */ +#define CR3_IREN_SET ((uint16_t)0x0002) /* USART IrDA Enable MASK */ +#define CR3_IREN_RESET ((uint16_t)0xFFFD) /* USART IrDA Disable MASK */ +#define CR3_CLEAR_MASK ((uint16_t)0xFCFF) /* USART CR3 MASK */ + +#define GTPR_LSB_MASK ((uint16_t)0x00FF) /* Guard Time Register LSB MASK */ +#define GTPR_MSB_MASK ((uint16_t)0xFF00) /* Guard Time Register MSB MASK */ + +#define USART_IT_MASK ((uint16_t)0x001F) /* USART Interrupt MASK */ + +/* USART flags */ +#define USART_FLAG_CTS ((uint16_t)0x0200) +#define USART_FLAG_LBD ((uint16_t)0x0100) +#define USART_FLAG_TXE ((uint16_t)0x0080) +#define USART_FLAG_TC ((uint16_t)0x0040) +#define USART_FLAG_RXNE ((uint16_t)0x0020) +#define USART_FLAG_IDLE ((uint16_t)0x0010) +#define USART_FLAG_ORE ((uint16_t)0x0008) +#define USART_FLAG_NE ((uint16_t)0x0004) +#define USART_FLAG_FE ((uint16_t)0x0002) +#define USART_FLAG_PE ((uint16_t)0x0001) + +/* USART registers */ +struct stm32_usart +{ + reg16_t SR; + uint16_t _RESERVED0; + reg16_t DR; + uint16_t _RESERVED1; + reg16_t BRR; + uint16_t _RESERVED2; + reg16_t CR1; + uint16_t _RESERVED3; + reg16_t CR2; + uint16_t _RESERVED4; + reg16_t CR3; + uint16_t _RESERVED5; + reg16_t GTPR; + uint16_t _RESERVED6; +}; + +/* USART mode */ +#define USART_MODE_RX ((uint16_t)0x0004) +#define USART_MODE_TX ((uint16_t)0x0008) + +/* USART last bit */ +#define USART_LASTBIT_DISABLE ((uint16_t)0x0000) +#define USART_LASTBIT_ENABLE ((uint16_t)0x0100) + +#if CONFIG_KDEBUG_PORT == KDEBUG_PORT_DBGU + +#if CONFIG_KDEBUG_PORT == 0 + #define UART_BASE ((struct stm32_usart *)USART1_BASE) +#elif CONFIG_KDEBUG_PORT == 1 + #define UART_BASE ((struct stm32_usart *)USART2_BASE) +#elif CONFIG_KDEBUG_PORT == 2 + #define UART_BASE ((struct stm32_usart *)USART3_BASE) +#else + #error "UART port not supported in this board" +#endif + +#define KDBG_WAIT_READY() while (!(UART_BASE->SR & USART_FLAG_TXE)) +#define KDBG_WAIT_TXDONE() while (!(UART_BASE->SR & USART_FLAG_TC)) + +#define KDBG_WRITE_CHAR(c) do { UART_BASE->DR = (c) & 0x1ff; } while(0) + +/* Debug unit is used only for debug purposes so does not generate interrupts. */ +#define KDBG_MASK_IRQ(old) do { (void)old; } while(0) + +/* Debug unit is used only for debug purposes so does not generate interrupts. */ +#define KDBG_RESTORE_IRQ(old) do { (void)old; } while(0) + +typedef uint32_t kdbg_irqsave_t; + +#else +#error CONFIG_KDEBUG_PORT should be KDEBUG_PORT_DBGU +#endif + +#define GPIO_USART1_TX_PIN (1 << 9) +#define GPIO_USART1_RX_PIN (1 << 10) + +#define GPIO_USART2_TX_PIN (1 << 2) +#define GPIO_USART2_RX_PIN (1 << 3) + +#define GPIO_USART3_TX_PIN (1 << 13) +#define GPIO_USART3_RX_PIN (1 << 14) + +INLINE uint16_t evaluate_brr(void) +{ + uint32_t reg, div, frac; + + /* XXX: PCLK1 has been configured as CPU_FREQ / 2 */ + div = (0x19 * CPU_FREQ / 2) / (0x04 * CONFIG_KDEBUG_BAUDRATE); + reg = (div / 0x64) << 0x04; + frac = div - (0x64 * (reg >> 0x04)); + reg |= ((frac * 0x10 + 0x32) / 0x64) & 0x0f; + + return (uint16_t)reg; +} + +/* Initialize UART debug port */ +INLINE void kdbg_hw_init(void) +{ + /* Enable clocking on AFIO */ + RCC->APB2ENR |= RCC_APB2_AFIO; + /* Configure USART pins */ +#if CONFIG_KDEBUG_PORT == 0 + RCC->APB2ENR |= RCC_APB2_GPIOA; + RCC->APB2ENR |= RCC_APB2_USART1; + stm32_gpioPinConfig((struct stm32_gpio *)GPIOA_BASE, GPIO_USART1_TX_PIN, + GPIO_SPEED_50MHZ, GPIO_MODE_AF_PP); +#elif CONFIG_KDEBUG_PORT == 1 + RCC->APB2ENR |= RCC_APB2_GPIOA; + RCC->APB1ENR |= RCC_APB1_USART2; + stm32_gpioPinConfig((struct stm32_gpio *)GPIOA_BASE, GPIO_USART2_TX_PIN, + GPIO_SPEED_50MHZ, GPIO_MODE_AF_PP); +#elif CONFIG_KDEBUG_PORT == 2 + RCC->APB2ENR |= RCC_APB2_GPIOB; + RCC->APB2ENR |= RCC_APB1_USART3; + stm32_gpioPinConfig((struct stm32_gpio *)GPIOB_BASE, GPIO_USART3_TX_PIN, + GPIO_SPEED_50MHZ, GPIO_MODE_AF_PP); +#else + #error "UART port not supported in this board" +#endif + /* Enable the USART by writing the UE bit */ + UART_BASE->CR1 |= CR1_RUN_SET; + /* Configure the desired baud rate */ + UART_BASE->BRR = evaluate_brr(); + /* Set the Transmitter Enable bit in CR1 */ + UART_BASE->CR1 |= USART_MODE_TX; +} diff --git a/bertos/cpu/cortex-m3/drv/kdebug_stm32.h b/bertos/cpu/cortex-m3/drv/kdebug_stm32.h new file mode 100644 index 00000000..ed51dbe1 --- /dev/null +++ b/bertos/cpu/cortex-m3/drv/kdebug_stm32.h @@ -0,0 +1,53 @@ +/** + * \file + * + * + * \brief STM32 debug support (interface). + * + * \author Andrea Righi + */ + +#ifndef DRV_KDEBUG_STM32_H +#define DRV_KDEBUG_STM32_H + +/** + * \name Values for CONFIG_KDEBUG_PORT. + * + * Select which hardware UART to use for system debug. + * + * \{ + */ +#define KDEBUG_PORT_DBGU 1 ///< Debug on Debug Unit. + +#define KDEBUG_PORT_DEFAULT KDEBUG_PORT_DBGU ///< Default debug port. +/* \} */ + +#endif /* DRV_KDEBUG_STM32_H */ diff --git a/bertos/cpu/cortex-m3/drv/timer_cm3.h b/bertos/cpu/cortex-m3/drv/timer_cm3.h index 6311d506..54bb4beb 100644 --- a/bertos/cpu/cortex-m3/drv/timer_cm3.h +++ b/bertos/cpu/cortex-m3/drv/timer_cm3.h @@ -84,7 +84,7 @@ INLINE bool timer_hw_triggered(void) INLINE hptime_t timer_hw_hpread(void) { - return HWREG(NVIC_ST_CURRENT); + return NVIC_ST_CURRENT_R; } void timer_hw_init(void); diff --git a/bertos/cpu/cortex-m3/io/stm32_memmap.h b/bertos/cpu/cortex-m3/io/stm32_memmap.h index 1c86443f..a99577a1 100644 --- a/bertos/cpu/cortex-m3/io/stm32_memmap.h +++ b/bertos/cpu/cortex-m3/io/stm32_memmap.h @@ -50,7 +50,7 @@ #define OB_BASE (0x1FFFF800) /* Peripheral memory map */ -#define APB1PERIPH_BASE ((uint32_t)PERIPH_BASE) +#define APB1PERIPH_BASE (PERIPH_BASE) #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) #define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) diff --git a/examples/stm32p103/cfg/cfg_debug.h b/examples/stm32p103/cfg/cfg_debug.h index ef7c4a75..20fec2d3 100644 --- a/examples/stm32p103/cfg/cfg_debug.h +++ b/examples/stm32p103/cfg/cfg_debug.h @@ -42,7 +42,7 @@ * Debug console port. * $WIZ$ type = "int"; min = 0 */ -#define CONFIG_KDEBUG_PORT 0 +#define CONFIG_KDEBUG_PORT 1 /** * Baudrate for the debug console. diff --git a/examples/stm32p103/cfg/cfg_proc.h b/examples/stm32p103/cfg/cfg_proc.h index eb5506b4..b13b657a 100644 --- a/examples/stm32p103/cfg/cfg_proc.h +++ b/examples/stm32p103/cfg/cfg_proc.h @@ -58,7 +58,7 @@ * $WIZ$ type = "boolean" * $WIZ$ conditional_deps = "timer" */ -#define CONFIG_KERN_PREEMPT 1 +#define CONFIG_KERN_PREEMPT 0 /** * Time sharing quantum (a prime number prevents interference effects) [ms]. @@ -72,14 +72,14 @@ * Priority-based scheduling policy. * $WIZ$ type = "boolean" */ -#define CONFIG_KERN_PRI 1 +#define CONFIG_KERN_PRI 0 /** * Dynamic memory allocation for processes. * $WIZ$ type = "boolean" * $WIZ$ conditional_deps = "heap" */ -#define CONFIG_KERN_HEAP 1 +#define CONFIG_KERN_HEAP 0 /** * Size of the dynamic memory pool used by processes. -- 2.25.1