Skip to main content
Visitor II
February 2, 2021
Question

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

  • February 2, 2021
  • 6 replies
  • 1701 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

    Super User
    February 2, 2021

    Can you show any related program?

    JW

    NTric.1Author
    Visitor 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);
     
     
     }

    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.1Author
    Visitor 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.

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

    Thank you, JW.

    I will try this way.