@@ -255,9 +255,16 @@ Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t cs,
255255 @param rst Arduino pin # for display reset (optional, display reset
256256 can be tied to MCU reset, default of -1 means unused).
257257 @return Adafruit_SPITFT object.
258- @note Output pins are not initialized; application typically will
259- need to call subclass' begin() function, which in turn calls
260- this library's initSPI() function to initialize pins.
258+ @note Output pins are not initialized in constructor; application
259+ typically will need to call subclass' begin() function, which
260+ in turn calls this library's initSPI() function to initialize
261+ pins. EXCEPT...if you have built your own SERCOM SPI peripheral
262+ (calling the SPIClass constructor) rather than one of the
263+ built-in SPI devices (e.g. &SPI, &SPI1 and so forth), you will
264+ need to call the begin() function for your object as well as
265+ pinPeripheral() for the MOSI, MISO and SCK pins to configure
266+ GPIO manually. Do this BEFORE calling the display-specific
267+ begin or init function. Unfortunate but unavoidable.
261268*/
262269Adafruit_SPITFT::Adafruit_SPITFT (uint16_t w, uint16_t h, SPIClass *spiClass,
263270 int8_t cs, int8_t dc, int8_t rst) : Adafruit_GFX(w, h),
@@ -517,8 +524,40 @@ void Adafruit_SPITFT::initSPI(uint32_t freq) {
517524#else
518525 hwspi._freq = freq; // Save freq value for later
519526#endif
520- hwspi._spi ->begin ();
521-
527+ // Call hwspi._spi->begin() ONLY if this is among the 'established'
528+ // SPI interfaces in variant.h. For DIY roll-your-own SERCOM SPIs,
529+ // begin() and pinPeripheral() calls MUST be made in one's calling
530+ // code, BEFORE the screen-specific begin/init function is called.
531+ // Reason for this is that SPI::begin() makes its own calls to
532+ // pinPeripheral() based on g_APinDescription[n].ulPinType, which
533+ // on non-established SPI interface pins will always be PIO_DIGITAL
534+ // or similar, while we need PIO_SERCOM or PIO_SERCOM_ALT...it's
535+ // highly unique between devices and variants for each pin or
536+ // SERCOM so we can't make those calls ourselves here. And the SPI
537+ // device needs to be set up before calling this because it's
538+ // immediately followed with initialization commands. Blargh.
539+ if (
540+ #if SPI_INTERFACES_COUNT > 0
541+ (hwspi._spi == &SPI)
542+ #endif
543+ #if SPI_INTERFACES_COUNT > 1
544+ || (hwspi._spi == &SPI1)
545+ #endif
546+ #if SPI_INTERFACES_COUNT > 2
547+ || (hwspi._spi == &SPI2)
548+ #endif
549+ #if SPI_INTERFACES_COUNT > 3
550+ || (hwspi._spi == &SPI3)
551+ #endif
552+ #if SPI_INTERFACES_COUNT > 4
553+ || (hwspi._spi == &SPI4)
554+ #endif
555+ #if SPI_INTERFACES_COUNT > 5
556+ || (hwspi._spi == &SPI5)
557+ #endif
558+ ) {
559+ hwspi._spi ->begin ();
560+ }
522561 } else if (connection == TFT_SOFT_SPI) {
523562
524563 pinMode (swspi._mosi , OUTPUT);
0 commit comments