AnsweredAssumed Answered

SPI master with DMA - problem

Question asked by rogel.zohar on Jun 19, 2014
Latest reply on Jun 21, 2014 by knik
Hello,

I'm trying to use SPI master with DMA in full duplex to communicate with accelerometer. I don't want to use DMA interrupts (or should I?).
I've managed to activate the SPI with polling mode and got the correct reading from the accelerometer.
I'm using STM32L152 discovery board, SPI1 and DMA1.

The configurations are:

void DMA_Configuration(void)
{
     
/* Enable the DMA peripheral */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 

DMA_InitTypeDef  DMA_InitStructure;
     
     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize =  DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
     
     
     /* DMA channel Rx of SPI Configuration */
     DMA_InitStructure.DMA_BufferSize = 1;
     DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(SPI1->DR);
     DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&Rx_Buffer;
     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
     DMA_InitStructure.DMA_Priority = DMA_Priority_High;
     DMA_Init(DMA1_Channel2, &DMA_InitStructure);
     
     /* DMA channel Tx Configuration */
     DMA_InitStructure.DMA_BufferSize = (uint16_t)1;
     DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(SPI1->DR);
     DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&Tx_Buffer;
     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
     DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
     DMA_Init(DMA1_Channel3, &DMA_InitStructure);
}


The function handling the SPI comm is:

void SPI_Comm(SPI_TypeDef* SPI_x, uint16_t inBuffer, uint16_t *outBuffer)
{
     Tx_Buffer = inBuffer;
     
     /* Enable the SPI Rx and Tx DMA request */
     SPI_DMACmd(SPI1, SPI_DMAReq_Tx, ENABLE);
     SPI_DMACmd(SPI1, SPI_DMAReq_Rx, ENABLE);
     
     /* Enable the DMA Rx and Tx channels */
     DMA_Cmd(DMA1_Channel3, ENABLE);
     DMA_Cmd(DMA1_Channel2, ENABLE);

     while(DMA_GetFlagStatus(DMA1_FLAG_TC3) == RESET);
     while(DMA_GetFlagStatus(DMA1_FLAG_TC2) == RESET);
     
     
     *outBuffer = Rx_Buffer;
          
     // DMA_ClearFlag(DMA1_FLAG_TC3);
     // DMA_ClearFlag(DMA1_FLAG_TC2);
     
     SPI_DMACmd(SPI1, SPI_DMAReq_Tx, DISABLE);
     SPI_DMACmd(SPI1, SPI_DMAReq_Rx, DISABLE);
     
     
     DMA_Cmd(DMA1_Channel3, DISABLE);
     DMA_Cmd(DMA1_Channel2, DISABLE);
}


Rx_Buffer and Tx_Buffer are globally defined.

The read register function that read the accelerometer is:
void Acc_Read_Register(uint16_t cmd, uint16_t *val)
{
     // Set CS to LOW
     ACC_CS_LOW();
     
     // Transmit cmd, receive dummy data (0xFF)
     SPI_Comm(ACC_SPI, (cmd | READ_MASK), val);
     
     // Transmit dummy cmd, receive correct data
     SPI_Comm(ACC_SPI, SPI_READ_DUMMY_CMD, val);
     
     // Set CS to HIGH
     ACC_CS_HIGH();
}

I'm keep getting 0xff in the Rx_Buffer for every read.
Can anyone help me?
Thanks

Outcomes