cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L0 SPI + DMA + interrupts = Problem

fiske23
Associate II
Posted on February 28, 2016 at 16:16

Hallo,

I have a problem with SPI and DMA in interrupt mode. on my stm32l053. When I start SPI transmition, SCK and NSS pins looks ok, but there is nothing at MOSI line. I checked DR register but it is 0 during whole transmition. At the end I receive TCI interrupt from DMA (what would suggest that it transmited some data from memory to SPI_DR).

Below DMA Initialization:

void MX_DMA_Init(void)

{

  __DMA1_CLK_ENABLE();

  //Channel2 Rx

  DMA1_Channel2->CCR |= (1 << MINC) | (1 << CIRC) |

          (1 << TCIE);

  DMA1_Channel3->CCR |= (1 << MINC) | (1 << CIRC) |

          (1 << TCIE) | (1 << DIR);

//  DMA1_Channel2->CNDTR = 5;

//  DMA1_Channel3->CNDTR = 5;

  DMA1_Channel2->CPAR = (uint32_t)(&(SPI1->DR));

  DMA1_Channel3->CPAR = (uint32_t)(&(SPI1->DR));

  DMA1_Channel2->CMAR = (uint32_t)(rxBuff);

  DMA1_Channel3->CMAR = (uint32_t)(txBuff);

  DMA1_CSELR->CSELR |= (1 << C2S0) | (1 << C3S0);

  /* DMA interrupt init */

  HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);

}

SPI Initialization

void MX_SPI1_Init(void)

{

    __SPI1_CLK_ENABLE();

    SPI1->CR1 |= (1 << BR2) | (1 << CPHA) |

            (1 << MSTR) | (1 << SSM) | (1 << SSI) | (1 << CPOL) | (1 << CPHA);

    SPI1->CR2 |= ( 1 << SSOE);

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);

    SPI1->CR2 |= (1 << TXEIE) | (1 << RXNEIE);

//    HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);

//    HAL_NVIC_EnableIRQ(SPI1_IRQn);

}

and ISR for DMA TCIE

void DMA1_Channel2_3_IRQHandler(void)

{

    if((DMA1->ISR >> TCIF3) & 1)

    {

        DMA1_Channel3->CCR &= ~(1 << EN);

        DMA1->IFCR |= (1 << CTCIF3);

    }

    if((DMA1->ISR >> TCIF2) & 1)

    {

        DMA1_Channel2->CCR &= ~(1 << EN);

        DMA1->IFCR |= (1 << CTCIF2);

        while((SPI1->SR) >> BSY){}

        StopSPI();

    }

}

Could anybody suggest where to look for a problem?

Regards

#je-ne-l'aime-cube #no-hablo-hal
7 REPLIES 7
Posted on February 28, 2016 at 17:23

Could anybody suggest where to look for a problem?

I'd start with the defines and the pin configurations.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
fiske23
Associate II
Posted on February 28, 2016 at 19:53

Thank you for your response.

I checked defines and GPIO configuration. Found 2 mistakes in bit's definitions but were not important and it's still not working.

    __SPI1_CLK_ENABLE();

    __GPIOA_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct;

    GPIO_InitTypeDef GPIO_InitStruct2;

    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

    GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct2.Pin = GPIO_PIN_4;

    GPIO_InitStruct2.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_InitStruct2.Speed = GPIO_SPEED_HIGH;

    GPIO_InitStruct2.Pull = GPIO_PULLUP;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct2);

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);

That's my GPIO configuration. It's generated in Cube MX, and it lokk ok for me.

My rxBuff and txBuff are in embedded SRAM is it important? All registers MAR2, MAR3 and PAR2, PAR3 point into correct locations, DMA counters are loaded with correct values but at the end of transmition they have different, not zero values. I do not understand why.

fiske23
Associate II
Posted on February 28, 2016 at 22:08

I found out that SPI_DR register is 0 all the time. Any ideas why?

Regard

Posted on February 28, 2016 at 23:42

What happens if you don't use DMA, just manually write to SPI_DR in a loop?

JW

Posted on February 29, 2016 at 01:13

The SPIx->DR will not reflect what you write to the other side of the register, pull MISO high and see if it is still zero.

If you think DMA is an issue, walk through the process using the registers. With the STM32 Cortex-M0 parts one also needs to look at the width of the access

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
fiske23
Associate II
Posted on March 01, 2016 at 22:56

Hello,

Thank you for your answers.

First of all, I switched to SPI2 because I use discovery board (I didn't mention that) and there are some interactions between SPI1 and other parts on the board.

I was able to run transmition without DMA, I get correct data at MOSI, MISO pulled up  (0xFF in receive buffer what's correct). So fare so good. But DMA is still not working. I turned off CIRC bits so I get TCI interrupt from TX when CNTR = 0, what's good, but when I debugg, I observed  that TX transmition counter goes from initial value (0xa i.e) to 0 in one clock cycle just after SPI enable.

RX channel is enabled just before TX but it didn't transmit any data (it's value during TCI from TX interrupt = initial value).

So now I do not understand why transmition counter (CNDTR) is going down to 0 so quickly and RX CNTR is freeze.

Regards

fiske23
Associate II
Posted on March 02, 2016 at 22:23

Hello,

Problem solved.

I didn't changed data register to SPI2 that's why I didn't see any data in DR and CNTR worked incorecly.

Thank you for help.

Regards