Merge branch 'master' into pgm_mem_patch

This commit is contained in:
Oleksandr Masliuchenko 2019-06-07 09:08:42 +03:00
commit 5cf3b4fbc8
5 changed files with 208 additions and 224 deletions

View File

@ -1179,38 +1179,6 @@ size_t Adafruit_GFX::write(uint8_t c) {
return 1; return 1;
} }
/**************************************************************************/
/*!
@brief Set text cursor location
@param x X coordinate in pixels
@param y Y coordinate in pixels
*/
/**************************************************************************/
void Adafruit_GFX::setCursor(int16_t x, int16_t y) {
cursor_x = x;
cursor_y = y;
}
/**************************************************************************/
/*!
@brief Get text cursor X location
@returns X coordinate in pixels
*/
/**************************************************************************/
int16_t Adafruit_GFX::getCursorX(void) const {
return cursor_x;
}
/**************************************************************************/
/*!
@brief Get text cursor Y location
@returns Y coordinate in pixels
*/
/**************************************************************************/
int16_t Adafruit_GFX::getCursorY(void) const {
return cursor_y;
}
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Set text 'magnification' size. Each increase in s makes 1 pixel that much bigger. @brief Set text 'magnification' size. Each increase in s makes 1 pixel that much bigger.
@ -1221,50 +1189,6 @@ void Adafruit_GFX::setTextSize(uint8_t s) {
textsize = (s > 0) ? s : 1; textsize = (s > 0) ? s : 1;
} }
/**************************************************************************/
/*!
@brief Set text font color with transparant background
@param c 16-bit 5-6-5 Color to draw text with
*/
/**************************************************************************/
void Adafruit_GFX::setTextColor(uint16_t c) {
// For 'transparent' background, we'll set the bg
// to the same as fg instead of using a flag
textcolor = textbgcolor = c;
}
/**************************************************************************/
/*!
@brief Set text font color with custom background color
@param c 16-bit 5-6-5 Color to draw text with
@param b 16-bit 5-6-5 Color to draw background/fill with
*/
/**************************************************************************/
void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) {
textcolor = c;
textbgcolor = b;
}
/**************************************************************************/
/*!
@brief Whether text that is too long should 'wrap' around to the next line.
@param w Set true for wrapping, false for clipping
*/
/**************************************************************************/
void Adafruit_GFX::setTextWrap(boolean w) {
wrap = w;
}
/**************************************************************************/
/*!
@brief Get rotation setting for display
@returns 0 thru 3 corresponding to 4 cardinal rotations
*/
/**************************************************************************/
uint8_t Adafruit_GFX::getRotation(void) const {
return rotation;
}
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Set rotation setting for display @brief Set rotation setting for display
@ -1287,22 +1211,6 @@ void Adafruit_GFX::setRotation(uint8_t x) {
} }
} }
/**************************************************************************/
/*!
@brief Enable (or disable) Code Page 437-compatible charset.
There was an error in glcdfont.c for the longest time -- one character
(#176, the 'light shade' block) was missing -- this threw off the index
of every character that followed it. But a TON of code has been written
with the erroneous character indices. By default, the library uses the
original 'wrong' behavior and old sketches will still work. Pass 'true'
to this function to use correct CP437 character values in your code.
@param x Whether to enable (True) or not (False)
*/
/**************************************************************************/
void Adafruit_GFX::cp437(boolean x) {
_cp437 = x;
}
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Set the font to display when print()ing, either custom or default @brief Set the font to display when print()ing, either custom or default
@ -1486,26 +1394,6 @@ void Adafruit_GFX::getTextBounds(const __FlashStringHelper *str,
} }
} }
/**************************************************************************/
/*!
@brief Get width of the display, accounting for the current rotation
@returns Width in pixels
*/
/**************************************************************************/
int16_t Adafruit_GFX::width(void) const {
return _width;
}
/**************************************************************************/
/*!
@brief Get height of the display, accounting for the current rotation
@returns Height in pixels
*/
/**************************************************************************/
int16_t Adafruit_GFX::height(void) const {
return _height;
}
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Invert the display (ideally using built-in hardware command) @brief Invert the display (ideally using built-in hardware command)
@ -1617,10 +1505,10 @@ void Adafruit_GFX_Button::drawButton(boolean inverted) {
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Helper to let us know if a coordinate is within the bounds of the button @brief Helper to let us know if a coordinate is within the bounds of the button
@param x The X coordinate to check @param x The X coordinate to check
@param y The Y coordinate to check @param y The Y coordinate to check
@returns True if within button graphics outline @returns True if within button graphics outline
*/ */
/**************************************************************************/ /**************************************************************************/
boolean Adafruit_GFX_Button::contains(int16_t x, int16_t y) { boolean Adafruit_GFX_Button::contains(int16_t x, int16_t y) {
@ -1628,25 +1516,6 @@ boolean Adafruit_GFX_Button::contains(int16_t x, int16_t y) {
(y >= _y1) && (y < (int16_t) (_y1 + _h))); (y >= _y1) && (y < (int16_t) (_y1 + _h)));
} }
/**************************************************************************/
/*!
@brief Sets the state of the button, should be done by some touch function
@param p True for pressed, false for not.
*/
/**************************************************************************/
void Adafruit_GFX_Button::press(boolean p) {
laststate = currstate;
currstate = p;
}
/**************************************************************************/
/*!
@brief Query whether the button is currently pressed
@returns True if pressed
*/
/**************************************************************************/
boolean Adafruit_GFX_Button::isPressed() { return currstate; }
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Query whether the button was pressed since we last checked state @brief Query whether the button was pressed since we last checked state
@ -1707,20 +1576,10 @@ GFXcanvas1::~GFXcanvas1(void) {
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Get a pointer to the internal buffer memory @brief Draw a pixel to the canvas framebuffer
@returns A pointer to the allocated buffer @param x x coordinate
*/ @param y y coordinate
/**************************************************************************/ @param color 16-bit 5-6-5 Color to fill with
uint8_t* GFXcanvas1::getBuffer(void) {
return buffer;
}
/**************************************************************************/
/*!
@brief Draw a pixel to the canvas framebuffer
@param x x coordinate
@param y y coordinate
@param color 16-bit 5-6-5 Color to fill with
*/ */
/**************************************************************************/ /**************************************************************************/
void GFXcanvas1::drawPixel(int16_t x, int16_t y, uint16_t color) { void GFXcanvas1::drawPixel(int16_t x, int16_t y, uint16_t color) {
@ -1765,8 +1624,8 @@ void GFXcanvas1::drawPixel(int16_t x, int16_t y, uint16_t color) {
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Fill the framebuffer completely with one color @brief Fill the framebuffer completely with one color
@param color 16-bit 5-6-5 Color to fill with @param color 16-bit 5-6-5 Color to fill with
*/ */
/**************************************************************************/ /**************************************************************************/
void GFXcanvas1::fillScreen(uint16_t color) { void GFXcanvas1::fillScreen(uint16_t color) {
@ -1799,23 +1658,12 @@ GFXcanvas8::~GFXcanvas8(void) {
if(buffer) free(buffer); if(buffer) free(buffer);
} }
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Get a pointer to the internal buffer memory @brief Draw a pixel to the canvas framebuffer
@returns A pointer to the allocated buffer @param x x coordinate
*/ @param y y coordinate
/**************************************************************************/ @param color 16-bit 5-6-5 Color to fill with
uint8_t* GFXcanvas8::getBuffer(void) {
return buffer;
}
/**************************************************************************/
/*!
@brief Draw a pixel to the canvas framebuffer
@param x x coordinate
@param y y coordinate
@param color 16-bit 5-6-5 Color to fill with
*/ */
/**************************************************************************/ /**************************************************************************/
void GFXcanvas8::drawPixel(int16_t x, int16_t y, uint16_t color) { void GFXcanvas8::drawPixel(int16_t x, int16_t y, uint16_t color) {
@ -1846,8 +1694,8 @@ void GFXcanvas8::drawPixel(int16_t x, int16_t y, uint16_t color) {
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Fill the framebuffer completely with one color @brief Fill the framebuffer completely with one color
@param color 16-bit 5-6-5 Color to fill with @param color 16-bit 5-6-5 Color to fill with
*/ */
/**************************************************************************/ /**************************************************************************/
void GFXcanvas8::fillScreen(uint16_t color) { void GFXcanvas8::fillScreen(uint16_t color) {
@ -1916,20 +1764,10 @@ GFXcanvas16::~GFXcanvas16(void) {
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Get a pointer to the internal buffer memory @brief Draw a pixel to the canvas framebuffer
@returns A pointer to the allocated buffer @param x x coordinate
*/ @param y y coordinate
/**************************************************************************/ @param color 16-bit 5-6-5 Color to fill with
uint16_t* GFXcanvas16::getBuffer(void) {
return buffer;
}
/**************************************************************************/
/*!
@brief Draw a pixel to the canvas framebuffer
@param x x coordinate
@param y y coordinate
@param color 16-bit 5-6-5 Color to fill with
*/ */
/**************************************************************************/ /**************************************************************************/
void GFXcanvas16::drawPixel(int16_t x, int16_t y, uint16_t color) { void GFXcanvas16::drawPixel(int16_t x, int16_t y, uint16_t color) {
@ -1960,8 +1798,8 @@ void GFXcanvas16::drawPixel(int16_t x, int16_t y, uint16_t color) {
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Fill the framebuffer completely with one color @brief Fill the framebuffer completely with one color
@param color 16-bit 5-6-5 Color to fill with @param color 16-bit 5-6-5 Color to fill with
*/ */
/**************************************************************************/ /**************************************************************************/
void GFXcanvas16::fillScreen(uint16_t color) { void GFXcanvas16::fillScreen(uint16_t color) {
@ -1976,3 +1814,22 @@ void GFXcanvas16::fillScreen(uint16_t color) {
} }
} }
/**************************************************************************/
/*!
@brief Reverses the "endian-ness" of each 16-bit pixel within the
canvas; little-endian to big-endian, or big-endian to little.
Most microcontrollers (such as SAMD) are little-endian, while
most displays tend toward big-endianness. All the drawing
functions (including RGB bitmap drawing) take care of this
automatically, but some specialized code (usually involving
DMA) can benefit from having pixel data already in the
display-native order. Note that this does NOT convert to a
SPECIFIC endian-ness, it just flips the bytes within each word.
*/
/**************************************************************************/
void GFXcanvas16::byteSwap(void) {
if(buffer) {
uint32_t i, pixels = WIDTH * HEIGHT;
for(i=0; i<pixels; i++) buffer[i] = __builtin_bswap16(buffer[i]);
}
}

View File

@ -95,20 +95,70 @@ class Adafruit_GFX : public Print {
uint16_t *bitmap, uint8_t *mask, int16_t w, int16_t h), uint16_t *bitmap, uint8_t *mask, int16_t w, int16_t h),
drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color,
uint16_t bg, uint8_t size), uint16_t bg, uint8_t size),
setCursor(int16_t x, int16_t y),
setTextColor(uint16_t c),
setTextColor(uint16_t c, uint16_t bg),
setTextSize(uint8_t s),
setTextWrap(boolean w),
cp437(boolean x=true),
setFont(const GFXfont *f = NULL),
getTextBounds(const char *string, int16_t x, int16_t y, getTextBounds(const char *string, int16_t x, int16_t y,
int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h), int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h),
getTextBounds(const __FlashStringHelper *s, int16_t x, int16_t y, getTextBounds(const __FlashStringHelper *s, int16_t x, int16_t y,
int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h), int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h),
getTextBounds(const String &str, int16_t x, int16_t y, getTextBounds(const String &str, int16_t x, int16_t y,
int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h); int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h),
setTextSize(uint8_t s),
setFont(const GFXfont *f = NULL);
/**********************************************************************/
/*!
@brief Set text cursor location
@param x X coordinate in pixels
@param y Y coordinate in pixels
*/
/**********************************************************************/
void setCursor(int16_t x, int16_t y) { cursor_x = x; cursor_y = y; }
/**********************************************************************/
/*!
@brief Set text font color with transparant background
@param c 16-bit 5-6-5 Color to draw text with
@note For 'transparent' background, background and foreground
are set to same color rather than using a separate flag.
*/
/**********************************************************************/
void setTextColor(uint16_t c) { textcolor = textbgcolor = c; }
/**********************************************************************/
/*!
@brief Set text font color with custom background color
@param c 16-bit 5-6-5 Color to draw text with
@param bg 16-bit 5-6-5 Color to draw background/fill with
*/
/**********************************************************************/
void setTextColor(uint16_t c, uint16_t bg) {
textcolor = c;
textbgcolor = bg;
}
/**********************************************************************/
/*!
@brief Set whether text that is too long for the screen width should
automatically wrap around to the next line (else clip right).
@param w true for wrapping, false for clipping
*/
/**********************************************************************/
void setTextWrap(boolean w) { wrap = w; }
/**********************************************************************/
/*!
@brief Enable (or disable) Code Page 437-compatible charset.
There was an error in glcdfont.c for the longest time -- one
character (#176, the 'light shade' block) was missing -- this
threw off the index of every character that followed it.
But a TON of code has been written with the erroneous
character indices. By default, the library uses the original
'wrong' behavior and old sketches will still work. Pass
'true' to this function to use correct CP437 character values
in your code.
@param x true = enable (new behavior), false = disable (old behavior)
*/
/**********************************************************************/
void cp437(boolean x=true) { _cp437 = x; }
#if ARDUINO >= 100 #if ARDUINO >= 100
virtual size_t write(uint8_t); virtual size_t write(uint8_t);
@ -116,14 +166,47 @@ class Adafruit_GFX : public Print {
virtual void write(uint8_t); virtual void write(uint8_t);
#endif #endif
int16_t height(void) const; /************************************************************************/
int16_t width(void) const; /*!
@brief Get width of the display, accounting for current rotation
@returns Width in pixels
*/
/************************************************************************/
int16_t width(void) const { return _width; };
uint8_t getRotation(void) const; /************************************************************************/
/*!
@brief Get height of the display, accounting for current rotation
@returns Height in pixels
*/
/************************************************************************/
int16_t height(void) const { return _height; }
// get current cursor position (get rotation safe maximum values, using: width() for x, height() for y) /************************************************************************/
int16_t getCursorX(void) const; /*!
int16_t getCursorY(void) const; @brief Get rotation setting for display
@returns 0 thru 3 corresponding to 4 cardinal rotations
*/
/************************************************************************/
uint8_t getRotation(void) const { return rotation; }
// get current cursor position (get rotation safe maximum values,
// using: width() for x, height() for y)
/************************************************************************/
/*!
@brief Get text cursor X location
@returns X coordinate in pixels
*/
/************************************************************************/
int16_t getCursorX(void) const { return cursor_x; }
/************************************************************************/
/*!
@brief Get text cursor Y location
@returns Y coordinate in pixels
*/
/************************************************************************/
int16_t getCursorY(void) const { return cursor_y; };
protected: protected:
void void
@ -167,11 +250,25 @@ class Adafruit_GFX_Button {
void drawButton(boolean inverted = false); void drawButton(boolean inverted = false);
boolean contains(int16_t x, int16_t y); boolean contains(int16_t x, int16_t y);
void press(boolean p); /**********************************************************************/
boolean isPressed(); /*!
@brief Sets button state, should be done by some touch function
@param p True for pressed, false for not.
*/
/**********************************************************************/
void press(boolean p) { laststate = currstate; currstate = p; }
boolean justPressed(); boolean justPressed();
boolean justReleased(); boolean justReleased();
/**********************************************************************/
/*!
@brief Query whether the button is currently pressed
@returns True if pressed
*/
/**********************************************************************/
boolean isPressed(void) { return currstate; };
private: private:
Adafruit_GFX *_gfx; Adafruit_GFX *_gfx;
int16_t _x1, _y1; // Coordinates of top-left corner int16_t _x1, _y1; // Coordinates of top-left corner
@ -191,7 +288,13 @@ class GFXcanvas1 : public Adafruit_GFX {
~GFXcanvas1(void); ~GFXcanvas1(void);
void drawPixel(int16_t x, int16_t y, uint16_t color), void drawPixel(int16_t x, int16_t y, uint16_t color),
fillScreen(uint16_t color); fillScreen(uint16_t color);
uint8_t *getBuffer(void); /**********************************************************************/
/*!
@brief Get a pointer to the internal buffer memory
@returns A pointer to the allocated buffer
*/
/**********************************************************************/
uint8_t *getBuffer(void) const { return buffer; }
private: private:
uint8_t *buffer; uint8_t *buffer;
}; };
@ -205,8 +308,13 @@ class GFXcanvas8 : public Adafruit_GFX {
void drawPixel(int16_t x, int16_t y, uint16_t color), void drawPixel(int16_t x, int16_t y, uint16_t color),
fillScreen(uint16_t color), fillScreen(uint16_t color),
writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
/**********************************************************************/
uint8_t *getBuffer(void); /*!
@brief Get a pointer to the internal buffer memory
@returns A pointer to the allocated buffer
*/
/**********************************************************************/
uint8_t *getBuffer(void) const { return buffer; }
private: private:
uint8_t *buffer; uint8_t *buffer;
}; };
@ -218,8 +326,15 @@ class GFXcanvas16 : public Adafruit_GFX {
GFXcanvas16(uint16_t w, uint16_t h); GFXcanvas16(uint16_t w, uint16_t h);
~GFXcanvas16(void); ~GFXcanvas16(void);
void drawPixel(int16_t x, int16_t y, uint16_t color), void drawPixel(int16_t x, int16_t y, uint16_t color),
fillScreen(uint16_t color); fillScreen(uint16_t color),
uint16_t *getBuffer(void); byteSwap(void);
/**********************************************************************/
/*!
@brief Get a pointer to the internal buffer memory
@returns A pointer to the allocated buffer
*/
/**********************************************************************/
uint16_t *getBuffer(void) const { return buffer; }
private: private:
uint16_t *buffer; uint16_t *buffer;
}; };

View File

@ -496,16 +496,21 @@ Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, tftBusWidth busWidth,
/*! /*!
@brief Configure microcontroller pins for TFT interfacing. Typically @brief Configure microcontroller pins for TFT interfacing. Typically
called by a subclass' begin() function. called by a subclass' begin() function.
@param freq SPI frequency when using hardware SPI. If default (0) @param freq SPI frequency when using hardware SPI. If default (0)
is passed, will fall back on a device-specific value. is passed, will fall back on a device-specific value.
Value is ignored when using software SPI or parallel Value is ignored when using software SPI or parallel
connection. connection.
@param spiMode SPI mode when using hardware SPI. MUST be one of the
values SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3
defined in SPI.h. Do NOT attempt to pass '0' for
SPI_MODE0 and so forth...the values are NOT the same!
Use ONLY the defines! (Pity it's not an enum.)
@note Another anachronistically-named function; this is called even @note Another anachronistically-named function; this is called even
when the display connection is parallel (not SPI). Also, this when the display connection is parallel (not SPI). Also, this
could probably be made private...quite a few class functions could probably be made private...quite a few class functions
were generously put in the public section. were generously put in the public section.
*/ */
void Adafruit_SPITFT::initSPI(uint32_t freq) { void Adafruit_SPITFT::initSPI(uint32_t freq, uint8_t spiMode) {
if(!freq) freq = DEFAULT_SPI_FREQ; // If no freq specified, use default if(!freq) freq = DEFAULT_SPI_FREQ; // If no freq specified, use default
@ -520,10 +525,11 @@ void Adafruit_SPITFT::initSPI(uint32_t freq) {
if(connection == TFT_HARD_SPI) { if(connection == TFT_HARD_SPI) {
#if defined(SPI_HAS_TRANSACTION) #if defined(SPI_HAS_TRANSACTION)
hwspi.settings = SPISettings(freq, MSBFIRST, SPI_MODE0); hwspi.settings = SPISettings(freq, MSBFIRST, spiMode);
#else #else
hwspi._freq = freq; // Save freq value for later hwspi._freq = freq; // Save freq value for later
#endif #endif
hwspi._mode = spiMode; // Save spiMode value for later
// Call hwspi._spi->begin() ONLY if this is among the 'established' // Call hwspi._spi->begin() ONLY if this is among the 'established'
// SPI interfaces in variant.h. For DIY roll-your-own SERCOM SPIs, // SPI interfaces in variant.h. For DIY roll-your-own SERCOM SPIs,
// begin() and pinPeripheral() calls MUST be made in one's calling // begin() and pinPeripheral() calls MUST be made in one's calling
@ -1024,14 +1030,14 @@ void Adafruit_SPITFT::writePixels(uint16_t *colors, uint32_t len,
lastFillLen = 0; lastFillLen = 0;
if(block) { if(block) {
while(dma_busy); // Wait for last line to complete while(dma_busy); // Wait for last line to complete
#if defined(__SAMD51__) #if defined(__SAMD51__) || defined(_SAMD21_)
if(connection == TFT_HARD_SPI) { if(connection == TFT_HARD_SPI) {
// See SAMD51 note in writeColor() // See SAMD51/21 note in writeColor()
hwspi._spi->setDataMode(SPI_MODE0); hwspi._spi->setDataMode(hwspi._mode);
} else { } else {
pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO
} }
#endif // end __SAMD51__ #endif // end __SAMD51__ || _SAMD21_
} }
return; return;
} }
@ -1053,14 +1059,14 @@ void Adafruit_SPITFT::writePixels(uint16_t *colors, uint32_t len,
void Adafruit_SPITFT::dmaWait(void) { void Adafruit_SPITFT::dmaWait(void) {
#if defined(USE_SPI_DMA) #if defined(USE_SPI_DMA)
while(dma_busy); while(dma_busy);
#if defined(__SAMD51__) #if defined(__SAMD51__) || defined(_SAMD21_)
if(connection == TFT_HARD_SPI) { if(connection == TFT_HARD_SPI) {
// See SAMD51 note in writeColor() // See SAMD51/21 note in writeColor()
hwspi._spi->setDataMode(SPI_MODE0); hwspi._spi->setDataMode(hwspi._mode);
} else { } else {
pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO
} }
#endif // end __SAMD51__ #endif // end __SAMD51__ || _SAMD21_
#endif #endif
} }
@ -1176,11 +1182,13 @@ void Adafruit_SPITFT::writeColor(uint16_t color, uint32_t len) {
// turns out to be MUCH slower on many graphics operations (as when // turns out to be MUCH slower on many graphics operations (as when
// drawing lines, pixel-by-pixel), perhaps because it's a volatile // drawing lines, pixel-by-pixel), perhaps because it's a volatile
// type and doesn't cache. Working on this. // type and doesn't cache. Working on this.
#if defined(__SAMD51__) #if defined(__SAMD51__) || defined(_SAMD21_)
if(connection == TFT_HARD_SPI) { if(connection == TFT_HARD_SPI) {
// SAMD51: SPI DMA seems to leave the SPI peripheral in a freaky // SAMD51: SPI DMA seems to leave the SPI peripheral in a freaky
// state on completion. Workaround is to explicitly set it back... // state on completion. Workaround is to explicitly set it back...
hwspi._spi->setDataMode(SPI_MODE0); // (5/17/2019: apparently SAMD21 too, in certain cases, observed
// with ST7789 display.)
hwspi._spi->setDataMode(hwspi._mode);
} else { } else {
pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO
} }
@ -1782,7 +1790,7 @@ inline void Adafruit_SPITFT::SPI_BEGIN_TRANSACTION(void) {
hwspi._spi->setClock(hwspi._freq); hwspi._spi->setClock(hwspi._freq);
#endif #endif
hwspi._spi->setBitOrder(MSBFIRST); hwspi._spi->setBitOrder(MSBFIRST);
hwspi._spi->setDataMode(SPI_MODE0); hwspi._spi->setDataMode(hwspi._mode);
#endif // end !SPI_HAS_TRANSACTION #endif // end !SPI_HAS_TRANSACTION
} }
} }

View File

@ -66,7 +66,7 @@ typedef volatile PORT_t* PORTreg_t; ///< PORT register type
#define DEFAULT_SPI_FREQ 16000000L ///< Hardware SPI default speed #define DEFAULT_SPI_FREQ 16000000L ///< Hardware SPI default speed
#endif #endif
#if defined(ADAFRUIT_PYPORTAL) #if defined(ADAFRUIT_PYPORTAL) || defined(ADAFRUIT_PYBADGE_M4_EXPRESS) || defined(ADAFRUIT_PYGAMER_M4_EXPRESS)
#define USE_SPI_DMA ///< Auto DMA if using PyPortal #define USE_SPI_DMA ///< Auto DMA if using PyPortal
#else #else
//#define USE_SPI_DMA ///< If set, use DMA if available //#define USE_SPI_DMA ///< If set, use DMA if available
@ -181,8 +181,11 @@ class Adafruit_SPITFT : public Adafruit_GFX {
// Brief comments here...documented more thoroughly in .cpp file. // Brief comments here...documented more thoroughly in .cpp file.
// Subclass' begin() function invokes this to initialize hardware. // Subclass' begin() function invokes this to initialize hardware.
// freq=0 to use default SPI speed. spiMode must be one of the SPI_MODEn
// values defined in SPI.h, which are NOT the same as 0 for SPI_MODE0,
// 1 for SPI_MODE1, etc...use ONLY the SPI_MODEn defines! Only!
// Name is outdated (interface may be parallel) but for compatibility: // Name is outdated (interface may be parallel) but for compatibility:
void initSPI(uint32_t freq = 0); // 0 = use default SPI speed void initSPI(uint32_t freq = 0, uint8_t spiMode = SPI_MODE0);
// Chip select and/or hardware SPI transaction start as needed: // Chip select and/or hardware SPI transaction start as needed:
void startWrite(void); void startWrite(void);
// Chip deselect and/or hardware SPI transaction end as needed: // Chip deselect and/or hardware SPI transaction end as needed:
@ -393,6 +396,7 @@ class Adafruit_SPITFT : public Adafruit_GFX {
#else #else
uint32_t _freq; ///< SPI bitrate (if no SPI transactions) uint32_t _freq; ///< SPI bitrate (if no SPI transactions)
#endif #endif
uint32_t _mode; ///< SPI data mode (transactions or no)
} hwspi; ///< Hardware SPI values } hwspi; ///< Hardware SPI values
struct { // Values specific to SOFTWARE SPI: struct { // Values specific to SOFTWARE SPI:
#if defined(USE_FAST_PINIO) #if defined(USE_FAST_PINIO)

View File

@ -1,5 +1,5 @@
name=Adafruit GFX Library name=Adafruit GFX Library
version=1.5.0 version=1.5.3
author=Adafruit author=Adafruit
maintainer=Adafruit <info@adafruit.com> maintainer=Adafruit <info@adafruit.com>
sentence=Adafruit GFX graphics core library, this is the 'core' class that all our other graphics libraries derive from. sentence=Adafruit GFX graphics core library, this is the 'core' class that all our other graphics libraries derive from.