AnsweredAssumed Answered

DMA and SPI - TEIF error

Question asked by Teddy Bonkers on Jun 15, 2015
Latest reply on Jun 15, 2015 by Teddy Bonkers
Hello

I am a beginner in using STM32 devices, so please tell me if I am doing something incredibly wrong here. I am trying to enable DMA for SPI on STM21F411RE but I keep getting TEIF error on the SPI3 channel for DMA1 Stream 5. Here is DMA initialization code:
   
/*******************************************************************************************************************/
// DMA for SPI3: DMA1, Channel 0, Stream 5
DMA1->HIFCR = 0xffff;
DMA1->LIFCR = 0xffff;                       // clear interrupt flags for all streams
 
RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;         // Enable clock for DMA1
DMA1_Stream5->NDTR = 1;                     // One data item per transfer (1 byte)
DMA1_Stream5->PAR = (uint32_t) &SPI3->DR;   // Peripheral address register (address of SPI3 DR)
                                            // FIFO disabled (direct mode)
 
SPI3->CR2 |= SPI_CR2_TXDMAEN;               // Enable DMA for SPI
NVIC_EnableIRQ(DMA1_Stream5_IRQn);          // Enable DMA interrupt for the stream
DMA1_Stream5->CR = ((DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_2) | (DMA_SxCR_PL_0) | (DMA_SxCR_DIR_0) | (DMA_SxCR_TCIE));
// Channel 0, Stream 5 (SPI3 TX)
// Single memory burst transfer
// No buffer switching
// Medium priority
// Memory data size 1 byte
// Peripheral data size 1 byte
// Memory address pointer is fixed
// Peripheral address pointer is fixed
// Circular mode disabled
// Transfer direction: memory to peripheral
// The DMA is flow controller
// Transfer complete interrupt enable
/*******************************************************************************************************************/

I am enabling SPI3 before running the above code (works fine without DMA). In the debugger, I am able to see that the code runs fine and all the bits are set. Here are my two send routines:

void _TFT_DMA_wr_cmd(const uint8_t cmd) {
    TFT_DC(0);                                  // DC = 0 (command)
    TFT_CS(0);                                  // Select chip
    SPI3->CR1 &= ~SPI_CR1_SPE;                  // Disable peripheral
    DMA1->HIFCR = 0xffff;
    DMA1->LIFCR = 0xffff;                       // clear interrupt flags for all streams
    DMA2_Stream5->M0AR =  cmd;                  // Put command in MOAR register
    DMA1_Stream5->CR |= DMA_SxCR_EN;            // Enable DMA
    SPI3->CR1 |= SPI_CR1_SPE;                   // Enable peripheral
    SPI3->SR |= SPI_SR_TXE;                     // Request transfer
}
 
void _TFT_DMA_wr_data(uint8_t data) {
    TFT_DC(1);                                  // DC = 1 (data)
    TFT_CS(0);                                  // Select chip
    SPI3->CR1 &= ~SPI_CR1_SPE;                  // Disable peripheral
    DMA1->HIFCR = 0xffff;
    DMA1->LIFCR = 0xffff;                       // clear interrupt flags for all streams
    DMA2_Stream5->M0AR = data;                  // Pud data in MOAR
    DMA1_Stream5->CR |= DMA_SxCR_EN;            // Enable DMA
    SPI3->CR1 |= SPI_CR1_SPE;                   // Enable peripheral
    SPI3->SR |= SPI_SR_TXE;                     // Request transfer
}

The problem arises in the following two lines:
DMA2_Stream5->M0AR = data;                  // Pud data in MOAR
DMA1_Stream5->CR |= DMA_SxCR_EN;            // Enable DMA

When I run the code line by line I see that the data is not being copied in M0AR register, and immediately after trying to enable DMA I get an flag raised - the TEIF5 flag. No error flags are raised for the SPI peripheral. The datasheet states that "TEIF is set when a bus error occurs during a DMA read or a write access".
Any help will be greatly appreciated. Thanks

Outcomes