SPI by hand/prerequisites for SPI
Hi,
I've been trying to adapt the current SPI driver in RIOT OS to support the U5 series(STM32U585AI), due to my lack of success I've been trying to sidestep RIOT for a moment and try to do must of the setup manually. But so far I have not been able to get SPI3 to output anything, not even an SCLK signal, leading me to believe that I've just missed something simple like some clock domain etc.
My approach so far:
- enable HSI clock
- enable VddIO2
- select HSI timer for SPI3
- enable SPI3 peripheral
- enable GPIO ports B & G
- reset SPI3 CR1
- write SPI3 CFG1, CFG2, CR2
- set SPE, SSI bits in CR1
- set CSTART in CR1
- read write to TXDR, RXDR
However step 8, specifically setting the SPE is where the problem becomes apparent, the SPE bit does not stay enabled. Does anyone have any hints on where to look to get this running?
Snippiet I've been using so far, spi_init* and stmclk_enable* are provied by RIOT:
stmclk_enable_hsi();
stmclk_enable_lfclk();
// spi_init(0);
// spi_init_pins(0);
// spi_acquire(0, spi_config[0].cs_pin, SPI_MODE_0, SPI_CLK_10MHZ);
// spi_transfer_bytes(0, spi_config[0].cs_pin, false, "Hello World", NULL,
// strlen("Hello World")); spi_release(0);
// enable vddio2
PWR->SVMCR |= PWR_SVMCR_IO2SV;
// set SPI3 clk to HSI
RCC->CCIPR3 &= ~RCC_CCIPR3_SPI3SEL_Msk;
RCC->CCIPR3 |= RCC_SPI3CLKSOURCE_HSI;
assume(RCC->CCIPR3 & RCC_SPI3CLKSOURCE_HSI);
// enable peripheral
RCC->APB3ENR |= RCC_APB3ENR_SPI3EN;
assume(RCC->APB3ENR & RCC_APB3ENR_SPI3EN);
RCC->APB3RSTR &= ~RCC_APB3ENR_SPI3EN;
// enable GPIO ports
RCC->AHB2ENR1 |= RCC_AHB2ENR1_GPIOGEN | RCC_AHB2ENR1_GPIOBEN;
assume(RCC->AHB2ENR1 & (RCC_AHB2ENR1_GPIOGEN | RCC_AHB2ENR1_GPIOBEN));
spi_init_pins(0);
assume(spi_init_cs(0, spi_config[0].cs_pin) == SPI_OK);
const char *MSG = "Hello World";
const int MSG_LEN = strlen(MSG);
volatile char recv_buf[MSG_LEN];
// reset SPI
SPI3->CR1 = 0;
{
// SPE must be 0 to write CFG{1,2}
assume((SPI3->CR1 & SPI_CR1_SPE) == 0);
SPI3->CFG1 = 0b1100000000000000111 | (3 << 29);
SPI3->CFG2 = 0b1000100010000000000000000000000;
SPI3->CR2 = (uint16_t)MSG_LEN;
}
SPI3->CR1 |= SPI_CR1_SPE | SPI_CR1_SSI;
assume(SPI3->CR1 & SPI_CR1_SPE);
SPI3->CR1 |= SPI_CR1_CSTART;
volatile uint8_t *TXDR = (uint8_t *)&SPI3->TXDR;
volatile uint8_t *RXDR = (uint8_t *)&SPI3->RXDR;
for (uint16_t rx_rem = strlen(MSG), tx_rem = strlen(MSG);
rx_rem > 0 && tx_rem > 0 && !(SPI3->SR & SPI_SR_EOT);) {
if (SPI3->SR & SPI_SR_TXP && tx_rem) {
*TXDR = MSG[MSG_LEN - tx_rem];
tx_rem--;
}
if (SPI3->SR & SPI_SR_RXP && rx_rem) {
recv_buf[MSG_LEN - rx_rem] = *RXDR;
rx_rem--;
}
}
while (!(SPI3->SR & SPI_SR_EOT)) {
}

