/*
SD card test for stm32 and SdFat library
This example shows how use the utility libraries
SD card attached to the secondary SPI as follows:
SS = PB2;
MOSI = PC3;
MISO = PC2;
SCK = PB10;
by Mischianti Renzo <https://mischianti.org>
https://www.mischianti.org
*/
#include <SPI.h>
#include "SdFat.h"
SdFat SD;
// Define your pin configuration for SPI2
const int spi2ClockPin = PB10; // SCK (Serial Clock)
const int spi2MisoPin = PC2; // MISO (Master In Slave Out)
const int spi2MosiPin = PC3; // MOSI (Master Out Slave In)
const int spi2chipSelectPin = PB2; // CS (Chip Select)
#define SD2_CONFIG SdSpiConfig(spi2chipSelectPin, USER_SPI_BEGIN,SD_SCK_MHZ (10))
void printDirectory(File dir, int numTabs);
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
}
SPIClass SPI_2(spi2MosiPin, spi2MisoPin, spi2ClockPin);
SPI_2.begin(spi2chipSelectPin);
// SPI_2.setFrequency(1000000);
Serial.print("\nInitializing SD card...");
// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if (!SD.begin(SD2_CONFIG)) {
// if (!SD.begin(SD_CS_PIN)) {
Serial.println("initialization failed. Things to check:");
Serial.println("* is a card inserted?");
Serial.println("* is your wiring correct?");
Serial.println("* did you change the chipSelect pin to match your shield or module?");
while (1);
} else {
Serial.println("Wiring is correct and a card is present.");
}
uint32_t cardSize = SD.card()->sectorCount();
// print the type of card
Serial.println();
Serial.print("Card type: ");
switch (SD.card()->type()) {
case SD_CARD_TYPE_SD1:
Serial.println(F("SD1"));
break;
case SD_CARD_TYPE_SD2:
Serial.println(F("SD2"));
break;
case SD_CARD_TYPE_SDHC:
if (cardSize < 70000000) {
Serial.println(F("SDHC"));
} else {
Serial.println(F("SDXC"));
}
break;
default:
Serial.println(F("Unknown"));
}
// print the type and size of the first FAT-type volume
uint32_t volumesize;
Serial.print("Volume type is: FAT");
Serial.println(int(SD.vol()->fatType()), DEC);
Serial.print("Card size: ");
Serial.println((float) 0.000512*cardSize);
Serial.print("Total bytes: ");
Serial.println(0.000512*SD.vol()->clusterCount()*SD.sectorsPerCluster());
Serial.print("Free bytes: ");
Serial.println(0.000512*SD.vol()->freeClusterCount()*SD.sectorsPerCluster());
File dir = SD.open("/");
printDirectory(dir, 0);
}
void loop(void) {
}
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');
}
entry.printName(&Serial);
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs + 1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.print(entry.size(), DEC);
uint16_t pdate;
uint16_t ptime;
entry.getModifyDateTime(&pdate, &ptime);
Serial.printf("\tLAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", FS_YEAR(pdate), FS_MONTH(pdate), FS_DAY(pdate), FS_HOUR(ptime), FS_MINUTE(ptime), FS_SECOND(ptime));
}
entry.close();
}
}
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
/** Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) {
Error_Handler();
}
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) {
Error_Handler();
}
}
#ifdef __cplusplus
}
#endif
STM32L452 SPI2 port assignation not working
Hello,
I'm trying to connect my STM32L452 chip to an SD Card for logging purpose but it doesn't seem to work using port assignation delivered by STM32duino.
I tried using STM32Cube libraries and it's working, so the problem is not on my PCB but really the SdFat and/or STM32duino and the way I'm initializing things.
I tried to use the code example you provided in here which is shown bellow with the only modification being the SPI port values. I wonder if only STM32F1 and F4 are supported and is there a way to make it work for L4 boards.