2014-09-02 3:58 PM
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);}2014-09-03 9:33 AM
This similar format worked for UART for DMA mode, but SPI's not going. Anybody see a problem?
2014-09-03 10:13 AM
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 ???2014-09-03 10:55 AM
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
2014-09-03 11:06 AM
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.2014-09-03 6:01 PM
Visit the below link.
Even though it is written in Korean, you can see sample codes and it may be helpful to you.This is english version.We’re moving the ST Community to a new platform to give you a better and more reliable community experience.