aboutsummaryrefslogtreecommitdiff
path: root/main/InovaLedDisplay.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main/InovaLedDisplay.cpp')
-rw-r--r--main/InovaLedDisplay.cpp100
1 files changed, 100 insertions, 0 deletions
diff --git a/main/InovaLedDisplay.cpp b/main/InovaLedDisplay.cpp
new file mode 100644
index 0000000..db6e3f6
--- /dev/null
+++ b/main/InovaLedDisplay.cpp
@@ -0,0 +1,100 @@
+#include "InovaLedDisplay.h"
+
+#include <cstring>
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+
+
+InovaLedDisplay::InovaLedDisplay(uint8_t r0, uint8_t g0, uint8_t clk, uint8_t cs, uint8_t latchParam, uint8_t oeParam, uint8_t addr0Param, uint8_t addr1Param, uint8_t addr2Param) : Adafruit_GFX(NUM_COL, NUM_ROW){
+ latch = (gpio_num_t) latchParam;
+ oe = (gpio_num_t) oeParam;
+ addr0 = (gpio_num_t) addr0Param;
+ addr1 = (gpio_num_t) addr1Param;
+ addr2 = (gpio_num_t) addr2Param;
+
+ esp_err_t ret;
+
+ spi_bus_config_t buscfg;
+ buscfg.miso_io_num=g0;
+ buscfg.mosi_io_num=r0;
+ buscfg.sclk_io_num=clk;
+ buscfg.quadwp_io_num=-1;
+ buscfg.quadhd_io_num=-1;
+ buscfg.max_transfer_sz=3*600*2*8;
+ buscfg.flags=SPICOMMON_BUSFLAG_DUAL;
+
+ spi_device_interface_config_t devcfg;
+ devcfg.clock_speed_hz=1*1000*1000; //Clock out at 1 MHz
+ devcfg.mode=0; //SPI mode 0
+ devcfg.spics_io_num=cs; //CS pin
+ devcfg.queue_size=1; //We want to be able to queue 7 transactions at a time
+ devcfg.flags=SPI_DEVICE_HALFDUPLEX; //Needed to use both data lines for output
+
+ //Initialize the SPI bus and attach our device handle
+ ret=spi_bus_initialize(HSPI_HOST, &buscfg, SPI_DMA_CH_AUTO);
+ ESP_ERROR_CHECK(ret);
+ ret=spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
+ ESP_ERROR_CHECK(ret);
+
+ gpio_set_direction(latch, GPIO_MODE_OUTPUT);
+ gpio_set_direction(oe, GPIO_MODE_OUTPUT);
+ gpio_set_direction(addr0, GPIO_MODE_OUTPUT);
+ gpio_set_direction(addr1, GPIO_MODE_OUTPUT);
+ gpio_set_direction(addr2, GPIO_MODE_OUTPUT);
+}
+
+
+void InovaLedDisplay::drawPixel(int16_t x, int16_t y, uint16_t color) {
+ displayBuffer[y][x / 8] = displayBuffer[y][x / 8] & ~(0b0000000000000011 << (14 - (2 * (x % 8)))); // clear this column (note the bitwise inversion)
+ displayBuffer[y][x / 8] = displayBuffer[y][x / 8] | (color << (14 - (2 * (x % 8)))); // write color to column
+}
+
+
+void InovaLedDisplay::updateDisplay(void) {}
+
+
+void InovaLedDisplay::runDisplay(void) {
+ TickType_t xLastWakeTime;
+ const TickType_t xFrequency = 1 / portTICK_PERIOD_MS;
+ xLastWakeTime = xTaskGetTickCount();
+
+ uint8_t current_row = 0;
+ uint8_t i = 0;
+ uint16_t data;
+ esp_err_t ret;
+ run = true;
+ while(run) {
+ vTaskDelayUntil(&xLastWakeTime, xFrequency);
+
+ for(i = 0; i < (NUM_COL / 8); i++) {
+ spi_transaction_t t;
+ memset(&t, 0, sizeof(t));
+ t.length = 16;
+ data = SPI_SWAP_DATA_TX(displayBuffer[current_row][i], 16);
+ t.tx_buffer = &data;
+ t.flags = SPI_TRANS_MODE_DIO; // output on two data lines. Even bits go to GREEN, odd to RED
+ ret = spi_device_polling_transmit(spi, &t);
+ ESP_ERROR_CHECK(ret);
+ }
+
+ gpio_set_level(latch, 0);
+ gpio_set_level(oe, 1);
+
+ gpio_set_level(addr0, 1 & current_row);
+ gpio_set_level(addr1, 1 & (current_row >> 1));
+ gpio_set_level(addr2, 1 & (current_row >> 2));
+
+ gpio_set_level(latch, 1);
+ gpio_set_level(oe, 0);
+
+ if(++current_row == NUM_ROW) {
+ current_row = 0;
+ }
+ }
+}
+
+
+void InovaLedDisplay::stopDisplay(void) {
+ run = false;
+}