For the Arduino Giga how do you configure the SPI speed for use in the SD library for maximum speed, I have a device that supports up to 50Mhz SPI: https://www.adafruit.com/product/4899
Any help would be greatly appreciated thanks! ![]()
For the Arduino Giga how do you configure the SPI speed for use in the SD library for maximum speed, I have a device that supports up to 50Mhz SPI: https://www.adafruit.com/product/4899
Any help would be greatly appreciated thanks! ![]()
Just be forwarned you might be able to reach 50mhz unless you are using SDIO per the info on Adafruit webpage.
but with that said if you use the Cardinfo sketch:
/** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */
uint8_t const SPI_FULL_SPEED = 0;
/** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */
uint8_t const SPI_HALF_SPEED = 1;
/** Set SCK rate to F_CPU/8. Sd2Card::setSckRate(). */
uint8_t const SPI_QUARTER_SPEED = 2;
I just tested at Full speed and half speed and both work no issues.
You also can use this form of the SPI.begin:
begin(uint32_t clock, uint8_t csPin);
where clock is your desired SPI clock frequency.
Just as a follow on example. For listfiles example it would be:
/*
Listfiles
This example shows how print out the files in a
directory on a SD card
The circuit:
SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)
created Nov 2010
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
modified 2 Feb 2014
by Scott Fitzgerald
This example code is in the public domain.
*/
#include <SPI.h>
#include <SD.h>
File root;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
if (!SD.begin(50000000, 10)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
root = SD.open("/");
printDirectory(root, 0);
Serial.println("done!");
}
void loop() {
// nothing happens after setup finishes.
}
void printDirectory(File dir, int numTabs) {
while (true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
break;
}
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs + 1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}
which in my case displays:
Initializing SD card...initialization done.
BENCH.DAT 10000000
done!
Hope that helps
would you happen to know how to get the sdfat library going using SPI1 and set the SPI speed?
Its been awhile since I had to change SPI but for clock you simply follow the example - this is from DirectoryFunctions.ino
// Try max SPI clock for an SD. Reduce SPI_CLOCK if errors occur.
#define SPI_CLOCK SD_SCK_MHZ(50)
// Try to select the best SD card configuration.
#if HAS_SDIO_CLASS
#define SD_CONFIG SdioConfig(FIFO_SDIO)
#elif ENABLE_DEDICATED_SPI
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
#else // HAS_SDIO_CLASS
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
#endif // HAS_SDIO_CLASS
to change to using SPI1 you will probably have to edit the SDfat config file and take a look at the UserSPIDriver example. Pretty much explains it.
Will probably take a look at tomorrow for myself as well. Was on my todo list.
awesome, thank you Merlin! ![]()
Something like this might work:
This worked for me on stm32f446re arduino platformio,
static SPIClass mySPI2(PB15, PB14, PB13); // set for SPI2
SdFs sd;
sd.begin(SdSpiConfig(PB12, DEDICATED_SPI, SD_SCK_MHZ(18), &mySPI2));
you need to do your own mods based on the example. Found that on:
Does not compile with new STM32 Core framework from ST · Issue #189 · greiman/SdFat (github.com)
will probably try that tomorrow.
Could wait. This works. What was in previous doesnt work for the giga:
// An example of an external SPI driver.
//
#include "SPI.h" // Only required if you use features in the SPI library.
#include "SdFat.h"
#include "sdios.h"
#if SPI_DRIVER_SELECT == 3 // Must be set in SdFat/SdFatConfig.h
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
#define SD_FAT_TYPE 0
// SD chip select pin.
#define SD_CS_PIN 10
// This is a simple driver based on the the standard SPI.h library.
// You can write a driver entirely independent of SPI.h.
// It can be optimized for your board or a different SPI port can be used.
// The driver must be derived from SdSpiBaseClass.
// See: SdFat/src/SpiDriver/SdSpiBaseClass.h
class MySpiClass : public SdSpiBaseClass {
public:
// Activate SPI hardware with correct speed and mode.
void activate() { SPI1.beginTransaction(m_spiSettings); }
// Initialize the SPI bus.
void begin(SdSpiConfig config) {
(void)config;
SPI1.begin();
}
// Deactivate SPI hardware.
void deactivate() { SPI1.endTransaction(); }
// Receive a byte.
uint8_t receive() { return SPI1.transfer(0XFF); }
// Receive multiple bytes.
// Replace this function if your board has multiple byte receive.
uint8_t receive(uint8_t* buf, size_t count) {
for (size_t i = 0; i < count; i++) {
buf[i] = SPI1.transfer(0XFF);
}
return 0;
}
// Send a byte.
void send(uint8_t data) { SPI1.transfer(data); }
// Send multiple bytes.
// Replace this function if your board has multiple byte send.
void send(const uint8_t* buf, size_t count) {
for (size_t i = 0; i < count; i++) {
SPI1.transfer(buf[i]);
}
}
// Save SPISettings for new max SCK frequency
void setSckSpeed(uint32_t maxSck) {
m_spiSettings = SPISettings(maxSck, MSBFIRST, SPI_MODE0);
}
private:
SPISettings m_spiSettings;
} mySpi1;
#if ENABLE_DEDICATED_SPI
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SD_SCK_MHZ(50), &mySpi1)
#else // ENABLE_DEDICATED_SPI
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SD_SCK_MHZ(50), &mySpi1)
#endif // ENABLE_DEDICATED_SPI
//------------------------------------------------------------------------------
#if SD_FAT_TYPE == 0
SdFat sd;
File file;
File root;
#elif SD_FAT_TYPE == 1
SdFat32 sd;
File32 file;
File32 root;
#elif SD_FAT_TYPE == 2
SdExFat sd;
ExFile file;
ExFile root;
#elif SD_FAT_TYPE == 3
SdFs sd;
FsFile file;
FsFile root;
#endif // SD_FAT_TYPE
// Create a Serial output stream.
ArduinoOutStream cout(Serial);
//------------------------------------------------------------------------------
// Store error strings in flash to save RAM.
#define error(s) sd.errorHalt(&Serial, F(s))
//------------------------------------------------------------------------------
void setup() {
Serial.begin(9600);
// Wait for USB Serial
while (!Serial) {
yield();
}
delay(1000);
cout << F("Type any character to start\n");
while (!Serial.available()) {
yield();
}
// Initialize the SD card.
if (!sd.begin(SD_CONFIG)) {
sd.initErrorHalt(&Serial);
}
if (sd.exists("Folder1") || sd.exists("Folder1/file1.txt") ||
sd.exists("Folder1/File2.txt")) {
error("Please remove existing Folder1, file1.txt, and File2.txt");
}
int rootFileCount = 0;
if (!root.open("/")) {
error("open root");
}
while (file.openNext(&root, O_RDONLY)) {
if (!file.isHidden()) {
rootFileCount++;
}
file.close();
if (rootFileCount > 10) {
error("Too many files in root. Please use an empty SD.");
}
}
if (rootFileCount) {
cout << F("\nPlease use an empty SD for best results.\n\n");
delay(1000);
}
// Create a new folder.
if (!sd.mkdir("Folder1")) {
error("Create Folder1 failed");
}
cout << F("Created Folder1\n");
// Create a file in Folder1 using a path.
if (!file.open("Folder1/file1.txt", O_WRONLY | O_CREAT)) {
error("create Folder1/file1.txt failed");
}
file.close();
cout << F("Created Folder1/file1.txt\n");
// Change volume working directory to Folder1.
if (!sd.chdir("Folder1")) {
error("chdir failed for Folder1.\n");
}
cout << F("chdir to Folder1\n");
// Create File2.txt in current directory.
if (!file.open("File2.txt", O_WRONLY | O_CREAT)) {
error("create File2.txt failed");
}
file.close();
cout << F("Created File2.txt in current directory\n");
cout << F("\nList of files on the SD.\n");
sd.ls("/", LS_R);
// Remove files from current directory.
if (!sd.remove("file1.txt") || !sd.remove("File2.txt")) {
error("remove failed");
}
cout << F("\nfile1.txt and File2.txt removed.\n");
// Change current directory to root.
if (!sd.chdir()) {
error("chdir to root failed.\n");
}
cout << F("\nList of files on the SD.\n");
sd.ls(LS_R);
// Remove Folder1.
if (!sd.rmdir("Folder1")) {
error("rmdir for Folder1 failed\n");
}
cout << F("\nFolder1 removed.\n");
cout << F("\nList of files on the SD.\n");
sd.ls(LS_R);
cout << F("Done!\n");
}
//------------------------------------------------------------------------------
// Nothing happens in loop.
void loop() {}
#else // SPI_DRIVER_SELECT
#error SPI_DRIVER_SELECT must be three in SdFat/SdFatConfig.h
#endif // SPI_DRIVER_SELECT
with output:
Type any character to start
Please use an empty SD for best results.
Created Folder1
Created Folder1/file1.txt
chdir to Folder1
Created File2.txt in current directory
List of files on the SD.
bench.dat
Folder1/
file1.txt
File2.txt
file1.txt and File2.txt removed.
List of files on the SD.
bench.dat
Folder1/
Folder1 removed.
List of files on the SD.
bench.dat
Done!
I think I had it working…
Tried the example you posted with &SPI with Bills latest version of SDFat and its giving me errors:
In file included from C:\Users\Merli\AppData\Local\Arduino15\packages\arduino\hardware\mbed_giga\4.0.10\cores\arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/CMSIS/stm32h7xx.h:136:0,
from C:\Users\Merli\AppData\Local\Arduino15\packages\arduino\hardware\mbed_giga\4.0.10\cores\arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/cmsis.h:22,
from C:\Users\Merli\AppData\Local\Arduino15\packages\arduino\hardware\mbed_giga\4.0.10\cores\arduino/mbed/targets/TARGET_STM/PinNamesTypes.h:33,
from C:\Users\Merli\AppData\Local\Arduino15\packages\arduino\hardware\mbed_giga\4.0.10\variants\GIGA/pinmode_arduino.h:24,
from C:\Users\Merli\AppData\Local\Arduino15\packages\arduino\hardware\mbed_giga\4.0.10\cores\arduino/Arduino.h:26,
from C:\Users\Merli\AppData\Local\Temp\arduino\sketches\000C512E2861E2D9F37EDEDD75666907\sketch\sketch_dec2b.ino.cpp:1:
C:\Users\Merli\AppData\Local\Temp\.arduinoIDE-unsaved2023112-32112-1o42in3.3jlr\sketch_dec2b\sketch_dec2b.ino: In function 'void setup()':
C:\Users\Merli\AppData\Local\Arduino15\packages\arduino\hardware\mbed_giga\4.0.10\cores\arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/CMSIS/stm32h747xx.h:2650:55: error: lvalue required as unary '&' operand
#define SPI1 ((SPI_TypeDef *) SPI1_BASE)
^
C:\Users\Merli\AppData\Local\Temp\.arduinoIDE-unsaved2023112-32112-1o42in3.3jlr\sketch_dec2b\sketch_dec2b.ino:25:66: note: in expansion of macro 'SPI1'
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK, &SPI1)
^~~~
C:\Users\Merli\AppData\Local\Temp\.arduinoIDE-unsaved2023112-32112-1o42in3.3jlr\sketch_dec2b\sketch_dec2b.ino:66:17: note: in expansion of macro 'SD_CONFIG'
if (!sd.begin(SD_CONFIG)) {
^
exit status 1
Compilation error: exit status 1
Ok time for zzzz's
EDIT: just did a quick check the only version of the sdfat library is the Teensy SDFat version. Forgot why we added that - MTP/remove-replace drives etc ![]()
I am getting the following error: "Compilation error: #error SPI_DRIVER_SELECT must be three in SdFat/SdFatConfig.h" any ideas?
You have to edit the SdFatConfig.h file in the SDFat library and change
SPI_DRIVER_SELECT from 0 to 3.
I'm a little unfamiliar with how to do that in arduino IDE, could you give me a very short description of how I do that (on windows 11)... thanks, you have been so helpful! ![]()
You can;t do it from the IDE. Basically you go to Arduiono libraries folder. For me that is in:
D:\Users\[Your User Name]\Documents\Arduino\libraries
find the SDFat library then double click on the SdFatConfig.h file and open it with notepad or such then find the line SPI_DRIVER_SELECT change it to 3 and save the file.
amazing thank you!