1
0
mirror of https://github.com/armink/FlashDB.git synced 2025-01-16 20:12:52 +08:00
2020-07-12 20:37:39 +08:00

460 lines
12 KiB
C

/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-11-09 xiangxistu first version
* 2020-05-18 chenyaxing modify stm32_uart_config struct
*/
#include <string.h>
#include <stdlib.h>
#include <stm32f1xx.h>
#include "uart_config.h"
#include <board.h>
#define __STM32_PORT(port) GPIO##port##_BASE
#define GET_PIN(PORTx,PIN) (long)((16 * ( ((long)__STM32_PORT(PORTx) - (long)GPIOA_BASE)/(0x0400UL) )) + PIN)
static UART_HandleTypeDef handle;
/* stm32 config class */
struct stm32_uart_config
{
const char *name;
USART_TypeDef *Instance;
IRQn_Type irq_type;
const char *tx_pin_name;
const char *rx_pin_name;
};
static struct stm32_uart_config *_uart_config = NULL;
struct stm32_uart_config uart_config[] =
{
#ifdef BSP_USING_UART1
UART1_CONFIG,
#endif
#ifdef BSP_USING_UART2
UART2_CONFIG,
#endif
#ifdef BSP_USING_UART3
UART3_CONFIG,
#endif
#ifdef BSP_USING_UART4
UART4_CONFIG,
#endif
#ifdef BSP_USING_UART5
UART5_CONFIG,
#endif
#ifdef BSP_USING_UART6
UART6_CONFIG,
#endif
#ifdef BSP_USING_UART7
UART7_CONFIG,
#endif
#ifdef BSP_USING_UART8
UART8_CONFIG,
#endif
#ifdef BSP_USING_LPUART1
LPUART1_CONFIG,
#endif
};
static long stm32_uart_clk_enable(struct stm32_uart_config *config)
{
/* check the parameters */
assert_param(IS_UART_INSTANCE(config->Instance));
/* uart clock enable */
switch ((uint32_t)config->Instance)
{
#ifdef BSP_USING_UART1
case (uint32_t)USART1:
__HAL_RCC_USART1_CLK_ENABLE();
break;
#endif /* BSP_USING_UART1 */
#ifdef BSP_USING_UART2
case (uint32_t)USART2:
__HAL_RCC_USART2_CLK_ENABLE();
break;
#endif /* BSP_USING_UART2 */
#ifdef BSP_USING_UART3
case (uint32_t)USART3:
__HAL_RCC_USART3_CLK_ENABLE();
break;
#endif /* BSP_USING_UART3 */
#ifdef BSP_USING_UART4
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32L0) || \
defined(SOC_SERIES_STM32G0)
case (uint32_t)USART4:
__HAL_RCC_USART4_CLK_ENABLE();
#else
case (uint32_t)UART4:
__HAL_RCC_UART4_CLK_ENABLE();
#endif
break;
#endif /* BSP_USING_UART4 */
#ifdef BSP_USING_UART5
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32L0) || \
defined(SOC_SERIES_STM32G0)
case (uint32_t)USART5:
__HAL_RCC_USART5_CLK_ENABLE();
#else
case (uint32_t)UART5:
__HAL_RCC_UART5_CLK_ENABLE();
#endif
break;
#endif /* BSP_USING_UART5 */
#ifdef BSP_USING_UART6
case (uint32_t)USART6:
__HAL_RCC_USART6_CLK_ENABLE();
break;
#endif /* BSP_USING_UART6 */
#ifdef BSP_USING_UART7
#if defined(SOC_SERIES_STM32F0)
case (uint32_t)USART7:
__HAL_RCC_USART7_CLK_ENABLE();
#else
case (uint32_t)UART7:
__HAL_RCC_UART7_CLK_ENABLE();
#endif
break;
#endif /* BSP_USING_UART7 */
#ifdef BSP_USING_UART8
#if defined(SOC_SERIES_STM32F0)
case (uint32_t)USART8:
__HAL_RCC_USART8_CLK_ENABLE();
#else
case (uint32_t)UART8:
__HAL_RCC_UART8_CLK_ENABLE();
#endif
break;
#endif /* BSP_USING_UART8 */
#ifdef BSP_USING_LPUART1
case (uint32_t)LPUART1:
__HAL_RCC_LPUART1_CLK_ENABLE();
break;
#endif /* BSP_USING_LPUART1 */
default:
return -1;
}
return 0;
}
static long stm32_gpio_clk_enable(GPIO_TypeDef *gpiox)
{
/* check the parameters */
assert_param(IS_GPIO_ALL_INSTANCE(gpiox));
/* gpio ports clock enable */
switch ((uint32_t)gpiox)
{
#if defined(__HAL_RCC_GPIOA_CLK_ENABLE)
case (uint32_t)GPIOA:
__HAL_RCC_GPIOA_CLK_ENABLE();
break;
#endif
#if defined(__HAL_RCC_GPIOB_CLK_ENABLE)
case (uint32_t)GPIOB:
__HAL_RCC_GPIOB_CLK_ENABLE();
break;
#endif
#if defined(__HAL_RCC_GPIOC_CLK_ENABLE)
case (uint32_t)GPIOC:
__HAL_RCC_GPIOC_CLK_ENABLE();
break;
#endif
#if defined(__HAL_RCC_GPIOD_CLK_ENABLE)
case (uint32_t)GPIOD:
__HAL_RCC_GPIOD_CLK_ENABLE();
break;
#endif
#if defined(__HAL_RCC_GPIOE_CLK_ENABLE)
case (uint32_t)GPIOE:
__HAL_RCC_GPIOE_CLK_ENABLE();
break;
#endif
#if defined(__HAL_RCC_GPIOF_CLK_ENABLE)
case (uint32_t)GPIOF:
__HAL_RCC_GPIOF_CLK_ENABLE();
break;
#endif
#if defined(__HAL_RCC_GPIOG_CLK_ENABLE)
case (uint32_t)GPIOG:
__HAL_RCC_GPIOG_CLK_ENABLE();
break;
#endif
#if defined(__HAL_RCC_GPIOH_CLK_ENABLE)
case (uint32_t)GPIOH:
__HAL_RCC_GPIOH_CLK_ENABLE();
break;
#endif
#if defined(__HAL_RCC_GPIOI_CLK_ENABLE)
case (uint32_t)GPIOI:
__HAL_RCC_GPIOI_CLK_ENABLE();
break;
#endif
#if defined(__HAL_RCC_GPIOJ_CLK_ENABLE)
case (uint32_t)GPIOJ:
__HAL_RCC_GPIOJ_CLK_ENABLE();
break;
#endif
#if defined(__HAL_RCC_GPIOK_CLK_ENABLE)
case (uint32_t)GPIOK:
__HAL_RCC_GPIOK_CLK_ENABLE();
break;
#endif
default:
return -1;
}
return 0;
}
static int up_char(char * c)
{
if ((*c >= 'a') && (*c <= 'z'))
{
*c = *c - 32;
}
return 0;
}
static void get_pin_by_name(const char* pin_name, GPIO_TypeDef **port, uint16_t *pin)
{
int pin_num = atoi((char*) &pin_name[2]);
char port_name = pin_name[1];
up_char(&port_name);
up_char(&port_name);
*port = ((GPIO_TypeDef *) ((uint32_t) GPIOA
+ (uint32_t) (port_name - 'A') * ((uint32_t) GPIOB - (uint32_t) GPIOA)));
*pin = (GPIO_PIN_0 << pin_num);
}
const uint8_t __lowest_bit_bitmap[] =
{
/* 00 */ 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 10 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 20 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 30 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 40 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 50 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 60 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 70 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 80 */ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 90 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* A0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* B0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* C0 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* D0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* E0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* F0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};
/**
* This function finds the first bit set (beginning with the least significant bit)
* in value and return the index of that bit.
*
* Bits are numbered starting at 1 (the least significant bit). A return value of
* zero from any of these functions means that the argument was zero.
*
* @return return the index of the first bit set. If value is 0, then this function
* shall return 0.
*/
int __rt_ffs(int value)
{
if (value == 0) return 0;
if (value & 0xff)
return __lowest_bit_bitmap[value & 0xff] + 1;
if (value & 0xff00)
return __lowest_bit_bitmap[(value & 0xff00) >> 8] + 9;
if (value & 0xff0000)
return __lowest_bit_bitmap[(value & 0xff0000) >> 16] + 17;
return __lowest_bit_bitmap[(value & 0xff000000) >> 24] + 25;
}
static uint16_t stm32_get_pin(GPIO_TypeDef *pin_port, uint32_t pin_num)
{
return (uint16_t)((16 * (((long)pin_port - (long)GPIOA_BASE)/(0x0400UL))) + (__rt_ffs(pin_num) - 1));
}
static long stm32_gpio_configure(struct stm32_uart_config *config)
{
#define UART_IS_TX (1U<<7)
#define UART_IS_RX (0U)
uint16_t tx_pin_num = 0, rx_pin_num = 0;
int rx_index = 0, tx_index = 0, index = 0;
int uart_num = 0;
int uart_is_remap = 0;
GPIO_TypeDef *tx_port;
GPIO_TypeDef *rx_port;
uint16_t tx_pin;
uint16_t rx_pin;
get_pin_by_name(config->rx_pin_name, &rx_port, &rx_pin);
get_pin_by_name(config->tx_pin_name, &tx_port, &tx_pin);
struct gpio_uart_remap {
/* index get by GET_PIN */
uint16_t pin_index;
/* -1: not uart, 1: uart1, 2: uart2 ... */
int8_t normal_uart;
/* -1: not uart, 1: uart1, 2: uart2 ... */
int8_t remap_uart;
};
static const struct gpio_uart_remap uart_remaps[] =
{
/* usart1 configure */
{ .pin_index = GET_PIN(A, 9), .normal_uart = 1, .remap_uart = -1 },
{ .pin_index = GET_PIN(A, 10), .normal_uart = 1, .remap_uart = -1 },
{ .pin_index = GET_PIN(B, 6), .normal_uart = -1, .remap_uart = 1 },
{ .pin_index = GET_PIN(B, 7), .normal_uart = -1, .remap_uart = 1 },
/* usart2 configure */
{ .pin_index = GET_PIN(A, 2), .normal_uart = 2, .remap_uart = -1 },
{ .pin_index = GET_PIN(A, 3), .normal_uart = 2, .remap_uart = -1 },
{ .pin_index = GET_PIN(D, 5), .normal_uart = -1, .remap_uart = 2 },
{ .pin_index = GET_PIN(D, 6), .normal_uart = -1, .remap_uart = 2 },
/* usart3 configure */
{ .pin_index = GET_PIN(B, 10), .normal_uart = 3, .remap_uart = -1 },
{ .pin_index = GET_PIN(B, 11), .normal_uart = 3, .remap_uart = -1 },
{ .pin_index = GET_PIN(D, 8), .normal_uart = -1, .remap_uart = 3 },
{ .pin_index = GET_PIN(D, 9), .normal_uart = -1, .remap_uart = 3 },
{ .pin_index = GET_PIN(C, 10), .normal_uart = 4, .remap_uart = 3 },
{ .pin_index = GET_PIN(C, 11), .normal_uart = 4, .remap_uart = 3 },
};
/* get tx/rx pin index */
tx_pin_num = stm32_get_pin(tx_port, tx_pin);
rx_pin_num = stm32_get_pin(rx_port, rx_pin);
for (index = 0; index < sizeof(uart_remaps) / sizeof(struct gpio_uart_remap); index++)
{
if (uart_remaps[index].pin_index == tx_pin_num)
{
tx_index = index;
}
else if (uart_remaps[index].pin_index == rx_pin_num)
{
rx_index = index;
}
}
/* check tx/rx pin remap information */
assert_param(uart_remaps[tx_index].normal_uart == uart_remaps[rx_index].normal_uart);
assert_param(uart_remaps[tx_index].remap_uart == uart_remaps[rx_index].remap_uart);
uart_num = config->name[4] - '0';
uart_is_remap = uart_remaps[tx_index].remap_uart == uart_num ? 1 : 0;
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* gpio ports clock enable */
stm32_gpio_clk_enable(tx_port);
if (tx_port != rx_port)
{
stm32_gpio_clk_enable(rx_port);
}
/* tx pin initialize */
GPIO_InitStruct.Pin = tx_pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(tx_port, &GPIO_InitStruct);
/* rx pin initialize */
GPIO_InitStruct.Pin = rx_pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(rx_port, &GPIO_InitStruct);
/* enable the remapping of usart alternate */
if (uart_is_remap)
{
__HAL_RCC_AFIO_CLK_ENABLE();
switch (uart_num)
{
case 1:
__HAL_AFIO_REMAP_USART1_ENABLE();
break;
case 2:
__HAL_AFIO_REMAP_USART2_ENABLE();
break;
case 3:
if (uart_remaps[tx_index].normal_uart < 0)
{
#ifdef AFIO_MAPR_USART3_REMAP_FULLREMAP
__HAL_AFIO_REMAP_USART3_ENABLE();
#endif
}
else
{
#ifdef AFIO_MAPR_USART3_REMAP_PARTIALREMAP
__HAL_AFIO_REMAP_USART3_PARTIAL();
#endif
}
break;
default:
assert_param(0);
}
}
}
return 0;
}
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
/* if this uart is shell function */
if(huart == &handle)
{
stm32_gpio_configure(_uart_config);
}
}
static long stm32_configure(struct stm32_uart_config *config)
{
stm32_uart_clk_enable(config);
handle.Instance = config->Instance;
handle.Init.BaudRate = 115200;
handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
handle.Init.Mode = UART_MODE_TX_RX;
handle.Init.OverSampling = UART_OVERSAMPLING_16;
handle.Init.WordLength = UART_WORDLENGTH_8B;
handle.Init.StopBits = UART_STOPBITS_1;
handle.Init.Parity = UART_PARITY_NONE;
if (HAL_UART_Init(&handle) != HAL_OK)
{
return -1;
}
return 0;
}
int rt_hw_usart_init(void)
{
_uart_config = &uart_config[0];
stm32_configure(_uart_config);
return 0;
}
void print_char(char c)
{
HAL_UART_Transmit(&handle, (uint8_t *) (&c), 1, 1);
}