Hi, please can anybody help how to configure SPI to work on digital pins 10,11,12,13 for old SD card shields?
I am in the UK. So I can only buy the "Zero Pro" (now called "M0 Pro")
Since the warring Italians don't let you run a Zero Pro on v1.6.5 I can only show you how I have patched v1.7.5 "libraries/SPI/SPI.cpp"
void SPIClass::begin()
{
// PIO init
if (_p_sercom == &sercom1) {
// this forces the pads and pins for 11,12,13 regardless of pin descriptions or constructor()
pinPeripheral(12, PIO_SERCOM);
pinPeripheral(13, PIO_SERCOM);
pinPeripheral(11, PIO_SERCOM);
_p_sercom->initSPI(SPI_PAD_0_SCK_1, SERCOM_RX_PAD_3, SPI_CHAR_SIZE_8_BITS, MSB_FIRST);
}
else {
pinPeripheral(_uc_pinMiso, g_APinDescription[_uc_pinMiso].ulPinType);
pinPeripheral(_uc_pinSCK, g_APinDescription[_uc_pinSCK].ulPinType);
pinPeripheral(_uc_pinMosi, g_APinDescription[_uc_pinMosi].ulPinType);
// Default speed set to 4Mhz, SPI mode set to MODE 0 and Bit order set to MSB first.
_p_sercom->initSPI(SPI_PAD_2_SCK_3, SERCOM_RX_PAD_0, SPI_CHAR_SIZE_8_BITS, MSB_FIRST);
}
_p_sercom->initSPIClock(SERCOM_SPI_MODE_0, 4000000);
_p_sercom->enableSPI();
}
...
//SPIClass SPI(&sercom4, 18, 20, 21); // .kbv replace the default ICSP header pins
SPIClass SPI(&sercom1, 12, 13, 11); // .kbv with the traditional UNO pins
The g_APinDescription[] table in v1.7.5 does not have the relevant description for using SERCOM1 as SPI. As you can see, the constructor arguments are ignored if it is using SERCOM1. And the SERCOM4 code depends on you sending the correct ICSP pin numbers too.
I only hope that the v1.6.5 code has been written more carefully.
David.
I have since installed v1.6.5 which in turn installs the ZERO package with "SPI.cpp" into my "C:\Users\David Prentice\AppData\Roaming\Arduino15\packages\arduino\hardware\samd\1.6.0\libraries\SPI" directory
The v1.6.x code appears to be far better organised than the v1.7.5 stuff for the "M0" and "M0 Pro"
I installed the ZERO bootloader via EDBG and have been successfully running v1.6.5 on my "M0 Pro" (formerly known as Zero Pro)
A "better" patch of the v1.6.0 SPI.cpp file is in the config() method instead of the begin() method:
void SPIClass::config(SPISettings settings)
{
_p_sercom->disableSPI();
#if 1
if (_p_sercom == &sercom1) {
// this forces the pads and pins for 11,12,13 regardless of pin descriptions or constructor()
pinPeripheral(12, PIO_SERCOM);
pinPeripheral(13, PIO_SERCOM);
pinPeripheral(11, PIO_SERCOM);
_p_sercom->initSPI(SPI_PAD_0_SCK_1, SERCOM_RX_PAD_3, SPI_CHAR_SIZE_8_BITS, settings.bitOrder);
}
else {
_p_sercom->initSPI(SPI_PAD_2_SCK_3, SERCOM_RX_PAD_0, SPI_CHAR_SIZE_8_BITS, settings.bitOrder);
}
#else
_p_sercom->initSPI(SPI_PAD_2_SCK_3, SERCOM_RX_PAD_0, SPI_CHAR_SIZE_8_BITS, settings.bitOrder);
#endif
_p_sercom->initSPIClock(settings.dataMode, settings.clockFreq);
_p_sercom->enableSPI();
}
...
//SPIClass SPI( &sercom4, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI );
SPIClass SPI( &sercom1, 12, 13, 11 );
I also patched "variant.cpp" for the different assignment of digital#2 and #4 pins:
// 2..12
// Digital Low
#if M0_PRO
{ PORTA, 8, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0]
{ PORTA, 9, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1]
{ PORTA, 14, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0, EXTERNAL_INT_14 }, // TC3/WO[0]
#else
{ PORTA, 14, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 },
{ PORTA, 9, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1]
{ PORTA, 8, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0]
#endif
I can run a TFT display on the regular "UNO" SPI pins and read a microSD card connected to the same bus. If you use my "SERCOM1" patch, you should be able to run two independent SPI buses if you want to. Note that the <SD.h> library seems to require hard-named SPI object. Your TFT code could use a differently named object.
David.
Hi David,
I find your replies very helpful. I am just curios if the one you written would allow using both the ICSP SPI and the new declared 1
david_prentice:
//SPIClass SPI( &sercom4, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI );
SPIClass SPI( &sercom1, 12, 13, 11 );
I find your replies very helpful. I am just curios if the one you written would allow using both the ICSP SPI and the new declared 11, 12, 13 simultaneously.
Thank you