AnsweredAssumed Answered

STM32F3 UART DMA problem

Question asked by minthemerciless on Jan 4, 2017
Latest reply on Feb 25, 2017 by John Smiley

 Hi,

I am working  on an application on an STM32F303RET6 on a nucleo board. I am struggling to get DMA working on USART1 Rx.  I can successfully enable the USART port and it works correctly with the receive interrupt but once I enable the DMA it no longer works. I did have this code working on a STM32F103 nucleo board before but can't for the life of me get it to wrk on the F3 board. I don't have access t my code currently so will edit and add the it later.

Is there anything different about the F3 chip compared to then F1 that might catch me out?

 

Thanks in advance.

 

Edit: code below. Hopefully its sufficiently readable.

#define USART_SBUS USART1
#define USART_SBUS_GPIO GPIOC
#define USART_SBUS_CLK RCC_APB2Periph_USART1
#define USART_SBUS_GPIO_CLK RCC_AHBPeriph_GPIOC
#define USART_SBUS_RX_PIN GPIO_Pin_5
#define USART_SBUS_RX_PIN_SOURCE GPIO_PinSource5
#define USART_SBUS_RX_DMA_CHANNEL DMA1_Channel5
#define DMA_SBUS_IRQN DMA1_Channel5_IRQn
#define DMA_SBUS_IRQHandler DMA1_Channel5_IRQHandler

 

uint8_t rxBuffer[4] = {0,0,0,0};


uint8_t usart_init(void)
{

GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;

/* enable usart clock */
RCC_APB2PeriphClockCmd(USART_SBUS_CLK, ENABLE);

RCC_AHBPeriphClockCmd(USART_SBUS_GPIO_CLK, ENABLE);


GPIO_InitStructure.GPIO_Pin = USART_SBUS_RX_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(USART_SBUS_GPIO, &GPIO_InitStructure);

GPIO_PinAFConfig(USART_SBUS_GPIO, USART_SBUS_RX_PIN_SOURCE, GPIO_AF_7);


// /* Enable the USART Interrupt */
// NVIC_InitStructure.NVIC_IRQChannel = USART_SBUS_IRQN;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);

/* Enable the DMA Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = DMA_SBUS_IRQN;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);


USART_InitTypeDef USART_InitStructure;
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate = 100000;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_2;
USART_InitStructure.USART_Parity = USART_Parity_Even;
USART_InitStructure.USART_Mode = USART_Mode_Rx;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART_SBUS, &USART_InitStructure);

USART_InvPinCmd(USART_SBUS, USART_InvPin_Rx, ENABLE);

USART_ITConfig(USART_SBUS, USART_IT_RXNE, ENABLE);

USART_Cmd(USART_SBUS, ENABLE);

USART_DMACmd(USART_SBUS, USART_DMAReq_Rx, ENABLE);

// Enable DMA1 Controller.
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

// Clear USART1 RX DMA Channel config.
DMA_DeInit(DMA1_Channel5);

// Initialize USART1 RX DMA Channel:
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->RDR; // USART1 RX Data Register.
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)rxBuffer; // Copy data to RxBuffer.
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // Peripheral as source, memory as destination.
DMA_InitStructure.DMA_BufferSize = 4; // Defined above.
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // No increment on RDR address.
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Increment memory address.
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // Byte-wise copy.
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // Byte-wise copy.
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // Ring buffer - don't interrupt when at end of memory region.
DMA_InitStructure.DMA_Priority = DMA_Priority_High; // High priority.
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // Peripheral to memory, not M2M.

// Initialize USART1 RX DMA Channel.
DMA_Init(DMA1_Channel5, &DMA_InitStructure);

// Enable Transfer Complete, Half Transfer and Transfer Error interrupts.
DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);

// Enable USART1 RX DMA Channel.
DMA_Cmd(DMA1_Channel5, ENABLE);

 

return 0x01;
}

Outcomes