diff --git a/f1/usart/src/usart1_remap.c b/f1/usart/src/usart1_remap.c new file mode 100644 index 0000000000000000000000000000000000000000..9d17fb30df8ca20040f79212950894c20e0ff05f --- /dev/null +++ b/f1/usart/src/usart1_remap.c @@ -0,0 +1,340 @@ +#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_6 +#define USART_TX_GPIO_PORT GPIOB +#define USART_ENABLE_TX_GPIO_CLK __HAL_RCC_GPIOB_CLK_ENABLE() + +#define USART_RX_PIN GPIO_PIN_7 +#define USART_RX_GPIO_PORT GPIOB +#define USART_ENABLE_RX_GPIO_CLK __HAL_RCC_GPIOB_CLK_ENABLE() + +/* DMA configuration */ +#define USART_DMA DMA1 +#define USART_ENABLE_DMA_CLK __HAL_RCC_DMA1_CLK_ENABLE() + +#define USART_TX_DMA_CHANNEL DMA1_Channel4 +#define USART_RX_DMA_CHANNEL DMA1_Channel5 + +#define USART_DMA_TX_IRQn DMA1_Channel4_IRQn +#define USART_DMA_RX_IRQn DMA1_Channel5_IRQn +#define USART_DMA_TX_IRQHandler DMA1_Channel4_IRQHandler +#define USART_DMA_RX_IRQHandler DMA1_Channel5_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,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 + + USART_ENABLE_CLK; + + /* 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.Speed = GPIO_SPEED_HIGH; + HAL_GPIO_Init(USART_TX_GPIO_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = USART_RX_PIN; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Mode = GPIO_MODE_INPUT; + HAL_GPIO_Init(USART_RX_GPIO_PORT, &GPIO_InitStructure); + + __HAL_AFIO_REMAP_USART1_ENABLE(); + + Uart1Handle.Instance = USART; + usart1_config(comm_dev,conf); + + if(comm_dev->use_dma) + { + // configure the DMA channels + usart1_hdma_tx.Instance = USART_TX_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; + + 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_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; + + 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/f3/usart/include/usart1.h b/f3/usart/include/usart1.h new file mode 100644 index 0000000000000000000000000000000000000000..9cdff3ae9f45f13845e86784410cac68b9708cc2 --- /dev/null +++ b/f3/usart/include/usart1.h @@ -0,0 +1,22 @@ +#ifndef USART1_F3_H +#define USART1_F3_H + +#include "stm32f3xx_hal.h" +#include "usart_common.h" +#include "comm.h" + +/* public functions */ +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/f3/usart/include/usart_common.h b/f3/usart/include/usart_common.h new file mode 100644 index 0000000000000000000000000000000000000000..924628bc440c1fca59af82c1c425bc21ab3a087f --- /dev/null +++ b/f3/usart/include/usart_common.h @@ -0,0 +1,14 @@ +#ifndef USART_COMMON_F3_H +#define USART_COMMON_F3_H + +typedef struct +{ + unsigned char irq_priority; + unsigned char irq_subpriority; + unsigned char dma_rx_priority; + unsigned char dma_rx_subpriority; + unsigned char dma_tx_priority; + unsigned char dma_tx_subpriority; +}TUSART_IRQ_Priorities; + +#endif diff --git a/f3/usart/src/usart1.c b/f3/usart/src/usart1.c new file mode 100644 index 0000000000000000000000000000000000000000..9cf99d3c34ce6d5a8bf0f284e8be039ceac50765 --- /dev/null +++ b/f3/usart/src/usart1.c @@ -0,0 +1,348 @@ +#include "usart1.h" + +#define USART USART1 +#define USART_ENABLE_CLK __USART1_CLK_ENABLE() +#define USART_IRQn USART1_IRQn +#define USART_IRQHandler USART1_IRQHandler + +#define USART_TX_PIN GPIO_PIN_4 +#define USART_TX_GPIO_PORT GPIOC +#define USART_ENABLE_TX_GPIO_CLK __GPIOC_CLK_ENABLE() + +#define USART_RX_PIN GPIO_PIN_5 +#define USART_RX_GPIO_PORT GPIOC +#define USART_ENABLE_RX_GPIO_CLK __GPIOC_CLK_ENABLE() + +/* DMA configuration */ +#define USART_DMA DMA1 +#define USART_ENABLE_DMA_CLK __DMA1_CLK_ENABLE() + +#define USART_TX_DMA_CHANNEL DMA1_Channel4 +#define USART_RX_DMA_CHANNEL DMA1_Channel5 + +#define USART_DMA_TX_IRQn DMA1_Channel4_IRQn +#define USART_DMA_RX_IRQn DMA1_Channel5_IRQn +#define USART_DMA_TX_IRQHandler DMA1_Channel4_IRQHandler +#define USART_DMA_RX_IRQHandler DMA1_Channel5_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; + + /* USART parity error interrupt occured ------------------------------------*/ + if(__HAL_USART_GET_IT(&Uart1Handle, USART_IT_PE) != RESET) + { + if(__HAL_USART_GET_IT_SOURCE(&Uart1Handle, USART_IT_PE) != RESET) + { + __HAL_USART_CLEAR_IT(&Uart1Handle, USART_IT_PE); + } + } + + /* USART frame error interrupt occured -------------------------------------*/ + if(__HAL_USART_GET_IT(&Uart1Handle, USART_IT_FE) != RESET) + { + if(__HAL_USART_GET_IT_SOURCE(&Uart1Handle, USART_IT_ERR) != RESET) + { + __HAL_USART_CLEAR_IT(&Uart1Handle, USART_IT_FE); + } + } + + /* USART noise error interrupt occured -------------------------------------*/ + if(__HAL_USART_GET_IT(&Uart1Handle, USART_IT_NE) != RESET) + { + if(__HAL_USART_GET_IT_SOURCE(&Uart1Handle, USART_IT_ERR) != RESET) + { + __HAL_USART_CLEAR_IT(&Uart1Handle, USART_IT_NE); + } + } + + /* USART Over-Run interrupt occured ----------------------------------------*/ + if(__HAL_USART_GET_IT(&Uart1Handle, USART_IT_ORE) != RESET) + { + if(__HAL_USART_GET_IT_SOURCE(&Uart1Handle, USART_IT_ERR) != RESET) + { + __HAL_USART_CLEAR_IT(&Uart1Handle, USART_IT_ORE); + } + } + + /* USART in mode Receiver --------------------------------------------------*/ + if(__HAL_USART_GET_IT(&Uart1Handle, USART_IT_RXNE) != RESET) + { + if(__HAL_USART_GET_IT_SOURCE(&Uart1Handle, USART_IT_RXNE) != RESET) + { + __HAL_USART_CLEAR_IT(&Uart1Handle, USART_IT_RXNE); + data=(uint8_t)(Uart1Handle.Instance->RDR & (uint8_t)0x00FF); + // call the reception function + if(!comm_do_irq_receive(usart1_comm_dev,data)) + __HAL_UART_DISABLE_IT(&Uart1Handle, UART_IT_RXNE); + } + } + + /* USART in mode Transmitter -----------------------------------------------*/ + if(__HAL_USART_GET_IT(&Uart1Handle, USART_IT_TC) != RESET) + { + if(__HAL_USART_GET_IT_SOURCE(&Uart1Handle, USART_IT_TC) != RESET) + { + __HAL_UART_CLEAR_IT(&Uart1Handle,UART_IT_TC); + ret=comm_do_irq_send(usart1_comm_dev,&data); + if(ret==0x01) + Uart1Handle.Instance->TDR=data; + else if(ret==0x00) + __HAL_UART_DISABLE_IT(&Uart1Handle, UART_IT_TC); + } + } +} + +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,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; + + Uart1Handle.Instance = USART; + usart1_config(comm_dev,conf); + + if(comm_dev->use_dma) + { + // configure the DMA channels + usart1_hdma_tx.Instance = USART_TX_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; + + 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_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; + + 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; + Uart1Handle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; + 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_IT(&Uart1Handle,UART_IT_TC); + __HAL_UART_ENABLE_IT(&Uart1Handle, UART_IT_TC); + Uart1Handle.Instance->TDR=first_byte; + + return 0x00; +} + +unsigned char usart1_enable_tx_irq(void) +{ + __HAL_UART_CLEAR_IT(&Uart1Handle,UART_IT_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->TDR,length); + /* Clear the TC flag in the SR register by writing 0 to it */ + __HAL_UART_CLEAR_IT(&Uart1Handle,UART_IT_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->RDR,(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; +} +