AnsweredAssumed Answered

STM32F429 SPI4 via DMA

Question asked by Blubimo on Feb 6, 2014
Latest reply on Feb 18, 2014 by Blubimo
Hello everyone,

I'm using the SPI4 to read out data from an SD-card, witch is working. Now I want to let the DMA controller do the work at least I want him to do it... I pretty much used the code of the F4 discoveryboard and changed the needed settings. I'm at a point where I don't have a clue why the DMA controller won't start.
Here the code i ended with:

     GPIO_InitTypeDef GPIO_InitStructure;
     SPI_InitTypeDef  SPI_InitStructure;
     DMA_InitTypeDef DMA_InitStructure;

     /* peripheral clock enable */
     /* enable SPI clock */
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI4, ENABLE);
     
     /* enable GPIO clock */
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
     
     /* enable DMA clock */
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
     
     /* SPI GPIO Configuration */
     /* connect SPI pins to AF5 */
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource2, GPIO_AF_SPI4);
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource5, GPIO_AF_SPI4);
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource6, GPIO_AF_SPI4);
     
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
       GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;
     
       /* SPI SCK pin configuration */
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
       GPIO_Init(GPIOE, &GPIO_InitStructure);
  
       /* SPI RX pin configuration */
       GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5;
       GPIO_Init(GPIOE, &GPIO_InitStructure);  

       /* SPI TX pin configuration */
       GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6;
       GPIO_Init(GPIOE, &GPIO_InitStructure);
     
     /* SPI CS pin configuration */
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CS;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOE, &GPIO_InitStructure);
     
     /* no SPI Chip Select */
     GPIO_SetBits(GPIO_CS, GPIO_Pin_CS);
     
     /* SPI configuration */
     SPI_I2S_DeInit(SPI4);
     SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
     SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
     SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
     SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
     SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
     SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
     SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
     SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
     SPI_InitStructure.SPI_CRCPolynomial = 7;

     SPI_Init(SPI4, &SPI_InitStructure);
     SPI_CalculateCRC(SPI4, DISABLE);
     SPI_Cmd(SPI4, ENABLE);

     /* test SPI */
     SPI_I2S_SendData(SPI4, 0x55);
     while (SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_TXE) == RESET) { ; }
     SPI_Cmd(SPI4, DISABLE);

     /* Deinit both streams */
       DMA_DeInit(DMA2_Stream1);
       DMA_DeInit(DMA2_Stream0);

       /* Configure DMA Initialization Structure */
       DMA_InitStructure.DMA_BufferSize = 123;
       DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
       DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
       DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
       DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
       DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
       DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
       DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(SPI4->DR));
       DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
       DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
       DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
       DMA_InitStructure.DMA_Priority = DMA_Priority_High;

     /* Configure TX DMA */
       DMA_InitStructure.DMA_Channel = DMA_Channel_4;
       DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
       DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)aTxBuffer;
       DMA_Init(DMA2_Stream1, &DMA_InitStructure);
       /* Configure RX DMA */
       DMA_InitStructure.DMA_Channel = DMA_Channel_4;
       DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
       DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)aRxBuffer;
       DMA_Init(DMA2_Stream0, &DMA_InitStructure);
     
//     SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
//     SPI_Init(SPI4, &SPI_InitStructure);
     
       /* Enable DMA SPI TX Stream */
       DMA_Cmd(DMA2_Stream1,ENABLE);
     
       /* Enable DMA SPI RX Stream */
       DMA_Cmd(DMA2_Stream0,ENABLE);
     
       /* Enable SPI DMA TX Requsts */
       SPI_I2S_DMACmd(SPI4, SPI_I2S_DMAReq_Tx, ENABLE);

       /* Enable SPI DMA RX Requsts */
       SPI_I2S_DMACmd(SPI4, SPI_I2S_DMAReq_Rx, ENABLE);

     /* Enable the SPI peripheral */
       SPI_Cmd(SPI4, ENABLE);
     
       /* Waiting the end of Data transfer */
     while(DMA_GetFlagStatus(DMA2_Stream1,DMA_FLAG_TCIF1)==RESET);
       while(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==RESET);
     
       /* Clear DMA Transfer Complete Flags */
       DMA_ClearFlag(DMA2_Stream1,DMA_FLAG_TCIF1);
       DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);  
     
       /* Disable DMA SPI TX Stream */
       DMA_Cmd(DMA2_Stream1,DISABLE);
     
       /* Disable DMA SPI RX Stream */
       DMA_Cmd(DMA2_Stream0,DISABLE);
     
       /* Disable SPI DMA TX Requsts */
       SPI_I2S_DMACmd(SPI4, SPI_I2S_DMAReq_Tx, DISABLE);
     
       /* Disable SPI DMA RX Requsts */
       SPI_I2S_DMACmd(SPI4, SPI_I2S_DMAReq_Rx, DISABLE);
     
     /* Disable the SPI peripheral */
       SPI_Cmd(SPI4, DISABLE);

sending a test byte without DMA works properly, so the SPI sould be fine. But when I initialize the DMA controller and just want to sent 10 bytes afterwards nothing gets sent and the code is stuck in the while-loop for checking the transmitting complete flag.
Is there anything I have forgotten or done wrong? Any ideas?

Outcomes