From b03b2da888b8740ef0e8dc75abfbc1b78143c43b Mon Sep 17 00:00:00 2001 From: Sergi Hernandez Juan <shernand@iri.upc.edu> Date: Sat, 4 May 2024 22:16:42 +0200 Subject: [PATCH] Added usart2 module for the F3 family. Added the set_priorities() function. --- f3/usart/include/usart1.h | 1 + f3/usart/include/usart2.h | 23 +++ f3/usart/src/usart1.c | 6 + f3/usart/src/usart2.c | 354 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 384 insertions(+) create mode 100644 f3/usart/include/usart2.h create mode 100644 f3/usart/src/usart2.c diff --git a/f3/usart/include/usart1.h b/f3/usart/include/usart1.h index 9cdff3a..412262a 100644 --- a/f3/usart/include/usart1.h +++ b/f3/usart/include/usart1.h @@ -9,6 +9,7 @@ void usart1_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *priorities); void usart1_config(TComm *comm_dev,UART_InitTypeDef *conf); void usart1_set_priorities(TComm *comm_dev,TUSART_IRQ_Priorities *priorities); +void usart1_set_baudrate(TComm *comm_dev,unsigned int baudrate); /* IRQ functions */ unsigned char usart1_send_irq(unsigned char first_byte); unsigned char usart1_enable_tx_irq(void); diff --git a/f3/usart/include/usart2.h b/f3/usart/include/usart2.h new file mode 100644 index 0000000..54fee26 --- /dev/null +++ b/f3/usart/include/usart2.h @@ -0,0 +1,23 @@ +#ifndef USART2_F3_H +#define USART2_F3_H + +#include "stm32f3xx_hal.h" +#include "usart_common.h" +#include "comm.h" + +/* public functions */ +void usart2_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *priorities); +void usart2_config(TComm *comm_dev,UART_InitTypeDef *conf); +void usart2_set_priorities(TComm *comm_dev,TUSART_IRQ_Priorities *priorities); +void usart2_set_baudrate(TComm *comm_dev,unsigned int baudrate); +/* IRQ functions */ +unsigned char usart2_send_irq(unsigned char first_byte); +unsigned char usart2_enable_tx_irq(void); +unsigned char usart2_receive_irq(void); +unsigned char usart2_cancel_receive_irq(void); +/* DMA functions */ +unsigned char usart2_send_dma(unsigned char *data,unsigned short int length); +unsigned char usart2_receive_dma(unsigned char *data,unsigned short int length); +unsigned char usart2_cancel_receive_dma(void); + +#endif diff --git a/f3/usart/src/usart1.c b/f3/usart/src/usart1.c index 9cf99d3..5ae80c0 100644 --- a/f3/usart/src/usart1.c +++ b/f3/usart/src/usart1.c @@ -283,6 +283,12 @@ void usart1_set_priorities(TComm *comm_dev,TUSART_IRQ_Priorities *priorities) } } +void usart1_set_baudrate(TComm *comm_dev,unsigned int baudrate) +{ + Uart1Handle.Init.BaudRate = baudrate; + HAL_UART_Init(&Uart1Handle); +} + /* IRQ functions */ unsigned char usart1_send_irq(unsigned char first_byte) { diff --git a/f3/usart/src/usart2.c b/f3/usart/src/usart2.c new file mode 100644 index 0000000..1702723 --- /dev/null +++ b/f3/usart/src/usart2.c @@ -0,0 +1,354 @@ +#include "usart2.h" + +#define USART USART2 +#define USART_ENABLE_CLK __USART2_CLK_ENABLE() +#define USART_IRQn USART2_IRQn +#define USART_IRQHandler USART2_IRQHandler + +#define USART_TX_PIN GPIO_PIN_3 +#define USART_TX_GPIO_PORT GPIOB +#define USART_ENABLE_TX_GPIO_CLK __GPIOB_CLK_ENABLE() + +#define USART_RX_PIN GPIO_PIN_4 +#define USART_RX_GPIO_PORT GPIOB +#define USART_ENABLE_RX_GPIO_CLK __GPIOB_CLK_ENABLE() + +/* DMA configuration */ +#define USART_DMA DMA1 +#define USART_ENABLE_DMA_CLK __DMA1_CLK_ENABLE() + +#define USART_TX_DMA_CHANNEL DMA1_Channel7 +#define USART_RX_DMA_CHANNEL DMA1_Channel6 + +#define USART_DMA_TX_IRQn DMA1_Channel7_IRQn +#define USART_DMA_RX_IRQn DMA1_Channel6_IRQn +#define USART_DMA_TX_IRQHandler DMA1_Channel7_IRQHandler +#define USART_DMA_RX_IRQHandler DMA1_Channel6_IRQHandler + +// private variables +UART_HandleTypeDef Uart2Handle; +DMA_HandleTypeDef usart2_hdma_tx; +DMA_HandleTypeDef usart2_hdma_rx; +TComm *usart2_comm_dev; + +// interrupt handlers +void USART_IRQHandler(void) +{ + unsigned char data,ret; + + /* USART parity error interrupt occured ------------------------------------*/ + if(__HAL_USART_GET_IT(&Uart2Handle, USART_IT_PE) != RESET) + { + if(__HAL_USART_GET_IT_SOURCE(&Uart2Handle, USART_IT_PE) != RESET) + { + __HAL_USART_CLEAR_IT(&Uart2Handle, USART_IT_PE); + } + } + + /* USART frame error interrupt occured -------------------------------------*/ + if(__HAL_USART_GET_IT(&Uart2Handle, USART_IT_FE) != RESET) + { + if(__HAL_USART_GET_IT_SOURCE(&Uart2Handle, USART_IT_ERR) != RESET) + { + __HAL_USART_CLEAR_IT(&Uart2Handle, USART_IT_FE); + } + } + + /* USART noise error interrupt occured -------------------------------------*/ + if(__HAL_USART_GET_IT(&Uart2Handle, USART_IT_NE) != RESET) + { + if(__HAL_USART_GET_IT_SOURCE(&Uart2Handle, USART_IT_ERR) != RESET) + { + __HAL_USART_CLEAR_IT(&Uart2Handle, USART_IT_NE); + } + } + + /* USART Over-Run interrupt occured ----------------------------------------*/ + if(__HAL_USART_GET_IT(&Uart2Handle, USART_IT_ORE) != RESET) + { + if(__HAL_USART_GET_IT_SOURCE(&Uart2Handle, USART_IT_ERR) != RESET) + { + __HAL_USART_CLEAR_IT(&Uart2Handle, USART_IT_ORE); + } + } + + /* USART in mode Receiver --------------------------------------------------*/ + if(__HAL_USART_GET_IT(&Uart2Handle, USART_IT_RXNE) != RESET) + { + if(__HAL_USART_GET_IT_SOURCE(&Uart2Handle, USART_IT_RXNE) != RESET) + { + __HAL_USART_CLEAR_IT(&Uart2Handle, USART_IT_RXNE); + data=(uint8_t)(Uart2Handle.Instance->RDR & (uint8_t)0x00FF); + // call the reception function + if(!comm_do_irq_receive(usart2_comm_dev,data)) + __HAL_UART_DISABLE_IT(&Uart2Handle, UART_IT_RXNE); + } + } + + /* USART in mode Transmitter -----------------------------------------------*/ + if(__HAL_USART_GET_IT(&Uart2Handle, USART_IT_TC) != RESET) + { + if(__HAL_USART_GET_IT_SOURCE(&Uart2Handle, USART_IT_TC) != RESET) + { + __HAL_UART_CLEAR_IT(&Uart2Handle,UART_IT_TC); + ret=comm_do_irq_send(usart2_comm_dev,&data); + if(ret==0x01) + Uart2Handle.Instance->TDR=data; + else if(ret==0x00) + __HAL_UART_DISABLE_IT(&Uart2Handle, UART_IT_TC); + } + } +} + +void USART_DMA_TX_IRQHandler(void) +{ + if(__HAL_DMA_GET_FLAG(Uart2Handle.hdmatx,__HAL_DMA_GET_TE_FLAG_INDEX(Uart2Handle.hdmatx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart2Handle.hdmatx, DMA_IT_TE) != RESET) + { + /* Disable the transfer error interrupt */ + __HAL_DMA_DISABLE_IT(Uart2Handle.hdmatx, DMA_IT_TE); + /* Clear the transfer error flag */ + __HAL_DMA_CLEAR_FLAG(Uart2Handle.hdmatx, __HAL_DMA_GET_TE_FLAG_INDEX(Uart2Handle.hdmatx)); + } + } + if(__HAL_DMA_GET_FLAG(Uart2Handle.hdmatx,__HAL_DMA_GET_TC_FLAG_INDEX(Uart2Handle.hdmatx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart2Handle.hdmatx, DMA_IT_TC) != RESET) + { + /* Disable the half transfer interrupt */ + __HAL_DMA_DISABLE_IT(Uart2Handle.hdmatx, DMA_IT_TC); + /* Clear the transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(Uart2Handle.hdmatx, __HAL_DMA_GET_TC_FLAG_INDEX(Uart2Handle.hdmatx)); + CLEAR_BIT(Uart2Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR)); + HAL_DMA_Abort(Uart2Handle.hdmatx); + // call the user function + comm_do_dma_send(usart2_comm_dev); + } + } + if(__HAL_DMA_GET_FLAG(Uart2Handle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart2Handle.hdmatx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart2Handle.hdmatx, DMA_IT_HT) != RESET) + { + /* Disable the half transfer interrupt */ + __HAL_DMA_DISABLE_IT(Uart2Handle.hdmatx, DMA_IT_HT); + /* Clear the half transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(Uart2Handle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart2Handle.hdmatx)); + } + } +} + +void USART_DMA_RX_IRQHandler(void) +{ + if(__HAL_DMA_GET_FLAG(Uart2Handle.hdmarx,__HAL_DMA_GET_TE_FLAG_INDEX(Uart2Handle.hdmarx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart2Handle.hdmarx, DMA_IT_TE) != RESET) + { + /* Disable the transfer error interrupt */ + __HAL_DMA_DISABLE_IT(Uart2Handle.hdmarx, DMA_IT_TE); + /* Clear the transfer error flag */ + __HAL_DMA_CLEAR_FLAG(Uart2Handle.hdmarx, __HAL_DMA_GET_TE_FLAG_INDEX(Uart2Handle.hdmarx)); + } + } + if(__HAL_DMA_GET_FLAG(Uart2Handle.hdmarx,__HAL_DMA_GET_TC_FLAG_INDEX(Uart2Handle.hdmarx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart2Handle.hdmarx, DMA_IT_TC) != RESET) + { + /* Disable the transfer complete interrupt */ + __HAL_DMA_DISABLE_IT(Uart2Handle.hdmarx, DMA_IT_TC); + /* Clear the transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(Uart2Handle.hdmarx, __HAL_DMA_GET_TC_FLAG_INDEX(Uart2Handle.hdmarx)); + CLEAR_BIT(Uart2Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR)); + HAL_DMA_Abort(Uart2Handle.hdmarx); + // call the user function + comm_do_dma_receive(usart2_comm_dev); + } + } + if(__HAL_DMA_GET_FLAG(Uart2Handle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart2Handle.hdmarx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart2Handle.hdmarx, DMA_IT_HT) != RESET) + { + /* Disable the half transfer interrupt */ + __HAL_DMA_DISABLE_IT(Uart2Handle.hdmarx, DMA_IT_HT); + /* Clear the half transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(Uart2Handle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart2Handle.hdmarx)); + } + } +} + +/* public functions*/ +void usart2_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *priorities) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable GPIO clock */ + USART_ENABLE_TX_GPIO_CLK; + USART_ENABLE_RX_GPIO_CLK; + USART_ENABLE_DMA_CLK; + // configure the GPIO pins + + /* Configure USART Tx and Rx as alternate function push-pull */ + GPIO_InitStructure.Pin = USART_TX_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; + GPIO_InitStructure.Pull = GPIO_PULLUP; + GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; + GPIO_InitStructure.Alternate = GPIO_AF7_USART1; + HAL_GPIO_Init(USART_TX_GPIO_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = USART_RX_PIN; + HAL_GPIO_Init(USART_RX_GPIO_PORT, &GPIO_InitStructure); + + USART_ENABLE_CLK; + + Uart2Handle.Instance = USART; + usart2_config(comm_dev,conf); + + if(comm_dev->use_dma) + { + // configure the DMA channels + usart2_hdma_tx.Instance = USART_TX_DMA_CHANNEL; + usart2_hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + usart2_hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE; + usart2_hdma_tx.Init.MemInc = DMA_MINC_ENABLE; + usart2_hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + usart2_hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + usart2_hdma_tx.Init.Mode = DMA_NORMAL; + usart2_hdma_tx.Init.Priority = DMA_PRIORITY_LOW; + + HAL_DMA_Init(&usart2_hdma_tx); + + /* Associate the initialized DMA handle to the UART handle */ + __HAL_LINKDMA(&Uart2Handle, hdmatx, usart2_hdma_tx); + + /* Configure the DMA handler for reception process */ + usart2_hdma_rx.Instance = USART_RX_DMA_CHANNEL; + usart2_hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + usart2_hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE; + usart2_hdma_rx.Init.MemInc = DMA_MINC_ENABLE; + usart2_hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + usart2_hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + usart2_hdma_rx.Init.Mode = DMA_NORMAL; + usart2_hdma_rx.Init.Priority = DMA_PRIORITY_HIGH; + + HAL_DMA_Init(&usart2_hdma_rx); + + /* Associate the initialized DMA handle to the the UART handle */ + __HAL_LINKDMA(&Uart2Handle, hdmarx, usart2_hdma_rx); + } + usart2_set_priorities(comm_dev,priorities); + + /* Initialize the comm structure */ + comm_dev->send_irq=usart2_send_irq; + comm_dev->enable_tx_irq=usart2_enable_tx_irq; + comm_dev->receive_irq=usart2_receive_irq; + comm_dev->cancel_receive_irq=usart2_cancel_receive_irq; + if(comm_dev->use_dma) + { + comm_dev->send_dma=usart2_send_dma; + comm_dev->receive_dma=usart2_receive_dma; + comm_dev->cancel_receive_dma=usart2_cancel_receive_dma; + } + comm_dev->irq_send_cb=0x00000000; + comm_dev->irq_receive_cb=0x00000000; + comm_dev->dma_send_cb=0x00000000; + comm_dev->dma_receive_cb=0x00000000; + + /* initialize internal variables */ + usart2_comm_dev=comm_dev; +} + +void usart2_config(TComm *comm_dev,UART_InitTypeDef *conf) +{ + Uart2Handle.Init.BaudRate = conf->BaudRate; + Uart2Handle.Init.WordLength = conf->WordLength; + Uart2Handle.Init.StopBits = conf->StopBits; + Uart2Handle.Init.Parity = conf->Parity; + Uart2Handle.Init.Mode = conf->Mode; + Uart2Handle.Init.HwFlowCtl = conf->HwFlowCtl; + Uart2Handle.Init.OverSampling = conf->OverSampling; + Uart2Handle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; + HAL_UART_Init(&Uart2Handle); +} + +void usart2_set_priorities(TComm *comm_dev,TUSART_IRQ_Priorities *priorities) +{ + HAL_NVIC_SetPriority(USART_IRQn, priorities->irq_priority,priorities->irq_subpriority); + HAL_NVIC_EnableIRQ(USART_IRQn); + if(comm_dev->use_dma) + { + HAL_NVIC_SetPriority(USART_DMA_TX_IRQn, priorities->dma_tx_priority,priorities->dma_tx_subpriority); + HAL_NVIC_EnableIRQ(USART_DMA_TX_IRQn); + HAL_NVIC_SetPriority(USART_DMA_RX_IRQn, priorities->dma_rx_priority,priorities->dma_rx_subpriority); + HAL_NVIC_EnableIRQ(USART_DMA_RX_IRQn); + } +} + +void usart2_set_baudrate(TComm *comm_dev,unsigned int baudrate) +{ + Uart2Handle.Init.BaudRate = baudrate; + HAL_UART_Init(&Uart2Handle); +} + +/* IRQ functions */ +unsigned char usart2_send_irq(unsigned char first_byte) +{ + __HAL_UART_CLEAR_IT(&Uart2Handle,UART_IT_TC); + __HAL_UART_ENABLE_IT(&Uart2Handle, UART_IT_TC); + Uart2Handle.Instance->TDR=first_byte; + + return 0x00; +} + +unsigned char usart2_enable_tx_irq(void) +{ + __HAL_UART_CLEAR_IT(&Uart2Handle,UART_IT_TC); + __HAL_UART_ENABLE_IT(&Uart2Handle, UART_IT_TC); + + return 0x00; +} + +unsigned char usart2_receive_irq(void) +{ + /* enable the rx interrupt */ + __HAL_UART_ENABLE_IT(&Uart2Handle, UART_IT_RXNE); + + return 0x00; +} + +unsigned char usart2_cancel_receive_irq(void) +{ + /* disable the rx interrupt */ + __HAL_UART_DISABLE_IT(&Uart2Handle, UART_IT_RXNE); + + return 0x00; +} + +/* DMA functions */ +unsigned char usart2_send_dma(unsigned char *data,unsigned short int length) +{ + HAL_DMA_Start_IT(Uart2Handle.hdmatx,(uint32_t)data,(uint32_t)&Uart2Handle.Instance->TDR,length); + /* Clear the TC flag in the SR register by writing 0 to it */ + __HAL_UART_CLEAR_IT(&Uart2Handle,UART_IT_TC); + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the UART CR3 register */ + SET_BIT(Uart2Handle.Instance->CR3, USART_CR3_DMAT); + + return 0x00; +} + +unsigned char usart2_receive_dma(unsigned char *data,unsigned short int length) +{ + HAL_DMA_Start_IT(Uart2Handle.hdmarx,(uint32_t)&Uart2Handle.Instance->RDR,(uint32_t)data,length); + SET_BIT(Uart2Handle.Instance->CR3, USART_CR3_DMAR); + + return 0x00; +} + +unsigned char usart2_cancel_receive_dma(void) +{ + CLEAR_BIT(Uart2Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR)); + HAL_DMA_Abort(Uart2Handle.hdmarx); + + return 0x00; +} + -- GitLab