AnsweredAssumed Answered

STM32F091 SPI DMA Problem

Question asked by Clemens Ehm on Jul 17, 2017
Latest reply on Jul 18, 2017 by Clemens Ehm

Hello,

 

I try to read acceleration values from a LIS3DSHTR using the STM32F091 µC. I use SPI with DMA to read the values but I have trouble with the incoming datas in the RxBuffer.

On my two screenshots you can see the bus communication and the position of the data inside my RxBuffer. The order is totally wrong.

 

I hope someone can check the source code. I hope you can find a stupid mistake

 

void SPI_init()
{
    SPI_InitTypeDef SPI_InitStructure;

 

    // clk
    RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
    RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;

 

    // set af mode
    GPIOA->MODER = ( GPIOA->MODER & ~(GPIO_MODER_MODER5 | GPIO_MODER_MODER6 | GPIO_MODER_MODER7));
    GPIOA->MODER |= ( GPIO_MODER_MODER5_1 | GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1);

 

    GPIOA->AFR[1] = (GPIOA->AFR[1] &~ (GPIO_AFRL_AFR5)) | (0 << GPIO_AFR_POS5);
    GPIOA->AFR[1] = (GPIOA->AFR[1] &~ (GPIO_AFRL_AFR6)) | (0 << GPIO_AFR_POS6);
    GPIOA->AFR[1] = (GPIOA->AFR[1] &~ (GPIO_AFRL_AFR7)) | (0 << GPIO_AFR_POS7);

 

    SPIx_PORT->MODER |= ( GPIO_MODER_MODER4_0);
    SPIx_PORT->OTYPER &= ~( GPIO_OTYPER_OT_4);
    SPIx_PORT->OSPEEDR |= ( GPIO_OSPEEDER_OSPEEDR4);
    SPIx_PORT->PUPDR &= ~( GPIO_PUPDR_PUPDR4);

 

    SPIx_PORT->BSRR = GPIO_BSRR_BS_4; //High - Deselect ACC

 

    /*SPI1-Konfigurieren*/
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPIx,&SPI_InitStructure);

 

    //Use DMA for SPI
    SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, ENABLE);
    SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, ENABLE);

 

    SPI_Cmd(SPIx, ENABLE);

 

    //Init DMA
    DMA_Config();

 

    //Init the buffer with the needed registers of the acc
    AccelerationRequest[0] = ACCELEROMETER_OUT_X_L;
    AccelerationRequest[1] = 0x00; //dummy
    AccelerationRequest[2] = ACCELEROMETER_OUT_X_H;
    AccelerationRequest[3] = 0x00;
    AccelerationRequest[4] = ACCELEROMETER_OUT_Y_L;
    AccelerationRequest[5] = 0x00;
    AccelerationRequest[6] = ACCELEROMETER_OUT_Y_H;
    AccelerationRequest[7] = 0x00;
    AccelerationRequest[8] = ACCELEROMETER_OUT_Z_L;
    AccelerationRequest[9] = 0x00;
    AccelerationRequest[10] = ACCELEROMETER_OUT_Z_H;
    AccelerationRequest[11] = 0x00;
}

 

void DMA_Config()
{
    DMA_InitTypeDef DMA_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

 

    DMA_DeInit(DMA1_Channel2);
    DMA_DeInit(DMA1_Channel3);

 

    DMA_StructInit(&DMA_InitStructure);

 

    // Enable DMA1 Peripheral Clock (SPI_DECAWAVE and SPI_BUS)
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

 

    // Configure SPI_BUS RX Channel
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // From SPI to memory
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_BufferSize = sizeof(RxBuffer);
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel2, &DMA_InitStructure);

 

    // Configure SPI_BUS TX Channel
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // From memory to SPI
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_BufferSize = sizeof(TxBuffer);;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel3, &DMA_InitStructure);

 

    DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);

 

    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

 

//ReadAddrBuffer = AccelerationRequest with the Register values + DummyByte, Size = 12
void SPI_ReadRegisters(uint8_t* ReadAddrBuffer, uint8_t Size)
{
    for (uint8_t i=0; i < Size; i++)
    {
        if (ReadAddrBuffer[i] > 0x00)
            TxBuffer[i] = ReadAddrBuffer[i] | READ_FLAG;
        else
            TxBuffer[i] = 0x00;
    }

 

    DMA_Cmd(DMA1_Channel2, DISABLE);
    DMA_Cmd(DMA1_Channel3, DISABLE);

 

    DMA_SetCurrDataCounter(DMA1_Channel2, Size);
    DMA_SetCurrDataCounter(DMA1_Channel3, Size);

 

    SPI_SelectChip();

 

    DMA_Cmd(DMA1_Channel2, ENABLE);
    DMA_Cmd(DMA1_Channel3, ENABLE);
}

 


void DMA1_Channel2_3_IRQHandler(void)
{
    if (DMA_GetITStatus(DMA1_IT_TC2) != RESET)
    {
        SPI_DeselectChip();

 

        int16_t x = (int16_t)((RxBuffer[1] << 8) | RxBuffer[0]); // / 16384.0f;
        int16_t y = (int16_t)((RxBuffer[3] << 8) | RxBuffer[2]); // / 16384.0f;
        int16_t z = (int16_t)((RxBuffer[5] << 8) | RxBuffer[4]); // / 16384.0f;

 

        DMA_ClearFlag(DMA1_FLAG_TC2);
    }
}

Attachments

Outcomes