cancel
Showing results for 
Search instead for 
Did you mean: 

An example of STM8L SPI DMA regular buffer exchange between master and slave.

Gordon Freemansky
Associate II

The example from STM8L15x-16x-05x-AL31-L_StdPeriph_Lib doesn't explain the way a regular buffer (i.e. 20 - 30 bytes of data) exchange between two MCUs in master and slave mode. Can anyone explain the steps of configuration on both sides?

Now I have STM32 MCU acting as a master (for testing only), and sending a few bytes in burst mode five times per second. A slave, STM8L151K4, supposed to receive the command and return the status data (ADC and GPIO).

My SPI and DMA configurations for slave are (please disregard commented):

void SPI_Config(void)

{

 GPIO_DeInit(SPI_PORT);

 GPIO_Init(SPI_PORT, CLCK_PIN | MOSI_PIN | nSS_PIN, GPIO_Mode_In_PU_No_IT);

 GPIO_Init(SPI_PORT, MISO_PIN, GPIO_Mode_Out_PP_High_Fast);

 //GPIO_ExternalPullUpConfig(SPI_PORT, CLCK_PIN | MOSI_PIN | nSS_PIN, ENABLE);

 SPI_DeInit(SPI1);

 SPI_Init(SPI1, SPI_FirstBit_MSB, SPI_BaudRatePrescaler_2, SPI_Mode_Slave,

          SPI_CPOL_Low, SPI_CPHA_1Edge, SPI_Direction_2Lines_FullDuplex,

          SPI_NSS_Hard, (uint8_t)0x07);

 SPI_DMACmd(SPI1, SPI_DMAReq_RX, ENABLE);

 //SPI_DMACmd(SPI1, SPI_DMAReq_TX, ENABLE);

 //SPI_ITConfig(SPI1, SPI_IT_RXNE, ENABLE);

 //SPI_ITConfig(SPI1, SPI_IT_TXE, ENABLE);

 SPI_Cmd(SPI1, ENABLE);

}

void DMA_Config(void)

{

 /* DMA1 edisable */

 DMA_GlobalDeInit();

 DMA_GlobalCmd(DISABLE);

/* Connect ADC1 to DMA1 channel 3 */

 SYSCFG_REMAPDMAChannelConfig(REMAP_DMA1Channel_ADC1ToChannel3);

 DMA_Init(DMA1_Channel1, (uint16_t)(&SPIBufferIn),

                         SPI1_DR_ADDRESS,

                         SPIBUF_SIZE,

                         DMA_DIR_PeripheralToMemory,

                         DMA_Mode_Normal,

                         DMA_MemoryIncMode_Inc,

                         DMA_Priority_Medium,

                         DMA_MemoryDataSize_Byte);

 DMA_Init(DMA1_Channel2, (uint16_t)(&SPIBufferOut),

                         SPI1_DR_ADDRESS,

                         SPIBUF_SIZE,

                         DMA_DIR_MemoryToPeripheral,

                         DMA_Mode_Normal,

                         DMA_MemoryIncMode_Inc,

                         DMA_Priority_Medium,

                         DMA_MemoryDataSize_Byte);

 DMA_Init(DMA1_Channel3, BUFFER_ADDRESS,

                         ADC1_DR_ADDRESS,

                         BUFFER_SIZE,

                         DMA_DIR_PeripheralToMemory,

                         DMA_Mode_Circular,

                         DMA_MemoryIncMode_Inc,

                         DMA_Priority_High,

                         DMA_MemoryDataSize_HalfWord);

 /* Enable DMA1 channel1 Transfer complete interrupt */

//DMA_ITConfig(DMA1_Channel1, DMA_ITx_TC, ENABLE);

 /* DMA1 Channel1 enable */

 DMA_Cmd(DMA1_Channel1, ENABLE);

 /* Enable DMA1 channel2 Transfer complete interrupt */

 //DMA_ITConfig(DMA1_Channel2, DMA_ITx_TC, ENABLE);

 /* DMA1 Channel2 enable */

 DMA_Cmd(DMA1_Channel2, ENABLE);

 /* Enable DMA1 channel3 Transfer complete interrupt */

 DMA_ITConfig(DMA1_Channel3, DMA_ITx_TC, ENABLE);

 /* DMA1 Channel3 enable */

 DMA_Cmd(DMA1_Channel3, ENABLE);

 /* DMA1 enable */

 DMA_GlobalCmd(ENABLE);

}

With this code I'm able to receive a buffer only first time. If I change DMA Channel1 to circular mode, it works ok for the first time and then starts filling the buffer with the first byte of Rx buffer.

If I enable SPI DMA transmit request, then Rx buffer gets filled with some rubbish data.

Tried to utilize flags and interrupts, but that didn't work either (all commented).

RM0031 on page 558 explains "SPI communication using DMA", but that seems to be for master mode only.

Any ideas?

0 REPLIES 0