I currently use standard peripheral library to write a driver that enable memory to USART6_TX DMA transfer on a STM32 F407 ZGT6 chip. However, I tried for a long time but the initialization keeps on failing: DMA_GetCmdStatus always returns DISABLE. By using GDB, I found that after the DMA_Init try to write configuration into DMA register, DMA CR register remains 0. The DMA initialize code and execution are as follow:
void DMA_USART6_Init(char* DMA_Start_Pos, uint32_t DMA_Buffer_Size){
DMA_Buffer_Size_GV = DMA_Buffer_Size;
DMA_Start_Pos_GV = DMA_Start_Pos;
/*RCC config*/
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA2, ENABLE);
/*DMA init*/
//DMA_DeInit(DMA2_Stream7);
DMA_Cmd(DMA2_Stream7, DISABLE);
while ((DMA_GetCmdStatus(DMA2_Stream7) == ENABLE)){}
DMA_StructInit(&DMA_InitStruct);
DMA_InitStruct.DMA_Channel = DMA_Channel_5;
DMA_InitStruct.DMA_PeripheralBaseAddr = USART6_BASE + 0x04;//(uint32_t)&USART6->DR;
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t) dubuff;//(uint32_t) DMA_Start_Pos;
DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStruct.DMA_BufferSize = (uint16_t)sizeof(dubuff);//DMA_Buffer_Size;
printf("buffer size should be %d \r\n", (uint16_t)sizeof(dubuff));
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_Init(DMA2_Stream7, &DMA_InitStruct);
printf("data counter after init %d \r\n", DMA_GetCurrDataCounter(DMA2_Stream7));
}
for the ENABLE code
void DMA_USART6_Enable_DMA(char* DMA_Start_Pos, uint32_t DMA_Buffer_Size, int MB){
Max_Buffer = MB;
USART6_init_for_DMA();
DMA_USART6_Init(DMA_Start_Pos, DMA_Buffer_Size);
DMA_USART6_NVIC_Init();
DMA_ITConfig(DMA2_Stream7, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA2_Stream7, ENABLE);
while ((DMA_GetCmdStatus(DMA2_Stream7) == DISABLE)){}//program stucked in this loop
}
for the USART6 code:
void USART6_init_for_DMA(void){
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6);
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 57600;//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_Rx | USART_Mode_Tx;
USART_Init(USART6, &USART_InitStructure);
USART_Cmd(USART6, ENABLE);
USART_DMACmd(USART6, USART_DMAReq_Tx, ENABLE);
}
and the GDB result:
the value that should be written into DMA CR register
text in the picture 1:
367 DMAy_Streamx->CR = tmpreg;
(gdb) print tmpreg
$7 = 167904576
text in the picture2:
371 tmpreg = DMAy_Streamx->FCR;
(gdb) print *DMAy_Streamx
$10 = {CR = 0, NDTR = 0, PAR = 0, M0AR = 0, M1AR = 0, FCR = 0}
Please tell me if there is anything I can provide about my problem or things I can try further... Note: In the same program, my USART6 and GPIO works fine.