2013-12-13 06:43 AM
I've got a problem with using DMA and a Uart. When I reset my uart device, it sends 96 bytes worth of data back to me. I have my DMA and uart configured to put this into a buffer. Problem is that it only puts the first 80 bytes into the buffer. My program waits for the receive buffer to empty before sending a command to the device, which then responds with a message. At this stage, I see the buffer fill up with my remaining 16 bytes from the reset message, plus the response to my new command. Anyone able to pick out why it would be doing this and why I can't get the whole of my reset response into the buffer?
#include ''WIFI.h''
#include ''main.h''
#include ''stdint.h''
GPIO_InitTypeDef GPIO_InitStructure;
void Delay(__IO uint32_t nTime);
uint8_t uart_rd[100];
int i;
void WIFI(void){
Delay(1000);
DMA_GPIO_Config();
NVIC_Config();
Usart_Config();
DMA_Config();
Reset();
Enter_Cmd_Mode();
while(1);
}
void DMA_GPIO_Config(void){
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB, GPIO_Pin_10);
}
void NVIC_Config(void){
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the Priority Group to 2 bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
// * Enable the DMA Interrupt * /
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void Usart_Config(void){
/* USART2 configured as follow:
- Pins D5(TX) & D6(RX)
- BaudRate = 9600 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
/* Enable GPIO clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/* Enable UART clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
/* Connect PD5 to USART2_Tx*/
GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_USART2);
/* Connect PD6 to USART2_Rx*/
GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2);
/* Configure USART Tx as alternate function */
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Configure USART Rx as alternate function */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOD, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* USART configuration */
USART_Init(USART2, &USART_InitStructure);
/* Enable USART */
USART_Cmd(USART2, ENABLE);
}
void DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
DMA_DeInit(DMA1_Stream5);
DMA_InitStructure.DMA_Channel = DMA_Channel_4;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; // Receive
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) uart_rd;
DMA_InitStructure.DMA_BufferSize = sizeof(uart_rd);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream5, &DMA_InitStructure);
/* Enable the USART Rx DMA request */
USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
/* Enable DMA Stream Half Transfer and Transfer Complete interrupt */
DMA_ITConfig(DMA1_Stream5, DMA_IT_TC, ENABLE);
/* Enable the DMA RX Stream */
DMA_Cmd(DMA1_Stream5, ENABLE);
}
void Reset(void){
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_ResetBits(GPIOD, GPIO_Pin_1);
Delay(1);
GPIO_SetBits(GPIOD, GPIO_Pin_1);
}
void Enter_Cmd_Mode(void){
while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET);
for(i=0;i<3;i++)
{
USART_SendData(USART2, '$');
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
}
}
void DMA1_Stream5_IRQHandler(void)
{
GPIO_SetBits(GPIOB, GPIO_Pin_10);
/* Test on DMA Stream Transfer Complete interrupt */
if (DMA_GetITStatus(DMA1_Stream5, DMA_IT_TCIF2))
{
/* Clear DMA Stream Transfer Complete interrupt pending bit */
DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_TCIF2);
}
}
2013-12-13 07:10 AM
Managed to solve the issue by disabling my FIFO. FIFO wasn't filling up so data wasn't then getting transferred to my buffer. However, now want to be able to reset the point to my buffer so that the next time I receive data, it goes to the start of the buffer rather than starting where the last receive ended. Anyone know how I would go about doing that?