Page 1 of 2

How to use SPI2

Posted: Sun May 17, 2020 4:08 pm
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

Re: How to use SPI2

Posted: Sun May 17, 2020 4:13 pm
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

Re: How to use SPI2

Posted: Sun May 17, 2020 4:23 pm
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

Re: How to use SPI2

Posted: Sun May 17, 2020 4:35 pm
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
}



Re: How to use SPI2

Posted: Sun May 17, 2020 11:53 pm
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 :)

Re: How to use SPI2

Posted: Sun May 17, 2020 11:55 pm
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

Re: How to use SPI2

Posted: Sun May 17, 2020 11:56 pm
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!!

Re: How to use SPI2

Posted: Mon May 18, 2020 2:39 am
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

Re: How to use SPI2

Posted: Wed Jul 15, 2020 11:34 am
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)?

Re: How to use SPI2

Posted: Wed Jul 15, 2020 12:03 pm
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();