cancel
Showing results for 
Search instead for 
Did you mean: 

STM32f302cc SPI code assistance needed

conrad c
Associate II
Posted on March 25, 2018 at 22:51

Hi,

I have recently move from the STM32f101 to the stm32f302, I am using atollic IDE and the Hal library for the initial configuration of the peripherals.  I use register level setup for a lower overhead. having said this, I am having major issues accessing the a SPI eeprom with code that used to work beautifully. I know the register and architecture is different i have gone over the manual quite a few times. I have adjusted the registers to match but the interface still does not want to read the eeprom correctly. Hw is the same as with the old board . The only difference is the software and the MCU.

Attached is the eeprom.c which has a function called spi_ee_clear(), this functions tests both reading and writing of the eeprom. it works fie with the stm32f101 but the eeprom fails with the stm32f302

Below is my Hal config and the n my register level SPI config , please can someone have a look and let me know what i am missing?

HAL setup:

/* SPI1 init function */

static void MX_SPI1_Init(void)

{

/* SPI1 parameter configuration*/

hspi1.Instance = SPI1;

hspi1.Init.Mode = SPI_MODE_MASTER;

hspi1.Init.Direction = SPI_DIRECTION_2LINES;

hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;

hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;

hspi1.Init.NSS = SPI_NSS_SOFT;

hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;

hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi1.Init.CRCPolynomial = 7;

hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;

hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;

if (HAL_SPI_Init(&hspi1) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

__HAL_SPI_ENABLE(&hspi1);

}

Register config: (repeating hal on a register level)

void spi1_config0(void)//8bit

{

//1MHz

 RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;

 SPI1->CR1 = 0x0000;//first disable SPI

 SPI1->CR2 = 0x0000;

SPI1->CR1 = 0x0024;//8bit 1mhz cpha=0 cpol=0

 SPI1->CR1 |= 0x0300;// enable soft_NSS

 SPI1->CR2 =0x1700;

SPI1->CR1 |= 0x0040;

}

#stm32f302-spi
7 REPLIES 7
Michael Weston
Associate
Posted on April 06, 2018 at 06:18

Hi,

I've just started working with this chip and have discovered the same problem.  Ported code that should work does not work.  I have a logic analyzer and I can clearly see why it doesn't work but I can't figure out any way to actually make it work!

No matter what I do, every byte I send is followed by a zero byte.  I can't even try to force off the interface or do anything after one byte goes out because SPI_SR_TXE only becomes ready once it sends both bytes.

I really hope someone has an answer to that or thousands of dollars in prototypes are wasted if I have to design in a new chip!  I'm using version 9 of TrueSTUDIO and made the code as standard as possible, right out of the Cube software and then just software polled until I get it going.

What's the solution ST???

Posted on April 06, 2018 at 15:24

The SPIx->DR is sensitive to the width of the write, if you want to write a byte you need to cast the write properly to achieve that at a bus level.

*((volatile uint8_t *)&SPI1->DR) = byte; // send 8-bits

I accept PayPal...

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 06, 2018 at 19:10

Ha ha!  I love the PayPal comment.

But seriously, if that works I will be surprised but also super relieved!  DR is a 32 bit register so you can send data at any length between 4 and 16 bits and I have the CRx registers programmed for 8 bits.  To me, that should have been the trigger to send the right number of bits like it is for the STM32F4 chips but now I can't wait to get to the office and try this out.

Thanks for the advice!

Posted on April 06, 2018 at 23:32

Unfortunately Amazon won't deliver cases of beer.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 08, 2018 at 19:11

Hi Clive,

Funny Like the paypal comment, 

Can you also comment on the receive side of the SPI? what is the correct way to read the 4x8bit data frames in the RXFIFO.

If FRXTH is set to 8 bit data mode and the data size is set to 8bit , if i read the DR i dont get the value i expect.

regards

Posted on April 08, 2018 at 19:28

Not sure what you're reading or what you expect to read. The width is going to be impactful on the read and write. I would expect two values to be delivered for a 16-bit wide read and a FIFO holding two bytes.

...

  if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)

  {

    /* Transfer loop */

    while (hspi->RxXferCount > 0U)

    {

      /* Check the RXNE flag */

      if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))

      {

        /* read the received data */

        (* (uint8_t *)pData) = *(__IO uint8_t *)&hspi->Instance->DR;

        pData += sizeof(uint8_t);

        hspi->RxXferCount--;

      }

      else

      {

        /* Timeout management */

        if ((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >=  Timeout)))

        {

          errorcode = HAL_TIMEOUT;

          goto error;

        }

      }

    }

  }

...

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 08, 2018 at 19:42

Hi Clive,

Thanks for your reply, 

i actually solved it using your previous comment, If i could send you a beer i would.

It was all a problem with the reading and writing casts , casting the result as you suggested when i read and write to my eeprom it solved the problem. i tested this to make sure its not just returning the previous values and it looks so far like it worked

static u16 miso = 0;

//SPI1->DR = mosi; //old way

*((volatile uint8_t *)&SPI1->DR)=mosi; //clive suggestion

while ((SPI1->SR & 0x0002 ) == 0x00);//while transmit buffer not empty wait

while ((SPI1->SR & 0x0101) == 0x00);//while receive buffer is empty wait and fifo not 1/4 full

//miso = ((SPI1->DR)); //old way

miso = *((volatile uint8_t *)&SPI1->DR); //clive suggestion

return (miso);