How to change SPI clock source on custom SPI

Please tell us which board you are using.
For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
fvzeppelin
 
Posts: 5
Joined: Sat Sep 03, 2022 9:16 am

How to change SPI clock source on custom SPI

Post by fvzeppelin »

Hi,

I have a Grand Central M4, which is an awesome board for protoyping :) And I am using the Arduino IDE. And at first, I want to give a big thank you for providing all the boards and libraries for the Arduino IDE!!

Now, I need to connect one of those small SSD1331 SPI RGB OLEDs to an SPI interface on the pins in the range ~30-49 (default SPI is already in use). I followed the guide here
https://learn.adafruit.com/using-atsamd ... -a-new-spi
and basically, it "works", but display changes were even slower compared to a Soft-SPI. So, I measured the SCK, and it is running at ~150kHz, while the display should be able to handle at least 8MHz.

Now, my question is: How can I change the speed on sercom6 to an appropriate SPI speed? And maybe how to change the clock source if necessary? I am really stuck here.

Here are the relevant parts of my code which I guessed mainly from sercom.cpp:

Code: Select all

// SPI2 pins: SS: 46, MISO: 47, MOSI: 48, SCK: 49
#define OLED_SCK_PIN 49
#define OLED_MOSI_PIN 48
#define OLED_CS_PIN 45
#define OLED_DC_PIN 44
#define OLED_RST_PIN 43
#include "wiring_private.h" // pinPeripheral() function
SPIClass SPI2 (&sercom6, 47, OLED_SCK_PIN, OLED_MOSI_PIN, SPI_PAD_0_SCK_1, SERCOM_RX_PAD_3);
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <Fonts/FreeSerif9pt7b.h>
Adafruit_SSD1331 *oled;

void setup()
{
    sercom6.setClockSource(sercom6.getSercomIndex(), SERCOM_CLOCK_SOURCE_100M, true);
    sercom6.setClockSource(sercom6.getSercomIndex(), SERCOM_CLOCK_SOURCE_100M, false);
    SPI2.begin();
    pinPeripheral(OLED_SCK_PIN, PIO_SERCOM);
    pinPeripheral(OLED_MOSI_PIN, PIO_SERCOM);
    oled = new Adafruit_SSD1331(&SPI2, OLED_CS_PIN, OLED_DC_PIN, OLED_RST_PIN);
    oled->begin(100000000);
}
Can anyone give me a hint here on how to speed this up (I already removed the i2s definition which used to be on sercom6 in variant.h)?

Thank you very much!!

User avatar
fvzeppelin
 
Posts: 5
Joined: Sat Sep 03, 2022 9:16 am

Re: How to change SPI clock source on custom SPI

Post by fvzeppelin »

Ok, first fault was mine, as I didn't check the oscilloscope correctly: the serial clock is about 4MHz. The 150kHz was for subsequent bytes. I could improve the 150kHz by removing unnecessary begin/endTransaction() calls in the GFX lib. Nevertheless, I cannot get my SPI2 faster than 4MHz.
Can anyone give me a hint what I could do?

User avatar
fvzeppelin
 
Posts: 5
Joined: Sat Sep 03, 2022 9:16 am

Re: How to change SPI clock source on custom SPI

Post by fvzeppelin »

Ok, problem located, seems to be a bug in the ArduinoCore-samd:
SPIClassSAMD::beginTransaction calls
SPIClassSAMD::config which calls
SERCOM::initSPIClock to set the SPI baudrate.
But this will not work, because the clock channel is enable protected and the channel is already enabled. A working example is
SERCOM::setBaudrateSPI
which can be used after SPI initialization as a workaround. In my example, this sets the baudrate to 24MHz:

Code: Select all

sercom6.setBaudrateSPI(2);

Locked
Please be positive and constructive with your questions and comments.

Return to “Metro, Metro Express, and Grand Central Boards”