Skip to content

Trying to figure out two devices on the SPI bus #504

Open
@brightproject

Description

@brightproject

Good day @greiman

According to GitHub tradition, I express my gratitude to you for your work🙂

My microcontroller stm32f411ceu6

STM32F411CEU6_WeAct_Black_Pill_V2 0-1 1

I compile the code into vscode + .pio and use the framework

https://github.com/platformio/platform-ststm32

I also have a BNO08x sensor, which is connected via the I2C bus via the library

https://github.com/adafruit/Adafruit_BNO08x

Bus speed is 400 kHz.

I connect two different devices to it via SPI:
CAN bus transceiver

398922519-d7f98f14-8745-4e5d-863a-4c51b6c6bb63

module with microSD

398922643-14263056-a90a-4820-9cbe-5afab92b90f0

Two device boards are connected to one SPI, only different SS contacts.

The connection is very simple, I use standard contacts for the SPI:

MOSI - PA7
MISO - PA6
SCK - PA5
SD_CS/SS - PB0
CAN_CS/SS - PA4

The CAN module works fine, checked in another code.
Now I decided to launch in addition to the CAN module also a module for saving data to the micro SDHC card.
I have three microSD cards - 512 MB(fat16), 8 GB(fat32) and 32 GB(fat32).

398924883-3ca4aacd-cca2-4cc0-82bf-b0635663c3d4

The cards are not of the best quality, the 512 MB card stopped being detected after the first attempt to consider it a SD module, and it can't even be formatted via the program.

https://www.sdcard.org/downloads/formatter/sd-memory-card-formatter-for-windows-download/

The best and fastest working microSD is 8GB, its SdInfo report is below:

sdFat version: 2.2.3

Assuming the SD is the only SPI device.
Edit DISABLE_CS_PIN to disable an SPI device.

Assuming the SD chip select pin is: 200
Edit SD_CS_PIN to change the SD chip select pin.

type any character to start
init time: 2 ms

Card type: SDHC
sdSpecVer: 6.00
HighSpeedMode: true

Manufacturer ID: 0XFE
OEM ID: 4V
Product: ASTC\0
Revision: 1.2
Serial number: 0X7C1
Manufacturing date: 8/2024
CID HEX: FE3456415354430012000007C1018883

cardSize: 7818.18 MB (MB = 1,000,000 bytes)
flashEraseSize: 128 blocks
eraseSingleBlock: true
dataAfterErase: ones
CSD HEX: 400E00325B5900003A3F7F800A400027

OCR: 0XC0FF8000

SD Partition Table
part,boot,bgnCHS[3],type,endCHS[3],start,length
1,0X0,0X82,0X3,0X0,0XB,0X81,0XCB,0XB6,8192,15261696
2,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0
3,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0
4,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0

Scanning FAT, please wait.

Volume is FAT32
sectorsPerCluster: 64
fatStartSector: 12658
dataStartSector: 16384
clusterCount: 238336
freeClusterCount: 238323

All this is just information, for the general picture.
The work of two modules CAN bus transceiver and microSD module on one SPI bus is interesting.
Using a logic analyzer, I measured the speed of one module CAN

can_no_sd

Two simultaneously working modules CAN and microSD

can_yes_sd

Probably screenshots are not as clear as viewing data directly in the analyzer.
As you can see, when

CAN.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ)

is running, the pauses between sending messages to CAN are on average 6 ms.
When

CAN.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ)

and

sd.begin(SD_CS_PIN, SD_SCK_MHZ(20))

are running, the pauses between sending messages to CAN are about 16-20 ms, which significantly affects the external device that receives data via the CAN bus - it begins to noticeably slow down with data display.
But my question is not specifically about this, my question is about how and where does the

SdFat.h

library configure the SPI bus?
The SPI bus for the CAN module is configured as follows

beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE3));

What mode does SdFat use?

Regarding SdFat, I don't understand what mode is needed, I set the speed directly in the Arduino Setup section:

SD_SCK_MHZ(20)

But despite the fact that both devices have a speed of 20 MHz on the SPI bus, the analyzer shows complete nonsense, there is never a stable speed, but the problem is still not in this, as it seems to me, but in the fact that the library for the CAN module closes the SPI connection every transaction

#define MCP2515_UNSELECT() digitalWrite(MCPCS, HIGH)

And the SdFat library does something of its own, and I don't understand it

CAN_FATSD_2

As you can see from the screenshot, the SdFat select pin chip occupies the SPI bus for 7 ms, and the select chip of the CAN module occupies the SPI bus for 1.18 ms.

As far as I understand, the CS pin for the operation of the microSD module begins its cycle by pressing the CS pin to 0 - label 0, then it pulls the CS pin twice and at label 1 it completes the recording cycle and then there is a pause until label 2. The CS pin of the CAN module operates between labels 1 and 2.

can_sd_duration_cs

In general, I am not a big expert in analyzing what is happening on the SPI bus, perhaps the community will help me figure out the issue and make the operation of two devices on the SPI bus correct and coordinated.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions