int hal_uart_config(int port, int32_t baudrate, uint8_t databits, uint8_t stopbits, enum hal_uart_parity parity, enum hal_uart_flow_ctl flow_ctl) { struct hal_uart *u; const struct stm32f3_uart_cfg *cfg; USART_InitTypeDef uart; if (port >= UART_CNT) { return -1; } u = &uarts[port]; if (u->u_open) { return -1; } cfg = bsp_uart_config(port); assert(cfg); /* * RCC * pin config * UART config * nvic config * enable uart */ uart.USART_BaudRate = baudrate; switch (databits) { case 8: uart.USART_WordLength = USART_WordLength_8b; break; case 9: uart.USART_WordLength = USART_WordLength_9b; break; default: assert(0); return -1; } switch (stopbits) { case 1: uart.USART_StopBits = USART_StopBits_1; break; case 2: uart.USART_StopBits = USART_StopBits_2; break; default: return -1; } switch (parity) { case HAL_UART_PARITY_NONE: uart.USART_Parity = USART_Parity_No; break; case HAL_UART_PARITY_ODD: uart.USART_Parity = USART_Parity_Odd; break; case HAL_UART_PARITY_EVEN: uart.USART_Parity = USART_Parity_Even; break; } uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; switch (flow_ctl) { case HAL_UART_FLOW_CTL_NONE: uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None; break; case HAL_UART_FLOW_CTL_RTS_CTS: uart.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS; if (cfg->suc_pin_rts < 0 || cfg->suc_pin_cts < 0) { /* * Can't turn on HW flow control if pins to do that are not * defined. */ assert(0); return -1; } break; } cfg->suc_rcc_cmd(cfg->suc_rcc_dev, ENABLE); hal_gpio_init_af(cfg->suc_pin_tx, cfg->suc_pin_af, 0); hal_gpio_init_af(cfg->suc_pin_rx, cfg->suc_pin_af, 0); if (flow_ctl == HAL_UART_FLOW_CTL_RTS_CTS) { hal_gpio_init_af(cfg->suc_pin_rts, cfg->suc_pin_af, 0); hal_gpio_init_af(cfg->suc_pin_cts, cfg->suc_pin_af, 0); } USART_Init(cfg->suc_uart, &uart); u->u_regs = cfg->suc_uart; (void)u->u_regs->RDR; (void)u->u_regs->ISR; hal_uart_set_nvic(cfg->suc_irqn, u); u->u_regs->CR1 |= USART_CR1_RXNEIE; USART_Cmd(u->u_regs, ENABLE); u->u_open = 1; return 0; }
int hal_uart_config(int port, int32_t baudrate, uint8_t databits, uint8_t stopbits, enum hal_uart_parity parity, enum hal_uart_flow_ctl flow_ctl) { struct hal_uart *u; const struct stm32f4_uart_cfg *cfg; uint32_t cr1, cr2, cr3; if (port >= UART_CNT) { return -1; } u = &uarts[port]; if (u->u_open) { return -1; } cfg = bsp_uart_config(port); assert(cfg); /* * RCC * pin config * UART config * nvic config * enable uart */ cr1 = cfg->suc_uart->CR1; cr2 = cfg->suc_uart->CR2; cr3 = cfg->suc_uart->CR3; cr1 &= ~(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_RE | USART_CR1_OVER8); cr2 &= ~(USART_CR2_STOP); cr3 &= ~(USART_CR3_RTSE | USART_CR3_CTSE); switch (databits) { case 8: cr1 |= UART_WORDLENGTH_8B; break; case 9: cr1 |= UART_WORDLENGTH_9B; break; default: assert(0); return -1; } switch (stopbits) { case 1: cr2 |= UART_STOPBITS_1; break; case 2: cr2 |= UART_STOPBITS_2; break; default: return -1; } switch (parity) { case HAL_UART_PARITY_NONE: cr1 |= UART_PARITY_NONE; break; case HAL_UART_PARITY_ODD: cr1 |= UART_PARITY_ODD; break; case HAL_UART_PARITY_EVEN: cr1 |= UART_PARITY_EVEN; break; } switch (flow_ctl) { case HAL_UART_FLOW_CTL_NONE: cr3 |= UART_HWCONTROL_NONE; break; case HAL_UART_FLOW_CTL_RTS_CTS: cr3 |= UART_HWCONTROL_RTS_CTS; if (cfg->suc_pin_rts < 0 || cfg->suc_pin_cts < 0) { /* * Can't turn on HW flow control if pins to do that are not * defined. */ assert(0); return -1; } break; } cr1 |= (UART_MODE_RX | UART_MODE_TX | UART_OVERSAMPLING_16); *cfg->suc_rcc_reg |= cfg->suc_rcc_dev; hal_gpio_init_af(cfg->suc_pin_tx, cfg->suc_pin_af, 0); hal_gpio_init_af(cfg->suc_pin_rx, cfg->suc_pin_af, 0); if (flow_ctl == HAL_UART_FLOW_CTL_RTS_CTS) { hal_gpio_init_af(cfg->suc_pin_rts, cfg->suc_pin_af, 0); hal_gpio_init_af(cfg->suc_pin_cts, cfg->suc_pin_af, 0); } u->u_regs = cfg->suc_uart; u->u_regs->CR3 = cr3; u->u_regs->CR2 = cr2; u->u_regs->CR1 = cr1; if (cfg->suc_uart == USART1 || cfg->suc_uart == USART6) { u->u_regs->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK2Freq(), baudrate); } else { u->u_regs->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK1Freq(), baudrate); } (void)u->u_regs->DR; (void)u->u_regs->SR; hal_uart_set_nvic(cfg->suc_irqn, u); u->u_regs->CR1 |= (USART_CR1_RXNEIE | USART_CR1_UE); u->u_open = 1; return 0; }