AnsweredAssumed Answered

SPI DMA recover from data shift

Question asked by van_der_putten.bob on Dec 11, 2014
Latest reply on Dec 12, 2014 by van_der_putten.bob
I implemented SPI DMA communication between two STM32F103 chips.
I transfer 50 unit16_t from master to slave and vice verse. When the transmission of the master is finished (DMA1_IT_TC3  interrupt) I will rise an output pin. This will generate an interrupt on the slave side. This interrupt is used to re-init the DMA transfer in the slave unit.
It seems to work fine, until a datashift occurs. The first byte seems to be at the second position. The last byte at the first.
How do I recover from such an event (apart from finding the source of the error).
I used the following code in the slave unit:

void InitSPI_DMA_Transfer(void){

    DMA_InitTypeDef DMA_InitStructure;    
    /*    Configure the DMA controller*/    
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);    
    
    /*init DMA1 Channel 3 for Transmission.*/    
    DMA_DeInit(DMA_SPI_TX_CHANNEL);    
    DMA_StructInit(&DMA_InitStructure);
    
    DMA_InitStructure.DMA_PeripheralBaseAddr  = (uint32_t) &(SPI1->DR);    
    DMA_InitStructure.DMA_MemoryBaseAddr  = (uint32_t) &SPI_Slave_MISO_TX_Buffer;    
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;    
    DMA_InitStructure.DMA_BufferSize  = SPI_BUFFER_SIZE;    
    DMA_InitStructure.DMA_PeripheralInc  = DMA_PeripheralInc_Disable;    
    DMA_InitStructure.DMA_MemoryInc  = DMA_MemoryInc_Enable;    
    DMA_InitStructure.DMA_PeripheralDataSize  = DMA_PeripheralDataSize_HalfWord;    
    DMA_InitStructure.DMA_MemoryDataSize  = DMA_MemoryDataSize_HalfWord;    
    DMA_InitStructure.DMA_Mode  = DMA_Mode_Normal;    
    DMA_InitStructure.DMA_Priority  = DMA_Priority_High;    
    DMA_Init(DMA_SPI_TX_CHANNEL, &DMA_InitStructure);
    
    /*init DMA1 Channel 2 for Reception.*/    
    DMA_DeInit(DMA_SPI_RX_CHANNEL);    
    DMA_StructInit(&DMA_InitStructure);    
    
    DMA_InitStructure.DMA_PeripheralBaseAddr  = (uint32_t) &(SPI1->DR);    
    DMA_InitStructure.DMA_MemoryBaseAddr  = (uint32_t) &SPI_Slave_MOSI_RX_Buffer;    
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;    
    DMA_InitStructure.DMA_BufferSize  = SPI_BUFFER_SIZE;    
    DMA_InitStructure.DMA_PeripheralInc  = DMA_PeripheralInc_Disable;    
    DMA_InitStructure.DMA_MemoryInc  = DMA_MemoryInc_Enable;    
    DMA_InitStructure.DMA_PeripheralDataSize  = DMA_PeripheralDataSize_HalfWord;    
    DMA_InitStructure.DMA_MemoryDataSize  = DMA_MemoryDataSize_HalfWord;    
    DMA_InitStructure.DMA_Mode  = DMA_Mode_Normal;    
    DMA_InitStructure.DMA_Priority  = DMA_Priority_High;    
    DMA_Init(DMA_SPI_RX_CHANNEL, &DMA_InitStructure);
}

void HardwareSPI_init(void)
{    
    SPI_InitTypeDef SPI_InitStructure;    
    GPIO_InitTypeDef SPI_GPIO_InitStructure;    
    EXTI_InitTypeDef EXTI_InitStructure;    
    NVIC_InitTypeDef NVIC_InitStructure;
    
    GPIO_StructInit(&SPI_GPIO_InitStructure);
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO | SPI_MISO_GPIO_CLK | SPI_SCK_GPIO_CLK | SPI_MOSI_GPIO_CLK | SPI_CS_GPIO_CLK, ENABLE);    
    
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);                  /*JTAG-DP Disabled and SW-DP Enabled*/    
    /* Configure REmapped- SPI pins: SCK, MISO and MOSI*/    
    GPIO_PinRemapConfig (GPIO_Remap_SPI1,ENABLE );    

    /*Configure SPI pins:  SCLK=PB3, MISO=PB4, MOSI=PB5, CS=PA15*/        
    SPI_GPIO_InitStructure.GPIO_Pin = SPI_CS_PIN;    
    SPI_GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;    
    SPI_GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    
    GPIO_Init(SPI_CS_GPIO_PORT, &SPI_GPIO_InitStructure);
    
    /*create a external interrupt for the NSS (CS) line.*/    
    EXTI_StructInit(&EXTI_InitStructure);    
    EXTI_InitStructure.EXTI_Line = EXTI_Line15;    
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;    
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;    
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;    
    EXTI_Init(&EXTI_InitStructure);
    
    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;    
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;    
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;    
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    
    NVIC_Init(&NVIC_InitStructure);
    
    SPI_GPIO_InitStructure.GPIO_Pin = SPI_MOSI_PIN;    
    SPI_GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    
    SPI_GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    
    GPIO_Init(SPI_MOSI_GPIO_PORT, &SPI_GPIO_InitStructure);
    
    SPI_GPIO_InitStructure.GPIO_Pin = SPI_MISO_PIN ;    
    SPI_GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    
    SPI_GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    
    GPIO_Init(SPI_MISO_GPIO_PORT, &SPI_GPIO_InitStructure);
    
    SPI_GPIO_InitStructure.GPIO_Pin = SPI_SCK_PIN ;    
    SPI_GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    
    SPI_GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    
    GPIO_Init(SPI_SCK_GPIO_PORT, &SPI_GPIO_InitStructure);
    
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;    
    SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;    
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;    
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;    
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;    
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;    
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;    
    SPI_InitStructure.SPI_CRCPolynomial = 7;    
    SPI_Init(SPI1, &SPI_InitStructure);    
 
    InitSPI_DMA_Transfer();
    DMA_Cmd(DMA_SPI_TX_CHANNEL,ENABLE);
    DMA_Cmd(DMA_SPI_RX_CHANNEL,ENABLE);
    SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx,ENABLE);
    SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Rx,ENABLE);
    SPI_Cmd(SPI_PORT, ENABLE);
}

 

void         EXTI15_10_IRQHandler(void)
{
    InitSPI_DMA_Transfer();    
    DMA_Cmd(DMA_SPI_TX_CHANNEL,ENABLE);    
    DMA_Cmd(DMA_SPI_RX_CHANNEL,ENABLE);
    SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx,ENABLE);    
    SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Rx,ENABLE);    
    SPI_Cmd(SPI_PORT, ENABLE);    
    EXTI_ClearITPendingBit(EXTI_Line15);

 }

Outcomes