Getting SPI to work on STM32F7 Topic is solved

Report here problems in any of ChibiOS components. This forum is NOT for support.
JSStabl
Posts: 78
Joined: Tue Feb 25, 2020 4:06 pm
Has thanked: 3 times
Been thanked: 2 times

Getting SPI to work on STM32F7  Topic is solved

Postby JSStabl » Thu Feb 27, 2020 9:07 am

I'm just starting with chibiOS and I'm using the STM32F767 Nucleo-144 Board.

With ChibiStudio I have the running LED Demo Project working, now I wanted to get the SPI to work. I jused the SPI Example from the HAL examples and added it to the SMT32F767 Demo Project. SPI HAL driver was enabled I also set the SPI STM32_SPI_USE_SPI2.

Now, the SPI Threads do nothing, the Thread is not being executed (I tested it with toggling an LED there). I also connected an Osci to the D13 Port. What am I doing wrong?

I disabled the Blinker Thread, enabling that makes the LED Blink though, just to show my program compiles and start properly.

Code: Select all

/*
    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

#include "ch.h"
#include "hal.h"
#include "rt_test_root.h"
#include "oslib_test_root.h"


/*===========================================================================*/
/* SPI driver related.                                                       */
/*===========================================================================*/

/*
 * Low speed SPI configuration (421.875kHz, CPHA=0, CPOL=0, MSb first).
 */
static const SPIConfig ls_spicfg = {
  false,
  NULL,
  GPIOB,
  GPIOB_ARD_D14,
  SPI_CR1_BR_2 | SPI_CR1_BR_1,
  SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0
};

/*
 * SPI TX and RX buffers.
 * Note, the buffer are aligned to a 32 bytes boundary because limitations
 * imposed by the data cache. Note, this is GNU specific, it must be
 * handled differently for other compilers.
 */
#define SPI_BUFFERS_SIZE    128U

static uint8_t txbuf[SPI_BUFFERS_SIZE];
static uint8_t rxbuf[SPI_BUFFERS_SIZE];

/*
 * SPI bus contender 1.
 */
static THD_WORKING_AREA(spi_thread_1_wa, 256);
static THD_FUNCTION(spi_thread_1, p) {

  (void)p;
  chRegSetThreadName("SPI thread 1");
  while (true) {
    unsigned i;

    palSetLine(LINE_LED1);
    chThdSleepMilliseconds(200);
    palClearLine(LINE_LED1);
    chThdSleepMilliseconds(200);

    /* Bush acquisition and SPI reprogramming.*/
    spiAcquireBus(&SPID2);
    spiStart(&SPID2, &ls_spicfg);

    /* Preparing data buffer and flushing cache.*/
    for (i = 0; i < SPI_BUFFERS_SIZE; i++)
      txbuf[i] = (uint8_t)i;

    /* Slave selection and data exchange.*/
    spiSelect(&SPID2);
    //spiExchange(&SPID2, SPI_BUFFERS_SIZE, txbuf, rxbuf);
    spiSend(&SPID2, SPI_BUFFERS_SIZE, txbuf);
    spiUnselect(&SPID2);

    /* Releasing the bus.*/
    spiReleaseBus(&SPID2);
  }
}

/*
 * This is a periodic thread that does absolutely nothing except flashing
 * a LED.
 */
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {

  (void)arg;
  chRegSetThreadName("blinker");
  while (true) {
    palSetLine(LINE_LED1);
    chThdSleepMilliseconds(50);
    palSetLine(LINE_LED2);
    chThdSleepMilliseconds(50);
    palSetLine(LINE_LED3);
    chThdSleepMilliseconds(200);
    palClearLine(LINE_LED1);
    chThdSleepMilliseconds(50);
    palClearLine(LINE_LED2);
    chThdSleepMilliseconds(50);
    palClearLine(LINE_LED3);
    chThdSleepMilliseconds(200);
  }
}

/*
 * Application entry point.
 */
int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * SPI2 I/O pins setup.
   */
  palSetLineMode(LINE_ARD_D13,
                 PAL_MODE_ALTERNATE(5) |
                 PAL_STM32_OSPEED_HIGHEST);         /* SPI SCK.             */
  palSetLineMode(LINE_ARD_D12,
                 PAL_MODE_ALTERNATE(5) |
                 PAL_STM32_OSPEED_HIGHEST);         /* MISO.                */
  palSetLineMode(LINE_ARD_D11,
                 PAL_MODE_ALTERNATE(5) |
                 PAL_STM32_OSPEED_HIGHEST);         /* MOSI.                */
  palSetLine(LINE_ARD_D15);
  palSetLineMode(LINE_ARD_D15,
                 PAL_MODE_OUTPUT_PUSHPULL);         /* CS0.                 */
  palSetLine(LINE_ARD_D14);
  palSetLineMode(LINE_ARD_D14,
                 PAL_MODE_OUTPUT_PUSHPULL);         /* CS1.                 */

  /*
   * Activates the serial driver 3 using the driver default configuration.
   */
  sdStart(&SD3, NULL);

  /*
   * Creates the example thread.
   */
//  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO + 1, Thread1, NULL);
  chThdCreateStatic(spi_thread_1_wa, sizeof(spi_thread_1_wa),
                    NORMALPRIO, spi_thread_1, NULL);

  /*
   * Normal main() thread activity, in this demo it does nothing except
   * sleeping in a loop and check the button state.
   */
  while (true) {
    chThdSleepMilliseconds(500);
  }
}


Debugging shows that the Code never returns after the first spiSend().

JSStabl
Posts: 78
Joined: Tue Feb 25, 2020 4:06 pm
Has thanked: 3 times
Been thanked: 2 times

Re: Getting SPI to work on STM32F7

Postby JSStabl » Thu Feb 27, 2020 1:58 pm

Got it working with SPI1, I believe the Alternate 5 is incorrect for SPI2

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Getting SPI to work on STM32F7

Postby Giovanni » Thu Feb 27, 2020 2:29 pm

Thanks, moving in bug reports.

Giovanni

JSStabl
Posts: 78
Joined: Tue Feb 25, 2020 4:06 pm
Has thanked: 3 times
Been thanked: 2 times

Re: Getting SPI to work on STM32F7

Postby JSStabl » Mon Mar 02, 2020 5:08 pm

I actually still have issues with SPI 4 and 5. I can't get them to work, SPI1-3 work fine. I enabled the SPI5 in the mcuconf.h and created a new thread. I took the same configuration as for 1-3 and sent a message, however the I/Os don't do anything at all. Has anybody tested those SPI Channels on ChibiOS? Port and Bus CFG for SPI5:

Code: Select all

        /*
    * SPID5 I/O pins setup.(Overwriting board.h configurations)
    */
    palSetPadMode(GPIOF, 7,
                  PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST);    /* New SCK */
    palSetPadMode(GPIOF, 8,
                  PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST);    /* New MISO*/
    palSetPadMode(GPIOF, 9,
                  PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST);    /* New MOSI*/
    palSetPadMode(GPIOF, 6,
                  PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); /* New CS*/


Code: Select all

const SPIConfig ls_spicfg = {
        false,
        NULL,
        GPIOB,
        GPIOB_ARD_D14,
        SPI_CR1_BR_2 | SPI_CR1_BR_0,
        SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0
};


SPI1 and 5 share a buscfg, is the repeated CS Port a problem? I'm not using the select anway. Replacing SPI5 with SPI1 in the same thread works, so it's not a thread issue. For full disclosure here's the thread:

Code: Select all

THD_WORKING_AREA(spi_thread_afe_wa, 64);
THD_FUNCTION(spi_thread_afe, p) {
    (void)p;
    chRegSetThreadName("SPI Thread AFE");

    while (true) {
        unsigned i;

/* Preparing data buffer and flushing cache.*/
        for (i = 0; i < SPI_BUFFERS_SIZE; i++){
            if(i==0){
                txbuf[i] = (uint8_t)i | 0b10000000;
            }
            else{
                txbuf[i] = (uint8_t)i;
            }
        }
        sendSPI(&SPID5);
        chThdSleepMicroseconds(200);
    }

}


and this is sendSPI:

Code: Select all

void sendSPI(SPIDriver *spip) {
    //    /* Bus acquisition and SPI reprogramming.*/
    spiAcquireBus(spip);

//    spiSelect(spip);
    spiStartSend(spip,SPI_BUFFERS_SIZE, txbuf);
//    spiUnselect(spip);

    spiReleaseBus(spip);
}


I haven't tested SPI6, because the pins are not routed on my Nucleo-144 board. I'm also considering if SPI4-6 aren't working on the NUCLEO-144 for some reason. They aren't mentioned in the reference manual for the board. (For they F767 they definitely exist)

JSStabl
Posts: 78
Joined: Tue Feb 25, 2020 4:06 pm
Has thanked: 3 times
Been thanked: 2 times

Re: Getting SPI to work on STM32F7

Postby JSStabl » Tue Mar 03, 2020 11:02 am

Running a regular CubeMX Example produces results on SPI5, so I assume there is an issue either with my configuration (which I can't seem to find) or the HAL Driver for the STM32F7, whats the best way to debug this?

Here are the SPI status bits from the debugger

Code: Select all

CR1 = {volatile uint32_t} 8 [0x8]
CR2 = {volatile uint32_t} 5895 [0x1707]
SR = {volatile uint32_t} 34 [0x22]
DR = {volatile uint32_t} 0 [0x0]
CRCPR = {volatile uint32_t} 7 [0x7]
RXCRCR = {volatile uint32_t} 0 [0x0]
TXCRCR = {volatile uint32_t} 0 [0x0]
I2SCFGR = {volatile uint32_t} 0 [0x0]
I2SPR = {volatile uint32_t} 0 [0x0]

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Getting SPI to work on STM32F7

Postby Giovanni » Tue Mar 03, 2020 11:40 am

You should verify the DMA channels assigned to SPIs, must not be shared. Are debug options in chconf.h enabled?

Giovanni

JSStabl
Posts: 78
Joined: Tue Feb 25, 2020 4:06 pm
Has thanked: 3 times
Been thanked: 2 times

Re: Getting SPI to work on STM32F7

Postby JSStabl » Tue Mar 03, 2020 12:35 pm

Here is the SPI config:

Code: Select all

/*
 * SPI driver system settings.
 */
#define STM32_SPI_USE_SPI1                  TRUE
#define STM32_SPI_USE_SPI2                  TRUE
#define STM32_SPI_USE_SPI3                  TRUE
#define STM32_SPI_USE_SPI4                  FALSE
#define STM32_SPI_USE_SPI5                  TRUE
#define STM32_SPI_USE_SPI6                  FALSE
#define STM32_SPI_SPI1_RX_DMA_STREAM        STM32_DMA_STREAM_ID(2, 0)
#define STM32_SPI_SPI1_TX_DMA_STREAM        STM32_DMA_STREAM_ID(2, 3)
#define STM32_SPI_SPI2_RX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 3)
#define STM32_SPI_SPI2_TX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 4)
#define STM32_SPI_SPI3_RX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 0)
#define STM32_SPI_SPI3_TX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 7)
#define STM32_SPI_SPI4_RX_DMA_STREAM        STM32_DMA_STREAM_ID(2, 0)
#define STM32_SPI_SPI4_TX_DMA_STREAM        STM32_DMA_STREAM_ID(2, 1)
#define STM32_SPI_SPI5_RX_DMA_STREAM        STM32_DMA_STREAM_ID(2, 3)
#define STM32_SPI_SPI5_TX_DMA_STREAM        STM32_DMA_STREAM_ID(2, 4)
#define STM32_SPI_SPI6_RX_DMA_STREAM        STM32_DMA_STREAM_ID(2, 6)
#define STM32_SPI_SPI6_TX_DMA_STREAM        STM32_DMA_STREAM_ID(2, 5)
#define STM32_SPI_SPI1_DMA_PRIORITY         1
#define STM32_SPI_SPI2_DMA_PRIORITY         1
#define STM32_SPI_SPI3_DMA_PRIORITY         1
#define STM32_SPI_SPI4_DMA_PRIORITY         1
#define STM32_SPI_SPI5_DMA_PRIORITY         1
#define STM32_SPI_SPI6_DMA_PRIORITY         1
#define STM32_SPI_SPI1_IRQ_PRIORITY         10
#define STM32_SPI_SPI2_IRQ_PRIORITY         10
#define STM32_SPI_SPI3_IRQ_PRIORITY         10
#define STM32_SPI_SPI4_IRQ_PRIORITY         10
#define STM32_SPI_SPI5_IRQ_PRIORITY         10
#define STM32_SPI_SPI6_IRQ_PRIORITY         10
#define STM32_SPI_DMA_ERROR_HOOK(spip)      osalSysHalt("DMA failure")


Looks like the DMA is fine though. I'm using the RT-STM32F767-Nucleo144 example so it should be okay by default. Debug options seem to be disabled, which ones would be useful to enable to further diagnose the problem?

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Getting SPI to work on STM32F7

Postby Giovanni » Tue Mar 03, 2020 2:11 pm

Assertions, checks, state checker.

Also define the failure mode:
- Do SPI functions return?
- Are SPI callbacks invoked?

Giovanni

JSStabl
Posts: 78
Joined: Tue Feb 25, 2020 4:06 pm
Has thanked: 3 times
Been thanked: 2 times

Re: Getting SPI to work on STM32F7

Postby JSStabl » Tue Mar 03, 2020 2:46 pm

Actually on second thought DMA(2,3) is used for SPI1 and 5. Is that an issue?

Changing the #define STM32_SPI_SPI5_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) worked! Thanks for the support Giovanni :)

Should we add that as a bugreport as well? Maybe we should throw a warning if the same DMA channels are used here.

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Getting SPI to work on STM32F7

Postby Giovanni » Tue Mar 03, 2020 3:01 pm

You cannot use the same DMA channel on multiple peripherals and have those started at same time, an assertion is triggered in those cases.

Giovanni


Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 6 guests