How to use SPI2

Post here first, or if you can't find a relevant section!
SphericalSound
Posts: 11
Joined: Sun May 17, 2020 3:59 pm

How to use SPI2

Post by SphericalSound »

Hi!. So happy to see the forum working again. First time poster here!! :D

Im using a library in the bluepill that uses the SPI. It works but it´s glitchy.

The SPI standard pins are :

PA7 - mosi
PA5 - clk

I would like use the alterante pins:

PB5 - mosi
PB3 - clk

Or SPI2

PB15 mosi2
PB13 clk2

How do I signal to use alternate pins? Im using bluepill under arduino or platformio IDEs

Roger Clark, the creator of the libary said to do:

SPI.setMOSI(PB15);
SPI.setMISO(PB14);
SPI.setSCLK(PB13);
SPI.begin();

Or:

SPIClass SPI_2(PB15,PB14,PB13);
SPI_2.begin();

But this commands are not anymore in the library.

I have read something about SPIclass but I can´t get it to work... Any hints?

Thank you so much
stas2z
Posts: 131
Joined: Mon Feb 24, 2020 8:17 pm
Answers: 8

Re: How to use SPI2

Post by stas2z »

SphericalSound wrote: Sun May 17, 2020 4:08 pm Roger Clark, the creator of the libary said to do:

SPI.setMOSI(PB15);
SPI.setMISO(PB14);
SPI.setSCLK(PB13);
SPI.begin();

Or:

SPIClass SPI_2(PB15,PB14,PB13);
SPI_2.begin();

But this commands are not anymore in the library.

I have read something about SPIclass but I can´t get it to work... Any hints?

Thank you so much
you are wrong a little bit ) Roger never said what you mentioned
cuz these commands work only with offcial core, not Roger's one)

in case of using roger's core check the example provided py Roger
https://github.com/rogerclarkmelbourne/ ... _ports.ino

a few words about platformio
depends on which board you selected, your platformio project can use roger's (maple target) or official (stm32 target) core and those cores are not compatible in case of SPI
feluga
Posts: 64
Joined: Wed Mar 18, 2020 2:50 am

Re: How to use SPI2

Post by feluga »

SphericalSound wrote: Sun May 17, 2020 4:08 pm
Roger Clark, the creator of the libary said to do:

SPI.setMOSI(PB15);
SPI.setMISO(PB14);
SPI.setSCLK(PB13);
SPI.begin();

Or:

SPIClass SPI_2(PB15,PB14,PB13);
SPI_2.begin();
This is related to Official STM32 Core.
https://github.com/rogerclarkmelbourne/ ... issues/432
feluga
Posts: 64
Joined: Wed Mar 18, 2020 2:50 am

Re: How to use SPI2

Post by feluga »

This post has an exemple on how to use SPI2 with Roger's core:
https://github.com/rogerclarkmelbourne/ ... 2/pull/536

Code: Select all


void setup() {
  // Source: https://community.platformio.org/t/pio-arduino-stm32f103cbt6-remap/6786/5
  afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY); // PB3 free
  afio_remap(AFIO_REMAP_SPI1);

  gpio_set_mode (GPIOB, 3, GPIO_AF_OUTPUT_PP);
  gpio_set_mode (GPIOB, 4, GPIO_INPUT_FLOATING);
  gpio_set_mode (GPIOB, 5, GPIO_AF_OUTPUT_PP);

// put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

Example:

/**
    SPI_1 and SPI_2 port example code

    Description:
    This sketch sends one byte with value 0x55 over the SPI_1 or SPI_2 port.
    The received byte (the answer from the SPI slave device) is stored to the <data> variable.

    The sketch as it is, works with SPI_1 port. For using the SPI_2 port, just
    un-comment all the nessesary code lines marked with <SPI_2> word.

    Created on 10 Jun 2015 by Vassilis Serasidis
    email:  avrsite@yahoo.gr

    Using the first SPI port (SPI_1)
    SS    <-->  PA4 <-->  BOARD_SPI1_NSS_PIN
    SCK   <-->  PA5 <-->  BOARD_SPI1_SCK_PIN
    MISO  <-->  PA6 <-->  BOARD_SPI1_MISO_PIN
    MOSI  <-->  PA7 <-->  BOARD_SPI1_MOSI_PIN

    Using the first SPI port (SPI_1) REMAPPED
    SS    <-->  PA15 <-->  BOARD_SPI1_NSS_PIN
    SCK   <-->  PB3 <-->  BOARD_SPI1_SCK_PIN
    MISO  <-->  PB4 <-->  BOARD_SPI1_MISO_PIN
    MOSI  <-->  PB5 <-->  BOARD_SPI1_MOSI_PIN

    Using the second SPI port (SPI_2)
    SS    <-->  PB12 <-->  BOARD_SPI2_NSS_PIN
    SCK   <-->  PB13 <-->  BOARD_SPI2_SCK_PIN
    MISO  <-->  PB14 <-->  BOARD_SPI2_MISO_PIN
    MOSI  <-->  PB15 <-->  BOARD_SPI2_MOSI_PIN
*/


#include <SPI.h>

#define SPI1_NSS_PIN PA15 //PA4    //SPI_1 Chip Select pin is PA4. You can change it to the STM32 pin you want.
#define SPI2_NSS_PIN PB12   //SPI_2 Chip Select pin is PB12. You can change it to the STM32 pin you want.

SPIClass SPI_2(2); //Create an instance of the SPI Class called SPI_2 that uses the 2nd SPI Port
byte data;

void setup() {
  // Remap SPI 1
  // Source: https://community.platformio.org/t/pio-arduino-stm32f103cbt6-remap/6786/5
  afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY); // PB3 free
  afio_remap(AFIO_REMAP_SPI1);

  gpio_set_mode (GPIOB, 3, GPIO_AF_OUTPUT_PP);
  gpio_set_mode (GPIOB, 4, GPIO_INPUT_FLOATING);
  gpio_set_mode (GPIOB, 5, GPIO_AF_OUTPUT_PP);
  
  // Setup SPI 1
  SPI.begin(); //Initialize the SPI_1 port.
  SPI.setBitOrder(MSBFIRST); // Set the SPI_1 bit order
  SPI.setDataMode(SPI_MODE0); //Set the  SPI_2 data mode 0
  SPI.setClockDivider(SPI_CLOCK_DIV16);      // Slow speed (72 / 16 = 4.5 MHz SPI_1 speed)
  pinMode(SPI1_NSS_PIN, OUTPUT);

  // Setup SPI 2
  SPI_2.begin(); //Initialize the SPI_2 port.
  SPI_2.setBitOrder(MSBFIRST); // Set the SPI_2 bit order
  SPI_2.setDataMode(SPI_MODE0); //Set the  SPI_2 data mode 0
  SPI_2.setClockDivider(SPI_CLOCK_DIV16);  // Use a different speed to SPI 1
  pinMode(SPI2_NSS_PIN, OUTPUT);


}

void loop() {

  sendSPI();
  sendSPI2();

  delayMicroseconds(10);    //Delay 10 micro seconds.
}

void sendSPI()
{
  digitalWrite(SPI1_NSS_PIN, LOW); // manually take CSN low for SPI_1 transmission
  data = SPI.transfer(0x55); //Send the HEX data 0x55 over SPI-1 port and store the received byte to the <data> variable.
  digitalWrite(SPI1_NSS_PIN, HIGH); // manually take CSN high between spi transmissions
}


void sendSPI2()
{
  digitalWrite(SPI2_NSS_PIN, LOW); // manually take CSN low for SPI_2 transmission
  data = SPI_2.transfer(0x55); //Send the HEX data 0x55 over SPI-2 port and store the received byte to the <data> variable.
  digitalWrite(SPI2_NSS_PIN, HIGH); // manually take CSN high between spi transmissions
}


SphericalSound
Posts: 11
Joined: Sun May 17, 2020 3:59 pm

Re: How to use SPI2

Post by SphericalSound »

stas2z wrote: Sun May 17, 2020 4:13 pm
a few words about platformio
depends on which board you selected, your platformio project can use roger's (maple target) or official (stm32 target) core and those cores are not compatible in case of SPI
Thank you so much for the info. What are the differences between Roger´s and Official ones?

What would you use?

Thank you so much :)
SphericalSound
Posts: 11
Joined: Sun May 17, 2020 3:59 pm

Re: How to use SPI2

Post by SphericalSound »

feluga wrote: Sun May 17, 2020 4:23 pm
SphericalSound wrote: Sun May 17, 2020 4:08 pm
Roger Clark, the creator of the libary said to do:

SPI.setMOSI(PB15);
SPI.setMISO(PB14);
SPI.setSCLK(PB13);
SPI.begin();

Or:

SPIClass SPI_2(PB15,PB14,PB13);
SPI_2.begin();
This is related to Official STM32 Core.
https://github.com/rogerclarkmelbourne/ ... issues/432
I totally didnt know that there were 2 cores. Im only one week with the bluepill but loving it to bits. thanks for explaining this
SphericalSound
Posts: 11
Joined: Sun May 17, 2020 3:59 pm

Re: How to use SPI2

Post by SphericalSound »

feluga wrote: Sun May 17, 2020 4:35 pm This post has an exemple on how to use SPI2 with Roger's core:
https://github.com/rogerclarkmelbourne/ ... 2/pull/536

Code: Select all


void setup() {
  // Source: https://community.platformio.org/t/pio-arduino-stm32f103cbt6-remap/6786/5
  afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY); // PB3 free
  afio_remap(AFIO_REMAP_SPI1);

  gpio_set_mode (GPIOB, 3, GPIO_AF_OUTPUT_PP);
  gpio_set_mode (GPIOB, 4, GPIO_INPUT_FLOATING);
  gpio_set_mode (GPIOB, 5, GPIO_AF_OUTPUT_PP);

// put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

Example:

/**
    SPI_1 and SPI_2 port example code

    Description:
    This sketch sends one byte with value 0x55 over the SPI_1 or SPI_2 port.
    The received byte (the answer from the SPI slave device) is stored to the <data> variable.

    The sketch as it is, works with SPI_1 port. For using the SPI_2 port, just
    un-comment all the nessesary code lines marked with <SPI_2> word.

    Created on 10 Jun 2015 by Vassilis Serasidis
    email:  avrsite@yahoo.gr

    Using the first SPI port (SPI_1)
    SS    <-->  PA4 <-->  BOARD_SPI1_NSS_PIN
    SCK   <-->  PA5 <-->  BOARD_SPI1_SCK_PIN
    MISO  <-->  PA6 <-->  BOARD_SPI1_MISO_PIN
    MOSI  <-->  PA7 <-->  BOARD_SPI1_MOSI_PIN

    Using the first SPI port (SPI_1) REMAPPED
    SS    <-->  PA15 <-->  BOARD_SPI1_NSS_PIN
    SCK   <-->  PB3 <-->  BOARD_SPI1_SCK_PIN
    MISO  <-->  PB4 <-->  BOARD_SPI1_MISO_PIN
    MOSI  <-->  PB5 <-->  BOARD_SPI1_MOSI_PIN

    Using the second SPI port (SPI_2)
    SS    <-->  PB12 <-->  BOARD_SPI2_NSS_PIN
    SCK   <-->  PB13 <-->  BOARD_SPI2_SCK_PIN
    MISO  <-->  PB14 <-->  BOARD_SPI2_MISO_PIN
    MOSI  <-->  PB15 <-->  BOARD_SPI2_MOSI_PIN
*/


#include <SPI.h>

#define SPI1_NSS_PIN PA15 //PA4    //SPI_1 Chip Select pin is PA4. You can change it to the STM32 pin you want.
#define SPI2_NSS_PIN PB12   //SPI_2 Chip Select pin is PB12. You can change it to the STM32 pin you want.

SPIClass SPI_2(2); //Create an instance of the SPI Class called SPI_2 that uses the 2nd SPI Port
byte data;

void setup() {
  // Remap SPI 1
  // Source: https://community.platformio.org/t/pio-arduino-stm32f103cbt6-remap/6786/5
  afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY); // PB3 free
  afio_remap(AFIO_REMAP_SPI1);

  gpio_set_mode (GPIOB, 3, GPIO_AF_OUTPUT_PP);
  gpio_set_mode (GPIOB, 4, GPIO_INPUT_FLOATING);
  gpio_set_mode (GPIOB, 5, GPIO_AF_OUTPUT_PP);
  
  // Setup SPI 1
  SPI.begin(); //Initialize the SPI_1 port.
  SPI.setBitOrder(MSBFIRST); // Set the SPI_1 bit order
  SPI.setDataMode(SPI_MODE0); //Set the  SPI_2 data mode 0
  SPI.setClockDivider(SPI_CLOCK_DIV16);      // Slow speed (72 / 16 = 4.5 MHz SPI_1 speed)
  pinMode(SPI1_NSS_PIN, OUTPUT);

  // Setup SPI 2
  SPI_2.begin(); //Initialize the SPI_2 port.
  SPI_2.setBitOrder(MSBFIRST); // Set the SPI_2 bit order
  SPI_2.setDataMode(SPI_MODE0); //Set the  SPI_2 data mode 0
  SPI_2.setClockDivider(SPI_CLOCK_DIV16);  // Use a different speed to SPI 1
  pinMode(SPI2_NSS_PIN, OUTPUT);


}

void loop() {

  sendSPI();
  sendSPI2();

  delayMicroseconds(10);    //Delay 10 micro seconds.
}

void sendSPI()
{
  digitalWrite(SPI1_NSS_PIN, LOW); // manually take CSN low for SPI_1 transmission
  data = SPI.transfer(0x55); //Send the HEX data 0x55 over SPI-1 port and store the received byte to the <data> variable.
  digitalWrite(SPI1_NSS_PIN, HIGH); // manually take CSN high between spi transmissions
}


void sendSPI2()
{
  digitalWrite(SPI2_NSS_PIN, LOW); // manually take CSN low for SPI_2 transmission
  data = SPI_2.transfer(0x55); //Send the HEX data 0x55 over SPI-2 port and store the received byte to the <data> variable.
  digitalWrite(SPI2_NSS_PIN, HIGH); // manually take CSN high between spi transmissions
}


I have been looking for this something like one solid week non stop... No idea wjere you get it, but to me it seems solid gold. I will try. Thank you all!!
mrburnette
Posts: 633
Joined: Thu Dec 19, 2019 1:23 am
Answers: 7

Re: How to use SPI2

Post by mrburnette »

SphericalSound wrote: Sun May 17, 2020 11:53 pm ...
Thank you so much for the info. What are the differences between Roger´s and Official ones?

What would you use?

Thank you so much :)
There are 4 or more cores, 3 which are viable: Official, Roger's, Steve's
https://stm32duinoforum.com/forum/viewt ... _3111.html

But only one core has the weight of STM and a dedicated staff and this forum to dialog with casual users of STM32 ARM uC, we call that one "Official" core: https://github.com/stm32duino/Arduino_Core_STM32

Steve (a founding member) uses Steve's core which is derived from Roger's core with some nice tweets. Roger's core was inherited from LeafLab's original effort: https://github.com/leaflabs/maple but that effort became unsupported around the time of ArduinoIDE ver 1.5x

If you are a professional developer, use the Official core as it is well supported, has an upgrade path to professional tools and corporate support. If you are a hobbyist or even doing a really small for-sale project or prototype, then Roger's core will conform well to Arduino'ish expectations.

Of course, others may have different opinions.

Ray
mrguen
Posts: 24
Joined: Tue Mar 03, 2020 1:21 pm
Answers: 2

Re: How to use SPI2

Post by mrguen »

Hello, Thanks for the code example.

1) I get the error
'AFIO_DEBUG_SW_ONLY' was not declared in this scope

on STM32F401RCT6 (CoreBoard) / STM32 Cores 1.9.0

2) Is it possible to use the remapped SPI2 (SCK: PB13, MOSI: PC3, MISO: PC2)?
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: How to use SPI2

Post by fpiSTM »

mrguen wrote: Wed Jul 15, 2020 11:34 am Hello, Thanks for the code example.

1) I get the error
'AFIO_DEBUG_SW_ONLY' was not declared in this scope

on STM32F401RCT6 (CoreBoard) / STM32 Cores 1.9.0
As mentionned by @feluga the given example code using AFIO_DEBUG_SW_ONLY is for LibMaple core from Roger:

https://github.com/rogerclarkmelbourne/ ... pio.h#L399
mrguen wrote: Wed Jul 15, 2020 11:34 am 2) Is it possible to use the remapped SPI2 (SCK: PB13, MOSI: PC3, MISO: PC2)?
For the Core board (STM32F401RC) by default the SPI instance uses SPI1 with pins:
SCK: PA5, MOSI: PA7, MISO: PA6.
You have two possibilities:
  1. Change the pins used by default if you don't want use the SPI1 as explained in the WiKi:
    https://github.com/stm32duino/wiki/wiki ... tance-pins

    Code: Select all

    SPI.setMOSI(PC3);
    SPI.setMISO(PC2);
    SPI.setSCLK(PB13);
    SPI.begin();
    
  • Define a new instance:

    Code: Select all

    SPIClass SPI_2(PC3, PC2, PB13);
    SPI_2.begin(); 
    
Post Reply

Return to “General discussion”