AnsweredAssumed Answered

STM32F207 Uni Directional SPI  - Rx using DMA

Question asked by mackenzie.john on Mar 7, 2017
Latest reply on Mar 7, 2017 by mackenzie.john

Hi Everyone,

 

my set-up is an STM32F205 transmitting fixed length data ( < 64 bytes ) periodically to an STM32F207 via SPI. I am only interested in receiving data, nothing is sent on the 207's MISO line.

 

The 207 receives data Ok when using spi interrupts, but doesn't when using DMA. 

 

The DMA transfer complete interrupt fires (TCIF flag = 1, and I see HTIF = 1 that gives some confidence DMA is seeing something),  but data never appears in the memory buffer.

 

It is so close to working - there must be a bit I'm missing somewhere.  I've spent the last few days googling SPI configurations and reading the STM ref manual and I can't see why this shouldn't work!

 

Any ideas?

 

NB I haven't included the interrupt handler as it is just an empty function, but am breaking on it in the debugger to read registers etc.


#define SPIipc SPI2

 

static __IO uint8_t DMAbufferRx[64];

 

 

void ipc_spi_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;

// Enable peripheral clock
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);

GPIO_Clk_Init(SPIipc_GPIO_Clk, ENABLE); // GPIOB
SPIipc_Clk_Init(SPIipc_Clk, ENABLE); // SPI2

GPIO_PinAFConfig(SPIipc_GPIO, SPIipc_SCK_Src, SPIipc_SCK_AF);
GPIO_PinAFConfig(SPIipc_GPIO, SPIipc_MOSI_Src, SPIipc_MOSI_AF);
GPIO_PinAFConfig(SPIipc_GPIO, SPIipc_MISO_Src, SPIipc_MISO_AF);

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;

GPIO_InitStructure.GPIO_Pin = SPIipc_SCK_Pin; // Pin 13
GPIO_Init(SPIipc_GPIO, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = SPIipc_MOSI_Pin; // Pin 15
GPIO_Init(SPIipc_GPIO, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = SPIipc_MISO_Pin; // Pin 14
GPIO_Init(SPIipc_GPIO, &GPIO_InitStructure);

// SPI configuration
SPI_StructInit(&SPI_InitStructure);
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Rx;

SPI_I2S_DeInit(SPIipc);
SPI_Init(SPIipc, &SPI_InitStructure);
while(SPI_I2S_GetFlagStatus(SPIipc, SPI_I2S_FLAG_TXE) == RESET);

// Configure Rx DMA
DMA_Cmd(DMA1_Stream3, DISABLE);
while (DMA1_Stream3->CR & DMA_SxCR_EN);
DMA_DeInit(DMA1_Stream3);
DMA_StructInit( &DMA_InitStructure );
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI2->DR;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &DMAbufferRx[0];
DMA_InitStructure.DMA_BufferSize = sizeof( DMAbufferRx );
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_Init(DMA1_Stream3, &DMA_InitStructure);

// Clear any pending (old) DMA1 Stream 3 Interrupts
DMA1->LIFCR = (uint32_t)0x0F400000;
while(DMA1->LISR & 0x0F400000 );

// DMA transfer complete interrupt enable
DMA_ITConfig(DMA1_Stream3, DMA_IT_TC, ENABLE);

// Enable DMA interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// Enable the DMA SPI RX Stream
DMA_Cmd(DMA1_Stream3, ENABLE);

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

// Enable the SPI peripheral
SPI_Cmd(SPIipc, ENABLE);
}

Outcomes