AnsweredAssumed Answered

SPI DMA Problem, please help

Question asked by yao.randy.001 on Sep 3, 2014
Latest reply on Sep 4, 2014 by kim.james.003
I'm trying to run SPI on DMA Mode for STM32F407 (Discovery). I'm stuck with the below code, with the oscilloscope showing SPI CLK but no data. I'm wondering:

1. How do you do slave select in DMA Mode?
2. Is the DMA Channel for SPI2 right? I found this info before but forgot where it is.
3. If I want to do 2 SPI channels, both using DMA, is this possible?

Code:

#include <stm32f4xx_gpio.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_dma.h>
#include <stm32f4xx_spi.h>
#include <semihosting.h>


void Setup(void);


char SPI_Buffer[] = "AAA";


int main(void)
{
     Setup();
    while(1)
    {
    }
}


void Setup(void)
{
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 | RCC_AHB1Periph_GPIOB, ENABLE);


     GPIO_InitTypeDef GPIO_InitStructure;
     SPI_InitTypeDef SPI_InitStructure;
     DMA_InitTypeDef DMA_InitStructure;


     //PB13 SPI2_SCK
     //PB14 SPI2_MISO
     //PB15 SPI2_MOSI
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOB,&GPIO_InitStructure);


     GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2);
     GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2);
     GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);


     //Slave Select PC10
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
     GPIO_Init(GPIOC,&GPIO_InitStructure);


     SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //Should be Full Duplex
     SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
     SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
     SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;        //SCK idle high
     SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;       //Second transition
     SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;              //SPI_BaudRatePrescaler
     SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //SPI_CRCPolynomial
     SPI_Init(SPI2, &SPI_InitStructure);


//     DMA_DeInit(DMA1_Stream4);
     DMA_InitStructure.DMA_Channel               = DMA_Channel_0;
     DMA_InitStructure.DMA_DIR                   = DMA_DIR_MemoryToPeripheral; //Transmit
     DMA_InitStructure.DMA_Memory0BaseAddr       = (uint32_t)SPI_Buffer;
     DMA_InitStructure.DMA_BufferSize            = (uint16_t)(sizeof(SPI_Buffer)-1);
     DMA_InitStructure.DMA_PeripheralBaseAddr    = (uint32_t)&SPI2->DR;
     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_FIFOMode              = DMA_FIFOMode_Enable;
     DMA_InitStructure.DMA_FIFOThreshold         = DMA_FIFOThreshold_1QuarterFull;
     DMA_InitStructure.DMA_MemoryBurst           = DMA_MemoryBurst_Single;
     DMA_InitStructure.DMA_PeripheralBurst       = DMA_PeripheralBurst_Single;


     //Setup the Dual Buffer mode for the Tx DMA
     //DMA_DoubleBufferModeConfig(DMA1_Stream4, (uint32_t)SPI_Buffer, DMA_Memory_0);
     //DMA_DoubleBufferModeCmd(DMA1_Stream4, ENABLE);
     SPI_DMACmd(SPI2, SPI_DMAReq_Tx | SPI_DMAReq_Rx,ENABLE);
     DMA_Init(DMA1_Stream4, &DMA_InitStructure);
     DMA_Cmd(DMA1_Stream4, ENABLE);
}

Outcomes