From ee53173ac95ac68e7082f344340cb5096fba3295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Szyma=C5=84ski?= Date: Sat, 17 Feb 2024 05:12:03 +0100 Subject: [PATCH] implement Adafruit_GFX override --- .gitignore | 1 + .../src/Adafruit_GFX_Pixel.cpp | 206 ++++++++++++++++++ .../src/Adafruit_GFX_Pixel.hpp | 38 ++++ lib/PixelBydgoszcz/src/Pixel.hpp | 3 +- platformio.ini | 5 +- src/main.cpp | 27 ++- 6 files changed, 271 insertions(+), 9 deletions(-) create mode 100644 lib/Adafruit_GFX_Pixel/src/Adafruit_GFX_Pixel.cpp create mode 100644 lib/Adafruit_GFX_Pixel/src/Adafruit_GFX_Pixel.hpp diff --git a/.gitignore b/.gitignore index 89cc49c..20b454e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .vscode/c_cpp_properties.json .vscode/launch.json .vscode/ipch +LN_BUILD \ No newline at end of file diff --git a/lib/Adafruit_GFX_Pixel/src/Adafruit_GFX_Pixel.cpp b/lib/Adafruit_GFX_Pixel/src/Adafruit_GFX_Pixel.cpp new file mode 100644 index 0000000..fb71ffb --- /dev/null +++ b/lib/Adafruit_GFX_Pixel/src/Adafruit_GFX_Pixel.cpp @@ -0,0 +1,206 @@ +#include +#include +#include "Adafruit_GFX_Pixel.hpp" + +Adafruit_Pixel::Adafruit_Pixel(PixelClass &pixel, uint16_t w) : _pixel(&pixel), + Adafruit_GFX(w, 16) +{ +} + +Adafruit_Pixel::~Adafruit_Pixel(void) +{ + for (uint8_t i = 0; i < PIXEL_BUFFER_CNT; i++) + { + if (_buffers[i]) + { + free(_buffers[i]); + } + } + + free(_drawBuffer); + free(_packetBuffer); + free(_messageBuffer); +} + +void Adafruit_Pixel::init() +{ + for (uint8_t i = 0; i < PIXEL_BUFFER_CNT; i++) + { + if (!_buffers[i]) + { + _buffers[i] = (uint16_t *)malloc(_width * PIXEL_DISP_HEIGHT); + memset(_buffers[i], 0, _width * PIXEL_DISP_HEIGHT); + } + } + + _drawBuffer = (uint8_t *)malloc(_width * (PIXEL_DISP_HEIGHT / 2)); + _packetBuffer = (uint8_t *)malloc(_width * (PIXEL_DISP_HEIGHT / 2) + 16); // with space for header and CRC + _messageBuffer = (uint8_t *)malloc((_width * (PIXEL_DISP_HEIGHT / 2) + 16) * 2); // with space for packetBuffer + CRC +} + +void Adafruit_Pixel::selectBuffer(uint8_t bufferNo) +{ + if (bufferNo > PIXEL_BUFFER_CNT) + return; + + _currentBuffer = bufferNo; +} + +void Adafruit_Pixel::drawPixel(int16_t x, int16_t y, uint16_t color) +{ + if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) + return; + + if (color == 0x0000) + { + _buffers[_currentBuffer][x] &= ~(1 << y); + } + else + { + _buffers[_currentBuffer][x] |= (1 << y); + } +} + +uint8_t Adafruit_Pixel::commitBufferToPage(int8_t bufferNo, int8_t pageNo) +{ + uint8_t bfrId = (uint8_t)bufferNo; + if (bufferNo < 0) + bfrId = _currentBuffer; + uint8_t page = (uint8_t)pageNo; + if (pageNo < 0) + pageNo = bufferNo; + + bool firstDot = false; // start from black unless chosen otherwise + memset(_drawBuffer, 0, _width * (PIXEL_DISP_HEIGHT / 2)); + uint16_t currByte = 0; + uint8_t currNibble = 0; + uint16_t currCount = 0; + bool lastBit = false; + for (uint8_t i = 0; i < _width; i++) + { + if (i == 0) + { + firstDot = ((_buffers[bfrId][i]) & 0x8000); + lastBit = firstDot; + } + + for (uint8_t y = 0; y < 16; y++) + { + bool pixel = (_buffers[bfrId][i] & (1 << (15 - y))); + if (pixel == lastBit) + { + currCount++; + } + else + { + lastBit = pixel; + addBlockToDrawBuffer(currCount, currByte, currNibble); + currCount = 1; + } + } + } + + if (currCount > 0) + { + addBlockToDrawBuffer(currCount, currByte, currNibble); + } + + if (currNibble == 1) + { + currByte++; + } + uint16_t packetLen = currByte + 15; + + _packetBuffer[0] = packetLen & 0xFF; + _packetBuffer[1] = (packetLen >> 8) & 0xFF; + _packetBuffer[2] = pageNo; + _packetBuffer[3] = 0x01; + _packetBuffer[4] = 0x03; + _packetBuffer[5] = 0x00; + _packetBuffer[6] = 0x01; + _packetBuffer[7] = currByte + 6; + _packetBuffer[8] = 0x00; + _packetBuffer[9] = 0x00; // offset from left, setting whole display so don't care + _packetBuffer[10] = 0x00; // offset from bottom, setting whole display so don't care + _packetBuffer[11] = 0x50; // config, (rowCount & 0x1f) | ((1 if startWith else 0) << 5) | 0b01000000 + if (firstDot) + _packetBuffer[11] |= 0x20; // set first dot to white/yellow; + + _packetBuffer[12] = _width; // column number, setting whole display, so width; + + for (uint16_t i = 0; i < currByte; i++) + { + _packetBuffer[i + 13] = _drawBuffer[i]; + } + + uint16_t crc = _pixel->getCrc(_packetBuffer, currByte + 13); + _packetBuffer[currByte + 13] = crc & 0xFF; + _packetBuffer[currByte + 14] = (crc >> 8) & 0xFF; + + for (uint16_t i = 0; i < packetLen; i++) + { + byteToHex(_packetBuffer[i], _messageBuffer, i * 2); + } + + return _pixel->displayDataBlock(0, _messageBuffer, packetLen * 2); +} + +void Adafruit_Pixel::addBlockToDrawBuffer(uint16_t currCount, uint16_t &currByte, uint8_t &currNibble) +{ + if (currCount > 15) + { + uint8_t requiredZeroes = currCount / 15; + currByte += requiredZeroes / 2; + if (requiredZeroes % 2) + { + currNibble++; + if (currNibble == 2) + { + currNibble = 0; + currByte++; + } + } + uint8_t leftover = currCount % 15; + if (currNibble == 0) + { + _drawBuffer[currByte] |= (leftover << 4); + currNibble++; + } + else + { + _drawBuffer[currByte] |= leftover; + currNibble = 0; + currByte++; + } + } + else + { + if (currNibble == 0) + { + _drawBuffer[currByte] |= (currCount << 4); + currNibble++; + } + else + { + _drawBuffer[currByte] |= currCount; + currNibble = 0; + currByte++; + } + } +} + +void Adafruit_Pixel::byteToHex(uint8_t value, uint8_t *buffer, uint16_t position) +{ + uint8_t firstNibble = (value >> 4) & 0xF; + uint8_t secondNibble = value & 0xF; + buffer[position] = nibbleToHex(firstNibble); + buffer[position + 1] = nibbleToHex(secondNibble); +} + +uint8_t Adafruit_Pixel::nibbleToHex(uint8_t nibble) +{ + if (nibble < 0xA) + return nibble + 0x30; + + return nibble + 0x37; +} diff --git a/lib/Adafruit_GFX_Pixel/src/Adafruit_GFX_Pixel.hpp b/lib/Adafruit_GFX_Pixel/src/Adafruit_GFX_Pixel.hpp new file mode 100644 index 0000000..38a1757 --- /dev/null +++ b/lib/Adafruit_GFX_Pixel/src/Adafruit_GFX_Pixel.hpp @@ -0,0 +1,38 @@ +#ifndef __ADAFRUIT_PIXEL_BYDGOSZCZ__ +#define __ADAFRUIT_PIXEL_BYDGOSZCZ__ + +#include +#include +#include + +#define PIXEL_BUFFER_CNT 16 +#define PIXEL_DISP_HEIGHT 16 + +class Adafruit_Pixel : public Adafruit_GFX { + public: + Adafruit_Pixel(PixelClass &pixel, uint16_t w); + ~Adafruit_Pixel(void); + + void init(); + void selectBuffer(uint8_t bufferNo); + + void drawPixel(int16_t x, int16_t y, uint16_t color); + + uint8_t commitBufferToPage(int8_t bufferNo = -1, int8_t pageNo = -1); + + private: + PixelClass *_pixel = NULL; + + uint8_t _currentBuffer = 0; + + uint16_t* _buffers[PIXEL_BUFFER_CNT]; + uint8_t * _drawBuffer = NULL; + uint8_t *_packetBuffer = NULL; // Buffer for raw bytes + uint8_t *_messageBuffer = NULL; // Buffers for ASCII chars to send to display + + void addBlockToDrawBuffer(uint16_t currCount, uint16_t &currByte, uint8_t &currNibble); + void byteToHex(uint8_t value, uint8_t *buffer, uint16_t position); + uint8_t nibbleToHex(uint8_t nibble); +}; + +#endif \ No newline at end of file diff --git a/lib/PixelBydgoszcz/src/Pixel.hpp b/lib/PixelBydgoszcz/src/Pixel.hpp index 736ba7c..e7f9670 100644 --- a/lib/PixelBydgoszcz/src/Pixel.hpp +++ b/lib/PixelBydgoszcz/src/Pixel.hpp @@ -29,6 +29,8 @@ class PixelClass { uint8_t displayDataBlock(uint8_t displayNo, uint8_t data[], uint16_t length); + uint16_t getCrc(uint8_t buffer[], uint32_t len); + private: Stream* _serial; int _txEnPin; @@ -37,7 +39,6 @@ class PixelClass { void beginTransmit(); void endTransmit(); - uint16_t getCrc(uint8_t buffer[], uint32_t len); }; extern PixelClass Pixel; diff --git a/platformio.ini b/platformio.ini index 0c91588..4488b9f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -12,7 +12,8 @@ platform = espressif32 board = esp32dev framework = arduino - build_type = debug - monitor_speed = 115200 +monitor_filters = esp32_exception_decoder +lib_deps = adafruit/Adafruit GFX Library@^1.11.9 +lib_ldf_mode=deep \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index b485b6e..de62d57 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,20 +1,35 @@ #include #include +#include +#include +#include PixelClass Pixel(Serial2, 22, 23); - -uint8_t datablock[] = "9E00000105000195000600504961F19797F1F12797C12851285521216211212191510379715522833225122155121321232A131042419338211228212211315133315149970379E21212731212132415122D697314192419158215827A6025A7261151285151233251211131379602241933122421221233222112112223321221242213391420179637324722515116215835C3073C493D3014D390F8D7"; +Adafruit_Pixel Pixel_GFX(Pixel, 84); void setup() { Serial.begin(115200); Serial2.begin(4800, SERIAL_8E1, 19, 18); Pixel.begin(); - Serial.println("Checking GID..."); - char respMsg[2137]; - uint8_t errCode = Pixel.displayDataBlock(0, datablock, 317); + Serial.println("Sleeping some..."); + delay(5000); + Serial.println("Initializing driver..."); + Pixel_GFX.init(); + Serial.println("Drawing line..."); + Pixel_GFX.setFont(&FreeSerif9pt7b); + Pixel_GFX.setCursor(0, 15); + Pixel_GFX.print("Test text..."); + Pixel_GFX.selectBuffer(1); + Pixel_GFX.setCursor(0, 15); + Pixel_GFX.setFont(&FreeMono12pt7b); + Pixel_GFX.print("Let's see this..."); + uint8_t errCode = Pixel_GFX.commitBufferToPage(0); + Serial.print("Got response code: "); + Serial.println(errCode); + delay(1000); + errCode = Pixel_GFX.commitBufferToPage(1); Serial.print("Got response code: "); Serial.println(errCode); - Serial.println(respMsg); } void loop() {