[SOLVED] STM32F401RE SPI example not working Topic is solved

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
Engemil
Posts: 37
Joined: Thu Dec 19, 2024 12:50 am
Has thanked: 13 times
Been thanked: 10 times

[SOLVED] STM32F401RE SPI example not working

Post by Engemil »

Hi,

I'm working on a SPI example to learn how to work with SPI on ChibiOS, but it seems to be a problem with it, specifically the clock signal.

Platform: STM32F4xx
Board: NUCLEO64-F401RE (STM32F401RE chip)
ChibiOS version: (github branch: master . Commit: 9d34e55d210c26b669a0ff8f3f32a01b6739a426 (Mar 27, 2025))
Example code is based on: https://github.com/ChibiOS/ChibiOS/tree ... E-NUCLEO64

The idea is to have it work with a sensor module (cheap module named GY-91 that includes a MPU-9250). I have already tested the module with an arduino, confirming that the module works with existing libraries for Arduino.

I have the source code of the main.c-file here: https://gist.github.com/engemil/6c8dcef ... 4056486c9d

Code: Select all

#include "ch.h"
#include "hal.h"
#include "chprintf.h"

#define MPU9250_RW_BIT_READ     0x01
#define MPU9250_RW_BIT_WRITE    0x00
#define MPU9250_WHO_AM_I        0x75

/* NUCLEO64 F401RE board.h file:
 * https://github.com/ChibiOS/ChibiOS/blob/master/os/hal/boards/ST_NUCLEO64_F401RE/board.h
 */
#define SPI_MOSI_LINE            LINE_ARD_D11
#define SPI_MISO_LINE            LINE_ARD_D12
#define SPI_SCLK_LINE            LINE_ARD_D13
#define SPI_CS_MPU9250_LINE      LINE_ARD_D10
#define SPI_CS_BMP280_LINE       LINE_ARD_D9
#define LED_INDICATOR_LINE       LINE_LED_GREEN

/*
 * Non-circular SPI.
 * CR1: CPOL = 0, CPHA = 0, BR = 656,25kHz, Word Size: 8-bit
 */
static SPIConfig spicfg = {
    .circular       = false,                        // Non-circular mode
    .slave          = false,                        // Master mode
    .data_cb        = NULL,                         // No callback
    .error_cb       = NULL,                         // No callback
    .ssline         = SPI_CS_MPU9250_LINE,           // Chip Select Pin
    .cr1            = SPI_CR1_BR_2 | SPI_CR1_BR_1 | // Prescaler = 128 (for (656,25kHz) ~1MHz at 84 MHz PCLK2)
                      0,                            // CPOL = 0, CPHA = 0 (Mode 0), LSBFIRST = 0 (MSB first), SPI_CR1_DFF = 0 (8-bit data frame)
    .cr2            = 0                             // Default 8-bit data
};

/* Buffer declaration. */
static uint8_t txbuf[2], rxbuf[2];

/* Serial Configuration for Virtual COM Port (USART2) */
static SerialConfig serial_cfg = {
    .speed  = 115200,           // Baud rate
    .cr1    = 0,                // No parity, 8-bit data (default)
    .cr2    = 0,                // No specific control settings
    .cr3    = 0                 // No hardware flow control
};

int main(void) {

    /* System initializations. */
    halInit();
    chSysInit();

    /* Configure Serial Driver SD2 (USART2) for Virtual COM Port */
    palSetPadMode(GPIOA, GPIOA_USART2_TX, PAL_MODE_ALTERNATE(7) |
        PAL_STM32_OSPEED_MID2 |
        PAL_STM32_PUPDR_FLOATING |
        PAL_STM32_OTYPE_PUSHPULL);
    palSetPadMode(GPIOA, GPIOA_USART2_RX, PAL_MODE_ALTERNATE(7) |
        PAL_STM32_OSPEED_MID2 |
        PAL_STM32_PUPDR_FLOATING |
        PAL_STM32_OTYPE_PUSHPULL);
    sdStart(&SD2, &serial_cfg); // Start Serial Driver 2
   
    /* Print initial message */
    chprintf((BaseSequentialStream*)&SD2, "Starting MPU9250 Test...\r\n");

    /* Configuring the GPIOs used by the SPI1. */
    palSetLineMode(SPI_CS_MPU9250_LINE, PAL_MODE_OUTPUT_PUSHPULL);
    palSetLineMode(SPI_CS_BMP280_LINE, PAL_MODE_OUTPUT_PUSHPULL);
    palSetLineMode(SPI_MOSI_LINE, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST);
    palSetLineMode(SPI_MISO_LINE, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST);
    palSetLineMode(SPI_SCLK_LINE, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST);

    /* Configure the board LED Light as digital output push-pull. */
    palSetLineMode(LED_INDICATOR_LINE, PAL_MODE_OUTPUT_PUSHPULL);
   
    /* Set Chip Select Pins HIGH, to keep them "inactive" */
    palSetLine(SPI_CS_BMP280_LINE);
    palSetLine(SPI_CS_MPU9250_LINE);


    /* Activating the SPID1 with the chosen configuration. */
    spiStart(&SPID1, &spicfg);

    /* Print debug message before reading WHO_AM_I */
    chprintf((BaseSequentialStream*)&SD2, "Reading WHO_AM_I register...\r\n");

    /* Preparing the first word with the command to read the WHO_AM_I register.
       NB! Remember for out case W/R-bit is at MSB position. */
    txbuf[0] = (MPU9250_RW_BIT_READ << 7) | (MPU9250_WHO_AM_I << 0);

    chprintf((BaseSequentialStream*)&SD2, "Sending txbuf[0]: 0x%02X , txbuf[1]: 0x%02X\r\n", txbuf[0],txbuf[1]);

    while(true) {

        chThdSleepMilliseconds(5000);

        /* Performing an exchange. */
        spiSelect(&SPID1);
        spiExchange(&SPID1, 2, txbuf, rxbuf);
        spiUnselect(&SPID1);
        /* The value of the register is at this point
            stored in rxbuf[1]. */
       
        /* Print the received WHO_AM_I value */
        chprintf((BaseSequentialStream*)&SD2, "Receiving rxbuf[0]: 0x%02X , rxbuf[1]: 0x%02X\r\n", rxbuf[0],rxbuf[1]);
        chprintf((BaseSequentialStream*)&SD2, "WHO_AM_I value: 0x%02X\r\n", rxbuf[1]);
       
        /* Use LED light to indicate if it is as expected */
        if(rxbuf[1] != 0x00){
            palSetLine(LED_INDICATOR_LINE);
            chprintf((BaseSequentialStream*)&SD2, "MPU9250/9255 detected!\r\n");
        }else{
            palClearLine(LED_INDICATOR_LINE);
            chprintf((BaseSequentialStream*)&SD2, "Unknown device detected.\r\n");
        }
       
    }

}


I have made sure to enable the needed variables in cfg/halconf.h:

Code: Select all

#define HAL_USE_SPI                         TRUE


and in cfg/mcuconf.h

Code: Select all

#define STM32_SPI_USE_SPI1                  TRUE


The code runs fine, I also added the virtual COM port to print out for me. However, it seems like the clock line for the SPI isn't operating, as shown here:

Image

We are seeing the READ bit (1) at the beginning + 0x75 which equals 0b 1111 0101. But no clock signal.

What could be possible reasons for the clock line not working?
Last edited by Engemil on Wed Apr 02, 2025 4:03 pm, edited 1 time in total.
Engemil
Posts: 37
Joined: Thu Dec 19, 2024 12:50 am
Has thanked: 13 times
Been thanked: 10 times

Re: STM32F401RE SPI example not working

Post by Engemil »

I found out what the problem was in the end.

The clock signal for SPI1 on the NUCLEO64-F401RE board is also associated with the LD2 (arduino-compatible green LED light). I just removed the code related to the LED_INDICATOR_LINE and it now works.
Post Reply