From a453d081b4b1cec874ca59e5ccb9b4799a508e11 Mon Sep 17 00:00:00 2001 From: Phillip Burgess Date: Fri, 3 May 2019 11:36:29 -0700 Subject: [PATCH] SPITFT: work with any SERCOM SPIs --- Adafruit_SPITFT.cpp | 49 ++++++++++++++++++++++++++++++++++++++++----- library.properties | 2 +- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/Adafruit_SPITFT.cpp b/Adafruit_SPITFT.cpp index f34b270..d15ac39 100644 --- a/Adafruit_SPITFT.cpp +++ b/Adafruit_SPITFT.cpp @@ -255,9 +255,16 @@ Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t cs, @param rst Arduino pin # for display reset (optional, display reset can be tied to MCU reset, default of -1 means unused). @return Adafruit_SPITFT object. - @note Output pins are not initialized; application typically will - need to call subclass' begin() function, which in turn calls - this library's initSPI() function to initialize pins. + @note Output pins are not initialized in constructor; application + typically will need to call subclass' begin() function, which + in turn calls this library's initSPI() function to initialize + pins. EXCEPT...if you have built your own SERCOM SPI peripheral + (calling the SPIClass constructor) rather than one of the + built-in SPI devices (e.g. &SPI, &SPI1 and so forth), you will + need to call the begin() function for your object as well as + pinPeripheral() for the MOSI, MISO and SCK pins to configure + GPIO manually. Do this BEFORE calling the display-specific + begin or init function. Unfortunate but unavoidable. */ Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass, int8_t cs, int8_t dc, int8_t rst) : Adafruit_GFX(w, h), @@ -517,8 +524,40 @@ void Adafruit_SPITFT::initSPI(uint32_t freq) { #else hwspi._freq = freq; // Save freq value for later #endif - hwspi._spi->begin(); - + // Call hwspi._spi->begin() ONLY if this is among the 'established' + // SPI interfaces in variant.h. For DIY roll-your-own SERCOM SPIs, + // begin() and pinPeripheral() calls MUST be made in one's calling + // code, BEFORE the screen-specific begin/init function is called. + // Reason for this is that SPI::begin() makes its own calls to + // pinPeripheral() based on g_APinDescription[n].ulPinType, which + // on non-established SPI interface pins will always be PIO_DIGITAL + // or similar, while we need PIO_SERCOM or PIO_SERCOM_ALT...it's + // highly unique between devices and variants for each pin or + // SERCOM so we can't make those calls ourselves here. And the SPI + // device needs to be set up before calling this because it's + // immediately followed with initialization commands. Blargh. + if( +#if SPI_INTERFACES_COUNT > 0 + (hwspi._spi == &SPI) +#endif +#if SPI_INTERFACES_COUNT > 1 + || (hwspi._spi == &SPI1) +#endif +#if SPI_INTERFACES_COUNT > 2 + || (hwspi._spi == &SPI2) +#endif +#if SPI_INTERFACES_COUNT > 3 + || (hwspi._spi == &SPI3) +#endif +#if SPI_INTERFACES_COUNT > 4 + || (hwspi._spi == &SPI4) +#endif +#if SPI_INTERFACES_COUNT > 5 + || (hwspi._spi == &SPI5) +#endif + ) { + hwspi._spi->begin(); + } } else if(connection == TFT_SOFT_SPI) { pinMode(swspi._mosi, OUTPUT); diff --git a/library.properties b/library.properties index c183dfc..ad1192c 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit GFX Library -version=1.4.11 +version=1.4.12 author=Adafruit maintainer=Adafruit sentence=Adafruit GFX graphics core library, this is the 'core' class that all our other graphics libraries derive from.