SD library modification for using SPI1 minicore

Hello.

I’m trying to modify SD library to be able to use SPI1 for an atmega328PB, but my knowledge at C++ is too low to make it without help.

In the SD library, there is a file named Sd2PinMap.h where we can find pin definition. The problem is that, in this file, there is no AVR_ATmega328PB board. Despite this, I can compile this sketch without error (board ATMEGA328PB of minicore package, selected) :

#include <SPI1.h>
#include <SD.h>

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// MKRZero SD: SDCARD_SS_PIN
const int chipSelect = 19;//PIN_PE2; //PE2

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("\nInitializing SD card...");

  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    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.");
  }

  // print the type of card
  Serial.println();
  Serial.print("Card type:         ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    while (1);
  }

  Serial.print("Clusters:          ");
  Serial.println(volume.clusterCount());
  Serial.print("Blocks x Cluster:  ");
  Serial.println(volume.blocksPerCluster());

  Serial.print("Total Blocks:      ");
  Serial.println(volume.blocksPerCluster() * volume.clusterCount());
  Serial.println();

  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("Volume type is:    FAT");
  Serial.println(volume.fatType(), DEC);

  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize /= 2;                           // SD card blocks are always 512 bytes (2 blocks are 1KB)
  Serial.print("Volume size (Kb):  ");
  Serial.println(volumesize);
  Serial.print("Volume size (Mb):  ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Gb):  ");
  Serial.println((float)volumesize / 1024.0);

  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);

  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
}

void loop(void) {
}

So my first question is, what board name the compiler read in the Sd2PinMap.h file ? And where this board name come from ? (in which file it was written before reading the sd2pinmap.h) Is it defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)

Does minicore consider another name than atmega328pb to choose a name in the Sd2PinMap.h ?

I need to understand that before going further, thanks for your help.

I tried to change all SS, MISO, MOSI and SCK words in the Sd2PinMap.h file with right atmega328pb SPI1 pin (ie SS1=19; MOSI1=22; MISO1=23;SCK1=23), but it doesn’t work, nothing detected at de uc pin (oscilloscope measurement)

This is the Sd2PinMap.h code

#if defined(__arm__) // Arduino Due Board follows

#ifndef Sd2PinMap_h
  #define Sd2PinMap_h

  #include <Arduino.h>

  uint8_t const SS_PIN = SS;
  uint8_t const MOSI_PIN = MOSI;
  uint8_t const MISO_PIN = MISO;
  uint8_t const SCK_PIN = SCK;

#endif // Sd2PinMap_h

#elif defined(__AVR_ATmega4809__) // Arduino UNO WiFI Rev2 follows

#ifndef Sd2PinMap_h
  #define Sd2PinMap_h

  #include <Arduino.h>

  uint8_t const SS_PIN = SS;
  uint8_t const MOSI_PIN = MOSI;
  uint8_t const MISO_PIN = MISO;
  uint8_t const SCK_PIN = SCK;

#endif // Sd2PinMap_h

#elif defined(__AVR__) // Other AVR based Boards follows

// Warning this file was generated by a program.
#ifndef Sd2PinMap_h
#define Sd2PinMap_h
#include <avr/io.h>

//------------------------------------------------------------------------------
/** struct for mapping digital pins */
struct pin_map_t {
  volatile uint8_t* ddr;
  volatile uint8_t* pin;
  volatile uint8_t* port;
  uint8_t bit;
};
//------------------------------------------------------------------------------
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
// Mega

// Two Wire (aka I2C) ports
uint8_t const SDA_PIN = 20;
uint8_t const SCL_PIN = 21;

// SPI port
uint8_t const SS_PIN = 53;
uint8_t const MOSI_PIN = 51;
uint8_t const MISO_PIN = 50;
uint8_t const SCK_PIN = 52;

static const pin_map_t digitalPinMap[] = {
  {&DDRE, &PINE, &PORTE, 0},  // E0  0
  {&DDRE, &PINE, &PORTE, 1},  // E1  1
  {&DDRE, &PINE, &PORTE, 4},  // E4  2
  {&DDRE, &PINE, &PORTE, 5},  // E5  3
  {&DDRG, &PING, &PORTG, 5},  // G5  4
  {&DDRE, &PINE, &PORTE, 3},  // E3  5
  {&DDRH, &PINH, &PORTH, 3},  // H3  6
  {&DDRH, &PINH, &PORTH, 4},  // H4  7
  {&DDRH, &PINH, &PORTH, 5},  // H5  8
  {&DDRH, &PINH, &PORTH, 6},  // H6  9
  {&DDRB, &PINB, &PORTB, 4},  // B4 10
  {&DDRB, &PINB, &PORTB, 5},  // B5 11
  {&DDRB, &PINB, &PORTB, 6},  // B6 12
  {&DDRB, &PINB, &PORTB, 7},  // B7 13
  {&DDRJ, &PINJ, &PORTJ, 1},  // J1 14
  {&DDRJ, &PINJ, &PORTJ, 0},  // J0 15
  {&DDRH, &PINH, &PORTH, 1},  // H1 16
  {&DDRH, &PINH, &PORTH, 0},  // H0 17
  {&DDRD, &PIND, &PORTD, 3},  // D3 18
  {&DDRD, &PIND, &PORTD, 2},  // D2 19
  {&DDRD, &PIND, &PORTD, 1},  // D1 20
  {&DDRD, &PIND, &PORTD, 0},  // D0 21
  {&DDRA, &PINA, &PORTA, 0},  // A0 22
  {&DDRA, &PINA, &PORTA, 1},  // A1 23
  {&DDRA, &PINA, &PORTA, 2},  // A2 24
  {&DDRA, &PINA, &PORTA, 3},  // A3 25
  {&DDRA, &PINA, &PORTA, 4},  // A4 26
  {&DDRA, &PINA, &PORTA, 5},  // A5 27
  {&DDRA, &PINA, &PORTA, 6},  // A6 28
  {&DDRA, &PINA, &PORTA, 7},  // A7 29
  {&DDRC, &PINC, &PORTC, 7},  // C7 30
  {&DDRC, &PINC, &PORTC, 6},  // C6 31
  {&DDRC, &PINC, &PORTC, 5},  // C5 32
  {&DDRC, &PINC, &PORTC, 4},  // C4 33
  {&DDRC, &PINC, &PORTC, 3},  // C3 34
  {&DDRC, &PINC, &PORTC, 2},  // C2 35
  {&DDRC, &PINC, &PORTC, 1},  // C1 36
  {&DDRC, &PINC, &PORTC, 0},  // C0 37
  {&DDRD, &PIND, &PORTD, 7},  // D7 38
  {&DDRG, &PING, &PORTG, 2},  // G2 39
  {&DDRG, &PING, &PORTG, 1},  // G1 40
  {&DDRG, &PING, &PORTG, 0},  // G0 41
  {&DDRL, &PINL, &PORTL, 7},  // L7 42
  {&DDRL, &PINL, &PORTL, 6},  // L6 43
  {&DDRL, &PINL, &PORTL, 5},  // L5 44
  {&DDRL, &PINL, &PORTL, 4},  // L4 45
  {&DDRL, &PINL, &PORTL, 3},  // L3 46
  {&DDRL, &PINL, &PORTL, 2},  // L2 47
  {&DDRL, &PINL, &PORTL, 1},  // L1 48
  {&DDRL, &PINL, &PORTL, 0},  // L0 49
  {&DDRB, &PINB, &PORTB, 3},  // B3 50
  {&DDRB, &PINB, &PORTB, 2},  // B2 51
  {&DDRB, &PINB, &PORTB, 1},  // B1 52
  {&DDRB, &PINB, &PORTB, 0},  // B0 53
  {&DDRF, &PINF, &PORTF, 0},  // F0 54
  {&DDRF, &PINF, &PORTF, 1},  // F1 55
  {&DDRF, &PINF, &PORTF, 2},  // F2 56
  {&DDRF, &PINF, &PORTF, 3},  // F3 57
  {&DDRF, &PINF, &PORTF, 4},  // F4 58
  {&DDRF, &PINF, &PORTF, 5},  // F5 59
  {&DDRF, &PINF, &PORTF, 6},  // F6 60
  {&DDRF, &PINF, &PORTF, 7},  // F7 61
  {&DDRK, &PINK, &PORTK, 0},  // K0 62
  {&DDRK, &PINK, &PORTK, 1},  // K1 63
  {&DDRK, &PINK, &PORTK, 2},  // K2 64
  {&DDRK, &PINK, &PORTK, 3},  // K3 65
  {&DDRK, &PINK, &PORTK, 4},  // K4 66
  {&DDRK, &PINK, &PORTK, 5},  // K5 67
  {&DDRK, &PINK, &PORTK, 6},  // K6 68
  {&DDRK, &PINK, &PORTK, 7}   // K7 69
};
//------------------------------------------------------------------------------
#elif (defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && defined(CORE_MICRODUINO)
// Microduino Core+

// Two Wire (aka I2C) ports
uint8_t const SDA_PIN = 20;
uint8_t const SCL_PIN = 21;

// SPI port
uint8_t const SS_PIN = 10;
uint8_t const MOSI_PIN = 11;
uint8_t const MISO_PIN = 12;
uint8_t const SCK_PIN = 13;

static const pin_map_t digitalPinMap[] = {
  {&DDRD, &PIND, &PORTD, 0},  // D0 PD0
  {&DDRD, &PIND, &PORTD, 1},  // D1 PD1
  {&DDRD, &PIND, &PORTD, 2},  // D2 PD2
  {&DDRD, &PIND, &PORTD, 3},  // D3 PD3
  {&DDRB, &PINB, &PORTB, 0},  // D4 PB0
  {&DDRB, &PINB, &PORTB, 1},  // D5 PB1
  {&DDRB, &PINB, &PORTB, 2},  // D6 PB2
  {&DDRB, &PINB, &PORTB, 3},  // D7 PB3
  {&DDRD, &PIND, &PORTD, 6},  // D8 PD6
  {&DDRD, &PIND, &PORTD, 5},  // D9 PD5
  {&DDRB, &PINB, &PORTB, 4},  // D10 PB4
  {&DDRB, &PINB, &PORTB, 5},  // D11 PB5
  {&DDRB, &PINB, &PORTB, 6},  // D12 PB6
  {&DDRB, &PINB, &PORTB, 7},  // D13 PB7
  {&DDRC, &PINC, &PORTC, 7},  // D14 PC7
  {&DDRC, &PINC, &PORTC, 6},  // D15 PC6
  {&DDRC, &PINC, &PORTC, 5},  // D16 PC5
  {&DDRC, &PINC, &PORTC, 4},  // D17 PC4
  {&DDRC, &PINC, &PORTC, 3},  // D18 PC3
  {&DDRC, &PINC, &PORTC, 2},  // D19 PC2
  {&DDRC, &PINC, &PORTC, 1},  // D20 PC1
  {&DDRC, &PINC, &PORTC, 0},  // D21 PC0
  {&DDRD, &PIND, &PORTD, 4},  // D22 PD4
  {&DDRD, &PIND, &PORTD, 7},  // D23 PD7
  {&DDRA, &PINA, &PORTA, 7},  // D24 PA7
  {&DDRA, &PINA, &PORTA, 6},  // D25 PA6
  {&DDRA, &PINA, &PORTA, 5},  // D26 PA5
  {&DDRA, &PINA, &PORTA, 4},  // D27 PA4
  {&DDRA, &PINA, &PORTA, 3},  // D28 PA3
  {&DDRA, &PINA, &PORTA, 2},  // D29 PA2
  {&DDRA, &PINA, &PORTA, 1},  // D30 PA1
  {&DDRA, &PINA, &PORTA, 0}   // D31 PA0
};
//------------------------------------------------------------------------------
#elif defined(__AVR_ATmega128RFA1__) && defined(CORE_MICRODUINO)
// Microduino Core RF

// Two Wire (aka I2C) ports
uint8_t const SDA_PIN = 18;
uint8_t const SCL_PIN = 19;

// SPI port
uint8_t const SS_PIN = 10;
uint8_t const MOSI_PIN = 11;
uint8_t const MISO_PIN = 12;
uint8_t const SCK_PIN = 13;

static const pin_map_t digitalPinMap[] = {
  {&DDRD, &PINE, &PORTE, 0},  // D0 PE0
  {&DDRD, &PINE, &PORTE, 1},  // D1 PE1
  {&DDRD, &PIND, &PORTD, 2},  // D2 PD2
  {&DDRD, &PIND, &PORTD, 3},  // D3 PD3
  {&DDRB, &PINE, &PORTE, 3},  // D4 PE3
  {&DDRB, &PINE, &PORTE, 4},  // D5 PE4
  {&DDRB, &PINE, &PORTE, 5},  // D6 PE5
  {&DDRB, &PINB, &PORTB, 7},  // D7 PB7
  {&DDRD, &PINB, &PORTB, 6},  // D8 PB6
  {&DDRD, &PINB, &PORTB, 5},  // D9 PB5
  {&DDRB, &PINB, &PORTB, 4},  // D10 PB4
  {&DDRB, &PINB, &PORTB, 2},  // D11 PB2
  {&DDRB, &PINB, &PORTB, 3},  // D12 PB3
  {&DDRB, &PINB, &PORTB, 1},  // D13 PB1
  {&DDRF, &PINF, &PORTF, 7},  // D14 PF7
  {&DDRF, &PINF, &PORTF, 6},  // D15 PF6
  {&DDRF, &PINF, &PORTF, 5},  // D16 PF5
  {&DDRF, &PINF, &PORTF, 4},  // D17 PF4
  {&DDRD, &PIND, &PORTD, 1},  // D18 PD1
  {&DDRD, &PIND, &PORTD, 0},  // D19 PD0
  {&DDRF, &PINF, &PORTF, 3},  // D20 PF3
  {&DDRF, &PINF, &PORTF, 2},  // D21 PF2
};
//------------------------------------------------------------------------------
#elif defined(__AVR_ATmega32U4__) && defined(CORE_MICRODUINO)
// Microduino Core USB

// Two Wire (aka I2C) ports
uint8_t const SDA_PIN = 18;
uint8_t const SCL_PIN = 19;

// SPI port
uint8_t const SS_PIN = 10;
uint8_t const MOSI_PIN = 11;
uint8_t const MISO_PIN = 12;
uint8_t const SCK_PIN = 13;

static const pin_map_t digitalPinMap[] = {
  {&DDRD, &PIND, &PORTD, 2},  // D0 - PD2
  {&DDRD, &PIND, &PORTD, 3},  // D1 - PD3
  {&DDRE, &PINE, &PORTE, 6},  // D2 - PE6
  {&DDRD, &PIND, &PORTD, 6},  // D3 - PD6
  {&DDRD, &PIND, &PORTD, 7},  // D4 - PD7
  {&DDRC, &PINC, &PORTC, 6},  // D5 - PC6
  {&DDRC, &PINC, &PORTC, 7},  // D6 - PC7
  {&DDRE, &PINE, &PORTE, 7},  // D7 - PE7
  {&DDRB, &PINB, &PORTB, 6},  // D8 - PB6
  {&DDRB, &PINB, &PORTB, 5},  // D9 - PB5
  {&DDRB, &PINB, &PORTB, 0},  // D10 - PB0
  {&DDRB, &PINB, &PORTB, 2},  // D11 - MOSI - PB2
  {&DDRB, &PINB, &PORTB, 3},  // D12 -MISO -  PB3
  {&DDRB, &PINB, &PORTB, 1},  // D13 -SCK -  PB1
  {&DDRF, &PINF, &PORTF, 7},  // D14 - A0 - PF7
  {&DDRF, &PINF, &PORTF, 6},  // D15 - A1 - PF6
  {&DDRF, &PINF, &PORTF, 5},  // D16 - A2 - PF5
  {&DDRF, &PINF, &PORTF, 4},  // D17 - A3 - PF4
  {&DDRD, &PIND, &PORTD, 1},  // D18 - PD1
  {&DDRD, &PIND, &PORTD, 0},  // D19 - PD0
  {&DDRF, &PINF, &PORTF, 1},  // D20 - A6 - PF1
  {&DDRF, &PINF, &PORTF, 0},  // D21 - A7 - PF0
};
//------------------------------------------------------------------------------
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
// Sanguino

// Two Wire (aka I2C) ports
uint8_t const SDA_PIN = 17;
uint8_t const SCL_PIN = 18;

// SPI port
uint8_t const SS_PIN = 4;
uint8_t const MOSI_PIN = 5;
uint8_t const MISO_PIN = 6;
uint8_t const SCK_PIN = 7;

static const pin_map_t digitalPinMap[] = {
  {&DDRB, &PINB, &PORTB, 0},  // B0  0
  {&DDRB, &PINB, &PORTB, 1},  // B1  1
  {&DDRB, &PINB, &PORTB, 2},  // B2  2
  {&DDRB, &PINB, &PORTB, 3},  // B3  3
  {&DDRB, &PINB, &PORTB, 4},  // B4  4
  {&DDRB, &PINB, &PORTB, 5},  // B5  5
  {&DDRB, &PINB, &PORTB, 6},  // B6  6
  {&DDRB, &PINB, &PORTB, 7},  // B7  7
  {&DDRD, &PIND, &PORTD, 0},  // D0  8
  {&DDRD, &PIND, &PORTD, 1},  // D1  9
  {&DDRD, &PIND, &PORTD, 2},  // D2 10
  {&DDRD, &PIND, &PORTD, 3},  // D3 11
  {&DDRD, &PIND, &PORTD, 4},  // D4 12
  {&DDRD, &PIND, &PORTD, 5},  // D5 13
  {&DDRD, &PIND, &PORTD, 6},  // D6 14
  {&DDRD, &PIND, &PORTD, 7},  // D7 15
  {&DDRC, &PINC, &PORTC, 0},  // C0 16
  {&DDRC, &PINC, &PORTC, 1},  // C1 17
  {&DDRC, &PINC, &PORTC, 2},  // C2 18
  {&DDRC, &PINC, &PORTC, 3},  // C3 19
  {&DDRC, &PINC, &PORTC, 4},  // C4 20
  {&DDRC, &PINC, &PORTC, 5},  // C5 21
  {&DDRC, &PINC, &PORTC, 6},  // C6 22
  {&DDRC, &PINC, &PORTC, 7},  // C7 23
  {&DDRA, &PINA, &PORTA, 7},  // A7 24
  {&DDRA, &PINA, &PORTA, 6},  // A6 25
  {&DDRA, &PINA, &PORTA, 5},  // A5 26
  {&DDRA, &PINA, &PORTA, 4},  // A4 27
  {&DDRA, &PINA, &PORTA, 3},  // A3 28
  {&DDRA, &PINA, &PORTA, 2},  // A2 29
  {&DDRA, &PINA, &PORTA, 1},  // A1 30
  {&DDRA, &PINA, &PORTA, 0}   // A0 31
};
//------------------------------------------------------------------------------
#elif defined(__AVR_ATmega32U4__)
// Leonardo

// Two Wire (aka I2C) ports
uint8_t const SDA_PIN = 2;
uint8_t const SCL_PIN = 3;

// SPI port
uint8_t const SS_PIN = 17;
uint8_t const MOSI_PIN = 16;
uint8_t const MISO_PIN = 14;
uint8_t const SCK_PIN = 15;

static const pin_map_t digitalPinMap[] = {
  {&DDRD, &PIND, &PORTD, 2},  // D2  0
  {&DDRD, &PIND, &PORTD, 3},  // D3  1
  {&DDRD, &PIND, &PORTD, 1},  // D1  2
  {&DDRD, &PIND, &PORTD, 0},  // D0  3
  {&DDRD, &PIND, &PORTD, 4},  // D4  4
  {&DDRC, &PINC, &PORTC, 6},  // C6  5
  {&DDRD, &PIND, &PORTD, 7},  // D7  6
  {&DDRE, &PINE, &PORTE, 6},  // E6  7
  {&DDRB, &PINB, &PORTB, 4},  // B4  8
  {&DDRB, &PINB, &PORTB, 5},  // B5  9
  {&DDRB, &PINB, &PORTB, 6},  // B6 10
  {&DDRB, &PINB, &PORTB, 7},  // B7 11
  {&DDRD, &PIND, &PORTD, 6},  // D6 12
  {&DDRC, &PINC, &PORTC, 7},  // C7 13
  {&DDRB, &PINB, &PORTB, 3},  // B3 14
  {&DDRB, &PINB, &PORTB, 1},  // B1 15
  {&DDRB, &PINB, &PORTB, 2},  // B2 16
  {&DDRB, &PINB, &PORTB, 0},  // B0 17
  {&DDRF, &PINF, &PORTF, 7},  // F7 18
  {&DDRF, &PINF, &PORTF, 6},  // F6 19
  {&DDRF, &PINF, &PORTF, 5},  // F5 20
  {&DDRF, &PINF, &PORTF, 4},  // F4 21
  {&DDRF, &PINF, &PORTF, 1},  // F1 22
  {&DDRF, &PINF, &PORTF, 0},  // F0 23
};
//------------------------------------------------------------------------------
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
// Teensy++ 1.0 & 2.0

// Two Wire (aka I2C) ports
uint8_t const SDA_PIN = 1;
uint8_t const SCL_PIN = 0;

// SPI port
uint8_t const SS_PIN = 20;
uint8_t const MOSI_PIN = 22;
uint8_t const MISO_PIN = 23;
uint8_t const SCK_PIN = 21;

static const pin_map_t digitalPinMap[] = {
  {&DDRD, &PIND, &PORTD, 0},  // D0  0
  {&DDRD, &PIND, &PORTD, 1},  // D1  1
  {&DDRD, &PIND, &PORTD, 2},  // D2  2
  {&DDRD, &PIND, &PORTD, 3},  // D3  3
  {&DDRD, &PIND, &PORTD, 4},  // D4  4
  {&DDRD, &PIND, &PORTD, 5},  // D5  5
  {&DDRD, &PIND, &PORTD, 6},  // D6  6
  {&DDRD, &PIND, &PORTD, 7},  // D7  7
  {&DDRE, &PINE, &PORTE, 0},  // E0  8
  {&DDRE, &PINE, &PORTE, 1},  // E1  9
  {&DDRC, &PINC, &PORTC, 0},  // C0 10
  {&DDRC, &PINC, &PORTC, 1},  // C1 11
  {&DDRC, &PINC, &PORTC, 2},  // C2 12
  {&DDRC, &PINC, &PORTC, 3},  // C3 13
  {&DDRC, &PINC, &PORTC, 4},  // C4 14
  {&DDRC, &PINC, &PORTC, 5},  // C5 15
  {&DDRC, &PINC, &PORTC, 6},  // C6 16
  {&DDRC, &PINC, &PORTC, 7},  // C7 17
  {&DDRE, &PINE, &PORTE, 6},  // E6 18
  {&DDRE, &PINE, &PORTE, 7},  // E7 19
  {&DDRB, &PINB, &PORTB, 0},  // B0 20
  {&DDRB, &PINB, &PORTB, 1},  // B1 21
  {&DDRB, &PINB, &PORTB, 2},  // B2 22
  {&DDRB, &PINB, &PORTB, 3},  // B3 23
  {&DDRB, &PINB, &PORTB, 4},  // B4 24
  {&DDRB, &PINB, &PORTB, 5},  // B5 25
  {&DDRB, &PINB, &PORTB, 6},  // B6 26
  {&DDRB, &PINB, &PORTB, 7},  // B7 27
  {&DDRA, &PINA, &PORTA, 0},  // A0 28
  {&DDRA, &PINA, &PORTA, 1},  // A1 29
  {&DDRA, &PINA, &PORTA, 2},  // A2 30
  {&DDRA, &PINA, &PORTA, 3},  // A3 31
  {&DDRA, &PINA, &PORTA, 4},  // A4 32
  {&DDRA, &PINA, &PORTA, 5},  // A5 33
  {&DDRA, &PINA, &PORTA, 6},  // A6 34
  {&DDRA, &PINA, &PORTA, 7},  // A7 35
  {&DDRE, &PINE, &PORTE, 4},  // E4 36
  {&DDRE, &PINE, &PORTE, 5},  // E5 37
  {&DDRF, &PINF, &PORTF, 0},  // F0 38
  {&DDRF, &PINF, &PORTF, 1},  // F1 39
  {&DDRF, &PINF, &PORTF, 2},  // F2 40
  {&DDRF, &PINF, &PORTF, 3},  // F3 41
  {&DDRF, &PINF, &PORTF, 4},  // F4 42
  {&DDRF, &PINF, &PORTF, 5},  // F5 43
  {&DDRF, &PINF, &PORTF, 6},  // F6 44
  {&DDRF, &PINF, &PORTF, 7}   // F7 45
};
//------------------------------------------------------------------------------
#else  // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
// 168 and 328 Arduinos

// Two Wire (aka I2C) ports
uint8_t const SDA_PIN = 18;
uint8_t const SCL_PIN = 19;

// SPI port
uint8_t const SS_PIN = 10;
uint8_t const MOSI_PIN = 11;
uint8_t const MISO_PIN = 12;
uint8_t const SCK_PIN = 13;

static const pin_map_t digitalPinMap[] = {
  {&DDRD, &PIND, &PORTD, 0},  // D0  0
  {&DDRD, &PIND, &PORTD, 1},  // D1  1
  {&DDRD, &PIND, &PORTD, 2},  // D2  2
  {&DDRD, &PIND, &PORTD, 3},  // D3  3
  {&DDRD, &PIND, &PORTD, 4},  // D4  4
  {&DDRD, &PIND, &PORTD, 5},  // D5  5
  {&DDRD, &PIND, &PORTD, 6},  // D6  6
  {&DDRD, &PIND, &PORTD, 7},  // D7  7
  {&DDRB, &PINB, &PORTB, 0},  // B0  8
  {&DDRB, &PINB, &PORTB, 1},  // B1  9
  {&DDRB, &PINB, &PORTB, 2},  // B2 10
  {&DDRB, &PINB, &PORTB, 3},  // B3 11
  {&DDRB, &PINB, &PORTB, 4},  // B4 12
  {&DDRB, &PINB, &PORTB, 5},  // B5 13
  {&DDRC, &PINC, &PORTC, 0},  // C0 14
  {&DDRC, &PINC, &PORTC, 1},  // C1 15
  {&DDRC, &PINC, &PORTC, 2},  // C2 16
  {&DDRC, &PINC, &PORTC, 3},  // C3 17
  {&DDRC, &PINC, &PORTC, 4},  // C4 18
  {&DDRC, &PINC, &PORTC, 5}   // C5 19
};
#endif  // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
//------------------------------------------------------------------------------
static const uint8_t digitalPinCount = sizeof(digitalPinMap) / sizeof(pin_map_t);

uint8_t badPinNumber(void)
__attribute__((error("Pin number is too large or not a constant")));

static inline __attribute__((always_inline))
uint8_t getPinMode(uint8_t pin) {
  if (__builtin_constant_p(pin) && pin < digitalPinCount) {
    return (*digitalPinMap[pin].ddr >> digitalPinMap[pin].bit) & 1;
  } else {
    return badPinNumber();
  }
}
static inline __attribute__((always_inline))
void setPinMode(uint8_t pin, uint8_t mode) {
  if (__builtin_constant_p(pin) && pin < digitalPinCount) {
    if (mode) {
      *digitalPinMap[pin].ddr |= 1 << digitalPinMap[pin].bit;
    } else {
      *digitalPinMap[pin].ddr &= ~(1 << digitalPinMap[pin].bit);
    }
  } else {
    badPinNumber();
  }
}
static inline __attribute__((always_inline))
uint8_t fastDigitalRead(uint8_t pin) {
  if (__builtin_constant_p(pin) && pin < digitalPinCount) {
    return (*digitalPinMap[pin].pin >> digitalPinMap[pin].bit) & 1;
  } else {
    return badPinNumber();
  }
}
static inline __attribute__((always_inline))
void fastDigitalWrite(uint8_t pin, uint8_t value) {
  if (__builtin_constant_p(pin) && pin < digitalPinCount) {
    if (value) {
      *digitalPinMap[pin].port |= 1 << digitalPinMap[pin].bit;
    } else {
      *digitalPinMap[pin].port &= ~(1 << digitalPinMap[pin].bit);
    }
  } else {
    badPinNumber();
  }
}
#endif  // Sd2PinMap_h

#elif defined (__CPU_ARC__)

#if defined (__ARDUINO_ARC__)
  // Two Wire (aka I2C) ports
  uint8_t const SDA_PIN = 18;
  uint8_t const SCL_PIN = 19;

  // SPI port
  uint8_t const SS_PIN = 10;
  uint8_t const MOSI_PIN = 11;
  uint8_t const MISO_PIN = 12;
  uint8_t const SCK_PIN = 13;

#endif	// Arduino ARC

#else
#error Architecture or board not supported.
#endif

Tip: You can always follow-open the files in VSCode (.pio/libdeps/ in this case) to see which sections are activated and which not. Zero guesswork required.

In regards to the actual problem: This has been partly discussed in

already. The crucial thing to recognize is that, by default, the SPI access are done with the SPI library

(since #define USE_SPI_LIB is set in Sd2Card.h), and as such it is trivial to rewrite from “SPI” (and “SPI.h”) to “SPI1” and “SPI1.h”.

And even as you can see, we don’t even need to modify SDCARD_SPI because we can define it in our build_flags globally and it’ll just use that. But we will need to #include <SPI1.h> instead of <SPI.h>, which also means that all those SPISettings must now be SPI1Settings (the library creates different classes for that).

I’ve reworked that into a macro too so that you can choose to either use SPI or SPI1 in

Meaning you should be able to compile your current application perfectly fine with

[env:ATmega328PB]
platform = atmelavr
board = ATmega328PB
framework = arduino
lib_deps =
   https://github.com/maxgerhardt/SD/archive/refs/heads/master.zip
build_flags = 
  -D SDCARD_SPI=SPI1
  -D SDCARD_SPI_SETTINGS=SPI1Settings

Hi @maxgerhardt thank you very much for you fast and complete response, my bad level at programming don’t make me understand easily what you wrote. So,

First, I never use VScode, so it will be my first time.

I don’t understand it, how can I do that ? How to use the root you gave me ?

So how to use this macro you wrote ? Is it a simple copy/paste of all you write in the Sd2PinMap.h ? My knowledge in C++ is near 0 ^^

And last question,

What all this code means ? I have to download the master.zip folder ? And use it instead of the standard SD library ?

Thanks

It’s inside the project directory. When using lib_deps = ..., the library will be downloaded in there.

From there you can open any source or header file and see their syntax-highlighted version.

I didn’t modify anything in Sd2PinMap.h, as it seemed to me that adjusting the used SPI object was enough for MISO, MOSI, SCLK. CS should be controlled with regular functions or maybe portOutputRegister() and friends. I didn’t look further than that.

This is the platformio.ini where you write all the configuration options. See documentation It’s much quicker to edit this file directly than go through the e.g., library manager to add new libraries. And some options like build_flags are not exposed at all through the GUI.

You don’t need to manually download anything, that’s the point of the configuration file. You override your old platformio.ini with the new given content, save it, then PlatformIO will reload the project with the new settings – this includes downloading my modified version of the SD library as pointed to by its github download link, same link you would get when clicking “Download ZIP”

grafik

Thank you @maxgerhardt for these explanation, I’ve to work now by myself to understand how VScode works.

For the USE of SPI1, I don’t understand what you advice me to do so. Like I said on my first message, I’ve already done some things that doesn’t work and I get no signal at the 328PB SPI1 pins.
I’ve also try to change SPI.h called in Sd2Card.cpp by SPI1.h and also change alors “SPI” word by “SPI1”, compilation goes right, by no signal also.

So can you please tell what modification I can do to be able to setup right pins for having signal at SPI1 pins.
I’m afraid that I don’t understand your explanation without an exemple with code ^^

Precision, this is the sketch I use for my test :

#include <SPI1.h>
#include <SD.h>

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;


const int chipSelect = PIN_PE2; //PE2

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
  }

  //pinMode(PIN_PE2, OUTPUT);
  //digitalWrite(PIN_PE2, HIGH);

  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 (!card.init(SPI_HALF_SPEED, chipSelect)) {
    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.");
  }

And the result is always “initialization failed”, because no signal detected on SPI1 pins (oscillocope measurement)

You already have the example code. With the exact platformio.ini configuration I gave you, there is still no signals at SP1?

Ha okay. I understand better now.

is a command to download automatically a library

platformio.ini I was look at this folder everywhere in my computer, but I realise that I had to create it by myself and only copy/paste the code you give me, is it right ?

So I don’t need to modify any SD file, even not the Sd2Card.cpp ?

What means the -D in this instruction ?
-D SDCARD_SPI_SETTINGS=SPI1Settings

This is my new problem, I never use VScode, so I’m trying to find how to upload a file, directly to the atmega328pb (optiboot bootloader).
I used to do it with arduino ide

Is it obligatory to download arduino for vscode package to be able to upload the sketch test ?

Exactly, the piont is that I hopefully did all needed modifications

-D is for “Define a macro name to the following value”. That’s a GCC setting. See here for documentation. The point is that I modified the library to accept a previously set SDCARD_SPI_SETTINGS macro that would be the type of the SPI settings object to use. See above commit for the code.

Does the regular upload button not work? Toolbar → Upload, or project task → Upload. Of course, PlatformIO has the upload program built-in. You might just need to adjust the settings if something fails.

Thanks for the documentation

I get this error when I try to compile


I think that the platformio.ini file can’t download the github file ?

Can you confirm that my platformio.ini config syntax is ok ?
Because I don’t understand why it can find the Arduino.h

PIN_PE2 is not a valid Arduino pin. Minicore maps this to Arduino pin number 25. Can you use that instead? Setting const int chipSelect = A6; should work too isntead of 25.

Yes, I did it, but it does’nt solve my compilation error. I think its about finding “Arduino.h” before compiling. So i guess my platformio.ini is not written correctly

Actually no. Line 7 to 9 should be deleted. All Arduino framework and built-in libraries are already built in and need not to be added via lib_deps.

Always get this error
MissingPackageManifestError: Could not find one of ‘package.json’ manifest files in the package

At this point the PlatformIO packages might be corrupted.

  1. Close VScode
  2. Delete the C:\Users\<user>\.platformio directory completely
  3. Reopen VSCode
  4. Wait for it to reinstall itself, then build again

Yeaahhhhhhhhh !!! Thank you very much !!! It works fine !!! I’m able to use without problem the sketch and read my SD card info !!!

So the last question, do you have any suggestion to learn how platformio.ini and programmation on vscode work ?
Because, I really need to understand all you said at the beginning of this subject.

When you wrote build_flags =
-D SDCARD_SPI=SPI1
-D SDCARD_SPI_SETTINGS=SPI1Settings

How to be sure that you remplace only items on a selected file and not on file that we don’t want to make change ?

So, the code won’t work with SD standard library, its only with SD-master library ?

And last question please, how did you know that you have to add this code in Sd2Card.cpp :

#ifdef MCUDUDE_MINICORE
    #include <SPI1.h>
  #endif

Which file define MCUDUDE_MINICORE words ?

I’ve already linked the documentation above-

When going via build_flags, these are global compiler settings, so the macro definition SDCARD_SPI=SPI1 etc. will be visible in every .c/.cpp file. The point is that only the SD library reacts to these macros, the first one it already did before, the second one was added.

Correct, because of the needed modification to repoint the used SPI and SPI Settings object as well as the missing inclusion of the SPI1.h header.

You can see in the Minicore’s pins_arduino.h

this file is included as part of Arduino.h

meaning that after #include <Arduino.h> is done, this macro can be used to check whether we’re working in the Minicore.

Do you mean SDCARD_SPI is already declared on some SD file so all will be replace by SPI1 ?

But, there is many board version on the minicore library, in my case atmega328PB, so how it knows that i’m using this board to be able to set the right SS, MISO… pins ?
I don’t understand at what step, the type of board is found and put automatically in a file.

I promise, this is my last question :blush: