AnsweredAssumed Answered

DMA to SPI hangs at second transfer

Question asked by switalski.pawel on Jan 1, 2012
Latest reply on Jan 2, 2012 by switalski.pawel
When I use DMA to trasfer data from memory to SPI2 everything works well util I try do another trasfer, then I reload NDTR register I try enable DMA, but nothing happens, there are no errors in setatus register, just cant set EN bit for stream. When I do deinitialization of DMA stream, and initialize again, it works well.

Siple code where problem occurs:
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI2, &SPI_InitStructure);

    SPI_Cmd(SPI2, ENABLE);

    DMA_DeInit(DMA1_Stream4);

    DMA_Cmd(DMA1_Stream4, DISABLE);
    DMA_InitTypeDef DMA_InitStructure;
    DMA_InitStructure.DMA_Channel = DMA_Channel_0;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) (&(SPI2->DR));
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) (&buuf);
    DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
    DMA_InitStructure.DMA_BufferSize = (uint32_t) 10;
    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_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init(DMA1_Stream4, &DMA_InitStructure);

    DMA_Cmd(DMA1_Stream4, ENABLE);   //THIS TRANSATION WORK WELL
    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);


  while (DMA_GetCurrDataCounter(DMA1_Stream4));
    DMA_Cmd(DMA1_Stream4,DISABLE);
    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, DISABLE);
    while (DMA1_Stream4->CR & 0x01 == 1);
    DMA1_Stream4->NDTR=17;
    DMA_Cmd(DMA1_Stream4,ENABLE); //THIS WILL NOT ENABLE STREAM EN=0
    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); //HANG HERE
    while (DMA_GetCurrDataCounter(DMA1_Stream4));
    DMA_Cmd(DMA1_Stream4,DISABLE);
    while (DMA1_Stream4->CR & 0x01 == 1);
    DMA1_Stream4->M0AR = (uint32_t) (&buuf);
    DMA1_Stream4->NDTR=27;
    DMA_Cmd(DMA1_Stream4,ENABLE);

Outcomes