diff --git a/f4/usart/include/usart1.h b/f4/usart/include/usart1.h index 8291075445980ee2f908e8621e0a1e9379997b0a..4c5f41eebcd5d2205f0e88f030e2d1bdb911f815 100644 --- a/f4/usart/include/usart1.h +++ b/f4/usart/include/usart1.h @@ -1,9 +1,22 @@ #ifndef USART1_F4_H #define USART1_F4_H +#include "stm32f4xx_hal.h" +#include "usart_common.h" #include "comm.h" /* public functions */ -void usart1_init(TComm *comm_dev); +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); +/* IRQ functions */ +unsigned char usart1_send_irq(unsigned char first_byte); +unsigned char usart1_enable_tx_irq(void); +unsigned char usart1_receive_irq(void); +unsigned char usart1_cancel_receive_irq(void); +/* DMA functions */ +unsigned char usart1_send_dma(unsigned char *data,unsigned short int length); +unsigned char usart1_receive_dma(unsigned char *data,unsigned short int length); +unsigned char usart1_cancel_receive_dma(void); #endif diff --git a/f4/usart/include/usart2.h b/f4/usart/include/usart2.h index fd9c29fd28d12df3369275a6b3a4f6df525e402c..65bbfaea37e42f7987a7c62ffe0f996b625a4864 100644 --- a/f4/usart/include/usart2.h +++ b/f4/usart/include/usart2.h @@ -1,18 +1,22 @@ #ifndef USART2_F4_H #define USART2_F4_H +#include "stm32f4xx_hal.h" #include "usart_common.h" #include "comm.h" /* public functions */ -void usart2_init(TComm *comm_dev,TUSART_IRQ_Priorities *priorities); +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); /* IRQ functions */ -unsigned char usart2_send_irq(unsigned char *data,unsigned int length); -unsigned char usart2_receive_irq(unsigned int length); +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 int lenght); -unsigned char usart2_receive_dma(unsigned int length); +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/f4/usart/include/usart4.h b/f4/usart/include/usart4.h new file mode 100644 index 0000000000000000000000000000000000000000..78213da290f03c2c9769082e76f6625ef558b146 --- /dev/null +++ b/f4/usart/include/usart4.h @@ -0,0 +1,22 @@ +#ifndef USART4_F4_H +#define USART4_F4_H + +#include "stm32f4xx_hal.h" +#include "usart_common.h" +#include "comm.h" + +/* public functions */ +void usart4_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *priorities); +void usart4_config(TComm *comm_dev,UART_InitTypeDef *conf); +void usart4_set_priorities(TComm *comm_dev,TUSART_IRQ_Priorities *priorities); +/* IRQ functions */ +unsigned char usart4_send_irq(unsigned char first_byte); +unsigned char usart4_enable_tx_irq(void); +unsigned char usart4_receive_irq(void); +unsigned char usart4_cancel_receive_irq(void); +/* DMA functions */ +unsigned char usart4_send_dma(unsigned char *data,unsigned short int length); +unsigned char usart4_receive_dma(unsigned char *data,unsigned short int length); +unsigned char usart4_cancel_receive_dma(void); + +#endif diff --git a/f4/usart/src/usart1.c b/f4/usart/src/usart1.c index 70304ca31394486265883f654f427a772a3b2a3c..1622ccfd6e2d6e00906f044f30bc4243f20462a4 100644 --- a/f4/usart/src/usart1.c +++ b/f4/usart/src/usart1.c @@ -1,7 +1,342 @@ #include "usart1.h" +#define USART USART1 +#define USART_ENABLE_CLK __HAL_RCC_USART1_CLK_ENABLE() +#define USART_IRQn USART1_IRQn +#define USART_IRQHandler USART1_IRQHandler + +#define USART_TX_PIN GPIO_PIN_9 +#define USART_TX_GPIO_PORT GPIOA +#define USART_ENABLE_TX_GPIO_CLK __HAL_RCC_GPIOA_CLK_ENABLE() + +#define USART_RX_PIN GPIO_PIN_10 +#define USART_RX_GPIO_PORT GPIOA +#define USART_ENABLE_RX_GPIO_CLK __HAL_RCC_GPIOA_CLK_ENABLE() + +/* DMA configuration */ +#define USART_DMA_CHANNEL DMA_CHANNEL_4 +#define USART_ENABLE_DMA_CLK __HAL_RCC_DMA2_CLK_ENABLE() + +#define USART_TX_DMA_STREAM DMA2_Stream7 +#define USART_RX_DMA_STREAM DMA2_Stream2 + +#define USART_DMA_TX_IRQn DMA2_Stream7_IRQn +#define USART_DMA_RX_IRQn DMA2_Stream2_IRQn +#define USART_DMA_TX_IRQHandler DMA2_Stream7_IRQHandler +#define USART_DMA_RX_IRQHandler DMA2_Stream2_IRQHandler + +// private variables +UART_HandleTypeDef Uart1Handle; +DMA_HandleTypeDef usart1_hdma_tx; +DMA_HandleTypeDef usart1_hdma_rx; +TComm *usart1_comm_dev; + +// interrupt handlers +void USART_IRQHandler(void) +{ + unsigned char data,ret; + uint32_t source; + + if(__HAL_UART_GET_FLAG(&Uart1Handle, UART_FLAG_RXNE) != RESET) + { + if(__HAL_UART_GET_IT_SOURCE(&Uart1Handle, UART_IT_RXNE) !=RESET) + { + __HAL_UART_CLEAR_FLAG(&Uart1Handle,UART_FLAG_RXNE); + data=(uint8_t)(Uart1Handle.Instance->DR & (uint8_t)0x00FF); + // call the reception function + if(!comm_do_irq_receive(usart1_comm_dev,data)) + __HAL_UART_DISABLE_IT(&Uart1Handle, UART_IT_RXNE); + } + } + if(__HAL_UART_GET_FLAG(&Uart1Handle, UART_FLAG_TC) != RESET) + { + if(__HAL_UART_GET_IT_SOURCE(&Uart1Handle, UART_IT_TC) !=RESET) + { + __HAL_UART_CLEAR_FLAG(&Uart1Handle,UART_FLAG_TC); + ret=comm_do_irq_send(usart1_comm_dev,&data); + if(ret==0x01) + Uart1Handle.Instance->DR=data; + else if(ret==0x00) + __HAL_UART_DISABLE_IT(&Uart1Handle, UART_IT_TC); + } + } + if(__HAL_UART_GET_FLAG(&Uart1Handle, UART_FLAG_PE) != RESET)// parity error + { + if(__HAL_UART_GET_IT_SOURCE(&Uart1Handle, UART_IT_PE) !=RESET) + { + __HAL_UART_CLEAR_PEFLAG(&Uart1Handle); + } + } + source=__HAL_UART_GET_IT_SOURCE(&Uart1Handle, UART_IT_ERR); + if(__HAL_UART_GET_FLAG(&Uart1Handle, UART_FLAG_FE) != RESET)// frame error + { + if(source !=RESET) + { + __HAL_UART_CLEAR_FEFLAG(&Uart1Handle); + } + } + if(__HAL_UART_GET_FLAG(&Uart1Handle, UART_FLAG_NE) != RESET)// noise error + { + if(source !=RESET) + { + __HAL_UART_CLEAR_NEFLAG(&Uart1Handle); + } + } + if(__HAL_UART_GET_FLAG(&Uart1Handle, UART_FLAG_ORE) != RESET)// overrun error + { + if(source !=RESET) + { + __HAL_UART_CLEAR_OREFLAG(&Uart1Handle); + } + } +} + +void USART_DMA_TX_IRQHandler(void) +{ + if(__HAL_DMA_GET_FLAG(Uart1Handle.hdmatx,__HAL_DMA_GET_TE_FLAG_INDEX(Uart1Handle.hdmatx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart1Handle.hdmatx, DMA_IT_TE) != RESET) + { + /* Disable the transfer error interrupt */ + __HAL_DMA_DISABLE_IT(Uart1Handle.hdmatx, DMA_IT_TE); + /* Clear the transfer error flag */ + __HAL_DMA_CLEAR_FLAG(Uart1Handle.hdmatx, __HAL_DMA_GET_TE_FLAG_INDEX(Uart1Handle.hdmatx)); + } + } + if(__HAL_DMA_GET_FLAG(Uart1Handle.hdmatx,__HAL_DMA_GET_TC_FLAG_INDEX(Uart1Handle.hdmatx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart1Handle.hdmatx, DMA_IT_TC) != RESET) + { + /* Disable the half transfer interrupt */ + __HAL_DMA_DISABLE_IT(Uart1Handle.hdmatx, DMA_IT_TC); + /* Clear the transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(Uart1Handle.hdmatx, __HAL_DMA_GET_TC_FLAG_INDEX(Uart1Handle.hdmatx)); + CLEAR_BIT(Uart1Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR)); + HAL_DMA_Abort(Uart1Handle.hdmatx); + // call the user function + comm_do_dma_send(usart1_comm_dev); + } + } + if(__HAL_DMA_GET_FLAG(Uart1Handle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart1Handle.hdmatx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart1Handle.hdmatx, DMA_IT_HT) != RESET) + { + /* Disable the half transfer interrupt */ + __HAL_DMA_DISABLE_IT(Uart1Handle.hdmatx, DMA_IT_HT); + /* Clear the half transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(Uart1Handle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart1Handle.hdmatx)); + } + } +} + +void USART_DMA_RX_IRQHandler(void) +{ + if(__HAL_DMA_GET_FLAG(Uart1Handle.hdmarx,__HAL_DMA_GET_TE_FLAG_INDEX(Uart1Handle.hdmarx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart1Handle.hdmarx, DMA_IT_TE) != RESET) + { + /* Disable the transfer error interrupt */ + __HAL_DMA_DISABLE_IT(Uart1Handle.hdmarx, DMA_IT_TE); + /* Clear the transfer error flag */ + __HAL_DMA_CLEAR_FLAG(Uart1Handle.hdmarx, __HAL_DMA_GET_TE_FLAG_INDEX(Uart1Handle.hdmarx)); + } + } + if(__HAL_DMA_GET_FLAG(Uart1Handle.hdmarx,__HAL_DMA_GET_TC_FLAG_INDEX(Uart1Handle.hdmarx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart1Handle.hdmarx, DMA_IT_TC) != RESET) + { + /* Disable the transfer complete interrupt */ + __HAL_DMA_DISABLE_IT(Uart1Handle.hdmarx, DMA_IT_TC); + /* Clear the transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(Uart1Handle.hdmarx, __HAL_DMA_GET_TC_FLAG_INDEX(Uart1Handle.hdmarx)); + CLEAR_BIT(Uart1Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR)); + HAL_DMA_Abort(Uart1Handle.hdmarx); + // call the user function + comm_do_dma_receive(usart1_comm_dev); + } + } + if(__HAL_DMA_GET_FLAG(Uart1Handle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart1Handle.hdmarx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart1Handle.hdmarx, DMA_IT_HT) != RESET) + { + /* Disable the half transfer interrupt */ + __HAL_DMA_DISABLE_IT(Uart1Handle.hdmarx, DMA_IT_HT); + /* Clear the half transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(Uart1Handle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart1Handle.hdmarx)); + } + } +} + /* public functions*/ -void usart1_init(TComm *comm_dev) +void usart1_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_LOW; + 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; + + Uart1Handle.Instance = USART; + usart1_config(comm_dev,conf); + + if(comm_dev->use_dma) + { + // configure the DMA channels + usart1_hdma_tx.Instance = USART_TX_DMA_STREAM; + usart1_hdma_tx.Init.Channel = USART_DMA_CHANNEL; + usart1_hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + usart1_hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE; + usart1_hdma_tx.Init.MemInc = DMA_MINC_ENABLE; + usart1_hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + usart1_hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + usart1_hdma_tx.Init.Mode = DMA_NORMAL; + usart1_hdma_tx.Init.Priority = DMA_PRIORITY_LOW; + usart1_hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + + HAL_DMA_Init(&usart1_hdma_tx); + + /* Associate the initialized DMA handle to the UART handle */ + __HAL_LINKDMA(&Uart1Handle, hdmatx, usart1_hdma_tx); + + /* Configure the DMA handler for reception process */ + usart1_hdma_rx.Instance = USART_RX_DMA_STREAM; + usart1_hdma_rx.Init.Channel = USART_DMA_CHANNEL; + usart1_hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + usart1_hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE; + usart1_hdma_rx.Init.MemInc = DMA_MINC_ENABLE; + usart1_hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + usart1_hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + usart1_hdma_rx.Init.Mode = DMA_NORMAL; + usart1_hdma_rx.Init.Priority = DMA_PRIORITY_HIGH; + usart1_hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + + HAL_DMA_Init(&usart1_hdma_rx); + + /* Associate the initialized DMA handle to the the UART handle */ + __HAL_LINKDMA(&Uart1Handle, hdmarx, usart1_hdma_rx); + } + usart1_set_priorities(comm_dev,priorities); + + /* Initialize the comm structure */ + comm_dev->send_irq=usart1_send_irq; + comm_dev->enable_tx_irq=usart1_enable_tx_irq; + comm_dev->receive_irq=usart1_receive_irq; + comm_dev->cancel_receive_irq=usart1_cancel_receive_irq; + if(comm_dev->use_dma) + { + comm_dev->send_dma=usart1_send_dma; + comm_dev->receive_dma=usart1_receive_dma; + comm_dev->cancel_receive_dma=usart1_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 */ + usart1_comm_dev=comm_dev; +} + +void usart1_config(TComm *comm_dev,UART_InitTypeDef *conf) +{ + Uart1Handle.Init.BaudRate = conf->BaudRate; + Uart1Handle.Init.WordLength = conf->WordLength; + Uart1Handle.Init.StopBits = conf->StopBits; + Uart1Handle.Init.Parity = conf->Parity; + Uart1Handle.Init.Mode = conf->Mode; + Uart1Handle.Init.HwFlowCtl = conf->HwFlowCtl; + Uart1Handle.Init.OverSampling = conf->OverSampling; + HAL_UART_Init(&Uart1Handle); +} + +void usart1_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); + } +} + +/* IRQ functions */ +unsigned char usart1_send_irq(unsigned char first_byte) +{ + __HAL_UART_CLEAR_FLAG(&Uart1Handle,UART_FLAG_TC); + __HAL_UART_ENABLE_IT(&Uart1Handle, UART_IT_TC); + Uart1Handle.Instance->DR=first_byte; + + return 0x00; +} + +unsigned char usart1_enable_tx_irq(void) +{ + __HAL_UART_CLEAR_FLAG(&Uart1Handle,UART_FLAG_TC); + __HAL_UART_ENABLE_IT(&Uart1Handle, UART_IT_TC); + + return 0x00; +} + +unsigned char usart1_receive_irq(void) +{ + /* enable the rx interrupt */ + __HAL_UART_ENABLE_IT(&Uart1Handle, UART_IT_RXNE); + + return 0x00; +} + +unsigned char usart1_cancel_receive_irq(void) +{ + /* disable the rx interrupt */ + __HAL_UART_DISABLE_IT(&Uart1Handle, UART_IT_RXNE); + + return 0x00; +} + +/* DMA functions */ +unsigned char usart1_send_dma(unsigned char *data,unsigned short int length) +{ + HAL_DMA_Start_IT(Uart1Handle.hdmatx,(uint32_t)data,(uint32_t)&Uart1Handle.Instance->DR,length); + /* Clear the TC flag in the SR register by writing 0 to it */ + __HAL_UART_CLEAR_FLAG(&Uart1Handle,UART_FLAG_TC); + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the UART CR3 register */ + SET_BIT(Uart1Handle.Instance->CR3, USART_CR3_DMAT); + + return 0x00; +} + +unsigned char usart1_receive_dma(unsigned char *data,unsigned short int length) +{ + HAL_DMA_Start_IT(Uart1Handle.hdmarx,(uint32_t)&Uart1Handle.Instance->DR,(uint32_t)data,length); + SET_BIT(Uart1Handle.Instance->CR3, USART_CR3_DMAR); + + return 0x00; +} + +unsigned char usart1_cancel_receive_dma(void) { + CLEAR_BIT(Uart1Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR)); + HAL_DMA_Abort(Uart1Handle.hdmarx); + return 0x00; } + diff --git a/f4/usart/src/usart2.c b/f4/usart/src/usart2.c index 2d9a4c2aca734d62621df44d306208dba5840cd3..ee1cc5562244f5717523f9479216bb3873d0f5a5 100644 --- a/f4/usart/src/usart2.c +++ b/f4/usart/src/usart2.c @@ -1,41 +1,24 @@ #include "usart2.h" #define USART USART2 -#define USART_CLK RCC_APB1Periph_USART2 -#define USART_CLK_INIT RCC_APB1PeriphClockCmd +#define USART_ENABLE_CLK __HAL_RCC_USART2_CLK_ENABLE() #define USART_IRQn USART2_IRQn #define USART_IRQHandler USART2_IRQHandler -#define USART_TX_PIN GPIO_Pin_2 -#define USART_TX_GPIO_PORT GPIOA -#define USART_TX_GPIO_CLK RCC_AHB1Periph_GPIOA -#define USART_TX_SOURCE GPIO_PinSource2 -#define USART_TX_AF GPIO_AF_USART2 +#define USART_TX_PIN GPIO_PIN_2 +#define USART_TX_GPIO_PORT GPIOA +#define USART_ENABLE_TX_GPIO_CLK __HAL_RCC_GPIOA_CLK_ENABLE() -#define USART_RX_PIN GPIO_Pin_3 +#define USART_RX_PIN GPIO_PIN_3 #define USART_RX_GPIO_PORT GPIOA -#define USART_RX_GPIO_CLK RCC_AHB1Periph_GPIOA -#define USART_RX_SOURCE GPIO_PinSource3 -#define USART_RX_AF GPIO_AF_USART2 +#define USART_ENABLE_RX_GPIO_CLK __HAL_RCC_GPIOA_CLK_ENABLE() -#define USART_DMA DMA1 -#define USART_DMA_CLK RCC_AHB1Periph_DMA1 +/* DMA configuration */ +#define USART_DMA_CHANNEL DMA_CHANNEL_4 +#define USART_ENABLE_DMA_CLK __HAL_RCC_DMA1_CLK_ENABLE() -#define USART_TX_DMA_CHANNEL DMA_Channel_4 #define USART_TX_DMA_STREAM DMA1_Stream6 -#define USART_TX_DMA_FLAG_FEIF DMA_FLAG_FEIF6 -#define USART_TX_DMA_FLAG_DMEIF DMA_FLAG_DMEIF6 -#define USART_TX_DMA_FLAG_TEIF DMA_FLAG_TEIF6 -#define USART_TX_DMA_FLAG_HTIF DMA_FLAG_HTIF6 -#define USART_TX_DMA_FLAG_TCIF DMA_FLAG_TCIF6 - -#define USART_RX_DMA_CHANNEL DMA_Channel_4 #define USART_RX_DMA_STREAM DMA1_Stream5 -#define USART_RX_DMA_FLAG_FEIF DMA_FLAG_FEIF5 -#define USART_RX_DMA_FLAG_DMEIF DMA_FLAG_DMEIF5 -#define USART_RX_DMA_FLAG_TEIF DMA_FLAG_TEIF5 -#define USART_RX_DMA_FLAG_HTIF DMA_FLAG_HTIF5 -#define USART_RX_DMA_FLAG_TCIF DMA_FLAG_TCIF5 #define USART_DMA_TX_IRQn DMA1_Stream6_IRQn #define USART_DMA_RX_IRQn DMA1_Stream5_IRQn @@ -43,182 +26,215 @@ #define USART_DMA_RX_IRQHandler DMA1_Stream5_IRQHandler // private variables -DMA_InitTypeDef DMA_TX_InitStructure; -DMA_InitTypeDef DMA_RX_InitStructure; +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; + unsigned char data,ret; + uint32_t source; - if(USART_GetITStatus(USART, USART_IT_RXNE) != RESET) + if(__HAL_UART_GET_FLAG(&Uart2Handle, UART_FLAG_RXNE) != RESET) + { + if(__HAL_UART_GET_IT_SOURCE(&Uart2Handle, UART_IT_RXNE) !=RESET) + { + __HAL_UART_CLEAR_FLAG(&Uart2Handle,UART_FLAG_RXNE); + data=(uint8_t)(Uart2Handle.Instance->DR & (uint8_t)0x00FF); + // call the reception function + if(!comm_do_irq_receive(usart2_comm_dev,data)) + __HAL_UART_DISABLE_IT(&Uart2Handle, UART_IT_RXNE); + } + } + if(__HAL_UART_GET_FLAG(&Uart2Handle, UART_FLAG_TC) != RESET) + { + if(__HAL_UART_GET_IT_SOURCE(&Uart2Handle, UART_IT_TC) !=RESET) + { + __HAL_UART_CLEAR_FLAG(&Uart2Handle,UART_FLAG_TC); + ret=comm_do_irq_send(usart2_comm_dev,&data); + if(ret==0x01) + Uart2Handle.Instance->DR=data; + else if(ret==0x00) + __HAL_UART_DISABLE_IT(&Uart2Handle, UART_IT_TC); + } + } + if(__HAL_UART_GET_FLAG(&Uart2Handle, UART_FLAG_PE) != RESET)// parity error { - USART_ClearFlag(USART,USART_FLAG_RXNE); - data=USART_ReceiveData(USART); - // call the reception function - if(!comm_do_irq_receive(usart2_comm_dev,data)) - USART_ITConfig(USART, USART_IT_RXNE, DISABLE); + if(__HAL_UART_GET_IT_SOURCE(&Uart2Handle, UART_IT_PE) !=RESET) + { + __HAL_UART_CLEAR_PEFLAG(&Uart2Handle); + } } - if(USART_GetITStatus(USART, USART_IT_TC) != RESET) + source=__HAL_UART_GET_IT_SOURCE(&Uart2Handle, UART_IT_ERR); + if(__HAL_UART_GET_FLAG(&Uart2Handle, UART_FLAG_FE) != RESET)// frame error { - USART_ClearFlag(USART,USART_FLAG_TC); - if(comm_do_irq_send(usart2_comm_dev,&data)) - USART_SendData(USART,data); - else - USART_ITConfig(USART, USART_IT_TC, DISABLE); + if(source !=RESET) + { + __HAL_UART_CLEAR_FEFLAG(&Uart2Handle); + } } - if(USART_GetITStatus(USART,USART_FLAG_ORE) != RESET)// overrun error + if(__HAL_UART_GET_FLAG(&Uart2Handle, UART_FLAG_NE) != RESET)// noise error { - // cancel any pending reception - USART_ITConfig(USART, USART_IT_RXNE, DISABLE); - usart2_comm_dev->irq_receiving=0x00; + if(source !=RESET) + { + __HAL_UART_CLEAR_NEFLAG(&Uart2Handle); + } } - if(USART_GetITStatus(USART,USART_IT_PE) != RESET)// parity error + if(__HAL_UART_GET_FLAG(&Uart2Handle, UART_FLAG_ORE) != RESET)// overrun error { - // cancel any pending reception - USART_ITConfig(USART, USART_IT_RXNE, DISABLE); - usart2_comm_dev->irq_receiving=0x00; + if(source !=RESET) + { + __HAL_UART_CLEAR_OREFLAG(&Uart2Handle); + } } } void USART_DMA_TX_IRQHandler(void) { - DMA_Cmd(USART_TX_DMA_STREAM,DISABLE); - DMA_ClearFlag(USART_TX_DMA_STREAM,USART_TX_DMA_FLAG_TCIF); - DMA_ClearITPendingBit(USART_TX_DMA_STREAM,USART_TX_DMA_FLAG_TCIF); - USART_DMACmd(USART, USART_DMAReq_Tx, DISABLE); - // call the user function + 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) { - DMA_Cmd(USART_RX_DMA_STREAM,DISABLE); - DMA_ClearFlag(USART_RX_DMA_STREAM,USART_RX_DMA_FLAG_TCIF); - DMA_ClearITPendingBit(USART_RX_DMA_STREAM,USART_RX_DMA_FLAG_TCIF); - USART_DMACmd(USART, USART_DMAReq_Rx, DISABLE); - // call the user function + 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,TUSART_IRQ_Priorities *priorities) +void usart2_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *priorities) { GPIO_InitTypeDef GPIO_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; /* Enable GPIO clock */ - USART_CLK_INIT(USART_CLK, ENABLE); - USART_TX_GPIO_CLK(USART_TX_GPIO_CLK,ENABLE) - USART_RX_GPIO_CLK(USART_RX_GPIO_CLK,ENABLE); - - /* Connect USART pins to AF7 */ - GPIO_PinAFConfig(USART_TX_GPIO_PORT, USART_TX_SOURCE, USART_TX_AF); - GPIO_PinAFConfig(USART_RX_GPIO_PORT, USART_RX_SOURCE, USART_RX_AF); + 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.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Pin = USART_TX_PIN; - GPIO_Init(USART_TX_GPIO_PORT, &GPIO_InitStructure); - - GPIO_InitStructure.GPIO_Pin = USART_RX_PIN; - GPIO_Init(USART_RX_GPIO_PORT, &GPIO_InitStructure); - - /* configure the interrupts */ - NVIC_InitStructure.NVIC_IRQChannel = USART_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = priorities->irq_priority; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = priorities->irq_subpriority; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - - USART_ITConfig(USART, USART_IT_RXNE | - USART_IT_ORE | - USART_IT_TXE | - USART_IT_CTS | - USART_IT_LBD | - USART_IT_IDLE | - USART_IT_PE | - USART_IT_ERR | - USART_IT_TC, DISABLE); - - /* Clear all USART interrupt flags */ - USART_ClearFlag(USART,USART_FLAG_RXNE | - USART_FLAG_ORE | - USART_FLAG_TXE | - USART_FLAG_CTS | - USART_FLAG_LBD | - USART_FLAG_IDLE | - USART_FLAG_PE | - USART_FLAG_TC); - - /* Clear all USART interrupt pending bits */ - USART_ClearITPendingBit(USART, USART_FLAG_RXNE | - USART_FLAG_ORE | - USART_FLAG_TXE | - USART_FLAG_CTS | - USART_FLAG_LBD | - USART_FLAG_IDLE | - USART_FLAG_PE | - USART_FLAG_TC); - - // configure the DMA channels + GPIO_InitStructure.Pin = USART_TX_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; + GPIO_InitStructure.Pull = GPIO_PULLUP; + GPIO_InitStructure.Speed = GPIO_SPEED_LOW; + GPIO_InitStructure.Alternate = GPIO_AF7_USART2; + 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) { - /* enable the DMA clock */ - USART_DMA_CLK(USART_DMA_CLK, ENABLE); - /* Configure TX DMA */ - DMA_DeInit(USART_TX_DMA_STREAM); - DMA_TX_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; - DMA_TX_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; - DMA_TX_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; - DMA_TX_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; - DMA_TX_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_TX_InitStructure.DMA_Mode = DMA_Mode_Normal; - DMA_TX_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(USART->DR)); - DMA_TX_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; - DMA_TX_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; - DMA_TX_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DMA_TX_InitStructure.DMA_Priority = DMA_Priority_High; - DMA_TX_InitStructure.DMA_Channel = USART_TX_DMA_CHANNEL; - DMA_TX_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; - /* initialize DMA interrupts */ - NVIC_InitStructure.NVIC_IRQChannel = USART_DMA_TX_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = priorities->dma_tx_priority; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = priorities->dma_tx_subpriority; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - DMA_ITConfig(USART_TX_DMA_STREAM,DMA_IT_TC,ENABLE); - DMA_ITConfig(USART_TX_DMA_STREAM,DMA_IT_HT | DMA_IT_TE | DMA_IT_FE | DMA_IT_DME,DISABLE); - - /* Configure RX DMA */ - DMA_DeInit(USART_RX_DMA_STREAM); - DMA_RX_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; - DMA_RX_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; - DMA_RX_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; - DMA_RX_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; - DMA_RX_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_RX_InitStructure.DMA_Mode = DMA_Mode_Normal; - DMA_RX_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(USART->DR)); - DMA_RX_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; - DMA_RX_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; - DMA_RX_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DMA_RX_InitStructure.DMA_Priority = DMA_Priority_High; - DMA_RX_InitStructure.DMA_Channel = USART_RX_DMA_CHANNEL; - DMA_RX_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; - /* initialize DMA interrupts */ - NVIC_InitStructure.NVIC_IRQChannel = USART_DMA_RX_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = priorities->dma_rx_priority; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = priority->dma_rx_subpriority; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - DMA_ITConfig(USART_RX_DMA_STREAM,DMA_IT_TC,ENABLE); - DMA_ITConfig(USART_RX_DMA_STREAM,DMA_IT_HT | DMA_IT_TE | DMA_IT_FE | DMA_IT_DME,DISABLE); + // configure the DMA channels + usart2_hdma_tx.Instance = USART_TX_DMA_STREAM; + usart2_hdma_tx.Init.Channel = USART_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; + usart2_hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + + 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_STREAM; + usart2_hdma_rx.Init.Channel = USART_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; + usart2_hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + + 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->receive=usart2_receive; 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) @@ -234,40 +250,93 @@ void usart2_init(TComm *comm_dev,TUSART_IRQ_Priorities *priorities) /* 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; + HAL_UART_Init(&Uart2Handle); +} - /* Enable the USART2 */ - USART_Cmd(USART, ENABLE); +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); + } } /* IRQ functions */ -unsigned char usart2_send_irq(unsigned char *data,unsigned int length) +unsigned char usart2_send_irq(unsigned char first_byte) { + __HAL_UART_CLEAR_FLAG(&Uart2Handle,UART_FLAG_TC); + __HAL_UART_ENABLE_IT(&Uart2Handle, UART_IT_TC); + Uart2Handle.Instance->DR=first_byte; + return 0x00; } -unsigned char usart2_receive_irq(unsigned int length) +unsigned char usart2_enable_tx_irq(void) { + __HAL_UART_CLEAR_FLAG(&Uart2Handle,UART_FLAG_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 int lenght) +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->DR,length); + /* Clear the TC flag in the SR register by writing 0 to it */ + __HAL_UART_CLEAR_FLAG(&Uart2Handle,UART_FLAG_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 int length) +unsigned char usart2_receive_dma(unsigned char *data,unsigned short int length) { + HAL_DMA_Start_IT(Uart2Handle.hdmarx,(uint32_t)&Uart2Handle.Instance->DR,(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; } diff --git a/f4/usart/src/usart3.c b/f4/usart/src/usart3.c index 24a1f696fa387bd43805a2657da20d58e4500807..921746cd4ead2ee457dbf592cf21524119d51954 100644 --- a/f4/usart/src/usart3.c +++ b/f4/usart/src/usart3.c @@ -182,7 +182,7 @@ void usart3_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *p 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.Speed = GPIO_SPEED_LOW; GPIO_InitStructure.Alternate = GPIO_AF7_USART3; HAL_GPIO_Init(USART_TX_GPIO_PORT, &GPIO_InitStructure); @@ -197,7 +197,7 @@ void usart3_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *p if(comm_dev->use_dma) { // configure the DMA channels - usart3_hdma_tx.Instance = USART_RX_DMA_STREAM; + usart3_hdma_tx.Instance = USART_TX_DMA_STREAM; usart3_hdma_tx.Init.Channel = USART_DMA_CHANNEL; usart3_hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; usart3_hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE; diff --git a/f4/usart/src/usart4.c b/f4/usart/src/usart4.c new file mode 100644 index 0000000000000000000000000000000000000000..301468416126104a99bf0ee869b01d5824fd4050 --- /dev/null +++ b/f4/usart/src/usart4.c @@ -0,0 +1,342 @@ +#include "usart4.h" + +#define USART USART4 +#define USART_ENABLE_CLK __HAL_RCC_USART4_CLK_ENABLE() +#define USART_IRQn USART4_IRQn +#define USART_IRQHandler USART4_IRQHandler + +#define USART_TX_PIN GPIO_PIN_10 +#define USART_TX_GPIO_PORT GPIOC +#define USART_ENABLE_TX_GPIO_CLK __HAL_RCC_GPIOC_CLK_ENABLE() + +#define USART_RX_PIN GPIO_PIN_11 +#define USART_RX_GPIO_PORT GPIOC +#define USART_ENABLE_RX_GPIO_CLK __HAL_RCC_GPIOC_CLK_ENABLE() + +/* DMA configuration */ +#define USART_DMA_CHANNEL DMA_CHANNEL_4 +#define USART_ENABLE_DMA_CLK __HAL_RCC_DMA1_CLK_ENABLE() + +#define USART_TX_DMA_STREAM DMA1_Stream4 +#define USART_RX_DMA_STREAM DMA1_Stream2 + +#define USART_DMA_TX_IRQn DMA1_Stream4_IRQn +#define USART_DMA_RX_IRQn DMA1_Stream2_IRQn +#define USART_DMA_TX_IRQHandler DMA1_Stream4_IRQHandler +#define USART_DMA_RX_IRQHandler DMA1_Stream2_IRQHandler + +// private variables +UART_HandleTypeDef Uart4Handle; +DMA_HandleTypeDef usart4_hdma_tx; +DMA_HandleTypeDef usart4_hdma_rx; +TComm *usart4_comm_dev; + +// interrupt handlers +void USART_IRQHandler(void) +{ + unsigned char data,ret; + uint32_t source; + + if(__HAL_UART_GET_FLAG(&Uart4Handle, UART_FLAG_RXNE) != RESET) + { + if(__HAL_UART_GET_IT_SOURCE(&Uart4Handle, UART_IT_RXNE) !=RESET) + { + __HAL_UART_CLEAR_FLAG(&Uart4Handle,UART_FLAG_RXNE); + data=(uint8_t)(Uart4Handle.Instance->DR & (uint8_t)0x00FF); + // call the reception function + if(!comm_do_irq_receive(usart4_comm_dev,data)) + __HAL_UART_DISABLE_IT(&Uart4Handle, UART_IT_RXNE); + } + } + if(__HAL_UART_GET_FLAG(&Uart4Handle, UART_FLAG_TC) != RESET) + { + if(__HAL_UART_GET_IT_SOURCE(&Uart4Handle, UART_IT_TC) !=RESET) + { + __HAL_UART_CLEAR_FLAG(&Uart4Handle,UART_FLAG_TC); + ret=comm_do_irq_send(usart4_comm_dev,&data); + if(ret==0x01) + Uart4Handle.Instance->DR=data; + else if(ret==0x00) + __HAL_UART_DISABLE_IT(&Uart4Handle, UART_IT_TC); + } + } + if(__HAL_UART_GET_FLAG(&Uart4Handle, UART_FLAG_PE) != RESET)// parity error + { + if(__HAL_UART_GET_IT_SOURCE(&Uart4Handle, UART_IT_PE) !=RESET) + { + __HAL_UART_CLEAR_PEFLAG(&Uart4Handle); + } + } + source=__HAL_UART_GET_IT_SOURCE(&Uart4Handle, UART_IT_ERR); + if(__HAL_UART_GET_FLAG(&Uart4Handle, UART_FLAG_FE) != RESET)// frame error + { + if(source !=RESET) + { + __HAL_UART_CLEAR_FEFLAG(&Uart4Handle); + } + } + if(__HAL_UART_GET_FLAG(&Uart4Handle, UART_FLAG_NE) != RESET)// noise error + { + if(source !=RESET) + { + __HAL_UART_CLEAR_NEFLAG(&Uart4Handle); + } + } + if(__HAL_UART_GET_FLAG(&Uart4Handle, UART_FLAG_ORE) != RESET)// overrun error + { + if(source !=RESET) + { + __HAL_UART_CLEAR_OREFLAG(&Uart4Handle); + } + } +} + +void USART_DMA_TX_IRQHandler(void) +{ + if(__HAL_DMA_GET_FLAG(Uart4Handle.hdmatx,__HAL_DMA_GET_TE_FLAG_INDEX(Uart4Handle.hdmatx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart4Handle.hdmatx, DMA_IT_TE) != RESET) + { + /* Disable the transfer error interrupt */ + __HAL_DMA_DISABLE_IT(Uart4Handle.hdmatx, DMA_IT_TE); + /* Clear the transfer error flag */ + __HAL_DMA_CLEAR_FLAG(Uart4Handle.hdmatx, __HAL_DMA_GET_TE_FLAG_INDEX(Uart4Handle.hdmatx)); + } + } + if(__HAL_DMA_GET_FLAG(Uart4Handle.hdmatx,__HAL_DMA_GET_TC_FLAG_INDEX(Uart4Handle.hdmatx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart4Handle.hdmatx, DMA_IT_TC) != RESET) + { + /* Disable the half transfer interrupt */ + __HAL_DMA_DISABLE_IT(Uart4Handle.hdmatx, DMA_IT_TC); + /* Clear the transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(Uart4Handle.hdmatx, __HAL_DMA_GET_TC_FLAG_INDEX(Uart4Handle.hdmatx)); + CLEAR_BIT(Uart4Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR)); + HAL_DMA_Abort(Uart4Handle.hdmatx); + // call the user function + comm_do_dma_send(usart4_comm_dev); + } + } + if(__HAL_DMA_GET_FLAG(Uart4Handle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart4Handle.hdmatx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart4Handle.hdmatx, DMA_IT_HT) != RESET) + { + /* Disable the half transfer interrupt */ + __HAL_DMA_DISABLE_IT(Uart4Handle.hdmatx, DMA_IT_HT); + /* Clear the half transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(Uart4Handle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart4Handle.hdmatx)); + } + } +} + +void USART_DMA_RX_IRQHandler(void) +{ + if(__HAL_DMA_GET_FLAG(Uart4Handle.hdmarx,__HAL_DMA_GET_TE_FLAG_INDEX(Uart4Handle.hdmarx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart4Handle.hdmarx, DMA_IT_TE) != RESET) + { + /* Disable the transfer error interrupt */ + __HAL_DMA_DISABLE_IT(Uart4Handle.hdmarx, DMA_IT_TE); + /* Clear the transfer error flag */ + __HAL_DMA_CLEAR_FLAG(Uart4Handle.hdmarx, __HAL_DMA_GET_TE_FLAG_INDEX(Uart4Handle.hdmarx)); + } + } + if(__HAL_DMA_GET_FLAG(Uart4Handle.hdmarx,__HAL_DMA_GET_TC_FLAG_INDEX(Uart4Handle.hdmarx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart4Handle.hdmarx, DMA_IT_TC) != RESET) + { + /* Disable the transfer complete interrupt */ + __HAL_DMA_DISABLE_IT(Uart4Handle.hdmarx, DMA_IT_TC); + /* Clear the transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(Uart4Handle.hdmarx, __HAL_DMA_GET_TC_FLAG_INDEX(Uart4Handle.hdmarx)); + CLEAR_BIT(Uart4Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR)); + HAL_DMA_Abort(Uart4Handle.hdmarx); + // call the user function + comm_do_dma_receive(usart4_comm_dev); + } + } + if(__HAL_DMA_GET_FLAG(Uart4Handle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart4Handle.hdmarx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(Uart4Handle.hdmarx, DMA_IT_HT) != RESET) + { + /* Disable the half transfer interrupt */ + __HAL_DMA_DISABLE_IT(Uart4Handle.hdmarx, DMA_IT_HT); + /* Clear the half transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(Uart4Handle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart4Handle.hdmarx)); + } + } +} + +/* public functions*/ +void usart4_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_LOW; + GPIO_InitStructure.Alternate = GPIO_AF7_USART4; + 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; + + Uart4Handle.Instance = USART; + usart4_config(comm_dev,conf); + + if(comm_dev->use_dma) + { + // configure the DMA channels + usart4_hdma_tx.Instance = USART_TX_DMA_STREAM; + usart4_hdma_tx.Init.Channel = USART_DMA_CHANNEL; + usart4_hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + usart4_hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE; + usart4_hdma_tx.Init.MemInc = DMA_MINC_ENABLE; + usart4_hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + usart4_hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + usart4_hdma_tx.Init.Mode = DMA_NORMAL; + usart4_hdma_tx.Init.Priority = DMA_PRIORITY_LOW; + usart4_hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + + HAL_DMA_Init(&usart4_hdma_tx); + + /* Associate the initialized DMA handle to the UART handle */ + __HAL_LINKDMA(&Uart4Handle, hdmatx, usart4_hdma_tx); + + /* Configure the DMA handler for reception process */ + usart4_hdma_rx.Instance = USART_RX_DMA_STREAM; + usart4_hdma_rx.Init.Channel = USART_DMA_CHANNEL; + usart4_hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + usart4_hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE; + usart4_hdma_rx.Init.MemInc = DMA_MINC_ENABLE; + usart4_hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + usart4_hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + usart4_hdma_rx.Init.Mode = DMA_NORMAL; + usart4_hdma_rx.Init.Priority = DMA_PRIORITY_HIGH; + usart4_hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + + HAL_DMA_Init(&usart4_hdma_rx); + + /* Associate the initialized DMA handle to the the UART handle */ + __HAL_LINKDMA(&Uart4Handle, hdmarx, usart4_hdma_rx); + } + usart4_set_priorities(comm_dev,priorities); + + /* Initialize the comm structure */ + comm_dev->send_irq=usart4_send_irq; + comm_dev->enable_tx_irq=usart4_enable_tx_irq; + comm_dev->receive_irq=usart4_receive_irq; + comm_dev->cancel_receive_irq=usart4_cancel_receive_irq; + if(comm_dev->use_dma) + { + comm_dev->send_dma=usart4_send_dma; + comm_dev->receive_dma=usart4_receive_dma; + comm_dev->cancel_receive_dma=usart4_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 */ + usart4_comm_dev=comm_dev; +} + +void usart4_config(TComm *comm_dev,UART_InitTypeDef *conf) +{ + Uart4Handle.Init.BaudRate = conf->BaudRate; + Uart4Handle.Init.WordLength = conf->WordLength; + Uart4Handle.Init.StopBits = conf->StopBits; + Uart4Handle.Init.Parity = conf->Parity; + Uart4Handle.Init.Mode = conf->Mode; + Uart4Handle.Init.HwFlowCtl = conf->HwFlowCtl; + Uart4Handle.Init.OverSampling = conf->OverSampling; + HAL_UART_Init(&Uart4Handle); +} + +void usart4_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); + } +} + +/* IRQ functions */ +unsigned char usart4_send_irq(unsigned char first_byte) +{ + __HAL_UART_CLEAR_FLAG(&Uart4Handle,UART_FLAG_TC); + __HAL_UART_ENABLE_IT(&Uart4Handle, UART_IT_TC); + Uart4Handle.Instance->DR=first_byte; + + return 0x00; +} + +unsigned char usart4_enable_tx_irq(void) +{ + __HAL_UART_CLEAR_FLAG(&Uart4Handle,UART_FLAG_TC); + __HAL_UART_ENABLE_IT(&Uart4Handle, UART_IT_TC); + + return 0x00; +} + +unsigned char usart4_receive_irq(void) +{ + /* enable the rx interrupt */ + __HAL_UART_ENABLE_IT(&Uart4Handle, UART_IT_RXNE); + + return 0x00; +} + +unsigned char usart4_cancel_receive_irq(void) +{ + /* disable the rx interrupt */ + __HAL_UART_DISABLE_IT(&Uart4Handle, UART_IT_RXNE); + + return 0x00; +} + +/* DMA functions */ +unsigned char usart4_send_dma(unsigned char *data,unsigned short int length) +{ + HAL_DMA_Start_IT(Uart4Handle.hdmatx,(uint32_t)data,(uint32_t)&Uart4Handle.Instance->DR,length); + /* Clear the TC flag in the SR register by writing 0 to it */ + __HAL_UART_CLEAR_FLAG(&Uart4Handle,UART_FLAG_TC); + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the UART CR3 register */ + SET_BIT(Uart4Handle.Instance->CR3, USART_CR3_DMAT); + + return 0x00; +} + +unsigned char usart4_receive_dma(unsigned char *data,unsigned short int length) +{ + HAL_DMA_Start_IT(Uart4Handle.hdmarx,(uint32_t)&Uart4Handle.Instance->DR,(uint32_t)data,length); + SET_BIT(Uart4Handle.Instance->CR3, USART_CR3_DMAR); + + return 0x00; +} + +unsigned char usart4_cancel_receive_dma(void) +{ + CLEAR_BIT(Uart4Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR)); + HAL_DMA_Abort(Uart4Handle.hdmarx); + + return 0x00; +} +