2016-08-06 06:06 AM
I have a problem, I wrote some code based of https://github.com/g4lvanix/STM32F1-workarea/tree/master/Project/STM32F10x_StdPeriph_Examples/USART/DMA_Polling and it only fires the USART1 TX DMA once for some reason, I tried to get smarter from the datasheet and reference manual but couldnt for the life of me figure out how to do it correctly.
The code is the following //RCC config
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
//GPIO config
#define USART1_PORT GPIOA
#define USART1_PIN_TX GPIO_Pin_9
#define USART1_PIN_RX GPIO_Pin_10
//initialize tx pin
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = USART1_PIN_TX;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(USART1_PORT, &GPIO_InitStructure);
//DMA config
DMA_InitTypeDef DMA_InitStructure;
#define USART1_TX_DMA_CHANNEL DMA1_Channel4
#define USART1_RX_DMA_CHANNEL DMA1_Channel5
/* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */
DMA_DeInit(USART1_TX_DMA_CHANNEL);
DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_BASE + 0x04;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)txbuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = BUFFERSIZE;
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_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(USART1_TX_DMA_CHANNEL, &DMA_InitStructure);
//usart config
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200;
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_Tx;
USART_Init(USART1, &USART_InitStructure);
//tx buffer for the first time
//disable spi and dma
USART_DMACmd(USART1, USART_DMAReq_Tx, DISABLE);
USART_Cmd(USART1, DISABLE);
DMA_Cmd(USART1_TX_DMA_CHANNEL, DISABLE);
//reconfigure dma
USART1_TX_DMA_CHANNEL->CMAR = (uint32_t)txbuffer;
DMA_SetCurrDataCounter(USART1_TX_DMA_CHANNEL, 4);
//tx dma
DMA_Cmd(USART1_TX_DMA_CHANNEL, ENABLE);
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
USART_Cmd(USART1, ENABLE);
while (DMA_GetFlagStatus((int)USART1_TX_DMA_CHANNEL) == RESET);
delay_ms(1000);
//tx buffer again
//disable spi and dma
USART_DMACmd(USART1, USART_DMAReq_Tx, DISABLE);
USART_Cmd(USART1, DISABLE);
DMA_Cmd(USART1_TX_DMA_CHANNEL, DISABLE);
//reconfigure dma
USART1_TX_DMA_CHANNEL->CMAR = (uint32_t)txbuffer;
DMA_SetCurrDataCounter(USART1_TX_DMA_CHANNEL, 4);
//tx dma
DMA_Cmd(USART1_TX_DMA_CHANNEL, ENABLE);
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
USART_Cmd(USART1, ENABLE);
while (DMA_GetFlagStatus((int)USART1_TX_DMA_CHANNEL) == RESET);
delay_ms(1000);
It correctly transmits the buffer one time but fails to do it for a second time. As I said I couldn't get smart from the documentation and would appreciate a pointer to ether my mistake and/or a reference to the documentation about it.
Thank you in advance.
#stm32-f1-usart-tx-dma
2016-08-06 07:07 AM
I can't tell exactely what's wrong, but I have a few remarks:
* DMA must be started after USART * no need to stop DMA as it is automatically disabled at end of transfer * keeping dma mode of TX enabled all time should make no harm * keeping USART enabled all time sb. harmless as well * in doubt, check status register of USART and DMA before the second run2016-08-06 07:10 AM
Not sure I have an F1 example to hand, but this is how I would demonstrate this.
[DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Java/Failing%20to%20set%20up%20USART%20DMA%20TX&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000F9A0E3A95BA69146A17C2E80209ADC21¤tviews=48]https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Java%2FFailing%20to%20set%20up%20USART%20DMA%20TX&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000F9A0E3A95BA69146A17C2E80209ADC21¤tviews=482016-08-06 01:25 PM
That you for the suggestions.
2016-08-06 01:26 PM
That you for that link! I didn't realize I had to reconfigure the DMA after every use, it works now.