Skip to content
Snippets Groups Projects
Commit 93d1598e authored by Sergi Hernandez's avatar Sergi Hernandez
Browse files

Solved a problem with the DMA in USART3 module.

Implemented modules USART1,USART2 and USART4 as module USART3.
parent 9e1aa128
No related branches found
No related tags found
No related merge requests found
#ifndef USART1_F4_H #ifndef USART1_F4_H
#define USART1_F4_H #define USART1_F4_H
#include "stm32f4xx_hal.h"
#include "usart_common.h"
#include "comm.h" #include "comm.h"
/* public functions */ /* 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 #endif
#ifndef USART2_F4_H #ifndef USART2_F4_H
#define USART2_F4_H #define USART2_F4_H
#include "stm32f4xx_hal.h"
#include "usart_common.h" #include "usart_common.h"
#include "comm.h" #include "comm.h"
/* public functions */ /* 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 */ /* IRQ functions */
unsigned char usart2_send_irq(unsigned char *data,unsigned int length); unsigned char usart2_send_irq(unsigned char first_byte);
unsigned char usart2_receive_irq(unsigned int length); unsigned char usart2_enable_tx_irq(void);
unsigned char usart2_receive_irq(void);
unsigned char usart2_cancel_receive_irq(void); unsigned char usart2_cancel_receive_irq(void);
/* DMA functions */ /* 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);
unsigned char usart2_receive_dma(unsigned int length); unsigned char usart2_receive_dma(unsigned char *data,unsigned short int length);
unsigned char usart2_cancel_receive_dma(void); unsigned char usart2_cancel_receive_dma(void);
#endif #endif
#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
#include "usart1.h" #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*/ /* 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;
} }
#include "usart2.h" #include "usart2.h"
#define USART USART2 #define USART USART2
#define USART_CLK RCC_APB1Periph_USART2 #define USART_ENABLE_CLK __HAL_RCC_USART2_CLK_ENABLE()
#define USART_CLK_INIT RCC_APB1PeriphClockCmd
#define USART_IRQn USART2_IRQn #define USART_IRQn USART2_IRQn
#define USART_IRQHandler USART2_IRQHandler #define USART_IRQHandler USART2_IRQHandler
#define USART_TX_PIN GPIO_Pin_2 #define USART_TX_PIN GPIO_PIN_2
#define USART_TX_GPIO_PORT GPIOA #define USART_TX_GPIO_PORT GPIOA
#define USART_TX_GPIO_CLK RCC_AHB1Periph_GPIOA #define USART_ENABLE_TX_GPIO_CLK __HAL_RCC_GPIOA_CLK_ENABLE()
#define USART_TX_SOURCE GPIO_PinSource2
#define USART_TX_AF GPIO_AF_USART2
#define USART_RX_PIN GPIO_Pin_3 #define USART_RX_PIN GPIO_PIN_3
#define USART_RX_GPIO_PORT GPIOA #define USART_RX_GPIO_PORT GPIOA
#define USART_RX_GPIO_CLK RCC_AHB1Periph_GPIOA #define USART_ENABLE_RX_GPIO_CLK __HAL_RCC_GPIOA_CLK_ENABLE()
#define USART_RX_SOURCE GPIO_PinSource3
#define USART_RX_AF GPIO_AF_USART2
#define USART_DMA DMA1 /* DMA configuration */
#define USART_DMA_CLK RCC_AHB1Periph_DMA1 #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_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_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_TX_IRQn DMA1_Stream6_IRQn
#define USART_DMA_RX_IRQn DMA1_Stream5_IRQn #define USART_DMA_RX_IRQn DMA1_Stream5_IRQn
...@@ -43,182 +26,215 @@ ...@@ -43,182 +26,215 @@
#define USART_DMA_RX_IRQHandler DMA1_Stream5_IRQHandler #define USART_DMA_RX_IRQHandler DMA1_Stream5_IRQHandler
// private variables // private variables
DMA_InitTypeDef DMA_TX_InitStructure; UART_HandleTypeDef Uart2Handle;
DMA_InitTypeDef DMA_RX_InitStructure; DMA_HandleTypeDef usart2_hdma_tx;
DMA_HandleTypeDef usart2_hdma_rx;
TComm *usart2_comm_dev; TComm *usart2_comm_dev;
// interrupt handlers // interrupt handlers
void USART_IRQHandler(void) 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); if(__HAL_UART_GET_IT_SOURCE(&Uart2Handle, UART_IT_PE) !=RESET)
data=USART_ReceiveData(USART); {
// call the reception function __HAL_UART_CLEAR_PEFLAG(&Uart2Handle);
if(!comm_do_irq_receive(usart2_comm_dev,data)) }
USART_ITConfig(USART, USART_IT_RXNE, DISABLE);
} }
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(source !=RESET)
if(comm_do_irq_send(usart2_comm_dev,&data)) {
USART_SendData(USART,data); __HAL_UART_CLEAR_FEFLAG(&Uart2Handle);
else }
USART_ITConfig(USART, USART_IT_TC, DISABLE);
} }
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 if(source !=RESET)
USART_ITConfig(USART, USART_IT_RXNE, DISABLE); {
usart2_comm_dev->irq_receiving=0x00; __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 if(source !=RESET)
USART_ITConfig(USART, USART_IT_RXNE, DISABLE); {
usart2_comm_dev->irq_receiving=0x00; __HAL_UART_CLEAR_OREFLAG(&Uart2Handle);
}
} }
} }
void USART_DMA_TX_IRQHandler(void) void USART_DMA_TX_IRQHandler(void)
{ {
DMA_Cmd(USART_TX_DMA_STREAM,DISABLE); if(__HAL_DMA_GET_FLAG(Uart2Handle.hdmatx,__HAL_DMA_GET_TE_FLAG_INDEX(Uart2Handle.hdmatx)) != RESET)
DMA_ClearFlag(USART_TX_DMA_STREAM,USART_TX_DMA_FLAG_TCIF); {
DMA_ClearITPendingBit(USART_TX_DMA_STREAM,USART_TX_DMA_FLAG_TCIF); if(__HAL_DMA_GET_IT_SOURCE(Uart2Handle.hdmatx, DMA_IT_TE) != RESET)
USART_DMACmd(USART, USART_DMAReq_Tx, DISABLE); {
// call the user function /* 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) void USART_DMA_RX_IRQHandler(void)
{ {
DMA_Cmd(USART_RX_DMA_STREAM,DISABLE); if(__HAL_DMA_GET_FLAG(Uart2Handle.hdmarx,__HAL_DMA_GET_TE_FLAG_INDEX(Uart2Handle.hdmarx)) != RESET)
DMA_ClearFlag(USART_RX_DMA_STREAM,USART_RX_DMA_FLAG_TCIF); {
DMA_ClearITPendingBit(USART_RX_DMA_STREAM,USART_RX_DMA_FLAG_TCIF); if(__HAL_DMA_GET_IT_SOURCE(Uart2Handle.hdmarx, DMA_IT_TE) != RESET)
USART_DMACmd(USART, USART_DMAReq_Rx, DISABLE); {
// call the user function /* 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*/ /* 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; GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable GPIO clock */ /* Enable GPIO clock */
USART_CLK_INIT(USART_CLK, ENABLE); USART_ENABLE_TX_GPIO_CLK;
USART_TX_GPIO_CLK(USART_TX_GPIO_CLK,ENABLE) USART_ENABLE_RX_GPIO_CLK;
USART_RX_GPIO_CLK(USART_RX_GPIO_CLK,ENABLE); USART_ENABLE_DMA_CLK;
// configure the GPIO pins
/* 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);
/* Configure USART Tx and Rx as alternate function push-pull */ /* Configure USART Tx and Rx as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.Pin = USART_TX_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.GPIO_Pin = USART_TX_PIN; GPIO_InitStructure.Alternate = GPIO_AF7_USART2;
GPIO_Init(USART_TX_GPIO_PORT, &GPIO_InitStructure); HAL_GPIO_Init(USART_TX_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = USART_RX_PIN; GPIO_InitStructure.Pin = USART_RX_PIN;
GPIO_Init(USART_RX_GPIO_PORT, &GPIO_InitStructure); HAL_GPIO_Init(USART_RX_GPIO_PORT, &GPIO_InitStructure);
/* configure the interrupts */ USART_ENABLE_CLK;
NVIC_InitStructure.NVIC_IRQChannel = USART_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = priorities->irq_priority; Uart2Handle.Instance = USART;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = priorities->irq_subpriority; usart2_config(comm_dev,conf);
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
if(comm_dev->use_dma) if(comm_dev->use_dma)
{ {
/* enable the DMA clock */ // configure the DMA channels
USART_DMA_CLK(USART_DMA_CLK, ENABLE); usart2_hdma_tx.Instance = USART_TX_DMA_STREAM;
/* Configure TX DMA */ usart2_hdma_tx.Init.Channel = USART_DMA_CHANNEL;
DMA_DeInit(USART_TX_DMA_STREAM); usart2_hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
DMA_TX_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; usart2_hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
DMA_TX_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; usart2_hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
DMA_TX_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; usart2_hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
DMA_TX_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; usart2_hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
DMA_TX_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; usart2_hdma_tx.Init.Mode = DMA_NORMAL;
DMA_TX_InitStructure.DMA_Mode = DMA_Mode_Normal; usart2_hdma_tx.Init.Priority = DMA_PRIORITY_LOW;
DMA_TX_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(USART->DR)); usart2_hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
DMA_TX_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_TX_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; HAL_DMA_Init(&usart2_hdma_tx);
DMA_TX_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_TX_InitStructure.DMA_Priority = DMA_Priority_High; /* Associate the initialized DMA handle to the UART handle */
DMA_TX_InitStructure.DMA_Channel = USART_TX_DMA_CHANNEL; __HAL_LINKDMA(&Uart2Handle, hdmatx, usart2_hdma_tx);
DMA_TX_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
/* initialize DMA interrupts */ /* Configure the DMA handler for reception process */
NVIC_InitStructure.NVIC_IRQChannel = USART_DMA_TX_IRQn; usart2_hdma_rx.Instance = USART_RX_DMA_STREAM;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = priorities->dma_tx_priority; usart2_hdma_rx.Init.Channel = USART_DMA_CHANNEL;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = priorities->dma_tx_subpriority; usart2_hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; usart2_hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
NVIC_Init(&NVIC_InitStructure); usart2_hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
DMA_ITConfig(USART_TX_DMA_STREAM,DMA_IT_TC,ENABLE); usart2_hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
DMA_ITConfig(USART_TX_DMA_STREAM,DMA_IT_HT | DMA_IT_TE | DMA_IT_FE | DMA_IT_DME,DISABLE); usart2_hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
usart2_hdma_rx.Init.Mode = DMA_NORMAL;
/* Configure RX DMA */ usart2_hdma_rx.Init.Priority = DMA_PRIORITY_HIGH;
DMA_DeInit(USART_RX_DMA_STREAM); usart2_hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
DMA_RX_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_RX_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; HAL_DMA_Init(&usart2_hdma_rx);
DMA_RX_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_RX_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /* Associate the initialized DMA handle to the the UART handle */
DMA_RX_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; __HAL_LINKDMA(&Uart2Handle, hdmarx, usart2_hdma_rx);
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);
} }
usart2_set_priorities(comm_dev,priorities);
/* Initialize the comm structure */ /* Initialize the comm structure */
comm_dev->receive=usart2_receive;
comm_dev->send_irq=usart2_send_irq; 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->receive_irq=usart2_receive_irq;
comm_dev->cancel_receive_irq=usart2_cancel_receive_irq; comm_dev->cancel_receive_irq=usart2_cancel_receive_irq;
if(comm_dev->use_dma) if(comm_dev->use_dma)
...@@ -234,40 +250,93 @@ void usart2_init(TComm *comm_dev,TUSART_IRQ_Priorities *priorities) ...@@ -234,40 +250,93 @@ void usart2_init(TComm *comm_dev,TUSART_IRQ_Priorities *priorities)
/* initialize internal variables */ /* initialize internal variables */
usart2_comm_dev=comm_dev; 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 */ void usart2_set_priorities(TComm *comm_dev,TUSART_IRQ_Priorities *priorities)
USART_Cmd(USART, ENABLE); {
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 */ /* 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) unsigned char usart2_cancel_receive_irq(void)
{ {
/* disable the rx interrupt */
__HAL_UART_DISABLE_IT(&Uart2Handle, UART_IT_RXNE);
return 0x00;
} }
/* DMA functions */ /* 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) 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;
} }
...@@ -182,7 +182,7 @@ void usart3_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *p ...@@ -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.Pin = USART_TX_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Alternate = GPIO_AF7_USART3; GPIO_InitStructure.Alternate = GPIO_AF7_USART3;
HAL_GPIO_Init(USART_TX_GPIO_PORT, &GPIO_InitStructure); 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 ...@@ -197,7 +197,7 @@ void usart3_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *p
if(comm_dev->use_dma) if(comm_dev->use_dma)
{ {
// configure the DMA channels // 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.Channel = USART_DMA_CHANNEL;
usart3_hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; usart3_hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
usart3_hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE; usart3_hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
......
#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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment