Return to the base of the memory destination when using DMA (STL library)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-02-02 02:22 AM
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.
At beginning of the program, the first of my data stored correctly in rxbuff[0]
However, when I transmitted the wrong size of the data package, the next time the first byte doesn't store at rxbuff[0].
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-02-02 05:11 AM
Can you show any related program?
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-02-02 06:56 PM
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);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-02-03 11:56 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-02-04 02:54 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-02-04 09:31 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-02-25 12:59 AM
Thank you, JW.
I will try this way.