cancel
Showing results for 
Search instead for 
Did you mean: 

SPI DMA Problem, please help

randyao12345
Associate II
Posted on September 03, 2014 at 00:58

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);

}

5 REPLIES 5
randyao12345
Associate II
Posted on September 03, 2014 at 18:33

This similar format worked for UART for DMA mode, but SPI's not going. Anybody see a problem?

stm322399
Senior
Posted on September 03, 2014 at 19:13

There are two things odd for me in your code:

* DMA peripheral size is set to byte whereas SPI is configured for 16b

* You never started SPI with SPI_Cmd(SPI2, ENABLE), but you see SCLK signal ???

randyao12345
Associate II
Posted on September 03, 2014 at 19:55

Yes, I saw a clock signal with around 1MHz clock even without enabling it, I suppose the SPI is configured to DMA, which setups the clock? But even after I add SPI enable and change the data length to 16 bit, currently it still is not sending data

randyao12345
Associate II
Posted on September 03, 2014 at 20:06

It started working.. I added this:

SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;   //SPI_BaudRatePrescaler

SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;

Prescaler to 32 and NSS_Soft. I'm wondering what happened. It's sending 0101 (AAAA) nonstop now.