cancel
Showing results for 
Search instead for 
Did you mean: 

Dma -> usart circular buffer questions

michaelmccartyeng
Associate II
Posted on August 29, 2013 at 04:24

I was trying to write out the usart using dma. I thought everything was working till I actually looked at the data. The data seemed to always be wrong so I extracted all the relevant code to test it separately and could not get it to run.

Anyone know why this does not work (I get no tx). Any suggestions as to what flags I should check to know if it has failed ? I could not find any usart circular dma examples.

u8 testbyteBuffer[255];
void
testLoop(
void
)
{
NVIC_InitTypeDef NVIC_InitStructure;
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure; 
int
i;
for
(i=0; i<=255; i++)
{
testbyteBuffer[i] = i;
}
// init clocks 
RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
// // int our vector table
// /* Enable the DMA Stream IRQ Channel */
// NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream6_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure); 
// 
// /* Enable the USARTz Interrupt */
// NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
USART_InitStructure.USART_BaudRate = 921600;
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(USART2, &USART_InitStructure);
// hold onto your butts
USART_Cmd(USART2, ENABLE);
DMA_InitStructure.DMA_Channel = DMA_Channel_4;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(USART2->DR); 
// usart2 data register
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)testbyteBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; 
DMA_InitStructure.DMA_BufferSize = 
sizeof
(testbyteBuffer);
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_VeryHigh;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream6, &DMA_InitStructure);
// USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
/* Enable DMA Stream Half Transfer and Transfer Complete interrupt */
// todo enable this and fix up int handler, setup for errors ! 
//DMA_ITConfig(zbCom_Usart_DMA_Stream, DMA_IT_TC, ENABLE);
// start the dma transfer, it will execute now
DMA_Cmd(DMA1_Stream6, ENABLE);
while
(
true
)
{
}
}

3 REPLIES 3
Posted on August 29, 2013 at 05:03

u8 testbyteBuffer[256]; // !! 0..255
void testLoop(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
int i;
for(i=0; i<=255; i++)
{
testbyteBuffer[i] = i;
}
// init clocks
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // !! AHB1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
USART_InitStructure.USART_BaudRate = 921600;
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(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
DMA_InitStructure.DMA_Channel = DMA_Channel_4;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR); // usart2 data register
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)testbyteBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_BufferSize = sizeof(testbyteBuffer);
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_VeryHigh;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream6, &DMA_InitStructure);
// start the dma transfer, it will execute now
DMA_Cmd(DMA1_Stream6, ENABLE);
USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
while(true)
{
}
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
michaelmccartyeng
Associate II
Posted on August 29, 2013 at 19:44

Thanks Clive,

  I never noticed that AHB, APB and to be honest have no idea what they mean. I'll look up the defines and check it out when I get home. 

michaelmccartyeng
Associate II
Posted on September 02, 2013 at 19:37

Tested verified, you were spot on Clive. 

In case anyone else reads this the 'apb' is for the slow bus 'ahb' for the fast bus. 

Also to others like me, if you get into a situation where your code does not work just look at the perph ''driver'' code. Had I simply looked at the stm32f4xx_usart.c under the ''how to use this driver'' section I would have been able to at least know I was doing things in the right order.