cancel
Showing results for 
Search instead for 
Did you mean: 

SPI3 v SPI1/2 on STM32U585 chips

EC.3
Associate III

Hello,

I'm porting code that worked on STM32U585CI using SPI1 as full duplex master with GPDMA1 CH4(Rx)/CH5(Tx) to an STM32U585QII using SPI3, again as master with GPDMA1 CH4(Rx)/CH5(Tx). Only 1 SPI is used. I'm using CubeIDE 1.13.2 to autogenerate HAL initialization code, which I confirmed calls MX_GPDMA1_Init() before MX_SPI3_Init(). I compared the autogenerated code between the two chips to see that all IOC-controlled settings came out the same. I've looked some through the reference manual to identify differences between SPI3 v SPI1/2, and also saw this ticket, warning that there is a SPI3 size limitation of 1023 bytes.

While I'm also in the process of determining whether there might be a board issue, I'm wondering if there are any subtle gotchas with what I'm trying to do, using SPI3 versus one of the other SPI peripherals. There is this blocking function (partially shown below) used during application initialization that gets called before DMA is even engaged. The U585QII gets stuck in this while() loop trying to transmit/receive less than 30 bytes. It transmits all bytes but receives none.

As far as I can tell, the control registers operate the same between the various SPIx peripherals – is that really the case or is this code snippet problematic for SPI3 for that or some other reason?

SPI_HandleTypeDef * hspi; // This is set to either hspi1 or hspi3 depending on chip
void blocking_func(uint8_t *tx_data, uint8_t *rx_data, uint16_t size)
{
uint16_t tx_size = size;
uint16_t rx_size = size;

if (hspi->State != HAL_SPI_STATE_READY) {
    return;
}

hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, size);
__HAL_SPI_ENABLE(hspi);
SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);

while ((tx_size > 0) || (rx_size > 0)) {
    if ((hspi->Instance->SR & SPI_FLAG_TXP) && (tx_size > 0)) {
        *(volatile uint8_t *)&hspi->Instance->TXDR = *tx_data++;
        tx_size--;
    }

    if ((hspi->Instance->SR & (SPI_FLAG_RXWNE | SPI_FLAG_FRLVL)) && (rx_size > 0)) {
        *rx_data++ = *(volatile uint8_t *)&hspi->Instance->RXDR;
        rx_size--;
    }
}
...

1 ACCEPTED SOLUTION

Accepted Solutions
EC.3
Associate III

It turns out that the answer to this is this ticket , which explains that HAL_PWREx_EnableVddIO2() needs to be called in order to enable PG[15:2], which in my case relates to SPI3's SCK and CS GPIO.

It would be good for the IOC to either auto-generate this code or at least warn/ask about enabling it if those pins are configured for use.

View solution in original post

1 REPLY 1
EC.3
Associate III

It turns out that the answer to this is this ticket , which explains that HAL_PWREx_EnableVddIO2() needs to be called in order to enable PG[15:2], which in my case relates to SPI3's SCK and CS GPIO.

It would be good for the IOC to either auto-generate this code or at least warn/ask about enabling it if those pins are configured for use.