Page 1 of 1

using SDFileSystem with PPS (18FxxQ71 example)

Posted: Sat Mar 04, 2023 2:06 pm
by Jerry Messina
SDFileSystem (SDFS) 4.1.9 now includes a feature to help support devices which use PPS to map the SPI peripheral.

Usually for most modules you can map PPS settings outside of the module in your main program.
However, for the SDFileSystem this poses a problem. To initialize the SD card, the SD.Init() function must first bit-bang a sequence to setup the card, after which it can switch to using hardware SPI functions. To do this, any PPS assignments must be mapped and unmapped to gain control of the IO pins.

SDFS V4.1.8 added two user-defined events, OnMapSPIPPS and OnUnmapSPIPPS that can be used to allow control over the PPS operation. If set, these two events will be called during the SD.InitSequence() function.

To set the events there is the new SD.Init() overloaded function that takes the two events as parameters:
public function Init(pOnMapSPIPPS as event_t, pOnUnmapSPIPPS as event_t) as byte


Here's an example for the 18F26Q71 of how this might be used:

Code: Select all

device = 18F26Q71
clock = 64

include "intosc.bas"
#option DIGITALIO_INIT=true     // automatically call setalldigital at startup
include "setdigitalio.bas"

// PPS module
include "pps.bas"

// SPI module pin definitions for SPI1XV (needs PPS)
#option SPI_SCK = PORTC.3
#option SPI_SDI = PORTC.4
#option SPI_SDO = PORTC.5

// SDFileSystem (uses SPI1 w/PPS)
#option SD_SPI = SPI1XV       // SPI module for xv18 core devices (18F26Q71)
#option SD_CS =  PORTC.0
include "SDFileSystem.bas"

//
// SDFileSystem v4.1.9 defines two user callback events - OnMapSPIPPS and OnUnmapSPIPPS
// SD.InitSequence() will call these to enable/disable PPS mapping during SD.Init()
//

// SD callback event to map SPI1 via PPS
// setup 18FxxQ71 SPI1 PPS
event mapSPI1PPS()
    pps.unlock()

    pps.assign_output(RC3PPS, PPS_SPI1_SCK)         'SCK1 > RC3
    pps.assign_input(SPI1SCKPPS, PPS_PORTC, 3)      'RC3 > SCK1 (bidir)
    pps.assign_input(SPI1SDIPPS, PPS_PORTC, 4)      'RC4 > SDI1
    pps.assign_output(RC5PPS, PPS_SPI1_SDO)         'SDO1 > RC5
end event

// SD callback event to unmap SPI1 PPS outputs (to allow bit-banging)
event unmapSPI1PPS()
    pps.unlock()

    pps.assign_output(RC3PPS, PPS_LAT)          // return SCK1 back to LAT
    pps.assign_output(RC5PPS, PPS_LAT)          // return SDO1 back to LAT
end event

// main code
dim stat as byte

// init SD and assign PPS events
stat = SD.Init(mapSPI1PPS, unmapSPI1PPS)

if (stat = SD.errOK) then
    // SD initialized
else
    // an error occurred
endif

SDFS v4.1.9 is included in the latest sf_update_3_1_2023