Skip to main content
NTric.1
Associate II
February 2, 2021
Question

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

  • February 2, 2021
  • 6 replies
  • 2897 views

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].

This topic has been closed for replies.

6 replies

waclawek.jan
Super User
February 2, 2021

Can you show any related program?

JW

NTric.1
NTric.1Author
Associate II
February 3, 2021

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);
 
 
 }

waclawek.jan
Super User
February 3, 2021

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
NTric.1Author
Associate II
February 4, 2021

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.

waclawek.jan
Super User
February 4, 2021

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
NTric.1Author
Associate II
February 25, 2021

Thank you, JW.

I will try this way.