cancel
Showing results for 
Search instead for 
Did you mean: 

Return to the base of the memory destination when using DMA (STL library)

NTric.1
Associate II

Hi there,

I wonder when I transmit the wrong data package from peripheral to memory, as the wrong size as I configured, where the offset pointer locates that the location for the next transmission is not at the start of the memory (memory 0 since I using direct mode), it starts as arbitrary locations within the range of memory location I configured.

How to return to the start of memory 0?

Thank you,

Have a good day.

0693W000007DZPtQAO.pngAt beginning of the program, the first of my data stored correctly in rxbuff[0]

0693W000007DZQDQA4.png0693W000007DZUjQAO.pngHowever, when I transmitted the wrong size of the data package, the next time the first byte doesn't store at rxbuff[0].

6 REPLIES 6

Can you show any related program?

JW

NTric.1
Associate II

Hi JW,

Sure. Here is my related code

int8_t rxbuff[8];
int alert = 0;
int set_point = 120;
 
 
int main(void){
	USART_DMA_Configuration(9600);
	while(1){}
}
 
 
// Using USART3 Pin D8 for TX and D9 for RX
void USART_DMA_Configuration(unsigned int BaudRate)
{
	
	 GPIO_InitTypeDef GPIO_InitStructure; 
	 USART_InitTypeDef USART_InitStructure; 
	 DMA_InitTypeDef DMA_InitStructure;
	 NVIC_InitTypeDef NVIC_InitStructure;
 
	 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
	 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
	 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
		
	 GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3);
	 GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3);
	 /* GPIO Configuration for USART Tx */
	 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	 GPIO_Init(GPIOD, &GPIO_InitStructure);
	 /* GPIO Configuration for USART Rx */
	 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	 GPIO_Init(GPIOD, &GPIO_InitStructure);
 
	 USART_InitStructure.USART_BaudRate = BaudRate;
	 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_Init(USART3, &USART_InitStructure);
	/* Enable USART */
	 USART_Cmd(USART3, ENABLE);
	/* Enable USART3 DMA */
	 USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);
	 USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
	 
	/* DMA1 Stream1 Channel1 for USART3 Rx configuration */
	 DMA_InitStructure.DMA_Channel = DMA_Channel_4;
	 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART3->DR;
	 DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)rxbuff;
	 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
	 DMA_InitStructure.DMA_BufferSize = 8;
	 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_Normal;//DMA_Mode_Circular;
	 DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
	 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
	 DMA_InitStructure.DMA_MemoryBurst = DMA_PeripheralBurst_INC16;
	 DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC16 ;
	 DMA_Init(DMA1_Stream1, &DMA_InitStructure);
	 DMA_Cmd(DMA1_Stream1, ENABLE);
	/* DMA1 Stream3 Channel4 for USART3 Tx configuration */
	 DMA_InitStructure.DMA_Channel = DMA_Channel_4;
	 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART3->DR;
	 DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)txbuff;
	 DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
	 DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE_TX;
	 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_Normal;
	 DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
	 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
	 DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
	 DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
	 DMA_Init(DMA1_Stream3, &DMA_InitStructure);
	 DMA_Cmd(DMA1_Stream3, ENABLE);
	 
	/* Enable DMA Interrupt to the highest priority */
	 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream1_IRQn;
	 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	 NVIC_Init(&NVIC_InitStructure);
	 /* Transfer complete interrupt mask */
	 DMA_ITConfig(DMA1_Stream1, DMA_IT_TC, ENABLE);
 
 }
 
 
 void DMA1_Stream1_IRQHandler(void){
 /* Clear the DMA1_Stream1 TCIF1 pending bit */
 DMA_ClearITPendingBit(DMA1_Stream1, DMA_IT_TCIF1);
 
 if (rxbuff[0] == '#' && rxbuff[5] == '#')
	set_point = (rxbuff[2] - 0x30)*100 + (rxbuff[3] - 0x30)*10 + (rxbuff[4] - 0x30);
 
	
  else{
	   alert = 1;
		
	   DMA_ClearFlag(DMA1_Stream3,DMA_FLAG_FEIF3);	// the FIFO error flag asserted when the transmitted data has a wrong size
	   USART_DMA_Configuration(9600);
	}
 
 DMA_Cmd(DMA1_Stream1, ENABLE);
 
 
 }

This looks roughly OK. If FIFO is disabled, the FEIF flag is harmless, it just indicates that you've enabled DMA on USART Tx before you've enabled the corresponding DMA stream.

What transmits data you receive by the UART Rx? Can't it be that the data shift is caused by this interrupt being delayed, e.g. by some other interrupt? Toggle a GPIO bit in this interrupt and observe it on oscilloscope/logic analyzer together with the Rx data stream.

JW

NTric.1
Associate II

Hi JW,

Thanks for your reply,

I mean that I am ok with the transmission, however, I don't know how the way that when my code pack bounded by the wrong character, the next transmission, will store the newly received byte at rxbuff[0].

In my case, with the wrong data pack's size (wrong bounded character), the next new byte will be stored somewhere of the rxbuff (as the 2nd and 3rd picture ), not the first location of rxbuff.

Please help me figure it.

You appear to have packets terminated by 0D/0A. So, in case of "synchronization loss", you might wait until those characters, and then start the packet reception again.

JW

NTric.1
Associate II

Thank you, JW.

I will try this way.