2014-09-02 03: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 09: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 06: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.