ssd1322_v1
This commit is contained in:
554
yoRadio/src/SSD1322/SSD1322.cpp
Normal file
554
yoRadio/src/SSD1322/SSD1322.cpp
Normal file
@@ -0,0 +1,554 @@
|
|||||||
|
/*!
|
||||||
|
* @file Jamis_SSD1322.h
|
||||||
|
*
|
||||||
|
* This is a partial port of Adafruit's SSD1306 library to the SSD1322
|
||||||
|
* display.
|
||||||
|
*
|
||||||
|
* These displays use SPI to communicate. SPI requires 4 pins (MOSI, SCK,
|
||||||
|
* select, data/command) and optionally a reset pin.
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Written by Limor Fried/Ladyada for Adafruit Industries, with
|
||||||
|
* contributions from the open source community.
|
||||||
|
*
|
||||||
|
* BSD license, all text above, and the splash screen header file,
|
||||||
|
* must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "../core/options.h"
|
||||||
|
#if DSP_MODEL==DSP_SSD1322
|
||||||
|
|
||||||
|
|
||||||
|
#define pgm_read_byte(addr) \
|
||||||
|
(*(const unsigned char *)(addr)) ///< PROGMEM workaround for non-AVR
|
||||||
|
|
||||||
|
#include <Adafruit_GFX.h>
|
||||||
|
#include "SSD1322.h"
|
||||||
|
//#include "splash.h"
|
||||||
|
|
||||||
|
#define ssd1322_swap(a, b) \
|
||||||
|
(((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) ///< No-temp-var swap operation
|
||||||
|
|
||||||
|
#define SSD1322_SELECT digitalWrite(csPin, LOW); ///< Device select
|
||||||
|
#define SSD1322_DESELECT digitalWrite(csPin, HIGH); ///< Device deselect
|
||||||
|
#define SSD1322_MODE_COMMAND digitalWrite(dcPin, LOW); ///< Command mode
|
||||||
|
#define SSD1322_MODE_DATA digitalWrite(dcPin, HIGH); ///< Data mode
|
||||||
|
|
||||||
|
#if defined(SPI_HAS_TRANSACTION)
|
||||||
|
#define SPI_TRANSACTION_START spi->beginTransaction(spiSettings) ///< Pre-SPI
|
||||||
|
#define SPI_TRANSACTION_END spi->endTransaction() ///< Post-SPI
|
||||||
|
#else // SPI transactions likewise not present in older Arduino SPI lib
|
||||||
|
#define SPI_TRANSACTION_START ///< Dummy stand-in define
|
||||||
|
#define SPI_TRANSACTION_END ///< keeps compiler happy
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TRANSACTION_START \
|
||||||
|
if(spi) { \
|
||||||
|
SPI_TRANSACTION_START; \
|
||||||
|
} \
|
||||||
|
SSD1322_SELECT;
|
||||||
|
#define TRANSACTION_END \
|
||||||
|
SSD1322_DESELECT; \
|
||||||
|
if(spi) { \
|
||||||
|
SPI_TRANSACTION_END; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Constructor for SPI SSD1306 displays, using native hardware SPI.
|
||||||
|
@param w
|
||||||
|
Display width in pixels
|
||||||
|
@param h
|
||||||
|
Display height in pixels
|
||||||
|
@param spi
|
||||||
|
Pointer to an existing SPIClass instance (e.g. &SPI, the
|
||||||
|
microcontroller's primary SPI bus).
|
||||||
|
@param dc_pin
|
||||||
|
Data/command pin (using Arduino pin numbering), selects whether
|
||||||
|
display is receiving commands (low) or data (high).
|
||||||
|
@param rst_pin
|
||||||
|
Reset pin (using Arduino pin numbering), or -1 if not used
|
||||||
|
(some displays might be wired to share the microcontroller's
|
||||||
|
reset pin).
|
||||||
|
@param cs_pin
|
||||||
|
Chip-select pin (using Arduino pin numbering) for sharing the
|
||||||
|
bus with other devices. Active low.
|
||||||
|
@param bitrate
|
||||||
|
SPI clock rate for transfers to this display. Default if
|
||||||
|
unspecified is 8000000UL (8 MHz).
|
||||||
|
@return Jamis_SSD1322 object.
|
||||||
|
@note Call the object's begin() function before use -- buffer
|
||||||
|
allocation is performed there!
|
||||||
|
*/
|
||||||
|
Jamis_SSD1322::Jamis_SSD1322(int16_t w, int16_t h, SPIClass *spi,
|
||||||
|
int8_t dc_pin, int8_t rst_pin, int8_t cs_pin, uint32_t bitrate) :
|
||||||
|
Adafruit_GFX(w, h), spi(spi ? spi : &SPI), buffer(NULL),
|
||||||
|
mosiPin(-1), clkPin(-1), dcPin(dc_pin), csPin(cs_pin), rstPin(rst_pin) {
|
||||||
|
#ifdef SPI_HAS_TRANSACTION
|
||||||
|
spiSettings = SPISettings(bitrate, MSBFIRST, SPI_MODE3);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Destructor for Jamis_SSD1322 object.
|
||||||
|
*/
|
||||||
|
Jamis_SSD1322::~Jamis_SSD1322(void) {
|
||||||
|
if(buffer) {
|
||||||
|
free(buffer);
|
||||||
|
buffer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LOW-LEVEL UTILS ---------------------------------------------------------
|
||||||
|
|
||||||
|
// Issue single byte out SPI, either soft or hardware as appropriate.
|
||||||
|
// SPI transaction/selection must be performed in calling function.
|
||||||
|
inline void Jamis_SSD1322::SPIwrite(uint8_t d) {
|
||||||
|
spi->transfer(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Issue single command to SSD1322, using hard SPI.
|
||||||
|
// Because command calls are often grouped, SPI transaction and selection
|
||||||
|
// must be started/ended in calling function for efficiency.
|
||||||
|
// This is a private function, not exposed (see ssd1322_command() instead).
|
||||||
|
void Jamis_SSD1322::ssd1322_command1(uint8_t c) {
|
||||||
|
SSD1322_MODE_COMMAND
|
||||||
|
SPIwrite(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Issue single byte of data out SPI.
|
||||||
|
void Jamis_SSD1322::ssd1322_data1(uint8_t c) {
|
||||||
|
SSD1322_MODE_DATA
|
||||||
|
SPIwrite(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// A public version of ssd1322_command1(), for existing user code that
|
||||||
|
// might rely on that function. This encapsulates the command transfer
|
||||||
|
// in a transaction start/end, similar to old library's handling of it.
|
||||||
|
/*!
|
||||||
|
@brief Issue a single low-level command directly to the SSD1306
|
||||||
|
display, bypassing the library.
|
||||||
|
@param c
|
||||||
|
Command to issue (0x00 to 0xFF, see datasheet).
|
||||||
|
@return None (void).
|
||||||
|
*/
|
||||||
|
void Jamis_SSD1322::ssd1322_command(uint8_t c) {
|
||||||
|
TRANSACTION_START
|
||||||
|
ssd1322_command1(c);
|
||||||
|
TRANSACTION_END
|
||||||
|
}
|
||||||
|
|
||||||
|
// ALLOCATE & INIT DISPLAY -------------------------------------------------
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Allocate RAM for image buffer, initialize peripherals and pins.
|
||||||
|
@param reset
|
||||||
|
If true, and if the reset pin passed to the constructor is
|
||||||
|
valid, a hard reset will be performed before initializing the
|
||||||
|
display. If using multiple SSD1322 displays on the same bus, and
|
||||||
|
if they all share the same reset pin, you should only pass true
|
||||||
|
on the first display being initialized, false on all others,
|
||||||
|
else the already-initialized displays would be reset. Default if
|
||||||
|
unspecified is true.
|
||||||
|
@param periphBegin
|
||||||
|
If true, and if a hardware peripheral is being used (I2C or SPI,
|
||||||
|
but not software SPI), call that peripheral's begin() function,
|
||||||
|
else (false) it has already been done in one's sketch code.
|
||||||
|
Cases where false might be used include multiple displays or
|
||||||
|
other devices sharing a common bus, or situations on some
|
||||||
|
platforms where a nonstandard begin() function is available
|
||||||
|
(e.g. a TwoWire interface on non-default pins, as can be done
|
||||||
|
on the ESP8266 and perhaps others).
|
||||||
|
@return true on successful allocation/init, false otherwise.
|
||||||
|
Well-behaved code should check the return value before
|
||||||
|
proceeding.
|
||||||
|
@note MUST call this function before any drawing or updates!
|
||||||
|
*/
|
||||||
|
boolean Jamis_SSD1322::begin(boolean reset, boolean periphBegin) {
|
||||||
|
// Note: The SSD1322 has 4 bit grayscale color.
|
||||||
|
if((!buffer) && !(buffer = (uint8_t *)malloc( WIDTH * ((HEIGHT) / 2) )))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
clearDisplay();
|
||||||
|
|
||||||
|
|
||||||
|
// Setup pin directions
|
||||||
|
pinMode(dcPin, OUTPUT); // Set data/command pin as output
|
||||||
|
pinMode(csPin, OUTPUT); // Same for chip select
|
||||||
|
SSD1322_DESELECT
|
||||||
|
|
||||||
|
// SPI peripheral begin same as wire check above.
|
||||||
|
if(periphBegin) spi->begin();
|
||||||
|
|
||||||
|
// Reset SSD1322 if requested and reset pin specified in constructor
|
||||||
|
if(reset && (rstPin >= 0)) {
|
||||||
|
pinMode( rstPin, OUTPUT);
|
||||||
|
digitalWrite(rstPin, HIGH);
|
||||||
|
delay(1); // VDD goes high at start, pause for 1 ms
|
||||||
|
digitalWrite(rstPin, LOW); // Bring reset low
|
||||||
|
delay(10); // Wait 10 ms
|
||||||
|
digitalWrite(rstPin, HIGH); // Bring out of reset
|
||||||
|
}
|
||||||
|
|
||||||
|
TRANSACTION_START
|
||||||
|
|
||||||
|
ssd1322_command1(0xFD); // Set Command Lock (MCU protection status)
|
||||||
|
ssd1322_data1(0x12); // 0x12 = Unlock Basic Commands; 0x16 = lock
|
||||||
|
|
||||||
|
ssd1322_command1(0xA4); // Set Display Mode = OFF
|
||||||
|
|
||||||
|
ssd1322_command1(0xB3); // Set Front Clock Divider / Oscillator Frequency
|
||||||
|
ssd1322_data1(0x91); // 0x91 = 80FPS; 0xD0 = default / 1100b
|
||||||
|
|
||||||
|
ssd1322_command1(0xCA); // Set MUX Ratio
|
||||||
|
ssd1322_data1(0x3F); // 0x3F = 63d = 64MUX (1/64 duty cycle)
|
||||||
|
|
||||||
|
ssd1322_command1(0xA2); // Set Display Offset
|
||||||
|
ssd1322_data1(0x00); // 0x00 = (default)
|
||||||
|
|
||||||
|
ssd1322_command1(0xA1); // Set Display Start Line
|
||||||
|
ssd1322_data1(0x00); // 0x00 = register 00h
|
||||||
|
|
||||||
|
ssd1322_command1(0xA0); // Set Re-map and Dual COM Line mode
|
||||||
|
ssd1322_data1(0x14); // 0x14 = Default except Enable Nibble Re-map, Scan from COM[N-1] to COM0, where N is the Multiplex ratio
|
||||||
|
ssd1322_data1(0x11); // 0x11 = Enable Dual COM mode (MUX <= 63)
|
||||||
|
|
||||||
|
ssd1322_command1(0xB5); // Set GPIO
|
||||||
|
ssd1322_data1(0x00); // 0x00 = {GPIO0, GPIO1 = HiZ (Input Disabled)}
|
||||||
|
|
||||||
|
ssd1322_command1(0xAB); // Function Selection
|
||||||
|
ssd1322_data1(0x01); // 0x01 = Enable internal VDD regulator (default)
|
||||||
|
|
||||||
|
ssd1322_command1(0xB4); // Display Enhancement A
|
||||||
|
ssd1322_data1(0xA0); // 0xA0 = Enable external VSL; 0xA2 = internal VSL
|
||||||
|
ssd1322_data1(0xB5); // 0xB5 = Normal (default); 0xFD = 11111101b = Enhanced low GS display quality
|
||||||
|
|
||||||
|
ssd1322_command1(0xC1); // Set Contrast Current
|
||||||
|
ssd1322_data1(0x7F); // 0x7F = (default)
|
||||||
|
|
||||||
|
ssd1322_command1(0xC7); // Master Contrast Current Control
|
||||||
|
ssd1322_data1(0x0F); // 0x0F = (default)
|
||||||
|
|
||||||
|
ssd1322_command1(0xB9); // Select Default Linear Gray Scale table
|
||||||
|
|
||||||
|
// ssd1322_command1(0xB8); // Select Custom Gray Scale table (GS0 = 0)
|
||||||
|
// ssd1322_command1(0x00); // GS1
|
||||||
|
// ssd1322_command1(0x08); // GS2
|
||||||
|
// ssd1322_command1(0x10); // GS3
|
||||||
|
// ssd1322_command1(0x18); // GS4
|
||||||
|
// ssd1322_command1(0x20); // GS5
|
||||||
|
// ssd1322_command1(0x28); // GS6
|
||||||
|
// ssd1322_command1(0x30); // GS7
|
||||||
|
// ssd1322_command1(0x38); // GS8
|
||||||
|
// ssd1322_command1(0x40); // GS9
|
||||||
|
// ssd1322_command1(0x48); // GS10
|
||||||
|
// ssd1322_command1(0x50); // GS11
|
||||||
|
// ssd1322_command1(0x58); // GS12
|
||||||
|
// ssd1322_command1(0x60); // GS13
|
||||||
|
// ssd1322_command1(0x68); // GS14
|
||||||
|
// ssd1322_command1(0x70); // GS15
|
||||||
|
// ssd1322_command1(0x00); // Enable Custom Gray Scale table
|
||||||
|
|
||||||
|
ssd1322_command1(0xB1); // Set Phase Length
|
||||||
|
ssd1322_data1(0xE2); // 0xE2 = Phase 1 period (reset phase length) = 5 DCLKs,
|
||||||
|
// Phase 2 period (first pre-charge phase length) = 14 DCLKs
|
||||||
|
|
||||||
|
ssd1322_command1(0xD1); // Display Enhancement B
|
||||||
|
ssd1322_data1(0xA2); // 0xA2 = Normal (default); 0x82 = reserved
|
||||||
|
ssd1322_data1(0x20); // 0x20 = as-is
|
||||||
|
|
||||||
|
ssd1322_command1(0xBB); // Set Pre-charge voltage
|
||||||
|
ssd1322_data1(0x1F); // 0x17 = default; 0x1F = 0.60*Vcc (spec example)
|
||||||
|
|
||||||
|
ssd1322_command1(0xB6); // Set Second Precharge Period
|
||||||
|
ssd1322_data1(0x08); // 0x08 = 8 dclks (default)
|
||||||
|
|
||||||
|
ssd1322_command1(0xBE); // Set VCOMH
|
||||||
|
ssd1322_data1(0x07); // 0x04 = 0.80*Vcc (default); 0x07 = 0.86*Vcc (spec example)
|
||||||
|
|
||||||
|
ssd1322_command1(0xA6); // Set Display Mode = Normal Display
|
||||||
|
|
||||||
|
ssd1322_command1(0xA9); // Exit Partial Display
|
||||||
|
|
||||||
|
ssd1322_command1(0xAF); // Set Sleep mode OFF (Display ON)
|
||||||
|
|
||||||
|
TRANSACTION_END
|
||||||
|
|
||||||
|
return true; // Success
|
||||||
|
}
|
||||||
|
|
||||||
|
// DRAWING FUNCTIONS -------------------------------------------------------
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Set/clear/invert a single pixel. This is also invoked by the
|
||||||
|
Adafruit_GFX library in generating many higher-level graphics
|
||||||
|
primitives.
|
||||||
|
@param x
|
||||||
|
Column of display -- 0 at left to (screen width - 1) at right.
|
||||||
|
@param y
|
||||||
|
Row of display -- 0 at top to (screen height -1) at bottom.
|
||||||
|
@param color
|
||||||
|
Pixel color, one of: BLACK, WHITE or INVERT.
|
||||||
|
@return None (void).
|
||||||
|
@note Changes buffer contents only, no immediate effect on display.
|
||||||
|
Follow up with a call to display(), or with other graphics
|
||||||
|
commands as needed by one's own application.
|
||||||
|
*/
|
||||||
|
void Jamis_SSD1322::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
||||||
|
if((x >= 0) && (x < width()) && (y >= 0) && (y < height())) {
|
||||||
|
// Pixel is in-bounds. Rotate coordinates if needed.
|
||||||
|
switch(getRotation()) {
|
||||||
|
case 1:
|
||||||
|
ssd1322_swap(x, y);
|
||||||
|
x = WIDTH - x - 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
x = WIDTH - x - 1;
|
||||||
|
y = HEIGHT - y - 1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ssd1322_swap(x, y);
|
||||||
|
y = HEIGHT - y - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buffer[(x >> 1) + (y)*WIDTH/2] &= (x % 2) ? 0xF0 : 0x0F;
|
||||||
|
buffer[(x >> 1) + (y)*WIDTH/2] |= (color << (!(x & 1) * 4) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Clear contents of display buffer (set all pixels to off).
|
||||||
|
@return None (void).
|
||||||
|
@note Changes buffer contents only, no immediate effect on display.
|
||||||
|
Follow up with a call to display(), or with other graphics
|
||||||
|
commands as needed by one's own application.
|
||||||
|
*/
|
||||||
|
void Jamis_SSD1322::clearDisplay(void) {
|
||||||
|
memset(buffer, 0, WIDTH * ((HEIGHT) / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Draw a horizontal line. This is also invoked by the Adafruit_GFX
|
||||||
|
library in generating many higher-level graphics primitives.
|
||||||
|
@param x
|
||||||
|
Leftmost column -- 0 at left to (screen width - 1) at right.
|
||||||
|
@param y
|
||||||
|
Row of display -- 0 at top to (screen height -1) at bottom.
|
||||||
|
@param w
|
||||||
|
Width of line, in pixels.
|
||||||
|
@param color
|
||||||
|
Line color, one of: BLACK, WHITE or INVERT.
|
||||||
|
@return None (void).
|
||||||
|
@note Changes buffer contents only, no immediate effect on display.
|
||||||
|
Follow up with a call to display(), or with other graphics
|
||||||
|
commands as needed by one's own application.
|
||||||
|
*/
|
||||||
|
void Jamis_SSD1322::drawFastHLine(
|
||||||
|
int16_t x, int16_t y, int16_t w, uint16_t color) {
|
||||||
|
boolean bSwap = false;
|
||||||
|
switch(rotation) {
|
||||||
|
case 1:
|
||||||
|
// 90 degree rotation, swap x & y for rotation, then invert x
|
||||||
|
bSwap = true;
|
||||||
|
ssd1322_swap(x, y);
|
||||||
|
x = WIDTH - x - 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
// 180 degree rotation, invert x and y, then shift y around for height.
|
||||||
|
x = WIDTH - x - 1;
|
||||||
|
y = HEIGHT - y - 1;
|
||||||
|
x -= (w-1);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
// 270 degree rotation, swap x & y for rotation,
|
||||||
|
// then invert y and adjust y for w (not to become h)
|
||||||
|
bSwap = true;
|
||||||
|
ssd1322_swap(x, y);
|
||||||
|
y = HEIGHT - y - 1;
|
||||||
|
y -= (w-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bSwap) drawFastVLineInternal(x, y, w, color);
|
||||||
|
else drawFastHLineInternal(x, y, w, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jamis_SSD1322::drawFastHLineInternal(
|
||||||
|
int16_t x, int16_t y, int16_t w, uint16_t color) {
|
||||||
|
|
||||||
|
if((y >= 0) && (y < HEIGHT)) { // Y coord in bounds?
|
||||||
|
if(x < 0) { // Clip left
|
||||||
|
w += x;
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
if((x + w) > WIDTH) { // Clip right
|
||||||
|
w = (WIDTH - x);
|
||||||
|
}
|
||||||
|
if(w > 0) { // Proceed only if width is positive
|
||||||
|
// NOTE: This is _not_ fast. But with 4bit packing, I just want this done.
|
||||||
|
uint16_t yOffset = (y)*WIDTH/2;
|
||||||
|
uint8_t b1 = (x % 2) ? 0xF0 : 0x0F;
|
||||||
|
while(w--) {
|
||||||
|
buffer[((x + w) >> 1) + yOffset] &= b1;
|
||||||
|
buffer[((x + w) >> 1) + yOffset] |= (color << (!((x + w) & 1) * 4) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Draw a vertical line. This is also invoked by the Adafruit_GFX
|
||||||
|
library in generating many higher-level graphics primitives.
|
||||||
|
@param x
|
||||||
|
Column of display -- 0 at left to (screen width -1) at right.
|
||||||
|
@param y
|
||||||
|
Topmost row -- 0 at top to (screen height - 1) at bottom.
|
||||||
|
@param h
|
||||||
|
Height of line, in pixels.
|
||||||
|
@param color
|
||||||
|
Line color, one of: BLACK, WHITE or INVERT.
|
||||||
|
@return None (void).
|
||||||
|
@note Changes buffer contents only, no immediate effect on display.
|
||||||
|
Follow up with a call to display(), or with other graphics
|
||||||
|
commands as needed by one's own application.
|
||||||
|
*/
|
||||||
|
void Jamis_SSD1322::drawFastVLine(
|
||||||
|
int16_t x, int16_t y, int16_t h, uint16_t color) {
|
||||||
|
boolean bSwap = false;
|
||||||
|
switch(rotation) {
|
||||||
|
case 1:
|
||||||
|
// 90 degree rotation, swap x & y for rotation,
|
||||||
|
// then invert x and adjust x for h (now to become w)
|
||||||
|
bSwap = true;
|
||||||
|
ssd1322_swap(x, y);
|
||||||
|
x = WIDTH - x - 1;
|
||||||
|
x -= (h-1);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
// 180 degree rotation, invert x and y, then shift y around for height.
|
||||||
|
x = WIDTH - x - 1;
|
||||||
|
y = HEIGHT - y - 1;
|
||||||
|
y -= (h-1);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
// 270 degree rotation, swap x & y for rotation, then invert y
|
||||||
|
bSwap = true;
|
||||||
|
ssd1322_swap(x, y);
|
||||||
|
y = HEIGHT - y - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bSwap) drawFastHLineInternal(x, y, h, color);
|
||||||
|
else drawFastVLineInternal(x, y, h, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jamis_SSD1322::drawFastVLineInternal(
|
||||||
|
int16_t x, int16_t __y, int16_t __h, uint16_t color) {
|
||||||
|
|
||||||
|
if((x >= 0) && (x < WIDTH)) { // X coord in bounds?
|
||||||
|
if(__y < 0) { // Clip top
|
||||||
|
__h += __y;
|
||||||
|
__y = 0;
|
||||||
|
}
|
||||||
|
if((__y + __h) > HEIGHT) { // Clip bottom
|
||||||
|
__h = (HEIGHT - __y);
|
||||||
|
}
|
||||||
|
if(__h > 0) { // Proceed only if height is now positive
|
||||||
|
|
||||||
|
//buffer[((x + w) >> 1) + yOffset] |= (color << (!(w & 1) * 4) );
|
||||||
|
uint16_t xOffset = (x >> 1);
|
||||||
|
uint16_t mask = (color << (!(x & 1) * 4) );
|
||||||
|
uint8_t b1 = (x % 2) ? 0xF0 : 0x0F;
|
||||||
|
while(__h--) {
|
||||||
|
//Serial.printf("xOffset + (__y+__h)*WIDTH/2=%d, WIDTH=%d\n", xOffset + (__y+__h)*WIDTH/2, WIDTH);
|
||||||
|
buffer[xOffset + (__y+__h)*WIDTH/2] &= b1;
|
||||||
|
buffer[xOffset + (__y+__h)*WIDTH/2] |= mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // endif positive height
|
||||||
|
} // endif x in bounds
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Return color of a single pixel in display buffer.
|
||||||
|
@param x
|
||||||
|
Column of display -- 0 at left to (screen width - 1) at right.
|
||||||
|
@param y
|
||||||
|
Row of display -- 0 at top to (screen height -1) at bottom.
|
||||||
|
@return true if pixel is set (usually WHITE, unless display invert mode
|
||||||
|
is enabled), false if clear (BLACK).
|
||||||
|
@note Reads from buffer contents; may not reflect current contents of
|
||||||
|
screen if display() has not been called.
|
||||||
|
*/
|
||||||
|
boolean Jamis_SSD1322::getPixel(int16_t x, int16_t y) {
|
||||||
|
if((x >= 0) && (x < width()) && (y >= 0) && (y < height())) {
|
||||||
|
// Pixel is in-bounds. Rotate coordinates if needed.
|
||||||
|
switch(getRotation()) {
|
||||||
|
case 1:
|
||||||
|
ssd1322_swap(x, y);
|
||||||
|
x = WIDTH - x - 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
x = WIDTH - x - 1;
|
||||||
|
y = HEIGHT - y - 1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ssd1322_swap(x, y);
|
||||||
|
y = HEIGHT - y - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (buffer[x + (y / 8) * WIDTH] & (1 << (y & 7)));
|
||||||
|
}
|
||||||
|
return false; // Pixel out of bounds
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Get base address of display buffer for direct reading or writing.
|
||||||
|
@return Pointer to an unsigned 8-bit array, column-major, columns padded
|
||||||
|
to full byte boundary if needed.
|
||||||
|
*/
|
||||||
|
uint8_t *Jamis_SSD1322::getBuffer(void) {
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// REFRESH DISPLAY ---------------------------------------------------------
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Push data currently in RAM to SSD1306 display.
|
||||||
|
@return None (void).
|
||||||
|
@note Drawing operations are not visible until this function is
|
||||||
|
called. Call after each graphics command, or after a whole set
|
||||||
|
of graphics commands, as best needed by one's own application.
|
||||||
|
*/
|
||||||
|
void Jamis_SSD1322::display(void) {
|
||||||
|
TRANSACTION_START
|
||||||
|
|
||||||
|
// Set column address: Set_Column_Address(0x00, MAXCOLS-1);
|
||||||
|
ssd1322_command1(0x15);
|
||||||
|
// Each Column address holds 4 horizontal pixels worth of data
|
||||||
|
const uint16_t Col0Off = 0x70;
|
||||||
|
const uint16_t ColDiv = 4;
|
||||||
|
ssd1322_data1( (Col0Off+0x00)/ColDiv );
|
||||||
|
ssd1322_data1( (Col0Off+WIDTH-1)/ColDiv );
|
||||||
|
|
||||||
|
// Set row address: Set_Row_Address(0x00, MAXROWS-1);
|
||||||
|
ssd1322_command1(0x75);
|
||||||
|
ssd1322_data1(0x00);
|
||||||
|
ssd1322_data1(HEIGHT-1);
|
||||||
|
|
||||||
|
// Enable writing into MCU RAM: Set_Write_RAM();
|
||||||
|
ssd1322_command1(0x5C);
|
||||||
|
|
||||||
|
uint16_t count = WIDTH * ((HEIGHT) / 2);
|
||||||
|
//Serial.printlnf("%i", count);
|
||||||
|
uint8_t *ptr = buffer;
|
||||||
|
SSD1322_MODE_DATA
|
||||||
|
while(count--) SPIwrite(*ptr++);
|
||||||
|
TRANSACTION_END
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //if DSP_MODEL==DSP_SSD1322
|
||||||
83
yoRadio/src/SSD1322/SSD1322.h
Normal file
83
yoRadio/src/SSD1322/SSD1322.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/*!
|
||||||
|
* @file Jamis_SSD1322.h
|
||||||
|
*
|
||||||
|
* This is a partial port of Adafruit's SSD1306 library to the SSD1322
|
||||||
|
* display.
|
||||||
|
*
|
||||||
|
* These displays use SPI to communicate. SPI requires 4 pins (MOSI, SCK,
|
||||||
|
* select, data/command) and optionally a reset pin.
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Written by Limor Fried/Ladyada for Adafruit Industries, with
|
||||||
|
* contributions from the open source community.
|
||||||
|
*
|
||||||
|
* BSD license, all text above, and the splash screen header file,
|
||||||
|
* must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _Jamis_SSD1322_H_
|
||||||
|
#define _Jamis_SSD1322_H_
|
||||||
|
|
||||||
|
#if defined(PARTICLE)
|
||||||
|
#include "Particle.h"
|
||||||
|
#define SPI_HAS_TRANSACTION
|
||||||
|
#define SPISettings __SPISettings
|
||||||
|
#define BUFFER_LENGTH 32
|
||||||
|
#else
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <Adafruit_GFX.h>
|
||||||
|
|
||||||
|
#define BLACK 0 ///< Draw 'off' pixels
|
||||||
|
#define WHITE 0xf ///< Draw 'on' pixels
|
||||||
|
#define INVERSE 2 ///< Invert pixels
|
||||||
|
|
||||||
|
#define SSD1322_DISPLAYOFF 0xAE
|
||||||
|
#define SSD1322_DISPLAYON 0xAF
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Class that stores state and functions for interacting with
|
||||||
|
SSD1322 OLED displays.
|
||||||
|
*/
|
||||||
|
class Jamis_SSD1322 : public Adafruit_GFX {
|
||||||
|
public:
|
||||||
|
Jamis_SSD1322(int16_t w, int16_t h, SPIClass *spi, int8_t dc_pin,
|
||||||
|
int8_t rst_pin, int8_t cs_pin, uint32_t bitrate=8000000UL);
|
||||||
|
|
||||||
|
~Jamis_SSD1322(void);
|
||||||
|
|
||||||
|
boolean begin(boolean reset=true, boolean periphBegin=true);
|
||||||
|
void display(void);
|
||||||
|
void clearDisplay(void);
|
||||||
|
void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||||
|
virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||||
|
virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||||
|
void ssd1322_command(uint8_t c);
|
||||||
|
boolean getPixel(int16_t x, int16_t y);
|
||||||
|
uint8_t *getBuffer(void);
|
||||||
|
void oled_command(uint8_t c) { ssd1322_command1(c); }
|
||||||
|
private:
|
||||||
|
inline void SPIwrite(uint8_t d) __attribute__((always_inline));
|
||||||
|
void drawFastHLineInternal(int16_t x, int16_t y, int16_t w,
|
||||||
|
uint16_t color);
|
||||||
|
void drawFastVLineInternal(int16_t x, int16_t y, int16_t h,
|
||||||
|
uint16_t color);
|
||||||
|
void ssd1322_command1(uint8_t c);
|
||||||
|
void ssd1322_data1(uint8_t c);
|
||||||
|
void ssd1322_commandList(const uint8_t *c, uint8_t n);
|
||||||
|
|
||||||
|
SPIClass *spi;
|
||||||
|
uint8_t *buffer;
|
||||||
|
int8_t mosiPin , clkPin , dcPin , csPin, rstPin;
|
||||||
|
#if defined(SPI_HAS_TRANSACTION)
|
||||||
|
SPISettings spiSettings;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _Jamis_SSD1322_H_
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef options_h
|
#ifndef options_h
|
||||||
#define options_h
|
#define options_h
|
||||||
|
|
||||||
#define YOVERSION "0.9.022"
|
#define YOVERSION "0.9.042"
|
||||||
|
|
||||||
/*******************************************************
|
/*******************************************************
|
||||||
DO NOT EDIT THIS FILE.
|
DO NOT EDIT THIS FILE.
|
||||||
@@ -48,6 +48,7 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
|
|||||||
#define DSP_GC9A01A 20 // 240x240 1.28' https://aliexpress.com/item/1005004069703494.html?sku_id=12000029869654615
|
#define DSP_GC9A01A 20 // 240x240 1.28' https://aliexpress.com/item/1005004069703494.html?sku_id=12000029869654615
|
||||||
#define DSP_ILI9488 21 // 480x320 3.5' https://aliexpress.com/item/1005001999296476.html?sku_id=12000018365356570
|
#define DSP_ILI9488 21 // 480x320 3.5' https://aliexpress.com/item/1005001999296476.html?sku_id=12000018365356570
|
||||||
#define DSP_ILI9486 22 // (Testing mode) 480x320 3.5' https://aliexpress.com/item/1005001999296476.html?sku_id=12000018365356568
|
#define DSP_ILI9486 22 // (Testing mode) 480x320 3.5' https://aliexpress.com/item/1005001999296476.html?sku_id=12000018365356568
|
||||||
|
#define DSP_SSD1322 23 // 256x64 2.8' https://aliexpress.com/item/1005003480981568.html
|
||||||
#define DSP_CUSTOM 101 // your display
|
#define DSP_CUSTOM 101 // your display
|
||||||
|
|
||||||
#ifndef DSP_MODEL
|
#ifndef DSP_MODEL
|
||||||
|
|||||||
70
yoRadio/src/displays/conf/displaySSD1322conf.h
Normal file
70
yoRadio/src/displays/conf/displaySSD1322conf.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
SSD1305 128x64 displays configuration file.
|
||||||
|
Copy this file to yoRadio/src/displays/conf/displaySSD1305conf_custom.h
|
||||||
|
and modify it
|
||||||
|
More info on https://github.com/e2002/yoradio/wiki/Widgets#widgets-description
|
||||||
|
*************************************************************************************/
|
||||||
|
|
||||||
|
#ifndef displaySSD1322conf_h
|
||||||
|
#define displaySSD1322conf_h
|
||||||
|
|
||||||
|
#define DSP_WIDTH 256
|
||||||
|
#define TFT_FRAMEWDT 1
|
||||||
|
#define MAX_WIDTH DSP_WIDTH-TFT_FRAMEWDT*2
|
||||||
|
|
||||||
|
#define HIDE_HEAPBAR
|
||||||
|
#define HIDE_VOL
|
||||||
|
#define HIDE_VU
|
||||||
|
//#define HIDE_TITLE2
|
||||||
|
|
||||||
|
#define bootLogoTop 68
|
||||||
|
|
||||||
|
/* SROLLS */ /* {{ left, top, fontsize, align }, buffsize, uppercase, width, scrolldelay, scrolldelta, scrolltime } */
|
||||||
|
const ScrollConfig metaConf PROGMEM = {{ TFT_FRAMEWDT+1, TFT_FRAMEWDT+1, 2, WA_LEFT }, 140, true, MAX_WIDTH-2, 5000, 2, 25 };
|
||||||
|
const ScrollConfig title1Conf PROGMEM = {{ 0, 20, 1, WA_LEFT }, 140, true, DSP_WIDTH/2+6, 5000, 2, 25 };
|
||||||
|
const ScrollConfig title2Conf PROGMEM = {{ 0, 29, 1, WA_LEFT }, 140, true, DSP_WIDTH/2+6, 5000, 2, 25 };
|
||||||
|
const ScrollConfig playlistConf PROGMEM = {{ TFT_FRAMEWDT, 30, 1, WA_LEFT }, 140, true, MAX_WIDTH, 500, 2, 25 };
|
||||||
|
const ScrollConfig apTitleConf PROGMEM = {{ TFT_FRAMEWDT+1, TFT_FRAMEWDT+1, 1, WA_CENTER }, 140, false, MAX_WIDTH-2, 0, 2, 25 };
|
||||||
|
const ScrollConfig apSettConf PROGMEM = {{ TFT_FRAMEWDT, 64-7, 1, WA_LEFT }, 140, false, MAX_WIDTH, 0, 2, 25 };
|
||||||
|
const ScrollConfig weatherConf PROGMEM = {{ 0, 64-12, 1, WA_LEFT }, 140, true, DSP_WIDTH/2+6, 0, 2, 25 }; // ПОГОДА!!
|
||||||
|
|
||||||
|
/* BACKGROUNGC9106DS */ /* {{ left, top, fontsize, align }, width, height, outlined } */
|
||||||
|
const FillConfig metaBGConf PROGMEM = {{ 0, 0, 0, WA_LEFT }, DSP_WIDTH, 18, false };
|
||||||
|
const FillConfig volbarConf PROGMEM = {{ 0, 64-1-1-1, 0, WA_LEFT }, DSP_WIDTH, 3, true };
|
||||||
|
const FillConfig playlBGConf PROGMEM = {{ 0, 26, 0, WA_LEFT }, DSP_WIDTH, 12, false };
|
||||||
|
const FillConfig heapbarConf PROGMEM = {{ 0, 63, 0, WA_LEFT }, DSP_WIDTH, 1, false };
|
||||||
|
|
||||||
|
/* WIDGETS */ /* { left, top, fontsize, align } */
|
||||||
|
const WidgetConfig bootstrConf PROGMEM = { 0, 64-8, 1, WA_CENTER };
|
||||||
|
const WidgetConfig bitrateConf PROGMEM = { TFT_FRAMEWDT+20, 64-11-10, 1, WA_LEFT };
|
||||||
|
//const WidgetConfig voltxtConf PROGMEM = { 32, 108, 1, WA_RIGHT };
|
||||||
|
const WidgetConfig iptxtConf PROGMEM = { 0, 64-12, 1, WA_LEFT };
|
||||||
|
const WidgetConfig rssiConf PROGMEM = { 0, 64-11-10, 1, WA_LEFT };
|
||||||
|
const WidgetConfig numConf PROGMEM = { TFT_FRAMEWDT, 57, 35, WA_CENTER };
|
||||||
|
const WidgetConfig apNameConf PROGMEM = { 0, 18, 1, WA_CENTER };
|
||||||
|
const WidgetConfig apName2Conf PROGMEM = { 0, 26, 1, WA_CENTER };
|
||||||
|
const WidgetConfig apPassConf PROGMEM = { 0, 37, 1, WA_CENTER };
|
||||||
|
const WidgetConfig apPass2Conf PROGMEM = { 0, 45, 1, WA_CENTER };
|
||||||
|
//const WidgetConfig clockConf PROGMEM = { 6, 34, 2, WA_CENTER };
|
||||||
|
const WidgetConfig clockConf PROGMEM = { 0, 57, 35, WA_RIGHT }; /* 35 is a fixed font size. do not change */
|
||||||
|
const WidgetConfig vuConf PROGMEM = { 1, 28, 1, WA_LEFT };
|
||||||
|
|
||||||
|
const WidgetConfig bootWdtConf PROGMEM = { 0, 64-8*2-5, 1, WA_CENTER };
|
||||||
|
const ProgressConfig bootPrgConf PROGMEM = { 90, 10, 4 };
|
||||||
|
|
||||||
|
/* BANDS */ /* { onebandwidth, onebandheight, bandsHspace, bandsVspace, numofbands, fadespeed } */
|
||||||
|
const VUBandsConfig bandsConf PROGMEM = { 12, 48, 2, 1, 8, 3 };
|
||||||
|
|
||||||
|
/* STRINGS */
|
||||||
|
const char numtxtFmt[] PROGMEM = "%d";
|
||||||
|
const char rssiFmt[] PROGMEM = "%d";
|
||||||
|
const char iptxtFmt[] PROGMEM = "%s";
|
||||||
|
//const char voltxtFmt[] PROGMEM = "%d";
|
||||||
|
const char bitrateFmt[] PROGMEM = "%d kBs";
|
||||||
|
|
||||||
|
/* MOVES */ /* { left, top, width } */
|
||||||
|
const MoveConfig clockMove PROGMEM = { 0, 0, -1 };
|
||||||
|
const MoveConfig weatherMove PROGMEM = { 0, 0, -1 };
|
||||||
|
const MoveConfig weatherMoveVU PROGMEM = { 0, 0, -1 };
|
||||||
|
|
||||||
|
#endif
|
||||||
220
yoRadio/src/displays/displaySSD1322.cpp
Normal file
220
yoRadio/src/displays/displaySSD1322.cpp
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
#include "../core/options.h"
|
||||||
|
#if DSP_MODEL==DSP_SSD1322
|
||||||
|
|
||||||
|
#include "displaySSD1322.h"
|
||||||
|
#include "../core/player.h"
|
||||||
|
#include "../core/config.h"
|
||||||
|
#include "../core/network.h"
|
||||||
|
|
||||||
|
#define LOGO_WIDTH 21
|
||||||
|
#define LOGO_HEIGHT 32
|
||||||
|
|
||||||
|
#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY)
|
||||||
|
#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl)
|
||||||
|
|
||||||
|
#ifndef DEF_SPI_FREQ
|
||||||
|
#define DEF_SPI_FREQ 16000000UL /* set it to 0 for system default */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const unsigned char logo [] PROGMEM=
|
||||||
|
{
|
||||||
|
0x06, 0x03, 0x00, 0x0f, 0x07, 0x80, 0x1f, 0x8f, 0xc0, 0x1f, 0x8f, 0xc0,
|
||||||
|
0x0f, 0x07, 0x80, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x03, 0xff, 0x00, 0x0f, 0xff, 0x80,
|
||||||
|
0x1f, 0xff, 0xc0, 0x1f, 0xff, 0xc0, 0x3f, 0x8f, 0xe0, 0x7e, 0x03, 0xf0,
|
||||||
|
0x7c, 0x01, 0xf0, 0x7c, 0x01, 0xf0, 0x7f, 0xff, 0xf0, 0xff, 0xff, 0xf8,
|
||||||
|
0xff, 0xff, 0xf8, 0xff, 0xff, 0xf8, 0x7c, 0x00, 0x00, 0x7c, 0x00, 0x00,
|
||||||
|
0x7e, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x3f, 0xc0, 0xe0, 0x3f, 0xff, 0xe0,
|
||||||
|
0x1f, 0xff, 0xe0, 0x0f, 0xff, 0xe0, 0x03, 0xff, 0xc0, 0x00, 0xfe, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if DSP_HSPI
|
||||||
|
DspCore::DspCore(): Jamis_SSD1322(256, 64, &SPI2, TFT_DC, TFT_RST, TFT_CS, DEF_SPI_FREQ) {}
|
||||||
|
#else
|
||||||
|
DspCore::DspCore(): Jamis_SSD1322(256, 64, &SPI, TFT_DC, TFT_RST, TFT_CS, DEF_SPI_FREQ) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "tools/utf8RusGFX.h"
|
||||||
|
|
||||||
|
void DspCore::initDisplay() {
|
||||||
|
#include "tools/oledcolorfix.h"
|
||||||
|
begin();
|
||||||
|
cp437(true);
|
||||||
|
flip();
|
||||||
|
invert();
|
||||||
|
setTextWrap(false);
|
||||||
|
|
||||||
|
plItemHeight = playlistConf.widget.textsize*(CHARHEIGHT-1)+playlistConf.widget.textsize*4;
|
||||||
|
plTtemsCount = round((float)height()/plItemHeight);
|
||||||
|
if(plTtemsCount%2==0) plTtemsCount++;
|
||||||
|
plCurrentPos = plTtemsCount/2;
|
||||||
|
plYStart = (height() / 2 - plItemHeight / 2) - plItemHeight * (plTtemsCount - 1) / 2 + playlistConf.widget.textsize*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::drawLogo(uint16_t top) {
|
||||||
|
drawBitmap( (width() - LOGO_WIDTH ) / 2, 8, logo, LOGO_WIDTH, LOGO_HEIGHT, 1);
|
||||||
|
display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::printPLitem(uint8_t pos, const char* item, ScrollWidget& current){
|
||||||
|
setTextSize(playlistConf.widget.textsize);
|
||||||
|
if (pos == plCurrentPos) {
|
||||||
|
current.setText(item);
|
||||||
|
} else {
|
||||||
|
uint8_t plColor = (abs(pos - plCurrentPos)-1)>4?4:abs(pos - plCurrentPos)-1;
|
||||||
|
setTextColor(config.theme.playlist[plColor], config.theme.background);
|
||||||
|
setCursor(TFT_FRAMEWDT, plYStart + pos * plItemHeight);
|
||||||
|
fillRect(0, plYStart + pos * plItemHeight - 1, width(), plItemHeight - 2, config.theme.background);
|
||||||
|
print(utf8Rus(item, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::drawPlaylist(uint16_t currentItem) {
|
||||||
|
uint8_t lastPos = config.fillPlMenu(currentItem - plCurrentPos, plTtemsCount);
|
||||||
|
if(lastPos<plTtemsCount){
|
||||||
|
fillRect(0, lastPos*plItemHeight+plYStart, width(), height()/2, config.theme.background);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::clearDsp(bool black) {
|
||||||
|
//fillScreen(TFT_BG);
|
||||||
|
clearDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
GFXglyph *pgm_read_glyph_ptr(const GFXfont *gfxFont, uint8_t c) {
|
||||||
|
return gfxFont->glyph + c;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t DspCore::_charWidth(unsigned char c){
|
||||||
|
GFXglyph *glyph = pgm_read_glyph_ptr(&DS_DIGI28pt7b, c - 0x20);
|
||||||
|
return pgm_read_byte(&glyph->xAdvance);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t DspCore::textWidth(const char *txt){
|
||||||
|
uint16_t w = 0, l=strlen(txt);
|
||||||
|
for(uint16_t c=0;c<l;c++) w+=_charWidth(txt[c]);
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::_getTimeBounds() {
|
||||||
|
_timewidth = textWidth(_timeBuf);
|
||||||
|
char buf[4];
|
||||||
|
strftime(buf, 4, "%H", &network.timeinfo);
|
||||||
|
_dotsLeft=textWidth(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::_clockSeconds(){
|
||||||
|
setTextSize(1);
|
||||||
|
setFont(&DS_DIGI28pt7b);
|
||||||
|
setTextColor((network.timeinfo.tm_sec % 2 == 0) ? config.theme.clock : config.theme.background, config.theme.background);
|
||||||
|
setCursor(_timeleft+_dotsLeft, clockTop);
|
||||||
|
print(":");
|
||||||
|
setFont();
|
||||||
|
/*
|
||||||
|
setTextSize(1);
|
||||||
|
setCursor(_timeleft+_timewidth+2, clockTop-CHARHEIGHT*2-1);
|
||||||
|
setTextColor(config.theme.clock, config.theme.background);
|
||||||
|
sprintf(_bufforseconds, "%02d", network.timeinfo.tm_sec);
|
||||||
|
print(_bufforseconds); */
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::_clockDate(){ }
|
||||||
|
|
||||||
|
void DspCore::_clockTime(){
|
||||||
|
if(_oldtimeleft>0) dsp.fillRect(_oldtimeleft, clockTop-clockTimeHeight+1, _oldtimewidth+CHARWIDTH*2+2, clockTimeHeight, config.theme.background);
|
||||||
|
//if(_oldtimeleft>0) dsp.fillRect(_oldtimeleft, clockTop-clockTimeHeight+1, _oldtimewidth, clockTimeHeight, config.theme.background);
|
||||||
|
_timeleft = (width()/*/2*/ - _timewidth/*/2*/)-clockRightSpace;
|
||||||
|
setTextSize(1);
|
||||||
|
setFont(&DS_DIGI28pt7b);
|
||||||
|
setTextColor(config.theme.clock, config.theme.background);
|
||||||
|
setCursor(_timeleft, clockTop);
|
||||||
|
print(_timeBuf);
|
||||||
|
setFont();
|
||||||
|
strlcpy(_oldTimeBuf, _timeBuf, sizeof(_timeBuf));
|
||||||
|
_oldtimewidth = _timewidth;
|
||||||
|
_oldtimeleft = _timeleft;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::printClock(uint16_t top, uint16_t rightspace, uint16_t timeheight, bool redraw){
|
||||||
|
clockTop = top;
|
||||||
|
clockRightSpace = rightspace;
|
||||||
|
clockTimeHeight = timeheight;
|
||||||
|
strftime(_timeBuf, sizeof(_timeBuf), "%H:%M", &network.timeinfo);
|
||||||
|
if(strcmp(_oldTimeBuf, _timeBuf)!=0 || redraw){
|
||||||
|
_getTimeBounds();
|
||||||
|
_clockTime();
|
||||||
|
}
|
||||||
|
_clockSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::clearClock(){
|
||||||
|
dsp.fillRect(_timeleft, clockTop-clockTimeHeight, _timewidth+2, clockTimeHeight, config.theme.background);
|
||||||
|
//dsp.fillRect(_timeleft, clockTop-clockTimeHeight, _timewidth+CHARWIDTH*3*2+24, clockTimeHeight+10+CHARHEIGHT, config.theme.background);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::startWrite(void) {
|
||||||
|
//TAKE_MUTEX();
|
||||||
|
Jamis_SSD1322::startWrite();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::endWrite(void) {
|
||||||
|
Jamis_SSD1322::endWrite();
|
||||||
|
//GIVE_MUTEX();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::loop(bool force) {
|
||||||
|
//clearDisplay();
|
||||||
|
display();
|
||||||
|
delay(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::charSize(uint8_t textsize, uint8_t& width, uint16_t& height){
|
||||||
|
width = textsize * CHARWIDTH;
|
||||||
|
height = textsize * CHARHEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::setTextSize(uint8_t s){
|
||||||
|
Adafruit_GFX::setTextSize(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::flip(){
|
||||||
|
setRotation(config.store.flipscreen?2:0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::invert(){
|
||||||
|
invertDisplay(config.store.invertdisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::sleep(void) { oled_command(SSD1322_DISPLAYOFF); }
|
||||||
|
void DspCore::wake(void) { oled_command(SSD1322_DISPLAYON); }
|
||||||
|
|
||||||
|
void DspCore::writePixel(int16_t x, int16_t y, uint16_t color) {
|
||||||
|
if(_clipping){
|
||||||
|
if ((x < _cliparea.left) || (x > _cliparea.left+_cliparea.width) || (y < _cliparea.top) || (y > _cliparea.top + _cliparea.height)) return;
|
||||||
|
}
|
||||||
|
Jamis_SSD1322::writePixel(x, y, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) {
|
||||||
|
if(_clipping){
|
||||||
|
if ((x < _cliparea.left) || (x >= _cliparea.left+_cliparea.width) || (y < _cliparea.top) || (y > _cliparea.top + _cliparea.height)) return;
|
||||||
|
}
|
||||||
|
Jamis_SSD1322::writeFillRect(x, y, w, h, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::setClipping(clipArea ca){
|
||||||
|
_cliparea = ca;
|
||||||
|
_clipping = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::clearClipping(){
|
||||||
|
_clipping = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DspCore::setNumFont(){
|
||||||
|
setFont(&DS_DIGI28pt7b);
|
||||||
|
setTextSize(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
43
yoRadio/src/displays/displaySSD1322.h
Normal file
43
yoRadio/src/displays/displaySSD1322.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#ifndef displaySSD1305_h
|
||||||
|
#define displaySSD1305_h
|
||||||
|
#include "../core/options.h"
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include <Adafruit_GFX.h>
|
||||||
|
#include "../SSD1322/SSD1322.h"
|
||||||
|
#include "fonts/DS_DIGI28pt7b.h"
|
||||||
|
#include "tools/l10n.h"
|
||||||
|
|
||||||
|
#define CHARWIDTH 6
|
||||||
|
#define CHARHEIGHT 8
|
||||||
|
|
||||||
|
#define DSP_OLED
|
||||||
|
|
||||||
|
typedef GFXcanvas1 Canvas;
|
||||||
|
#include "widgets/widgets.h"
|
||||||
|
#include "widgets/pages.h"
|
||||||
|
|
||||||
|
#if __has_include("conf/displaySSD1305conf_custom.h")
|
||||||
|
#include "conf/displaySSD1322conf_custom.h"
|
||||||
|
#else
|
||||||
|
#include "conf/displaySSD1322conf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class DspCore: public Jamis_SSD1322 {
|
||||||
|
#include "tools/commongfx.h"
|
||||||
|
};
|
||||||
|
|
||||||
|
extern DspCore dsp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OLED COLORS
|
||||||
|
*/
|
||||||
|
#define BOOT_PRG_COLOR WHITE
|
||||||
|
#define BOOT_TXT_COLOR WHITE
|
||||||
|
#define PINK WHITE
|
||||||
|
#define SILVER WHITE
|
||||||
|
#define TFT_BG BLACK
|
||||||
|
#define TFT_FG WHITE
|
||||||
|
#define TFT_LOGO WHITE
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -40,6 +40,8 @@
|
|||||||
#include "displayGC9A01A.h"
|
#include "displayGC9A01A.h"
|
||||||
#elif DSP_MODEL==DSP_ILI9488 || DSP_MODEL==DSP_ILI9486
|
#elif DSP_MODEL==DSP_ILI9488 || DSP_MODEL==DSP_ILI9486
|
||||||
#include "displayILI9488.h"
|
#include "displayILI9488.h"
|
||||||
|
#elif DSP_MODEL==DSP_SSD1322
|
||||||
|
#include "displaySSD1322.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//extern DspCore dsp;
|
//extern DspCore dsp;
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ void NumWidget::setText(const char* txt) {
|
|||||||
_getBounds();
|
_getBounds();
|
||||||
if (strcmp(_oldtext, _text) == 0) return;
|
if (strcmp(_oldtext, _text) == 0) return;
|
||||||
uint16_t realth = _textheight;
|
uint16_t realth = _textheight;
|
||||||
#ifdef DSP_OLED
|
#if defined(DSP_OLED) && DSP_MODEL!=DSP_SSD1322
|
||||||
realth = _textheight*CHARHEIGHT;
|
realth = _textheight*CHARHEIGHT;
|
||||||
#endif
|
#endif
|
||||||
if (_active) dsp.fillRect(_oldleft == 0 ? _realLeft() : min(_oldleft, _realLeft()), _config.top-_textheight+1, max(_oldtextwidth, _textwidth), realth, _bgcolor);
|
if (_active) dsp.fillRect(_oldleft == 0 ? _realLeft() : min(_oldleft, _realLeft()), _config.top-_textheight+1, max(_oldtextwidth, _textwidth), realth, _bgcolor);
|
||||||
|
|||||||
Reference in New Issue
Block a user