AnsweredAssumed Answered

[Help] SPI DMA STM32F4

Question asked by Duc_Sy.Nguyen on Oct 24, 2016
Latest reply on Nov 2, 2016 by Nesrine M
hi,
I am communicating with the handle of the ps2 using spi dma stm32f4,but encountered a few problems
While I do not use dma it works fine
i use
void PS2_Send_Recive(unsigned char commands[], unsigned char data[], int length)
{
int i = 0;
//set CS pin low to select PS2
GPIO_ResetBits(GPIOA, GPIO_Pin_4); //CS ON
delay_us(15); //15us delay before sending commands
 
for(i = 0; i < length; i = i + 1)
{
while(SPI_I2S_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1, commands[i]);
//delay_us(20);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET){}
data[i] = SPI_I2S_ReceiveData(SPI1);
delay_us(20); //15us delay before sending next command
}//set CS pin high to deselect PS2
GPIO_SetBits(GPIOA, GPIO_Pin_4);  //CS OFF
}
in main
int main(void)
{
PeriphClk_config();
GPIO_config();
Timer3_config();
SPI_config();
while(1)
{
PS2_Send_Recive(PS2_InitialPoll, Data, 9);
}
with 
unsigned char PS2_InitialPoll[9] = {0x01, 0x42, 0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00};
unsigned char Data[9] = {0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00};
i see Data on stmstudio : when send (0x01 is 255);   (0x42--115);    (0x00--90)   ;  (0x00--255)..... it correct
but when i use DMA
i setup 
void DMA_SPI()
{
  //TX
    DMA_Init_SPI.DMA_Channel = DMA_Channel_3;
    DMA_Init_SPI.DMA_PeripheralBaseAddr = (uint32_t)&(SPI1->DR);
    DMA_Init_SPI.DMA_Memory0BaseAddr = (uint32_t)SPI_Out;
    DMA_Init_SPI.DMA_DIR = DMA_DIR_MemoryToPeripheral;
    DMA_Init_SPI.DMA_BufferSize = 9;
    DMA_Init_SPI.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_Init_SPI.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_Init_SPI.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_Init_SPI.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_Init_SPI.DMA_Mode = DMA_Mode_Normal;
    DMA_Init_SPI.DMA_Priority = DMA_Priority_Medium;
    DMA_Init_SPI.DMA_FIFOMode = DMA_FIFOMode_Disable;
    DMA_Init_SPI.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
    DMA_Init_SPI.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_Init_SPI.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
     
    DMA_Init(DMA2_Stream3, &DMA_Init_SPI);
     
    NVIC_EnableIRQ(DMA2_Stream3_IRQn);
     
    DMA_ITConfig(DMA2_Stream3, DMA_IT_TC, ENABLE);
     
    SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
    //RX
    DMA_Init_SPI.DMA_Channel = DMA_Channel_3;
    DMA_Init_SPI.DMA_PeripheralBaseAddr = (uint32_t)&(SPI1->DR);
    DMA_Init_SPI.DMA_Memory0BaseAddr = (uint32_t)SPI_In;
    DMA_Init_SPI.DMA_DIR = DMA_DIR_PeripheralToMemory;
    DMA_Init_SPI.DMA_BufferSize = 9;
    DMA_Init_SPI.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_Init_SPI.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_Init_SPI.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_Init_SPI.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_Init_SPI.DMA_Mode = DMA_Mode_Normal;
    DMA_Init_SPI.DMA_Priority = DMA_Priority_Medium;
    DMA_Init_SPI.DMA_FIFOMode = DMA_FIFOMode_Disable;
    DMA_Init_SPI.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
    DMA_Init_SPI.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_Init_SPI.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
     
    DMA_Init(DMA2_Stream0, &DMA_Init_SPI);
     
    NVIC_EnableIRQ(DMA2_Stream0_IRQn);
     
    DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
     
    SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
}
void StartSPI(uint8_t number)
{
  DMA_SetCurrDataCounter(DMA2_Stream0,number);
    DMA_SetCurrDataCounter(DMA2_Stream3,number);
     
    SPI_work=1;
    GPIO_ResetBits(GPIOA, GPIO_Pin_4);
    DMA_Cmd(DMA2_Stream0,ENABLE);
    DMA_Cmd(DMA2_Stream3,ENABLE);
}
 
void SPIwait(void)
{
while(SPI_work){}
}
 
void SetSPI_Out(uint8_t Adr,uint8_t Data)
{
   if (Adr<9)
         {
         SPI_Out[Adr]=Data;
             
         }
}
 
uint8_t GetSPI_In(uint8_t Adr)
{
return SPI_In[Adr];
}
//RX
void DMA2_Stream0_IRQHandler(void)
{
    if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0) == SET)
    {
        DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
        GPIO_SetBits(GPIOA, GPIO_Pin_4);
        SPI_work=0;
        i++;
    }
}
 
//-----------------------------------------------------------------
//TX
void DMA2_Stream3_IRQHandler(void)
{
    if (DMA_GetITStatus(DMA2_Stream3, DMA_IT_TCIF3) == SET)
    {
        DMA_ClearITPendingBit(DMA2_Stream3, DMA_IT_TCIF3);
        j++;
         
    }
}
in main
int main(void)
{
  PeriphClk_config();
  GPIO_config();
  Timer3_config();
  SPI_config();
  DMA_SPI();
     
    SetSPI_Out(0,0x01);
    SetSPI_Out(1,0x42);
    SetSPI_Out(2,0x00);
    SetSPI_Out(3,0x00);
    SetSPI_Out(4,0x00);
    SetSPI_Out(5,0x00);
    SetSPI_Out(6,0x00);
    SetSPI_Out(7,0x00);
    SetSPI_Out(8,0x00);
     
    StartSPI(9);
    SPIwait();
while(1)
{
    GPIOD->ODR = GPIOD->ODR | GPIO_Pin_13;
}
data read is SPI_In on stmstudio is all value 255
and on board GPIO_Pin_13 not ON,i think cursor standing SPIwait() and can not access while(1)

Outcomes