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