STM32H745BI SPI port does not start
I am trying to get a SPI port up and running on an STM32H745BI chip but after configuring the port and starting the transmission I never see any signals on the pins and the port never gets an End Of Transmission (EOT) high signal. Startup code is listed below, it hangs while waiting for EOT. Relevant register values are in the attached image. Any ideas on why this code doesn't work? Thanks!
// define GPIO pin interface to external ADC, see DS12923 Table 9 for alternate function mapping // Schematic signal
static pinDef adc_rdl = { .port = GPIOI, .pin = PIN_0, .mode = Alternate, .type = PushPull, .speed = VeryHigh, .pull = None, .alternate = AF5 }; // SPI2_NSS
static pinDef adc_sck = { .port = GPIOI, .pin = PIN_1, .mode = Alternate, .type = PushPull, .speed = VeryHigh, .pull = None, .alternate = AF5 }; // SPI2_SCK
static pinDef adc_sdo = { .port = GPIOI, .pin = PIN_2, .mode = Alternate, .type = PushPull, .speed = VeryHigh, .pull = None, .alternate = AF5 }; // SPI2_MISO
static pinDef adc_sdi = { .port = GPIOI, .pin = PIN_3, .mode = Alternate, .type = PushPull, .speed = VeryHigh, .pull = None, .alternate = AF5 }; // SPI2_MOSI
void spi2::init(void)
{
// init hardware pins
configurePin(adc_rdl);
configurePin(adc_sck);
configurePin(adc_sdo);
configurePin(adc_sdi);
// init SPI2 port
SET_BIT(RCC->APB1LENR, RCC_APB1LENR_SPI2EN); // turn on SPI2 clock (read change in RCC_C1_APB1LENR)
SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_SPI2RST); // reset SPI2 peripheral
CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_SPI2RST); // release reset
SET_BIT(SPI2->CFG2, SPI_CFG2_SSOE); // enable SS pin output (this must be done before setting master)
SET_BIT(SPI2->CFG2, SPI_CFG2_MASTER); // act as SPI bus master
MODIFY_REG(SPI2->CR2, SPI_CR2_TSIZE_Msk, 4); // transfer four bytes
SET_BIT(SPI2->CR1, SPI_CR1_SPE); // enable the SPI port
// put dummy data into Tx FIFO
SPI2->TXDR = 0x01; // SPI2->SR TXTF goes high here, so we have data in the FIFO
SPI2->TXDR = 0x02;
SPI2->TXDR = 0x03;
SPI2->TXDR = 0x04;
// start transmission
SET_BIT(SPI2->CR1, SPI_CR1_CSTART);
while (!READ_BIT(SPI2->SR, SPI_SR_EOT)) {} // <-- program hangs here, EOT never goes high
}
Edit:
Just checking my clock inputs:
The SPI2 spi_ker_ck input source gets selected by RCC_D2CCIP1R_SPI123SEL which is set to 1 so that it uses pll2_p_ck as an input. I can route pll2_p_ck out of the MCO2 pin where it is 200MHz as expected.
Then spi_pclk comes from the APB1 clock that is running at 120MHz. I don't have a way to measure that directly but I can write to the SPI2 registers just fine so some kind of clock must be there.
There is a mention in the errata of a possible stall caused when spi_pclk is much faster than spi_ker_ck but that does not seem to be the case here.
