commit 5bae57fa1b612bb3a22a90a4a92e93d267f0a43d Author: NTEN\Nenninger Date: Mon Mar 4 12:35:37 2024 +0100 Version 2.1 diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_0026.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_0026.jpg new file mode 100644 index 0000000..b023dff Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_0026.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_0027.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_0027.jpg new file mode 100644 index 0000000..80c950f Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_0027.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_0028.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_0028.jpg new file mode 100644 index 0000000..b044e87 Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_0028.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_0693.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_0693.jpg new file mode 100644 index 0000000..45da2e8 Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_0693.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_0694.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_0694.jpg new file mode 100644 index 0000000..1ae4f52 Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_0694.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_0695.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_0695.jpg new file mode 100644 index 0000000..443848f Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_0695.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230303_121431.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230303_121431.jpg new file mode 100644 index 0000000..71a445a Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230303_121431.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230303_121447.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230303_121447.jpg new file mode 100644 index 0000000..76f42a8 Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230303_121447.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230306_110024.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230306_110024.jpg new file mode 100644 index 0000000..ebe37a6 Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230306_110024.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230306_110029.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230306_110029.jpg new file mode 100644 index 0000000..1f003f7 Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230306_110029.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230306_110038.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230306_110038.jpg new file mode 100644 index 0000000..faa74d0 Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230306_110038.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230310_152719.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230310_152719.jpg new file mode 100644 index 0000000..63576d5 Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230310_152719.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230310_152726.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230310_152726.jpg new file mode 100644 index 0000000..a315168 Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230310_152726.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230310_153016.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230310_153016.jpg new file mode 100644 index 0000000..c686b9f Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230310_153016.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230317_155123.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230317_155123.jpg new file mode 100644 index 0000000..ea4aa7a Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230317_155123.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230317_155130.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230317_155130.jpg new file mode 100644 index 0000000..a0a5e1f Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230317_155130.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230317_155139.jpg b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230317_155139.jpg new file mode 100644 index 0000000..94e7a23 Binary files /dev/null and b/ESP32_MasterPx_DesignUhr/Bilder/IMG_20230317_155139.jpg differ diff --git a/ESP32_MasterPx_DesignUhr/Blech.txt b/ESP32_MasterPx_DesignUhr/Blech.txt new file mode 100644 index 0000000..dd19016 --- /dev/null +++ b/ESP32_MasterPx_DesignUhr/Blech.txt @@ -0,0 +1,2 @@ +https://bleche-nach-mass.de/blechzuschnitte/1090-magnetwaende?gclid=EAIaIQobChMI1Mfgl8m__QIVyud3Ch3O-wPpEAAYASAAEgIasvD_BwE#002-1091-6 +235x120 \ No newline at end of file diff --git a/ESP32_MasterPx_DesignUhr/ESP32_MasterPx_DesignUhr/ESP32_MasterPx_DesignUhr.ino b/ESP32_MasterPx_DesignUhr/ESP32_MasterPx_DesignUhr/ESP32_MasterPx_DesignUhr.ino new file mode 100644 index 0000000..4c40dd9 --- /dev/null +++ b/ESP32_MasterPx_DesignUhr/ESP32_MasterPx_DesignUhr/ESP32_MasterPx_DesignUhr.ino @@ -0,0 +1,874 @@ +/* + N-Tools 2023 + 231112 -> Webseite Optimiert; kleinigkeiten für Uli; + 231210 -> Fehler in der Schrift NT7x10 behoben +*/ + +#define VERSION (char *) "V2.1" + +char ChipID[10] = "ERROR"; +uint64_t macAddress = ESP.getEfuseMac(); +uint64_t macAddressTrunc = (macAddress << 40); + +#define R1_PIN 13 +#define G1_PIN 27 +#define B1_PIN 25 +#define R2_PIN 12 +#define G2_PIN 26 +#define B2_PIN 4 +#define A_PIN 19 +#define B_PIN 23 // Changed from library default +#define C_PIN 18 +#define D_PIN 5 +#define E_PIN 15 +#define LAT_PIN 17 +#define OE_PIN 16 +#define CLK_PIN 14 + +#define PANEL_RES_X 96 // Number of pixels wide of each INDIVIDUAL panel module. +#define PANEL_RES_Y 48 // Number of pixels tall of each INDIVIDUAL panel module. + +#define NUM_ROWS 1 // Number of rows of chained INDIVIDUAL PANELS +#define NUM_COLS 1 // Number of INDIVIDUAL PANELS per ROW +#define PANEL_CHAIN NUM_ROWS*NUM_COLS // total number of panels chained one to another + +//#define PIXEL_COLOR_DEPTH_BITS 2 + +// library includes +//#include +#include + +MatrixPanel_I2S_DMA *display = nullptr; + +#include +#include +#include +#include +#include +#include +#include + AsyncWebServer webServer(80); + DNSServer dnsServer; + IPAddress ip_local(192, 168, 13, 1); + IPAddress ip_gateway(192, 168, 13, 1); + IPAddress ip_subnet(255, 255, 255, 0); + bool APEnabled = false; + char ssid[30] = ""; + char pass[30] = ""; + char appass[30] = ""; + char localip[16]; + + #include "index_html.h" + const char* PARAM_SET = "set"; + const char* PARAM_SAVE = "save"; + const char* PARAM_TO = "to"; + const char* PARAM_SHOWWHAT = "showWhat"; + const char* PARAM_BRIGHTNESS = "brightness"; + const char* PARAM_OPTIONS = "options"; + const char* PARAM_SSID = "ssid"; + const char* PARAM_PWD = "pwd"; + const char* PARAM_RESET = "reset"; + + // Replaces placeholder with button section in your web page + char * html_processor(const String& var){ + if(var == "VERSION"){ + return VERSION; + }else if(var == "ID"){ + return ChipID; + }else if(var == "LOCALIP"){ + return localip; + } + return (char *) "not defined"; + } + + String toStringIp(IPAddress ip) { + String res = ""; + for (int i = 0; i < 3; i++) { + res += String((ip >> (8 * i)) & 0xFF) + "."; + } + res += String(((ip >> 8 * 3)) & 0xFF); + return res; + } + + void html_handle_notsuccess(AsyncWebServerRequest *request); + void html_handle_notsuccess(AsyncWebServerRequest *request){ + request->send(200, "text/html", String("zur Konfigurationsseite")); + } + void html_root(AsyncWebServerRequest *request); + void html_root(AsyncWebServerRequest *request) { + request->send_P(200, "text/html", html_page_index, html_processor); + } + + void html_poll(AsyncWebServerRequest *request); + void html_do(AsyncWebServerRequest *request); + + +//permanenter Speicher +#include + +//i2c +#include +#include + + RV3028 rtc; + const int PINRTC_CLOCK = 34; + bool rtcEnabled = false; + bool doRTCSecond = false; + +#include +#include + + long ti_second = 0; + float brightness = 1.0; + + uint8_t timeColor[3] = {0xff,0xff,0xff}; + uint8_t tacticalTimeColor[3] = {0x88,0xff,0x00}; + uint8_t dateColor[3] {0x10,0xff,0x00}; + uint8_t kwColor[3] {0x10,0xff,0x00}; + + int8_t lastminutes = -1; + + bool iDL = false; + bool savediDL = false; + + long lastTimeSyncTime = 0; + uint8_t lastTimeSyncTyp = 0; + + bool EEPROMDataNotSaved = false; + uint8_t options = 0; + + uint8_t timeIndex = 0; + bool withSeconds = true; + bool alwaysAccessPoint = true; + +void setPixelColor(uint8_t x,uint8_t y, uint8_t red, uint8_t green ,uint8_t blue){ + display->drawPixelRGB888(x, y, red, green, blue); + +} + +//Zeichene eine Linie waagrecht x/y und z als länge +void LineH(uint8_t x, uint8_t y, uint8_t z, uint8_t red, uint8_t green ,uint8_t blue){ + display->drawFastHLine(x,y,z,display->color565(red, green, blue)); +} + +//Zeichene eine Linie senkrecht x/y und z als länge +void LineV(uint8_t x, uint8_t y, int16_t z, uint8_t red, uint8_t green, uint8_t blue){ + display->drawFastVLine(x,y,z,display->color565(red, green, blue)); +} + +void doClearTimeLEDs(uint8_t x=0,uint8_t y=0){ + for(uint8_t i=0;i<24;i++){ + display->drawFastHLine(x,y+i, 80, 0); + } +} + +void doClearTacticalLEDs(uint8_t x=0,uint8_t y=0){ + for(uint8_t i=0;i<16;i++){ + display->drawFastHLine(x,y+i, 96, 0); + } +} + +//eigene Schriften +#include +#include +#include + +#include +#include +#include +#include + + +void showNTOOLS(void){ + uint8_t zeile=12; + uint8_t spalte=25; + spalte += Out5x7Char('N',spalte,zeile,0,0,255)+1; + spalte += Out5x7Char('-',spalte,zeile,0,0,255)+1; + spalte += Out5x7Char('T',spalte,zeile,0,0,255)+1; + spalte += Out5x7Char('o',spalte,zeile,0,0,255)+1; + spalte += Out5x7Char('o',spalte,zeile-1,0,0,255)+1; + spalte += Out5x7Char('l',spalte,zeile,0,0,255)+1; + spalte += Out5x7Char('s',spalte,zeile,0,0,255)+1; + spalte += Out5x7Char('.',spalte,zeile,0,0,255)+1; + spalte += Out5x7Char('d',spalte,zeile,0,0,255)+1; + spalte += Out5x7Char('e',spalte,zeile,0,0,255)+1; +} + +void drawSeconds(time_t t, uint8_t x=0, uint8_t y=0){ + uint16_t tmp = 0; + + uint8_t r = timeColor[0]; + uint8_t g = timeColor[1]; + uint8_t b = timeColor[2]; + + for(uint8_t i=0;i<16;i++){ + display->drawFastHLine(x,y+i, 21, 0); + } + + tmp = second(t); + Out10x16Char((tmp/10)+0x30,x,y,r,g,b); + tmp -= (tmp/10)*10; + x += 11; + Out10x16Char((tmp)+0x30,x,y,r,g,b); +} + +void drawTime(time_t t,uint8_t x=0,uint8_t y=0){ + uint8_t tmp = 0; + + uint8_t r = timeColor[0]; + uint8_t g = timeColor[1]; + uint8_t b = timeColor[2]; + + tmp = hour(t); + + if((tmp/10 > 0)){ + if((tmp/10 == 1)) + Out16x24Char((tmp/10)+0x30,x+6,y,r,g,b); + else + Out16x24Char((tmp/10)+0x30,x,y,r,g,b); + tmp -= (tmp/10)*10; + } + x += 19; + if((tmp == 1)) + Out16x24Char((tmp)+0x30,x+3,y,r,g,b); + else + Out16x24Char((tmp)+0x30,x,y,r,g,b); + Out16x24Char(':',x+19,y,r,g,b); + x += 26; + tmp = minute(t); + if((tmp/10 == 1)) + Out16x24Char((tmp/10)+0x30,x+6,y,r,g,b); + else + Out16x24Char((tmp/10)+0x30,x,y,r,g,b); + tmp -= (tmp/10)*10; + x += 19; + if((tmp == 1)) + Out16x24Char((tmp)+0x30,x+3,y,r,g,b); + else + Out16x24Char((tmp)+0x30,x,y,r,g,b); +} + +void showTime(time_t t,uint8_t x=12,uint8_t y=22){ + uint16_t tmp = minute(t); + + if(withSeconds){ + drawSeconds(t,x+62,y+8); + x -= 11; + } + + if(lastminutes != tmp){ + lastminutes = tmp; + doClearTimeLEDs(x,y); + //Uhrzeit + drawTime(t,x,y); + } +} + +char tacticalString[12] = "ddHHiiMMMyy"; + +void drawTactical(time_t t,uint8_t x = 0, uint8_t y = 0, uint8_t doCenterOf = 0){ + uint8_t r = tacticalTimeColor[0]; + uint8_t g = tacticalTimeColor[1]; + uint8_t b = tacticalTimeColor[2]; + + display->setFont(&NT7x10); + display->setCursor(x, y+10); + display->setTextColor(display->color565(r,g,b)); + + uint16_t tmp = day(t); + tacticalString[0] = (tmp/10)+0x30; + tmp -= (tmp/10)*10; + tacticalString[1] = (tmp)+0x30; + + tmp = hour(t); + tacticalString[2] = (tmp/10)+0x30; + tmp -= (tmp/10)*10; + tacticalString[3] = (tmp)+0x30; + + tmp = minute(t); + tacticalString[4] = (tmp/10)+0x30; + tmp -= (tmp/10)*10; + tacticalString[5] = (tmp)+0x30; + + tmp = month(t); + switch(tmp){ + case 1: + tacticalString[6] = 'j'; + tacticalString[7] = 'a'; + tacticalString[8] = 'n'; + break; + case 2: + tacticalString[6] = 'f'; + tacticalString[7] = 'e'; + tacticalString[8] = 'b'; + break; + case 3: + tacticalString[6] = 'm'; + tacticalString[7] = 'a'; + tacticalString[8] = 'r'; + + break; + case 4: + tacticalString[6] = 'a'; + tacticalString[7] = 'p'; + tacticalString[8] = 'r'; + break; + case 5: + tacticalString[6] = 'm'; + tacticalString[7] = 'a'; + tacticalString[8] = 'y'; + break; + case 6: + tacticalString[6] = 'j'; + tacticalString[7] = 'u'; + tacticalString[8] = 'n'; + break; + case 7: + tacticalString[6] = 'j'; + tacticalString[7] = 'u'; + tacticalString[8] = 'l'; + break; + case 8: + tacticalString[6] = 'a'; + tacticalString[7] = 'u'; + tacticalString[8] = 'g'; + break; + case 9: + tacticalString[6] = 's'; + tacticalString[7] = 'e'; + tacticalString[8] = 'p'; + break; + case 10: + tacticalString[6] = 'o'; + tacticalString[7] = 'c'; + tacticalString[8] = 't'; + break; + case 11: + tacticalString[6] = 'n'; + tacticalString[7] = 'o'; + tacticalString[8] = 'v'; + break; + case 12: + tacticalString[6] = 'd'; + tacticalString[7] = 'e'; + tacticalString[8] = 'c'; + break; + } + + tmp = year(t)-2000; + tacticalString[9] = (tmp/10)+0x30; + tmp -= (tmp/10)*10; + tacticalString[10] = (tmp)+0x30; + + if(doCenterOf > 0){ + int16_t Tx,Ty; + uint16_t w,h; + display->getTextBounds(tacticalString,0,0,&Tx,&Ty,&w,&h); + x = ceil((doCenterOf - w)/2); + display->setCursor(x, y+10); + } + display->print(tacticalString); +} + +void showTimeTactical(time_t t){ + uint16_t tmp = minute(t); + uint8_t x = 8; + uint8_t y = 22; + if(withSeconds){ + drawSeconds(t,x+62,y+8); + x -= 11; + } + + if(lastminutes != tmp){ + lastminutes = tmp; + doClearTacticalLEDs(0,7); + drawTactical(t,0,7,96); + //Uhrzeit + doClearTimeLEDs(x,y); + drawTime(t,x,y); + } +} + +void doSetTime(unsigned long t){ + rtc.reset(); + rtc.setUNIX(t); +} + +uint8_t isDayLight(uint8_t hour, uint8_t day, uint8_t wday, uint8_t month){ + if( month < 3 || month > 10 ) // month 1, 2, 11, 12 + return 0; // -> Winter + if( day - wday >= 25 && (wday || hour >= 2) ){ // after last Sunday 2:00 + if( month == 10 ) // October -> Winter + return 0; + }else{ // before last Sunday 2:00 + if( month == 3 ) // March -> Winter + return 0; + } + return 1; +} + +uint8_t isDayLightEx(void){ + long currentUNIXTime = now(); + byte Month, Day, Hour, WDay; + Month = month(currentUNIXTime); + Day = day(currentUNIXTime); + Hour = hour(currentUNIXTime); + WDay = weekday(); + return isDayLight(Hour,Day,WDay,Month); +} + +void checkiDL(void){ + iDL = isDayLightEx(); + if(iDL != savediDL){ + long currentUNIXTime = now(); + if(iDL){ + currentUNIXTime += (SECS_PER_HOUR); + }else{ + currentUNIXTime -= (SECS_PER_HOUR); + } + setTime(currentUNIXTime); + doSetTime(currentUNIXTime); + savediDL = iDL; + EEPROM.put(10, savediDL); + EEPROM.commit(); + } +} + +void IRAM_ATTR rtc_clock(){ //Interrupt vom RTC + if(digitalRead(PINRTC_CLOCK)){ + doRTCSecond = true; + } +} + +void setup() { + //Serial.begin(115200); + //Dispolay INIT + HUB75_I2S_CFG::i2s_pins _pins = { + R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, + A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, + LAT_PIN, OE_PIN, CLK_PIN + }; + + HUB75_I2S_CFG mxconfig( + PANEL_RES_X, // module width + PANEL_RES_Y, // module height + PANEL_CHAIN, // chain length + _pins + ); + + mxconfig.double_buff = false; + mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_10M; + mxconfig.latch_blanking = 4; + mxconfig.min_refresh_rate = 50; + + display = new MatrixPanel_I2S_DMA(mxconfig); + display->begin(); + display->setPanelBrightness(100); + display->clearScreen(); + display->setFont(&TTHCENT8pt7b); + + EEPROM.begin(256); + EEPROM.get(0, timeIndex); + EEPROM.get(1, options); + withSeconds = bitRead(options,0); + alwaysAccessPoint = bitRead(options,1); + + EEPROM.get(5, brightness); + if(brightness < 0.10) + brightness = 0.10; + if(brightness > 1.0) + brightness = 1.0; + + EEPROM.get(10, savediDL); + + timeColor[0] = EEPROM.read(11); + timeColor[1] = EEPROM.read(12); + timeColor[2] = EEPROM.read(13); + + tacticalTimeColor[0] = EEPROM.read(21); + tacticalTimeColor[1] = EEPROM.read(22); + tacticalTimeColor[2] = EEPROM.read(23); + + dateColor[0] = EEPROM.read(31); + dateColor[1] = EEPROM.read(32); + dateColor[2] = EEPROM.read(33); + + kwColor[0] = EEPROM.read(41); + kwColor[1] = EEPROM.read(42); + kwColor[2] = EEPROM.read(43); + + EEPROM.get(101,ssid); + EEPROM.get(201,pass); + EEPROM.get(151,appass); + + + showNTOOLS(); + display->setCursor(1, 34); + display->print("bitte warten"); + + Wire.begin(21,22); + Wire.setClock(100000); + if (rtc.begin() == true) { + display->drawPixelRGB888(1,0,0,255,0); + rtcEnabled = true; + rtc.setBackupSwitchoverMode(3); + rtc.enableClockOut(FD_CLKOUT_1); + pinMode(PINRTC_CLOCK, INPUT_PULLUP); + attachInterrupt(digitalPinToInterrupt(PINRTC_CLOCK), rtc_clock, CHANGE); + setTime(rtc.getUNIX()); + + //prüfen ob Winterzeit + checkiDL(); + }else{ + display->drawPixelRGB888(1,0,255,0,0); + } + + macAddressTrunc = (macAddressTrunc >> 40); + ultoa(macAddressTrunc,ChipID,10); + + char NetName[30]; + strcpy(NetName, "NTDU"); + strcat(NetName, ChipID); + char APName[30]; + strcpy(APName, "NT DesignUhr "); + strcat(APName, ChipID); + + WiFi.persistent(false); + WiFi.begin(ssid,pass); + WiFi.hostname(NetName); + int xc = 0; + while ((WiFi.status() != WL_CONNECTED) && (xc < 10)) { + delay(1500); + xc++; + display->drawPixelRGB888(xc+6,0,255,255,0); + } + if (WiFi.status() == WL_CONNECTED) { + char str[5]; + IPAddress lip; + lip = WiFi.localIP(); + itoa(lip[0],str,10); + strcpy(localip, str); + strcat(localip, "."); + itoa(lip[1],str,10); + strcat(localip, str); + strcat(localip, "."); + itoa(lip[2],str,10); + strcat(localip, str); + strcat(localip, "."); + itoa(lip[3],str,10); + strcat(localip, str); + show5x7( 5, 2, localip, 255, 255, 255); + display->drawPixelRGB888(2, 0, 0, 255, 0); + configTime(0,0, "ptbtime1.ptb.de", "ptbtime2.ptb.de", "ptbtime3.ptb.de"); + time_t timenow = time(nullptr); + xc = 0; + while((timenow < SECS_YR_2000) && (xc < 10)) { + delay(1000); + timenow = time(nullptr); + xc++; + display->drawPixelRGB888(xc+17,0,255,255,0); + } + if(timenow > SECS_YR_2000){ + byte Month, Day, Hour; + setTime(timenow); + Month = month(timenow); + Day = day(timenow); + Hour = hour(timenow); + iDL = isDayLight(Hour,Day,weekday(),Month); + if(iDL) + timenow += (SECS_PER_HOUR * 2); + else + timenow += (SECS_PER_HOUR); + setTime(timenow); + if(rtcEnabled){ + doSetTime(timenow); + } + savediDL = iDL; + EEPROM.put(10, savediDL); + EEPROM.commit(); + display->drawPixelRGB888(3,0,0,255,0); + }else{ + display->drawPixelRGB888(3,0,255,0,255); + } + delay(5000); + }else{ + display->drawPixelRGB888(2,0,255,0,0); + APEnabled = true; + } + + if(APEnabled || alwaysAccessPoint){ + if(WiFi.status() == WL_CONNECTED) + WiFi.mode(WIFI_AP_STA); + else + WiFi.mode(WIFI_AP); + delay(100); + WiFi.softAPConfig(ip_local, ip_gateway, ip_subnet); + APEnabled = WiFi.softAP(APName, appass,2,0,1); + if(!APEnabled) + display->drawPixelRGB888(4,0,255,0,0); + else{ + display->drawPixelRGB888(4,0,0,255,0); + dnsServer.setErrorReplyCode(DNSReplyCode::NoError); + dnsServer.start(53, "*", ip_local); + } + }else{ + display->drawPixelRGB888(4,0,0,0,0); + } + + ElegantOTA.begin(&webServer); // Start AsyncElegantOTA + webServer.onNotFound([](AsyncWebServerRequest *request){html_handle_notsuccess(request);}); + webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request){html_root(request);}); + webServer.on("/do", HTTP_GET, [] (AsyncWebServerRequest *request) {html_do(request);}); + webServer.on("/poll", HTTP_GET, [] (AsyncWebServerRequest *request) {html_poll(request);}); + webServer.begin(); + + delay(1000); + + display->setPanelBrightness(ceil(255 * brightness)); + display->clearScreen(); + + /*display->setTextColor(display->color565(128,255,0)); + display->setFont(&NT7x10); + display->setCursor(13, 11); + display->print("alles gute im"); + display->setCursor(17, 22); + display->setTextColor(display->color565(255,0,0)); + display->print("neuen heim"); + */ +} + +void loop() { + if (millis() - ti_second > 1000) { + ti_second = millis(); + if(!rtcEnabled){ + doRTCSecond = true; + } + } + if(doRTCSecond){ + doRTCSecond = false; + time_t currentUNIXTime = now(); + if(rtcEnabled){ + currentUNIXTime = rtc.getUNIX(); + setTime(currentUNIXTime); + } + uint8_t Hour, Minute, Second, WDay; + Hour = hour(currentUNIXTime); + Minute = minute(currentUNIXTime); + Second = second(currentUNIXTime); + WDay = weekday(); + checkiDL(); + //Sonntag Reset .. + if((WDay == 1) && (Hour == 3) && (Minute == 1) && (Second == 0)){ + ESP.restart(); + } + switch(timeIndex){ + case 0: + showTimeTactical(currentUNIXTime); + break; + case 1: + showTime(currentUNIXTime,4,10); + break; + case 2: + //showDateTime(currentUNIXTime); + break; + case 3: + + showTime(currentUNIXTime,8,24); + break; + case 4: + //clock_center_x = 16; + //showAnalogTime(currentUNIXTime); + //showAnalogDate(currentUNIXTime); + break; + + } + + } + + if(APEnabled) + dnsServer.processNextRequest(); + ElegantOTA.loop(); +} + +void html_poll(AsyncWebServerRequest *request) { + long color = 0; + char ret[250]; + char tempBuff[30]; + strcpy(ret,(char *)"["); + if(rtcEnabled) + ltoa(rtc.getUNIX(),tempBuff,DEC); + else + ltoa(now(),tempBuff,DEC); + strcat(ret,tempBuff); + color = timeColor[0] << 16; + color += timeColor[1] << 8; + color += timeColor[2]; + itoa(color,tempBuff,DEC); + strcat(ret,(char *)","); + strcat(ret,tempBuff); + color = tacticalTimeColor[0] << 16; + color += tacticalTimeColor[1] << 8; + color += tacticalTimeColor[2]; + itoa(color,tempBuff,DEC); + strcat(ret,(char *)","); + strcat(ret,tempBuff); + color = dateColor[0] << 16; + color += dateColor[1] << 8; + color += dateColor[2]; + itoa(color,tempBuff,DEC); + strcat(ret,(char *)","); + strcat(ret,tempBuff); + itoa(timeIndex,tempBuff,DEC); + strcat(ret,(char *)","); + strcat(ret,tempBuff); + itoa(lastTimeSyncTyp,tempBuff,DEC); + strcat(ret,(char *)","); + strcat(ret,tempBuff); + itoa(lastTimeSyncTime,tempBuff,DEC); + strcat(ret,(char *)","); + strcat(ret,tempBuff); + dtostrf(brightness, 10, 2, tempBuff); + strcat(ret,(char *)",\""); + strcat(ret,tempBuff); + strcat(ret,(char *)"\""); + itoa(rtcEnabled,tempBuff,DEC); + strcat(ret,(char *)","); + strcat(ret,tempBuff); + itoa(EEPROMDataNotSaved,tempBuff,DEC); + strcat(ret,(char *)","); + strcat(ret,tempBuff); + strcat(ret,(char *)",\""); + strcat(ret,ssid); + strcat(ret,(char *)"\""); + itoa(options,tempBuff,DEC); + strcat(ret,(char *)","); + strcat(ret,tempBuff); + color = kwColor[0] << 16; + color += kwColor[1] << 8; + color += kwColor[2]; + itoa(color,tempBuff,DEC); + strcat(ret,(char *)","); + strcat(ret,tempBuff); + uint8_t kw = GetWeekNumber(year(now()),month(now()),day(now())); + itoa(kw,tempBuff,DEC); + strcat(ret,(char *)","); + strcat(ret,tempBuff); + itoa(iDL,tempBuff,DEC); + strcat(ret,(char *)","); + strcat(ret,tempBuff); + strcat(ret,(char *)"]"); + request->send(200, "text/plain", ret); +} + +void html_do(AsyncWebServerRequest *request) { + String s_set,s_value,s_idx,s_value2; + uint32_t l_value; + if (request->hasParam(PARAM_SET)) { + s_set = request->getParam(PARAM_SET)->value(); + if((s_set == "time") & (request->hasParam(PARAM_TO))) { + s_value = request->getParam(PARAM_TO)->value(); + l_value = strtol(s_value.c_str(), NULL, 10); + doSetTime(l_value); + lastTimeSyncTyp = 3; + lastTimeSyncTime = now(); + }else if(request->hasParam(PARAM_SHOWWHAT)) { + s_value = request->getParam(PARAM_SHOWWHAT)->value(); + timeIndex = s_value.toInt(); + display->clearScreen(); + EEPROM.put(0, timeIndex); + EEPROMDataNotSaved = true; + }else if(((s_set == "color") | (s_set == "tcolor") | (s_set == "dcolor") | (s_set == "kwcolor")) & (request->hasParam(PARAM_TO))) { + s_value = request->getParam(PARAM_TO)->value(); + uint8_t c[3]; + l_value = strtol(s_value.c_str(), NULL, 16); + c[0] = l_value >> 16; + c[1] = l_value >> 8; + c[2] = l_value; + if(s_set == "color"){ + timeColor[0] = c[0]; + timeColor[1] = c[1]; + timeColor[2] = c[2]; + EEPROM.write(11,timeColor[0]); + EEPROM.write(12,timeColor[1]); + EEPROM.write(13,timeColor[2]); + EEPROMDataNotSaved = true; + }else if(s_set == "tcolor"){ + tacticalTimeColor[0] = c[0]; + tacticalTimeColor[1] = c[1]; + tacticalTimeColor[2] = c[2]; + EEPROM.write(21,tacticalTimeColor[0]); + EEPROM.write(22,tacticalTimeColor[1]); + EEPROM.write(23,tacticalTimeColor[2]); + EEPROMDataNotSaved = true; + }else if(s_set == "dcolor"){ + dateColor[0] = c[0]; + dateColor[1] = c[1]; + dateColor[2] = c[2]; + EEPROM.write(31,dateColor[0]); + EEPROM.write(32,dateColor[1]); + EEPROM.write(33,dateColor[2]); + EEPROMDataNotSaved = true; + }else if(s_set == "kwcolor"){ + kwColor[0] = c[0]; + kwColor[1] = c[1]; + kwColor[2] = c[2]; + EEPROM.write(41,kwColor[0]); + EEPROM.write(42,kwColor[1]); + EEPROM.write(43,kwColor[2]); + EEPROMDataNotSaved = true; + } + }else if((s_set == "option")) { + if(request->hasParam(PARAM_BRIGHTNESS)) { + s_value = request->getParam(PARAM_BRIGHTNESS)->value(); + brightness = s_value.toFloat(); + EEPROM.put(5,brightness); + EEPROMDataNotSaved = true; + display->setPanelBrightness(ceil(255 * brightness)); + } + if(request->hasParam(PARAM_OPTIONS)) { + s_value = request->getParam(PARAM_OPTIONS)->value(); + options = s_value.toInt(); + EEPROM.put(1,options); + EEPROMDataNotSaved = true; + withSeconds = bitRead(options,0); + alwaysAccessPoint = bitRead(options,1); + display->clearScreen(); + } + }else if((s_set == "wifi")) { + if((request->hasParam(PARAM_SSID)) && (request->hasParam(PARAM_PWD))){ + s_value = request->getParam(PARAM_SSID)->value(); + s_value2 = request->getParam(PARAM_PWD )->value(); + if((s_value != ssid) || (s_value2 != pass)){ + s_value.toCharArray(ssid, 30); + s_value2.toCharArray(pass, 30); + EEPROM.put(101,ssid); + EEPROM.put(201,pass); + EEPROMDataNotSaved = true; + } + + } + }else if((s_set == "appass")) { + if(request->hasParam(PARAM_PWD)){ + s_value2 = request->getParam(PARAM_PWD )->value(); + if((s_value2 != appass)){ + s_value2.toCharArray(appass, 30); + EEPROM.put(151,appass); + EEPROMDataNotSaved = true; + } + + } + } + request->send(200, "text/plain", "OK"); + lastminutes = -1; + }else if (request->hasParam(PARAM_SAVE)){ + EEPROM.commit(); + EEPROMDataNotSaved = false; + request->send(200, "text/plain", "OK"); + }else if (request->hasParam(PARAM_RESET)){ + request->send(200, "text/plain", "OK"); + delay(1000); + ESP.restart(); + } + request->send(200, "text/plain", "NOK"); +} + diff --git a/ESP32_MasterPx_DesignUhr/ESP32_MasterPx_DesignUhr/esp32.svd b/ESP32_MasterPx_DesignUhr/ESP32_MasterPx_DesignUhr/esp32.svd new file mode 100644 index 0000000..783023f --- /dev/null +++ b/ESP32_MasterPx_DesignUhr/ESP32_MasterPx_DesignUhr/esp32.svd @@ -0,0 +1,46087 @@ + + + ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. + ESPRESSIF + ESP32 + ESP32 + 8 + 32-bit MCU & 2.4 GHz Wi-Fi & Bluetooth/Bluetooth LE + + Copyright 2022 Espressif Systems (Shanghai) PTE LTD + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Xtensa LX6 + r0p0 + little + false + true + 3 + false + + 32 + 32 + 0x00000000 + 0xFFFFFFFF + + + AES + AES (Advanced Encryption Standard) Accelerator + AES + 0x3FF01000 + + 0x0 + 0x40 + registers + + + + START + 0x0 + 0x20 + + + START + Write 1 to start the AES operation. + 0 + 1 + write-only + + + + + IDLE + 0x4 + 0x20 + + + IDLE + AES Idle register. Reads ’zero’ while the AES Accelerator is busy processing; reads ’one’ otherwise. + 0 + 1 + read-only + + + + + MODE + 0x8 + 0x20 + + + MODE + Selects the AES accelerator mode of operation. See Table 22-1 for details. + 0 + 8 + read-write + + + + + 8 + 0x4 + KEY_%s + 0x10 + 0x20 + + + KEY + AES key material register. + 0 + 8 + read-write + + + + + 4 + 0x4 + TEXT_%s + 0x30 + 0x20 + + + TEXT + Plaintext and ciphertext register. + 0 + 8 + read-write + + + + + ENDIAN + 0x40 + 0x20 + + + ENDIAN + Endianness selection register. See Table 22-2 for details. + 0 + 2 + read-write + + + + + + + APB_CTRL + Advanced Peripheral Bus Controller + APB_CTRL + 0x3FF66000 + + 0x0 + 0x44 + registers + + + + SYSCLK_CONF + 0x0 + 0x20 + 0x00002000 + + + PRE_DIV_CNT + 0 + 10 + read-write + + + CLK_320M_EN + 10 + 1 + read-write + + + CLK_EN + 11 + 1 + read-write + + + RST_TICK_CNT + 12 + 1 + read-write + + + QUICK_CLK_CHNG + 13 + 1 + read-write + + + + + XTAL_TICK_CONF + 0x4 + 0x20 + 0x00000027 + + + XTAL_TICK_NUM + 0 + 8 + read-write + + + + + PLL_TICK_CONF + 0x8 + 0x20 + 0x0000004F + + + PLL_TICK_NUM + 0 + 8 + read-write + + + + + CK8M_TICK_CONF + 0xC + 0x20 + 0x0000000B + + + CK8M_TICK_NUM + 0 + 8 + read-write + + + + + APB_SARADC_CTRL + 0x10 + 0x20 + 0x007F8240 + + + SARADC_START_FORCE + 0 + 1 + read-write + + + SARADC_START + 1 + 1 + read-write + + + SARADC_SAR2_MUX + 1: SAR ADC2 is controlled by DIG ADC2 CTRL 0: SAR ADC2 is controlled by PWDET CTRL + 2 + 1 + read-write + + + SARADC_WORK_MODE + 0: single mode 1: double mode 2: alternate mode + 3 + 2 + read-write + + + SARADC_SAR_SEL + 0: SAR1 1: SAR2 only work for single SAR mode + 5 + 1 + read-write + + + SARADC_SAR_CLK_GATED + 6 + 1 + read-write + + + SARADC_SAR_CLK_DIV + SAR clock divider + 7 + 8 + read-write + + + SARADC_SAR1_PATT_LEN + 0 ~ 15 means length 1 ~ 16 + 15 + 4 + read-write + + + SARADC_SAR2_PATT_LEN + 0 ~ 15 means length 1 ~ 16 + 19 + 4 + read-write + + + SARADC_SAR1_PATT_P_CLEAR + clear the pointer of pattern table for DIG ADC1 CTRL + 23 + 1 + read-write + + + SARADC_SAR2_PATT_P_CLEAR + clear the pointer of pattern table for DIG ADC2 CTRL + 24 + 1 + read-write + + + SARADC_DATA_SAR_SEL + 1: sar_sel will be coded by the MSB of the 16-bit output data in this case the resolution should not be larger than 11 bits. + 25 + 1 + read-write + + + SARADC_DATA_TO_I2S + 1: I2S input data is from SAR ADC (for DMA) 0: I2S input data is from GPIO matrix + 26 + 1 + read-write + + + + + APB_SARADC_CTRL2 + 0x14 + 0x20 + 0x000001FE + + + SARADC_MEAS_NUM_LIMIT + 0 + 1 + read-write + + + SARADC_MAX_MEAS_NUM + max conversion number + 1 + 8 + read-write + + + SARADC_SAR1_INV + 1: data to DIG ADC1 CTRL is inverted otherwise not + 9 + 1 + read-write + + + SARADC_SAR2_INV + 1: data to DIG ADC2 CTRL is inverted otherwise not + 10 + 1 + read-write + + + + + APB_SARADC_FSM + 0x18 + 0x20 + 0x0208FF08 + + + SARADC_RSTB_WAIT + 0 + 8 + read-write + + + SARADC_STANDBY_WAIT + 8 + 8 + read-write + + + SARADC_START_WAIT + 16 + 8 + read-write + + + SARADC_SAMPLE_CYCLE + sample cycles + 24 + 8 + read-write + + + + + APB_SARADC_SAR1_PATT_TAB1 + 0x1C + 0x20 + 0x0F0F0F0F + + + SARADC_SAR1_PATT_TAB1 + item 0 ~ 3 for pattern table 1 (each item one byte) + 0 + 32 + read-write + + + + + APB_SARADC_SAR1_PATT_TAB2 + 0x20 + 0x20 + 0x0F0F0F0F + + + SARADC_SAR1_PATT_TAB2 + Item 4 ~ 7 for pattern table 1 (each item one byte) + 0 + 32 + read-write + + + + + APB_SARADC_SAR1_PATT_TAB3 + 0x24 + 0x20 + 0x0F0F0F0F + + + SARADC_SAR1_PATT_TAB3 + Item 8 ~ 11 for pattern table 1 (each item one byte) + 0 + 32 + read-write + + + + + APB_SARADC_SAR1_PATT_TAB4 + 0x28 + 0x20 + 0x0F0F0F0F + + + SARADC_SAR1_PATT_TAB4 + Item 12 ~ 15 for pattern table 1 (each item one byte) + 0 + 32 + read-write + + + + + APB_SARADC_SAR2_PATT_TAB1 + 0x2C + 0x20 + 0x0F0F0F0F + + + SARADC_SAR2_PATT_TAB1 + item 0 ~ 3 for pattern table 2 (each item one byte) + 0 + 32 + read-write + + + + + APB_SARADC_SAR2_PATT_TAB2 + 0x30 + 0x20 + 0x0F0F0F0F + + + SARADC_SAR2_PATT_TAB2 + Item 4 ~ 7 for pattern table 2 (each item one byte) + 0 + 32 + read-write + + + + + APB_SARADC_SAR2_PATT_TAB3 + 0x34 + 0x20 + 0x0F0F0F0F + + + SARADC_SAR2_PATT_TAB3 + Item 8 ~ 11 for pattern table 2 (each item one byte) + 0 + 32 + read-write + + + + + APB_SARADC_SAR2_PATT_TAB4 + 0x38 + 0x20 + 0x0F0F0F0F + + + SARADC_SAR2_PATT_TAB4 + Item 12 ~ 15 for pattern table 2 (each item one byte) + 0 + 32 + read-write + + + + + APLL_TICK_CONF + 0x3C + 0x20 + 0x00000063 + + + APLL_TICK_NUM + 0 + 8 + read-write + + + + + DATE + 0x7C + 0x20 + 0x16042000 + + + DATE + 0 + 32 + read-write + + + + + + + BB + Peripheral BB + BB + 0x3FF5D000 + + 0x0 + 0x4 + registers + + + + BBPD_CTRL + Baseband control register + 0x54 + 0x20 + + + DC_EST_FORCE_PD + 0 + 1 + read-write + + + DC_EST_FORCE_PU + 1 + 1 + read-write + + + FFT_FORCE_PD + 2 + 1 + read-write + + + FFT_FORCE_PU + 3 + 1 + read-write + + + + + + + DPORT + Peripheral DPORT + DPORT + 0x3FF00000 + + 0x0 + 0x5C0 + registers + + + WIFI_MAC + 0 + + + WIFI_NMI + 1 + + + WIFI_BB + 2 + + + BT_MAC + 3 + + + BT_BB + 4 + + + BT_BB_NMI + 5 + + + RWBT + 6 + + + RWBLE + 7 + + + RWBT_NMI + 8 + + + RWBLE_NMI + 9 + + + + PRO_BOOT_REMAP_CTRL + 0x0 + 0x20 + + + PRO_BOOT_REMAP + 0 + 1 + read-write + + + + + APP_BOOT_REMAP_CTRL + 0x4 + 0x20 + + + APP_BOOT_REMAP + 0 + 1 + read-write + + + + + ACCESS_CHECK + 0x8 + 0x20 + + + PRO + 0 + 1 + read-only + + + APP + 8 + 1 + read-only + + + + + PRO_DPORT_APB_MASK0 + 0xC + 0x20 + + + PRODPORT_APB_MASK0 + 0 + 32 + read-write + + + + + PRO_DPORT_APB_MASK1 + 0x10 + 0x20 + + + PRODPORT_APB_MASK1 + 0 + 32 + read-write + + + + + APP_DPORT_APB_MASK0 + 0x14 + 0x20 + + + APPDPORT_APB_MASK0 + 0 + 32 + read-write + + + + + APP_DPORT_APB_MASK1 + 0x18 + 0x20 + + + APPDPORT_APB_MASK1 + 0 + 32 + read-write + + + + + PERI_CLK_EN + 0x1C + 0x20 + + + PERI_CLK_EN + 0 + 32 + read-write + + + + + PERI_RST_EN + 0x20 + 0x20 + + + PERI_RST_EN + 0 + 32 + read-write + + + + + WIFI_BB_CFG + 0x24 + 0x20 + + + WIFI_BB_CFG + 0 + 32 + read-write + + + + + WIFI_BB_CFG_2 + 0x28 + 0x20 + + + WIFI_BB_CFG_2 + 0 + 32 + read-write + + + + + APPCPU_CTRL_A + 0x2C + 0x20 + 0x00000001 + + + APPCPU_RESETTING + 0 + 1 + read-write + + + + + APPCPU_CTRL_B + 0x30 + 0x20 + + + APPCPU_CLKGATE_EN + 0 + 1 + read-write + + + + + APPCPU_CTRL_C + 0x34 + 0x20 + + + APPCPU_RUNSTALL + 0 + 1 + read-write + + + + + APPCPU_CTRL_D + 0x38 + 0x20 + + + APPCPU_BOOT_ADDR + 0 + 32 + read-write + + + + + CPU_PER_CONF + 0x3C + 0x20 + + + CPUPERIOD_SEL + 0 + 2 + read-write + + + LOWSPEED_CLK_SEL + 2 + 1 + read-write + + + FAST_CLK_RTC_SEL + 3 + 1 + read-write + + + + + PRO_CACHE_CTRL + 0x40 + 0x20 + 0x00000010 + + + PRO_CACHE_MODE + 2 + 1 + read-write + + + PRO_CACHE_ENABLE + 3 + 1 + read-write + + + PRO_CACHE_FLUSH_ENA + 4 + 1 + read-write + + + PRO_CACHE_FLUSH_DONE + 5 + 1 + read-only + + + PRO_CACHE_LOCK_0_EN + 6 + 1 + read-write + + + PRO_CACHE_LOCK_1_EN + 7 + 1 + read-write + + + PRO_CACHE_LOCK_2_EN + 8 + 1 + read-write + + + PRO_CACHE_LOCK_3_EN + 9 + 1 + read-write + + + PRO_SINGLE_IRAM_ENA + 10 + 1 + read-write + + + PRO_DRAM_SPLIT + 11 + 1 + read-write + + + PRO_AHB_SPI_REQ + 12 + 1 + read-only + + + PRO_SLAVE_REQ + 13 + 1 + read-only + + + AHB_SPI_REQ + 14 + 1 + read-only + + + SLAVE_REQ + 15 + 1 + read-only + + + PRO_DRAM_HL + 16 + 1 + read-write + + + + + PRO_CACHE_CTRL1 + 0x44 + 0x20 + 0x000008FF + + + PRO_CACHE_MASK_IRAM0 + 0 + 1 + read-write + + + PRO_CACHE_MASK_IRAM1 + 1 + 1 + read-write + + + PRO_CACHE_MASK_IROM0 + 2 + 1 + read-write + + + PRO_CACHE_MASK_DRAM1 + 3 + 1 + read-write + + + PRO_CACHE_MASK_DROM0 + 4 + 1 + read-write + + + PRO_CACHE_MASK_OPSDRAM + 5 + 1 + read-write + + + PRO_CMMU_SRAM_PAGE_MODE + 6 + 3 + read-write + + + PRO_CMMU_FLASH_PAGE_MODE + 9 + 2 + read-write + + + PRO_CMMU_FORCE_ON + 11 + 1 + read-write + + + PRO_CMMU_PD + 12 + 1 + read-write + + + PRO_CACHE_MMU_IA_CLR + 13 + 1 + read-write + + + + + PRO_CACHE_LOCK_0_ADDR + 0x48 + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + PRO_CACHE_LOCK_1_ADDR + 0x4C + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + PRO_CACHE_LOCK_2_ADDR + 0x50 + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + PRO_CACHE_LOCK_3_ADDR + 0x54 + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + APP_CACHE_CTRL + 0x58 + 0x20 + 0x00000010 + + + APP_CACHE_MODE + 2 + 1 + read-write + + + APP_CACHE_ENABLE + 3 + 1 + read-write + + + APP_CACHE_FLUSH_ENA + 4 + 1 + read-write + + + APP_CACHE_FLUSH_DONE + 5 + 1 + read-only + + + APP_CACHE_LOCK_0_EN + 6 + 1 + read-write + + + APP_CACHE_LOCK_1_EN + 7 + 1 + read-write + + + APP_CACHE_LOCK_2_EN + 8 + 1 + read-write + + + APP_CACHE_LOCK_3_EN + 9 + 1 + read-write + + + APP_SINGLE_IRAM_ENA + 10 + 1 + read-write + + + APP_DRAM_SPLIT + 11 + 1 + read-write + + + APP_AHB_SPI_REQ + 12 + 1 + read-only + + + APP_SLAVE_REQ + 13 + 1 + read-only + + + APP_DRAM_HL + 14 + 1 + read-write + + + + + APP_CACHE_CTRL1 + 0x5C + 0x20 + 0x000008FF + + + APP_CACHE_MASK_IRAM0 + 0 + 1 + read-write + + + APP_CACHE_MASK_IRAM1 + 1 + 1 + read-write + + + APP_CACHE_MASK_IROM0 + 2 + 1 + read-write + + + APP_CACHE_MASK_DRAM1 + 3 + 1 + read-write + + + APP_CACHE_MASK_DROM0 + 4 + 1 + read-write + + + APP_CACHE_MASK_OPSDRAM + 5 + 1 + read-write + + + APP_CMMU_SRAM_PAGE_MODE + 6 + 3 + read-write + + + APP_CMMU_FLASH_PAGE_MODE + 9 + 2 + read-write + + + APP_CMMU_FORCE_ON + 11 + 1 + read-write + + + APP_CMMU_PD + 12 + 1 + read-write + + + APP_CACHE_MMU_IA_CLR + 13 + 1 + read-write + + + + + APP_CACHE_LOCK_0_ADDR + 0x60 + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + APP_CACHE_LOCK_1_ADDR + 0x64 + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + APP_CACHE_LOCK_2_ADDR + 0x68 + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + APP_CACHE_LOCK_3_ADDR + 0x6C + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + TRACEMEM_MUX_MODE + 0x70 + 0x20 + + + TRACEMEM_MUX_MODE + 0 + 2 + read-write + + + + + PRO_TRACEMEM_ENA + 0x74 + 0x20 + + + PRO_TRACEMEM_ENA + 0 + 1 + read-write + + + + + APP_TRACEMEM_ENA + 0x78 + 0x20 + + + APP_TRACEMEM_ENA + 0 + 1 + read-write + + + + + CACHE_MUX_MODE + 0x7C + 0x20 + + + CACHE_MUX_MODE + 0 + 2 + read-write + + + + + IMMU_PAGE_MODE + 0x80 + 0x20 + + + INTERNAL_SRAM_IMMU_ENA + 0 + 1 + read-write + + + IMMU_PAGE_MODE + 1 + 2 + read-write + + + + + DMMU_PAGE_MODE + 0x84 + 0x20 + + + INTERNAL_SRAM_DMMU_ENA + 0 + 1 + read-write + + + DMMU_PAGE_MODE + 1 + 2 + read-write + + + + + ROM_MPU_ENA + 0x88 + 0x20 + + + SHARE_ROM_MPU_ENA + 0 + 1 + read-write + + + PRO_ROM_MPU_ENA + 1 + 1 + read-write + + + APP_ROM_MPU_ENA + 2 + 1 + read-write + + + + + MEM_PD_MASK + 0x8C + 0x20 + 0x00000001 + + + LSLP_MEM_PD_MASK + 0 + 1 + read-write + + + + + ROM_PD_CTRL + 0x90 + 0x20 + + + PRO_ROM_PD + 0 + 1 + read-write + + + APP_ROM_PD + 1 + 1 + read-write + + + SHARE_ROM_PD + 2 + 6 + read-write + + + + + ROM_FO_CTRL + 0x94 + 0x20 + 0x00000003 + + + PRO_ROM_FO + 0 + 1 + read-write + + + APP_ROM_FO + 1 + 1 + read-write + + + SHARE_ROM_FO + 2 + 6 + read-write + + + + + SRAM_PD_CTRL_0 + 0x98 + 0x20 + + + SRAM_PD_0 + 0 + 32 + read-write + + + + + SRAM_PD_CTRL_1 + 0x9C + 0x20 + + + SRAM_PD_1 + 0 + 1 + read-write + + + + + SRAM_FO_CTRL_0 + 0xA0 + 0x20 + 0xFFFFFFFF + + + SRAM_FO_0 + 0 + 32 + read-write + + + + + SRAM_FO_CTRL_1 + 0xA4 + 0x20 + 0x00000001 + + + SRAM_FO_1 + 0 + 1 + read-write + + + + + IRAM_DRAM_AHB_SEL + 0xA8 + 0x20 + + + MASK_PRO_IRAM + 0 + 1 + read-write + + + MASK_APP_IRAM + 1 + 1 + read-write + + + MASK_PRO_DRAM + 2 + 1 + read-write + + + MASK_APP_DRAM + 3 + 1 + read-write + + + MASK_AHB + 4 + 1 + read-write + + + MAC_DUMP_MODE + 5 + 2 + read-write + + + + + TAG_FO_CTRL + 0xAC + 0x20 + 0x00000101 + + + PRO_CACHE_TAG_FORCE_ON + 0 + 1 + read-write + + + PRO_CACHE_TAG_PD + 1 + 1 + read-write + + + APP_CACHE_TAG_FORCE_ON + 8 + 1 + read-write + + + APP_CACHE_TAG_PD + 9 + 1 + read-write + + + + + AHB_LITE_MASK + 0xB0 + 0x20 + + + PRO + 0 + 1 + read-write + + + APP + 4 + 1 + read-write + + + SDIO + 8 + 1 + read-write + + + PRODPORT + 9 + 1 + read-write + + + APPDPORT + 10 + 1 + read-write + + + AHB_LITE_SDHOST_PID + 11 + 3 + read-write + + + + + AHB_MPU_TABLE_0 + 0xB4 + 0x20 + 0xFFFFFFFF + + + AHB_ACCESS_GRANT_0 + 0 + 32 + read-write + + + + + AHB_MPU_TABLE_1 + 0xB8 + 0x20 + 0x000001FF + + + AHB_ACCESS_GRANT_1 + 0 + 9 + read-write + + + + + HOST_INF_SEL + 0xBC + 0x20 + + + PERI_IO_SWAP + 0 + 8 + read-write + + + LINK_DEVICE_SEL + 8 + 8 + read-write + + + + + PERIP_CLK_EN + 0xC0 + 0x20 + 0xF9C1E06F + + + TIMERS_CLK_EN + 0 + 1 + read-write + + + SPI01_CLK_EN + 1 + 1 + read-write + + + UART_CLK_EN + 2 + 1 + read-write + + + WDG_CLK_EN + 3 + 1 + read-write + + + I2S0_CLK_EN + 4 + 1 + read-write + + + UART1_CLK_EN + 5 + 1 + read-write + + + SPI2_CLK_EN + 6 + 1 + read-write + + + I2C0_EXT0_CLK_EN + 7 + 1 + read-write + + + UHCI0_CLK_EN + 8 + 1 + read-write + + + RMT_CLK_EN + 9 + 1 + read-write + + + PCNT_CLK_EN + 10 + 1 + read-write + + + LEDC_CLK_EN + 11 + 1 + read-write + + + UHCI1_CLK_EN + 12 + 1 + read-write + + + TIMERGROUP_CLK_EN + 13 + 1 + read-write + + + EFUSE_CLK_EN + 14 + 1 + read-write + + + TIMERGROUP1_CLK_EN + 15 + 1 + read-write + + + SPI3_CLK_EN + 16 + 1 + read-write + + + PWM0_CLK_EN + 17 + 1 + read-write + + + I2C_EXT1_CLK_EN + 18 + 1 + read-write + + + TWAI_CLK_EN + 19 + 1 + read-write + + + PWM1_CLK_EN + 20 + 1 + read-write + + + I2S1_CLK_EN + 21 + 1 + read-write + + + SPI_DMA_CLK_EN + 22 + 1 + read-write + + + UART2_CLK_EN + 23 + 1 + read-write + + + UART_MEM_CLK_EN + 24 + 1 + read-write + + + PWM2_CLK_EN + 25 + 1 + read-write + + + PWM3_CLK_EN + 26 + 1 + read-write + + + + + PERIP_RST_EN + 0xC4 + 0x20 + + + TIMERS_RST + 0 + 1 + read-write + + + SPI01_RST + 1 + 1 + read-write + + + UART_RST + 2 + 1 + read-write + + + WDG_RST + 3 + 1 + read-write + + + I2S0_RST + 4 + 1 + read-write + + + UART1_RST + 5 + 1 + read-write + + + SPI2_RST + 6 + 1 + read-write + + + I2C0_EXT0_RST + 7 + 1 + read-write + + + UHCI0_RST + 8 + 1 + read-write + + + RMT_RST + 9 + 1 + read-write + + + PCNT_RST + 10 + 1 + read-write + + + LEDC_RST + 11 + 1 + read-write + + + UHCI1_RST + 12 + 1 + read-write + + + TIMERGROUP_RST + 13 + 1 + read-write + + + EFUSE_RST + 14 + 1 + read-write + + + TIMERGROUP1_RST + 15 + 1 + read-write + + + SPI3_RST + 16 + 1 + read-write + + + PWM0_RST + 17 + 1 + read-write + + + I2C_EXT1_RST + 18 + 1 + read-write + + + TWAI_RST + 19 + 1 + read-write + + + PWM1_RST + 20 + 1 + read-write + + + I2S1_RST + 21 + 1 + read-write + + + SPI_DMA_RST + 22 + 1 + read-write + + + UART2_RST + 23 + 1 + read-write + + + UART_MEM_RST + 24 + 1 + read-write + + + PWM2_RST + 25 + 1 + read-write + + + PWM3_RST + 26 + 1 + read-write + + + + + SLAVE_SPI_CONFIG + 0xC8 + 0x20 + + + SLAVE_SPI_MASK_PRO + 0 + 1 + read-write + + + SLAVE_SPI_MASK_APP + 4 + 1 + read-write + + + SPI_ENCRYPT_ENABLE + 8 + 1 + read-write + + + SPI_DECRYPT_ENABLE + 12 + 1 + read-write + + + + + WIFI_CLK_EN + 0xCC + 0x20 + 0xFFFCE030 + + + WIFI_CLK_EN + 0 + 32 + read-write + + + WIFI_CLK_WIFI_EN + 0 + 3 + read-write + + + WIFI_CLK_WIFI_BT_COMMON + 0 + 6 + read-write + + + WIFI_CLK_BT_EN + 11 + 3 + read-write + + + + + CORE_RST_EN + 0xD0 + 0x20 + + + CORE_RST + 0 + 8 + read-write + + + BB_RST + 0 + 1 + read-write + + + FE_RST + 1 + 1 + read-write + + + MAC_RST + 2 + 1 + read-write + + + BT_RST + 3 + 1 + read-write + + + BTMAC_RST + 4 + 1 + read-write + + + SDIO_RST + 5 + 1 + read-write + + + SDIO_HOST_RST + 6 + 1 + read-write + + + EMAC_RST + 7 + 1 + read-write + + + MACPWR_RST + 8 + 1 + read-write + + + RW_BTMAC_RST + 9 + 1 + read-write + + + RW_BTLP_RST + 10 + 1 + read-write + + + + + BT_LPCK_DIV_INT + 0xD4 + 0x20 + 0x000000FF + + + BT_LPCK_DIV_NUM + 0 + 12 + read-write + + + BTEXTWAKEUP_REQ + 12 + 1 + read-write + + + + + BT_LPCK_DIV_FRAC + 0xD8 + 0x20 + 0x02001001 + + + BT_LPCK_DIV_B + 0 + 12 + read-write + + + BT_LPCK_DIV_A + 12 + 12 + read-write + + + LPCLK_SEL_RTC_SLOW + 24 + 1 + read-write + + + LPCLK_SEL_8M + 25 + 1 + read-write + + + LPCLK_SEL_XTAL + 26 + 1 + read-write + + + LPCLK_SEL_XTAL32K + 27 + 1 + read-write + + + + + CPU_INTR_FROM_CPU_0 + 0xDC + 0x20 + + + CPU_INTR_FROM_CPU_0 + 0 + 1 + read-write + + + + + CPU_INTR_FROM_CPU_1 + 0xE0 + 0x20 + + + CPU_INTR_FROM_CPU_1 + 0 + 1 + read-write + + + + + CPU_INTR_FROM_CPU_2 + 0xE4 + 0x20 + + + CPU_INTR_FROM_CPU_2 + 0 + 1 + read-write + + + + + CPU_INTR_FROM_CPU_3 + 0xE8 + 0x20 + + + CPU_INTR_FROM_CPU_3 + 0 + 1 + read-write + + + + + PRO_INTR_STATUS_0 + 0xEC + 0x20 + + + PRO_INTR_STATUS_0 + 0 + 32 + read-only + + + + + PRO_INTR_STATUS_1 + 0xF0 + 0x20 + + + PRO_INTR_STATUS_1 + 0 + 32 + read-only + + + + + PRO_INTR_STATUS_2 + 0xF4 + 0x20 + + + PRO_INTR_STATUS_2 + 0 + 32 + read-only + + + + + APP_INTR_STATUS_0 + 0xF8 + 0x20 + + + APP_INTR_STATUS_0 + 0 + 32 + read-only + + + + + APP_INTR_STATUS_1 + 0xFC + 0x20 + + + APP_INTR_STATUS_1 + 0 + 32 + read-only + + + + + APP_INTR_STATUS_2 + 0x100 + 0x20 + + + APP_INTR_STATUS_2 + 0 + 32 + read-only + + + + + PRO_MAC_INTR_MAP + 0x104 + 0x20 + 0x00000010 + + + PRO_MAC_INTR_MAP + 0 + 5 + read-write + + + + + PRO_MAC_NMI_MAP + 0x108 + 0x20 + 0x00000010 + + + PRO_MAC_NMI_MAP + 0 + 5 + read-write + + + + + PRO_BB_INT_MAP + 0x10C + 0x20 + 0x00000010 + + + PRO_BB_INT_MAP + 0 + 5 + read-write + + + + + PRO_BT_MAC_INT_MAP + 0x110 + 0x20 + 0x00000010 + + + PRO_BT_MAC_INT_MAP + 0 + 5 + read-write + + + + + PRO_BT_BB_INT_MAP + 0x114 + 0x20 + 0x00000010 + + + PRO_BT_BB_INT_MAP + 0 + 5 + read-write + + + + + PRO_BT_BB_NMI_MAP + 0x118 + 0x20 + 0x00000010 + + + PRO_BT_BB_NMI_MAP + 0 + 5 + read-write + + + + + PRO_RWBT_IRQ_MAP + 0x11C + 0x20 + 0x00000010 + + + PRO_RWBT_IRQ_MAP + 0 + 5 + read-write + + + + + PRO_RWBLE_IRQ_MAP + 0x120 + 0x20 + 0x00000010 + + + PRO_RWBLE_IRQ_MAP + 0 + 5 + read-write + + + + + PRO_RWBT_NMI_MAP + 0x124 + 0x20 + 0x00000010 + + + PRO_RWBT_NMI_MAP + 0 + 5 + read-write + + + + + PRO_RWBLE_NMI_MAP + 0x128 + 0x20 + 0x00000010 + + + PRO_RWBLE_NMI_MAP + 0 + 5 + read-write + + + + + PRO_SLC0_INTR_MAP + 0x12C + 0x20 + 0x00000010 + + + PRO_SLC0_INTR_MAP + 0 + 5 + read-write + + + + + PRO_SLC1_INTR_MAP + 0x130 + 0x20 + 0x00000010 + + + PRO_SLC1_INTR_MAP + 0 + 5 + read-write + + + + + PRO_UHCI0_INTR_MAP + 0x134 + 0x20 + 0x00000010 + + + PRO_UHCI0_INTR_MAP + 0 + 5 + read-write + + + + + PRO_UHCI1_INTR_MAP + 0x138 + 0x20 + 0x00000010 + + + PRO_UHCI1_INTR_MAP + 0 + 5 + read-write + + + + + PRO_TG_T0_LEVEL_INT_MAP + 0x13C + 0x20 + 0x00000010 + + + PRO_TG_T0_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG_T1_LEVEL_INT_MAP + 0x140 + 0x20 + 0x00000010 + + + PRO_TG_T1_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG_WDT_LEVEL_INT_MAP + 0x144 + 0x20 + 0x00000010 + + + PRO_TG_WDT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG_LACT_LEVEL_INT_MAP + 0x148 + 0x20 + 0x00000010 + + + PRO_TG_LACT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_T0_LEVEL_INT_MAP + 0x14C + 0x20 + 0x00000010 + + + PRO_TG1_T0_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_T1_LEVEL_INT_MAP + 0x150 + 0x20 + 0x00000010 + + + PRO_TG1_T1_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_WDT_LEVEL_INT_MAP + 0x154 + 0x20 + 0x00000010 + + + PRO_TG1_WDT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_LACT_LEVEL_INT_MAP + 0x158 + 0x20 + 0x00000010 + + + PRO_TG1_LACT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_GPIO_INTERRUPT_MAP + 0x15C + 0x20 + 0x00000010 + + + PRO_GPIO_INTERRUPT_PRO_MAP + 0 + 5 + read-write + + + + + PRO_GPIO_INTERRUPT_NMI_MAP + 0x160 + 0x20 + 0x00000010 + + + PRO_GPIO_INTERRUPT_PRO_NMI_MAP + 0 + 5 + read-write + + + + + PRO_CPU_INTR_FROM_CPU_0_MAP + 0x164 + 0x20 + 0x00000010 + + + PRO_CPU_INTR_FROM_CPU_0_MAP + 0 + 5 + read-write + + + + + PRO_CPU_INTR_FROM_CPU_1_MAP + 0x168 + 0x20 + 0x00000010 + + + PRO_CPU_INTR_FROM_CPU_1_MAP + 0 + 5 + read-write + + + + + PRO_CPU_INTR_FROM_CPU_2_MAP + 0x16C + 0x20 + 0x00000010 + + + PRO_CPU_INTR_FROM_CPU_2_MAP + 0 + 5 + read-write + + + + + PRO_CPU_INTR_FROM_CPU_3_MAP + 0x170 + 0x20 + 0x00000010 + + + PRO_CPU_INTR_FROM_CPU_3_MAP + 0 + 5 + read-write + + + + + PRO_SPI_INTR_0_MAP + 0x174 + 0x20 + 0x00000010 + + + PRO_SPI_INTR_0_MAP + 0 + 5 + read-write + + + + + PRO_SPI_INTR_1_MAP + 0x178 + 0x20 + 0x00000010 + + + PRO_SPI_INTR_1_MAP + 0 + 5 + read-write + + + + + PRO_SPI_INTR_2_MAP + 0x17C + 0x20 + 0x00000010 + + + PRO_SPI_INTR_2_MAP + 0 + 5 + read-write + + + + + PRO_SPI_INTR_3_MAP + 0x180 + 0x20 + 0x00000010 + + + PRO_SPI_INTR_3_MAP + 0 + 5 + read-write + + + + + PRO_I2S0_INT_MAP + 0x184 + 0x20 + 0x00000010 + + + PRO_I2S0_INT_MAP + 0 + 5 + read-write + + + + + PRO_I2S1_INT_MAP + 0x188 + 0x20 + 0x00000010 + + + PRO_I2S1_INT_MAP + 0 + 5 + read-write + + + + + PRO_UART_INTR_MAP + 0x18C + 0x20 + 0x00000010 + + + PRO_UART_INTR_MAP + 0 + 5 + read-write + + + + + PRO_UART1_INTR_MAP + 0x190 + 0x20 + 0x00000010 + + + PRO_UART1_INTR_MAP + 0 + 5 + read-write + + + + + PRO_UART2_INTR_MAP + 0x194 + 0x20 + 0x00000010 + + + PRO_UART2_INTR_MAP + 0 + 5 + read-write + + + + + PRO_SDIO_HOST_INTERRUPT_MAP + 0x198 + 0x20 + 0x00000010 + + + PRO_SDIO_HOST_INTERRUPT_MAP + 0 + 5 + read-write + + + + + PRO_EMAC_INT_MAP + 0x19C + 0x20 + 0x00000010 + + + PRO_EMAC_INT_MAP + 0 + 5 + read-write + + + + + PRO_PWM0_INTR_MAP + 0x1A0 + 0x20 + 0x00000010 + + + PRO_PWM0_INTR_MAP + 0 + 5 + read-write + + + + + PRO_PWM1_INTR_MAP + 0x1A4 + 0x20 + 0x00000010 + + + PRO_PWM1_INTR_MAP + 0 + 5 + read-write + + + + + PRO_PWM2_INTR_MAP + 0x1A8 + 0x20 + 0x00000010 + + + PRO_PWM2_INTR_MAP + 0 + 5 + read-write + + + + + PRO_PWM3_INTR_MAP + 0x1AC + 0x20 + 0x00000010 + + + PRO_PWM3_INTR_MAP + 0 + 5 + read-write + + + + + PRO_LEDC_INT_MAP + 0x1B0 + 0x20 + 0x00000010 + + + PRO_LEDC_INT_MAP + 0 + 5 + read-write + + + + + PRO_EFUSE_INT_MAP + 0x1B4 + 0x20 + 0x00000010 + + + PRO_EFUSE_INT_MAP + 0 + 5 + read-write + + + + + PRO_CAN_INT_MAP + 0x1B8 + 0x20 + 0x00000010 + + + PRO_CAN_INT_MAP + 0 + 5 + read-write + + + + + PRO_RTC_CORE_INTR_MAP + 0x1BC + 0x20 + 0x00000010 + + + PRO_RTC_CORE_INTR_MAP + 0 + 5 + read-write + + + + + PRO_RMT_INTR_MAP + 0x1C0 + 0x20 + 0x00000010 + + + PRO_RMT_INTR_MAP + 0 + 5 + read-write + + + + + PRO_PCNT_INTR_MAP + 0x1C4 + 0x20 + 0x00000010 + + + PRO_PCNT_INTR_MAP + 0 + 5 + read-write + + + + + PRO_I2C_EXT0_INTR_MAP + 0x1C8 + 0x20 + 0x00000010 + + + PRO_I2C_EXT0_INTR_MAP + 0 + 5 + read-write + + + + + PRO_I2C_EXT1_INTR_MAP + 0x1CC + 0x20 + 0x00000010 + + + PRO_I2C_EXT1_INTR_MAP + 0 + 5 + read-write + + + + + PRO_RSA_INTR_MAP + 0x1D0 + 0x20 + 0x00000010 + + + PRO_RSA_INTR_MAP + 0 + 5 + read-write + + + + + PRO_SPI1_DMA_INT_MAP + 0x1D4 + 0x20 + 0x00000010 + + + PRO_SPI1_DMA_INT_MAP + 0 + 5 + read-write + + + + + PRO_SPI2_DMA_INT_MAP + 0x1D8 + 0x20 + 0x00000010 + + + PRO_SPI2_DMA_INT_MAP + 0 + 5 + read-write + + + + + PRO_SPI3_DMA_INT_MAP + 0x1DC + 0x20 + 0x00000010 + + + PRO_SPI3_DMA_INT_MAP + 0 + 5 + read-write + + + + + PRO_WDG_INT_MAP + 0x1E0 + 0x20 + 0x00000010 + + + PRO_WDG_INT_MAP + 0 + 5 + read-write + + + + + PRO_TIMER_INT1_MAP + 0x1E4 + 0x20 + 0x00000010 + + + PRO_TIMER_INT1_MAP + 0 + 5 + read-write + + + + + PRO_TIMER_INT2_MAP + 0x1E8 + 0x20 + 0x00000010 + + + PRO_TIMER_INT2_MAP + 0 + 5 + read-write + + + + + PRO_TG_T0_EDGE_INT_MAP + 0x1EC + 0x20 + 0x00000010 + + + PRO_TG_T0_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG_T1_EDGE_INT_MAP + 0x1F0 + 0x20 + 0x00000010 + + + PRO_TG_T1_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG_WDT_EDGE_INT_MAP + 0x1F4 + 0x20 + 0x00000010 + + + PRO_TG_WDT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG_LACT_EDGE_INT_MAP + 0x1F8 + 0x20 + 0x00000010 + + + PRO_TG_LACT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_T0_EDGE_INT_MAP + 0x1FC + 0x20 + 0x00000010 + + + PRO_TG1_T0_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_T1_EDGE_INT_MAP + 0x200 + 0x20 + 0x00000010 + + + PRO_TG1_T1_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_WDT_EDGE_INT_MAP + 0x204 + 0x20 + 0x00000010 + + + PRO_TG1_WDT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_LACT_EDGE_INT_MAP + 0x208 + 0x20 + 0x00000010 + + + PRO_TG1_LACT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_MMU_IA_INT_MAP + 0x20C + 0x20 + 0x00000010 + + + PRO_MMU_IA_INT_MAP + 0 + 5 + read-write + + + + + PRO_MPU_IA_INT_MAP + 0x210 + 0x20 + 0x00000010 + + + PRO_MPU_IA_INT_MAP + 0 + 5 + read-write + + + + + PRO_CACHE_IA_INT_MAP + 0x214 + 0x20 + 0x00000010 + + + PRO_CACHE_IA_INT_MAP + 0 + 5 + read-write + + + + + APP_MAC_INTR_MAP + 0x218 + 0x20 + 0x00000010 + + + APP_MAC_INTR_MAP + 0 + 5 + read-write + + + + + APP_MAC_NMI_MAP + 0x21C + 0x20 + 0x00000010 + + + APP_MAC_NMI_MAP + 0 + 5 + read-write + + + + + APP_BB_INT_MAP + 0x220 + 0x20 + 0x00000010 + + + APP_BB_INT_MAP + 0 + 5 + read-write + + + + + APP_BT_MAC_INT_MAP + 0x224 + 0x20 + 0x00000010 + + + APP_BT_MAC_INT_MAP + 0 + 5 + read-write + + + + + APP_BT_BB_INT_MAP + 0x228 + 0x20 + 0x00000010 + + + APP_BT_BB_INT_MAP + 0 + 5 + read-write + + + + + APP_BT_BB_NMI_MAP + 0x22C + 0x20 + 0x00000010 + + + APP_BT_BB_NMI_MAP + 0 + 5 + read-write + + + + + APP_RWBT_IRQ_MAP + 0x230 + 0x20 + 0x00000010 + + + APP_RWBT_IRQ_MAP + 0 + 5 + read-write + + + + + APP_RWBLE_IRQ_MAP + 0x234 + 0x20 + 0x00000010 + + + APP_RWBLE_IRQ_MAP + 0 + 5 + read-write + + + + + APP_RWBT_NMI_MAP + 0x238 + 0x20 + 0x00000010 + + + APP_RWBT_NMI_MAP + 0 + 5 + read-write + + + + + APP_RWBLE_NMI_MAP + 0x23C + 0x20 + 0x00000010 + + + APP_RWBLE_NMI_MAP + 0 + 5 + read-write + + + + + APP_SLC0_INTR_MAP + 0x240 + 0x20 + 0x00000010 + + + APP_SLC0_INTR_MAP + 0 + 5 + read-write + + + + + APP_SLC1_INTR_MAP + 0x244 + 0x20 + 0x00000010 + + + APP_SLC1_INTR_MAP + 0 + 5 + read-write + + + + + APP_UHCI0_INTR_MAP + 0x248 + 0x20 + 0x00000010 + + + APP_UHCI0_INTR_MAP + 0 + 5 + read-write + + + + + APP_UHCI1_INTR_MAP + 0x24C + 0x20 + 0x00000010 + + + APP_UHCI1_INTR_MAP + 0 + 5 + read-write + + + + + APP_TG_T0_LEVEL_INT_MAP + 0x250 + 0x20 + 0x00000010 + + + APP_TG_T0_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_TG_T1_LEVEL_INT_MAP + 0x254 + 0x20 + 0x00000010 + + + APP_TG_T1_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_TG_WDT_LEVEL_INT_MAP + 0x258 + 0x20 + 0x00000010 + + + APP_TG_WDT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_TG_LACT_LEVEL_INT_MAP + 0x25C + 0x20 + 0x00000010 + + + APP_TG_LACT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_T0_LEVEL_INT_MAP + 0x260 + 0x20 + 0x00000010 + + + APP_TG1_T0_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_T1_LEVEL_INT_MAP + 0x264 + 0x20 + 0x00000010 + + + APP_TG1_T1_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_WDT_LEVEL_INT_MAP + 0x268 + 0x20 + 0x00000010 + + + APP_TG1_WDT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_LACT_LEVEL_INT_MAP + 0x26C + 0x20 + 0x00000010 + + + APP_TG1_LACT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_GPIO_INTERRUPT_MAP + 0x270 + 0x20 + 0x00000010 + + + APP_GPIO_INTERRUPT_APP_MAP + 0 + 5 + read-write + + + + + APP_GPIO_INTERRUPT_NMI_MAP + 0x274 + 0x20 + 0x00000010 + + + APP_GPIO_INTERRUPT_APP_NMI_MAP + 0 + 5 + read-write + + + + + APP_CPU_INTR_FROM_CPU_0_MAP + 0x278 + 0x20 + 0x00000010 + + + APP_CPU_INTR_FROM_CPU_0_MAP + 0 + 5 + read-write + + + + + APP_CPU_INTR_FROM_CPU_1_MAP + 0x27C + 0x20 + 0x00000010 + + + APP_CPU_INTR_FROM_CPU_1_MAP + 0 + 5 + read-write + + + + + APP_CPU_INTR_FROM_CPU_2_MAP + 0x280 + 0x20 + 0x00000010 + + + APP_CPU_INTR_FROM_CPU_2_MAP + 0 + 5 + read-write + + + + + APP_CPU_INTR_FROM_CPU_3_MAP + 0x284 + 0x20 + 0x00000010 + + + APP_CPU_INTR_FROM_CPU_3_MAP + 0 + 5 + read-write + + + + + APP_SPI_INTR_0_MAP + 0x288 + 0x20 + 0x00000010 + + + APP_SPI_INTR_0_MAP + 0 + 5 + read-write + + + + + APP_SPI_INTR_1_MAP + 0x28C + 0x20 + 0x00000010 + + + APP_SPI_INTR_1_MAP + 0 + 5 + read-write + + + + + APP_SPI_INTR_2_MAP + 0x290 + 0x20 + 0x00000010 + + + APP_SPI_INTR_2_MAP + 0 + 5 + read-write + + + + + APP_SPI_INTR_3_MAP + 0x294 + 0x20 + 0x00000010 + + + APP_SPI_INTR_3_MAP + 0 + 5 + read-write + + + + + APP_I2S0_INT_MAP + 0x298 + 0x20 + 0x00000010 + + + APP_I2S0_INT_MAP + 0 + 5 + read-write + + + + + APP_I2S1_INT_MAP + 0x29C + 0x20 + 0x00000010 + + + APP_I2S1_INT_MAP + 0 + 5 + read-write + + + + + APP_UART_INTR_MAP + 0x2A0 + 0x20 + 0x00000010 + + + APP_UART_INTR_MAP + 0 + 5 + read-write + + + + + APP_UART1_INTR_MAP + 0x2A4 + 0x20 + 0x00000010 + + + APP_UART1_INTR_MAP + 0 + 5 + read-write + + + + + APP_UART2_INTR_MAP + 0x2A8 + 0x20 + 0x00000010 + + + APP_UART2_INTR_MAP + 0 + 5 + read-write + + + + + APP_SDIO_HOST_INTERRUPT_MAP + 0x2AC + 0x20 + 0x00000010 + + + APP_SDIO_HOST_INTERRUPT_MAP + 0 + 5 + read-write + + + + + APP_EMAC_INT_MAP + 0x2B0 + 0x20 + 0x00000010 + + + APP_EMAC_INT_MAP + 0 + 5 + read-write + + + + + APP_PWM0_INTR_MAP + 0x2B4 + 0x20 + 0x00000010 + + + APP_PWM0_INTR_MAP + 0 + 5 + read-write + + + + + APP_PWM1_INTR_MAP + 0x2B8 + 0x20 + 0x00000010 + + + APP_PWM1_INTR_MAP + 0 + 5 + read-write + + + + + APP_PWM2_INTR_MAP + 0x2BC + 0x20 + 0x00000010 + + + APP_PWM2_INTR_MAP + 0 + 5 + read-write + + + + + APP_PWM3_INTR_MAP + 0x2C0 + 0x20 + 0x00000010 + + + APP_PWM3_INTR_MAP + 0 + 5 + read-write + + + + + APP_LEDC_INT_MAP + 0x2C4 + 0x20 + 0x00000010 + + + APP_LEDC_INT_MAP + 0 + 5 + read-write + + + + + APP_EFUSE_INT_MAP + 0x2C8 + 0x20 + 0x00000010 + + + APP_EFUSE_INT_MAP + 0 + 5 + read-write + + + + + APP_CAN_INT_MAP + 0x2CC + 0x20 + 0x00000010 + + + APP_CAN_INT_MAP + 0 + 5 + read-write + + + + + APP_RTC_CORE_INTR_MAP + 0x2D0 + 0x20 + 0x00000010 + + + APP_RTC_CORE_INTR_MAP + 0 + 5 + read-write + + + + + APP_RMT_INTR_MAP + 0x2D4 + 0x20 + 0x00000010 + + + APP_RMT_INTR_MAP + 0 + 5 + read-write + + + + + APP_PCNT_INTR_MAP + 0x2D8 + 0x20 + 0x00000010 + + + APP_PCNT_INTR_MAP + 0 + 5 + read-write + + + + + APP_I2C_EXT0_INTR_MAP + 0x2DC + 0x20 + 0x00000010 + + + APP_I2C_EXT0_INTR_MAP + 0 + 5 + read-write + + + + + APP_I2C_EXT1_INTR_MAP + 0x2E0 + 0x20 + 0x00000010 + + + APP_I2C_EXT1_INTR_MAP + 0 + 5 + read-write + + + + + APP_RSA_INTR_MAP + 0x2E4 + 0x20 + 0x00000010 + + + APP_RSA_INTR_MAP + 0 + 5 + read-write + + + + + APP_SPI1_DMA_INT_MAP + 0x2E8 + 0x20 + 0x00000010 + + + APP_SPI1_DMA_INT_MAP + 0 + 5 + read-write + + + + + APP_SPI2_DMA_INT_MAP + 0x2EC + 0x20 + 0x00000010 + + + APP_SPI2_DMA_INT_MAP + 0 + 5 + read-write + + + + + APP_SPI3_DMA_INT_MAP + 0x2F0 + 0x20 + 0x00000010 + + + APP_SPI3_DMA_INT_MAP + 0 + 5 + read-write + + + + + APP_WDG_INT_MAP + 0x2F4 + 0x20 + 0x00000010 + + + APP_WDG_INT_MAP + 0 + 5 + read-write + + + + + APP_TIMER_INT1_MAP + 0x2F8 + 0x20 + 0x00000010 + + + APP_TIMER_INT1_MAP + 0 + 5 + read-write + + + + + APP_TIMER_INT2_MAP + 0x2FC + 0x20 + 0x00000010 + + + APP_TIMER_INT2_MAP + 0 + 5 + read-write + + + + + APP_TG_T0_EDGE_INT_MAP + 0x300 + 0x20 + 0x00000010 + + + APP_TG_T0_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_TG_T1_EDGE_INT_MAP + 0x304 + 0x20 + 0x00000010 + + + APP_TG_T1_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_TG_WDT_EDGE_INT_MAP + 0x308 + 0x20 + 0x00000010 + + + APP_TG_WDT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_TG_LACT_EDGE_INT_MAP + 0x30C + 0x20 + 0x00000010 + + + APP_TG_LACT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_T0_EDGE_INT_MAP + 0x310 + 0x20 + 0x00000010 + + + APP_TG1_T0_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_T1_EDGE_INT_MAP + 0x314 + 0x20 + 0x00000010 + + + APP_TG1_T1_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_WDT_EDGE_INT_MAP + 0x318 + 0x20 + 0x00000010 + + + APP_TG1_WDT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_LACT_EDGE_INT_MAP + 0x31C + 0x20 + 0x00000010 + + + APP_TG1_LACT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_MMU_IA_INT_MAP + 0x320 + 0x20 + 0x00000010 + + + APP_MMU_IA_INT_MAP + 0 + 5 + read-write + + + + + APP_MPU_IA_INT_MAP + 0x324 + 0x20 + 0x00000010 + + + APP_MPU_IA_INT_MAP + 0 + 5 + read-write + + + + + APP_CACHE_IA_INT_MAP + 0x328 + 0x20 + 0x00000010 + + + APP_CACHE_IA_INT_MAP + 0 + 5 + read-write + + + + + AHBLITE_MPU_TABLE_UART + 0x32C + 0x20 + + + UART_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SPI1 + 0x330 + 0x20 + + + SPI1_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SPI0 + 0x334 + 0x20 + + + SPI0_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_GPIO + 0x338 + 0x20 + + + GPIO_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_FE2 + 0x33C + 0x20 + + + FE2_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_FE + 0x340 + 0x20 + + + FE_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_TIMER + 0x344 + 0x20 + + + TIMER_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_RTC + 0x348 + 0x20 + + + RTC_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_IO_MUX + 0x34C + 0x20 + + + IOMUX_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_WDG + 0x350 + 0x20 + + + WDG_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_HINF + 0x354 + 0x20 + + + HINF_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_UHCI1 + 0x358 + 0x20 + + + UHCI1_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_MISC + 0x35C + 0x20 + + + MISC_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_I2C + 0x360 + 0x20 + + + I2C_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_I2S0 + 0x364 + 0x20 + + + I2S0_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_UART1 + 0x368 + 0x20 + + + UART1_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_BT + 0x36C + 0x20 + + + BT_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_BT_BUFFER + 0x370 + 0x20 + + + BTBUFFER_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_I2C_EXT0 + 0x374 + 0x20 + + + I2CEXT0_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_UHCI0 + 0x378 + 0x20 + + + UHCI0_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SLCHOST + 0x37C + 0x20 + + + SLCHOST_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_RMT + 0x380 + 0x20 + + + RMT_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_PCNT + 0x384 + 0x20 + + + PCNT_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SLC + 0x388 + 0x20 + + + SLC_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_LEDC + 0x38C + 0x20 + + + LEDC_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_EFUSE + 0x390 + 0x20 + + + EFUSE_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SPI_ENCRYPT + 0x394 + 0x20 + + + SPI_ENCRYPY_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_BB + 0x398 + 0x20 + + + BB_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_PWM0 + 0x39C + 0x20 + + + PWM0_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_TIMERGROUP + 0x3A0 + 0x20 + + + TIMERGROUP_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_TIMERGROUP1 + 0x3A4 + 0x20 + + + TIMERGROUP1_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SPI2 + 0x3A8 + 0x20 + + + SPI2_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SPI3 + 0x3AC + 0x20 + + + SPI3_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_APB_CTRL + 0x3B0 + 0x20 + + + APBCTRL_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_I2C_EXT1 + 0x3B4 + 0x20 + + + I2CEXT1_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SDIO_HOST + 0x3B8 + 0x20 + + + SDIOHOST_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_EMAC + 0x3BC + 0x20 + + + EMAC_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_CAN + 0x3C0 + 0x20 + + + CAN_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_PWM1 + 0x3C4 + 0x20 + + + PWM1_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_I2S1 + 0x3C8 + 0x20 + + + I2S1_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_UART2 + 0x3CC + 0x20 + + + UART2_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_PWM2 + 0x3D0 + 0x20 + + + PWM2_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_PWM3 + 0x3D4 + 0x20 + + + PWM3_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_RWBT + 0x3D8 + 0x20 + + + RWBT_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_BTMAC + 0x3DC + 0x20 + + + BTMAC_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_WIFIMAC + 0x3E0 + 0x20 + + + WIFIMAC_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_PWR + 0x3E4 + 0x20 + + + PWR_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + MEM_ACCESS_DBUG0 + 0x3E8 + 0x20 + + + PRO_ROM_MPU_AD + 0 + 1 + read-only + + + PRO_ROM_IA + 1 + 1 + read-only + + + APP_ROM_MPU_AD + 2 + 1 + read-only + + + APP_ROM_IA + 3 + 1 + read-only + + + SHARE_ROM_MPU_AD + 4 + 2 + read-only + + + SHARE_ROM_IA + 6 + 4 + read-only + + + INTERNAL_SRAM_MMU_AD + 10 + 4 + read-only + + + INTERNAL_SRAM_IA + 14 + 12 + read-only + + + INTERNAL_SRAM_MMU_MULTI_HIT + 26 + 4 + read-only + + + + + MEM_ACCESS_DBUG1 + 0x3EC + 0x20 + + + INTERNAL_SRAM_MMU_MISS + 0 + 4 + read-only + + + ARB_IA + 4 + 2 + read-only + + + PIDGEN_IA + 6 + 2 + read-only + + + AHB_ACCESS_DENY + 8 + 1 + read-only + + + AHBLITE_ACCESS_DENY + 9 + 1 + read-only + + + AHBLITE_IA + 10 + 1 + read-only + + + + + PRO_DCACHE_DBUG0 + 0x3F0 + 0x20 + + + PRO_SLAVE_WDATA + 0 + 1 + read-write + + + PRO_CACHE_MMU_IA + 0 + 1 + read-only + + + PRO_CACHE_IA + 1 + 6 + read-only + + + PRO_CACHE_STATE + 7 + 12 + read-only + + + PRO_WR_BAK_TO_READ + 19 + 1 + read-only + + + PRO_TX_END + 20 + 1 + read-only + + + PRO_SLAVE_WR + 21 + 1 + read-only + + + PRO_SLAVE_WDATA_V + 22 + 1 + read-only + + + PRO_RX_END + 23 + 1 + read-only + + + + + PRO_DCACHE_DBUG1 + 0x3F4 + 0x20 + + + PRO_CTAG_RAM_RDATA + 0 + 32 + read-only + + + + + PRO_DCACHE_DBUG2 + 0x3F8 + 0x20 + + + PRO_CACHE_VADDR + 0 + 27 + read-only + + + + + PRO_DCACHE_DBUG3 + 0x3FC + 0x20 + + + PRO_MMU_RDATA + 0 + 9 + read-only + + + PRO_CPU_DISABLED_CACHE_IA + 9 + 6 + read-only + + + PRO_CPU_DISABLED_CACHE_IA_OPPOSITE + 9 + 1 + read-write + + + PRO_CPU_DISABLED_CACHE_IA_DRAM1 + 10 + 1 + read-write + + + PRO_CPU_DISABLED_CACHE_IA_IROM0 + 11 + 1 + read-write + + + PRO_CPU_DISABLED_CACHE_IA_IRAM1 + 12 + 1 + read-write + + + PRO_CPU_DISABLED_CACHE_IA_IRAM0 + 13 + 1 + read-write + + + PRO_CPU_DISABLED_CACHE_IA_DROM0 + 14 + 1 + read-write + + + PRO_CACHE_IRAM0_PID_ERROR + 15 + 1 + read-only + + + + + PRO_DCACHE_DBUG4 + 0x400 + 0x20 + + + PRO_DRAM1ADDR0_IA + 0 + 20 + read-only + + + + + PRO_DCACHE_DBUG5 + 0x404 + 0x20 + + + PRO_DROM0ADDR0_IA + 0 + 20 + read-only + + + + + PRO_DCACHE_DBUG6 + 0x408 + 0x20 + + + PRO_IRAM0ADDR_IA + 0 + 20 + read-only + + + + + PRO_DCACHE_DBUG7 + 0x40C + 0x20 + + + PRO_IRAM1ADDR_IA + 0 + 20 + read-only + + + + + PRO_DCACHE_DBUG8 + 0x410 + 0x20 + + + PRO_IROM0ADDR_IA + 0 + 20 + read-only + + + + + PRO_DCACHE_DBUG9 + 0x414 + 0x20 + + + PRO_OPSDRAMADDR_IA + 0 + 20 + read-only + + + + + APP_DCACHE_DBUG0 + 0x418 + 0x20 + + + APP_SLAVE_WDATA + 0 + 1 + read-write + + + APP_CACHE_MMU_IA + 0 + 1 + read-only + + + APP_CACHE_IA + 1 + 6 + read-only + + + APP_CACHE_STATE + 7 + 12 + read-only + + + APP_WR_BAK_TO_READ + 19 + 1 + read-only + + + APP_TX_END + 20 + 1 + read-only + + + APP_SLAVE_WR + 21 + 1 + read-only + + + APP_SLAVE_WDATA_V + 22 + 1 + read-only + + + APP_RX_END + 23 + 1 + read-only + + + + + APP_DCACHE_DBUG1 + 0x41C + 0x20 + + + APP_CTAG_RAM_RDATA + 0 + 32 + read-only + + + + + APP_DCACHE_DBUG2 + 0x420 + 0x20 + + + APP_CACHE_VADDR + 0 + 27 + read-only + + + + + APP_DCACHE_DBUG3 + 0x424 + 0x20 + + + APP_MMU_RDATA + 0 + 9 + read-only + + + APP_CPU_DISABLED_CACHE_IA + 9 + 6 + read-only + + + APP_CPU_DISABLED_CACHE_IA_OPPOSITE + 9 + 1 + read-write + + + APP_CPU_DISABLED_CACHE_IA_DRAM1 + 10 + 1 + read-write + + + APP_CPU_DISABLED_CACHE_IA_IROM0 + 11 + 1 + read-write + + + APP_CPU_DISABLED_CACHE_IA_IRAM1 + 12 + 1 + read-write + + + APP_CPU_DISABLED_CACHE_IA_IRAM0 + 13 + 1 + read-write + + + APP_CPU_DISABLED_CACHE_IA_DROM0 + 14 + 1 + read-write + + + APP_CACHE_IRAM0_PID_ERROR + 15 + 1 + read-only + + + + + APP_DCACHE_DBUG4 + 0x428 + 0x20 + + + APP_DRAM1ADDR0_IA + 0 + 20 + read-only + + + + + APP_DCACHE_DBUG5 + 0x42C + 0x20 + + + APP_DROM0ADDR0_IA + 0 + 20 + read-only + + + + + APP_DCACHE_DBUG6 + 0x430 + 0x20 + + + APP_IRAM0ADDR_IA + 0 + 20 + read-only + + + + + APP_DCACHE_DBUG7 + 0x434 + 0x20 + + + APP_IRAM1ADDR_IA + 0 + 20 + read-only + + + + + APP_DCACHE_DBUG8 + 0x438 + 0x20 + + + APP_IROM0ADDR_IA + 0 + 20 + read-only + + + + + APP_DCACHE_DBUG9 + 0x43C + 0x20 + + + APP_OPSDRAMADDR_IA + 0 + 20 + read-only + + + + + PRO_CPU_RECORD_CTRL + 0x440 + 0x20 + 0x00000100 + + + PRO_CPU_RECORD_ENABLE + 0 + 1 + read-write + + + PRO_CPU_RECORD_DISABLE + 4 + 1 + read-write + + + PRO_CPU_PDEBUG_ENABLE + 8 + 1 + read-write + + + + + PRO_CPU_RECORD_STATUS + 0x444 + 0x20 + + + PRO_CPU_RECORDING + 0 + 1 + read-only + + + + + PRO_CPU_RECORD_PID + 0x448 + 0x20 + + + RECORD_PRO_PID + 0 + 3 + read-only + + + + + PRO_CPU_RECORD_PDEBUGINST + 0x44C + 0x20 + + + RECORD_PRO_PDEBUGINST + 0 + 32 + read-only + + + RECORD_PDEBUGINST_SZ + 0 + 8 + read-write + + + RECORD_PDEBUGINST_ISRC + 12 + 3 + read-write + + + RECORD_PDEBUGINST_LOOP_REP + 20 + 1 + read-write + + + RECORD_PDEBUGINST_LOOP + 21 + 1 + read-write + + + RECORD_PDEBUGINST_CINTL + 24 + 4 + read-write + + + + + PRO_CPU_RECORD_PDEBUGSTATUS + 0x450 + 0x20 + + + RECORD_PRO_PDEBUGSTATUS + 0 + 8 + read-only + + + RECORD_PDEBUGSTATUS_BBCAUSE + 0 + 6 + read-write + + + RECORD_PDEBUGSTATUS_INSNTYPE + 0 + 6 + read-write + + + + + PRO_CPU_RECORD_PDEBUGDATA + 0x454 + 0x20 + + + RECORD_PRO_PDEBUGDATA + 0 + 32 + read-only + + + RECORD_PDEBUGDATA_DEP_OTHER + 0 + 1 + read-write + + + RECORD_PDEBUGDATA_EXCVEC + 0 + 5 + read-write + + + RECORD_PDEBUGDATA_INSNTYPE_SR + 0 + 8 + read-write + + + RECORD_PDEBUGDATA_INSNTYPE_RER + 0 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_BUFF + 1 + 1 + read-write + + + RECORD_PDEBUGDATA_INSNTYPE_WER + 1 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_BUFFCONFL + 2 + 1 + read-write + + + RECORD_PDEBUGDATA_INSNTYPE_ER + 2 + 12 + read-write + + + RECORD_PDEBUGDATA_STALL_DCM + 3 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_LSU + 4 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_ICM + 6 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_IRAMBUSY + 7 + 1 + read-write + + + RECORD_PDEBUGDATA_DEP_LSU + 8 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_IPIF + 8 + 1 + read-write + + + RECORD_PDEBUGDATA_INSNTYPE_RSR + 8 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_TIE + 9 + 1 + read-write + + + RECORD_PDEBUGDATA_INSNTYPE_WSR + 9 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_RUN + 10 + 1 + read-write + + + RECORD_PDEBUGDATA_INSNTYPE_XSR + 10 + 1 + read-write + + + RECORD_PDEBUGDATA_DEP_STR + 11 + 1 + read-write + + + RECORD_PDEBUGDATA_DEP + 12 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_BPIFETCH + 12 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_L32R + 13 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_LSPROC + 14 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_BPLOAD + 15 + 1 + read-write + + + RECORD_PDEBUGDATA_DEP_MEMW + 16 + 1 + read-write + + + RECORD_PDEBUGDATA_EXCCAUSE + 16 + 6 + read-write + + + RECORD_PDEBUGDATA_STALL_BANKCONFL + 16 + 1 + read-write + + + RECORD_PDEBUGDATA_DEP_HALT + 17 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_ITERMUL + 18 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_ITERDIV + 19 + 1 + read-write + + + + + PRO_CPU_RECORD_PDEBUGPC + 0x458 + 0x20 + + + RECORD_PRO_PDEBUGPC + 0 + 32 + read-only + + + + + PRO_CPU_RECORD_PDEBUGLS0STAT + 0x45C + 0x20 + + + RECORD_PRO_PDEBUGLS0STAT + 0 + 32 + read-only + + + RECORD_PDEBUGLS0STAT_TYPE + 0 + 4 + read-write + + + RECORD_PDEBUGLS0STAT_SZ + 4 + 4 + read-write + + + RECORD_PDEBUGLS0STAT_DTLBM + 8 + 1 + read-write + + + RECORD_PDEBUGLS0STAT_DCM + 9 + 1 + read-write + + + RECORD_PDEBUGLS0STAT_DCH + 10 + 1 + read-write + + + RECORD_PDEBUGLS0STAT_UC + 12 + 1 + read-write + + + RECORD_PDEBUGLS0STAT_WB + 13 + 1 + read-write + + + RECORD_PDEBUGLS0STAT_COH + 16 + 1 + read-write + + + RECORD_PDEBUGLS0STAT_STCOH + 17 + 2 + read-write + + + RECORD_PDEBUGLS0STAT_TGT + 20 + 4 + read-write + + + + + PRO_CPU_RECORD_PDEBUGLS0ADDR + 0x460 + 0x20 + + + RECORD_PRO_PDEBUGLS0ADDR + 0 + 32 + read-only + + + + + PRO_CPU_RECORD_PDEBUGLS0DATA + 0x464 + 0x20 + + + RECORD_PRO_PDEBUGLS0DATA + 0 + 32 + read-only + + + + + APP_CPU_RECORD_CTRL + 0x468 + 0x20 + 0x00000100 + + + APP_CPU_RECORD_ENABLE + 0 + 1 + read-write + + + APP_CPU_RECORD_DISABLE + 4 + 1 + read-write + + + APP_CPU_PDEBUG_ENABLE + 8 + 1 + read-write + + + + + APP_CPU_RECORD_STATUS + 0x46C + 0x20 + + + APP_CPU_RECORDING + 0 + 1 + read-only + + + + + APP_CPU_RECORD_PID + 0x470 + 0x20 + + + RECORD_APP_PID + 0 + 3 + read-only + + + + + APP_CPU_RECORD_PDEBUGINST + 0x474 + 0x20 + + + RECORD_APP_PDEBUGINST + 0 + 32 + read-only + + + + + APP_CPU_RECORD_PDEBUGSTATUS + 0x478 + 0x20 + + + RECORD_APP_PDEBUGSTATUS + 0 + 8 + read-only + + + + + APP_CPU_RECORD_PDEBUGDATA + 0x47C + 0x20 + + + RECORD_APP_PDEBUGDATA + 0 + 32 + read-only + + + + + APP_CPU_RECORD_PDEBUGPC + 0x480 + 0x20 + + + RECORD_APP_PDEBUGPC + 0 + 32 + read-only + + + + + APP_CPU_RECORD_PDEBUGLS0STAT + 0x484 + 0x20 + + + RECORD_APP_PDEBUGLS0STAT + 0 + 32 + read-only + + + + + APP_CPU_RECORD_PDEBUGLS0ADDR + 0x488 + 0x20 + + + RECORD_APP_PDEBUGLS0ADDR + 0 + 32 + read-only + + + + + APP_CPU_RECORD_PDEBUGLS0DATA + 0x48C + 0x20 + + + RECORD_APP_PDEBUGLS0DATA + 0 + 32 + read-only + + + + + RSA_PD_CTRL + 0x490 + 0x20 + + + RSA_PD + 0 + 1 + read-write + + + + + ROM_MPU_TABLE0 + 0x494 + 0x20 + 0x00000001 + + + ROM_MPU_TABLE0 + 0 + 2 + read-write + + + + + ROM_MPU_TABLE1 + 0x498 + 0x20 + 0x00000001 + + + ROM_MPU_TABLE1 + 0 + 2 + read-write + + + + + ROM_MPU_TABLE2 + 0x49C + 0x20 + 0x00000001 + + + ROM_MPU_TABLE2 + 0 + 2 + read-write + + + + + ROM_MPU_TABLE3 + 0x4A0 + 0x20 + 0x00000001 + + + ROM_MPU_TABLE3 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE0 + 0x4A4 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE0 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE1 + 0x4A8 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE1 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE2 + 0x4AC + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE2 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE3 + 0x4B0 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE3 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE4 + 0x4B4 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE4 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE5 + 0x4B8 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE5 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE6 + 0x4BC + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE6 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE7 + 0x4C0 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE7 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE8 + 0x4C4 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE8 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE9 + 0x4C8 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE9 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE10 + 0x4CC + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE10 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE11 + 0x4D0 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE11 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE12 + 0x4D4 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE12 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE13 + 0x4D8 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE13 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE14 + 0x4DC + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE14 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE15 + 0x4E0 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE15 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE16 + 0x4E4 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE16 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE17 + 0x4E8 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE17 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE18 + 0x4EC + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE18 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE19 + 0x4F0 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE19 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE20 + 0x4F4 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE20 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE21 + 0x4F8 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE21 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE22 + 0x4FC + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE22 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE23 + 0x500 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE23 + 0 + 2 + read-write + + + + + IMMU_TABLE0 + 0x504 + 0x20 + + + IMMU_TABLE0 + 0 + 7 + read-write + + + + + IMMU_TABLE1 + 0x508 + 0x20 + 0x00000001 + + + IMMU_TABLE1 + 0 + 7 + read-write + + + + + IMMU_TABLE2 + 0x50C + 0x20 + 0x00000002 + + + IMMU_TABLE2 + 0 + 7 + read-write + + + + + IMMU_TABLE3 + 0x510 + 0x20 + 0x00000003 + + + IMMU_TABLE3 + 0 + 7 + read-write + + + + + IMMU_TABLE4 + 0x514 + 0x20 + 0x00000004 + + + IMMU_TABLE4 + 0 + 7 + read-write + + + + + IMMU_TABLE5 + 0x518 + 0x20 + 0x00000005 + + + IMMU_TABLE5 + 0 + 7 + read-write + + + + + IMMU_TABLE6 + 0x51C + 0x20 + 0x00000006 + + + IMMU_TABLE6 + 0 + 7 + read-write + + + + + IMMU_TABLE7 + 0x520 + 0x20 + 0x00000007 + + + IMMU_TABLE7 + 0 + 7 + read-write + + + + + IMMU_TABLE8 + 0x524 + 0x20 + 0x00000008 + + + IMMU_TABLE8 + 0 + 7 + read-write + + + + + IMMU_TABLE9 + 0x528 + 0x20 + 0x00000009 + + + IMMU_TABLE9 + 0 + 7 + read-write + + + + + IMMU_TABLE10 + 0x52C + 0x20 + 0x0000000A + + + IMMU_TABLE10 + 0 + 7 + read-write + + + + + IMMU_TABLE11 + 0x530 + 0x20 + 0x0000000B + + + IMMU_TABLE11 + 0 + 7 + read-write + + + + + IMMU_TABLE12 + 0x534 + 0x20 + 0x0000000C + + + IMMU_TABLE12 + 0 + 7 + read-write + + + + + IMMU_TABLE13 + 0x538 + 0x20 + 0x0000000D + + + IMMU_TABLE13 + 0 + 7 + read-write + + + + + IMMU_TABLE14 + 0x53C + 0x20 + 0x0000000E + + + IMMU_TABLE14 + 0 + 7 + read-write + + + + + IMMU_TABLE15 + 0x540 + 0x20 + 0x0000000F + + + IMMU_TABLE15 + 0 + 7 + read-write + + + + + DMMU_TABLE0 + 0x544 + 0x20 + + + DMMU_TABLE0 + 0 + 7 + read-write + + + + + DMMU_TABLE1 + 0x548 + 0x20 + 0x00000001 + + + DMMU_TABLE1 + 0 + 7 + read-write + + + + + DMMU_TABLE2 + 0x54C + 0x20 + 0x00000002 + + + DMMU_TABLE2 + 0 + 7 + read-write + + + + + DMMU_TABLE3 + 0x550 + 0x20 + 0x00000003 + + + DMMU_TABLE3 + 0 + 7 + read-write + + + + + DMMU_TABLE4 + 0x554 + 0x20 + 0x00000004 + + + DMMU_TABLE4 + 0 + 7 + read-write + + + + + DMMU_TABLE5 + 0x558 + 0x20 + 0x00000005 + + + DMMU_TABLE5 + 0 + 7 + read-write + + + + + DMMU_TABLE6 + 0x55C + 0x20 + 0x00000006 + + + DMMU_TABLE6 + 0 + 7 + read-write + + + + + DMMU_TABLE7 + 0x560 + 0x20 + 0x00000007 + + + DMMU_TABLE7 + 0 + 7 + read-write + + + + + DMMU_TABLE8 + 0x564 + 0x20 + 0x00000008 + + + DMMU_TABLE8 + 0 + 7 + read-write + + + + + DMMU_TABLE9 + 0x568 + 0x20 + 0x00000009 + + + DMMU_TABLE9 + 0 + 7 + read-write + + + + + DMMU_TABLE10 + 0x56C + 0x20 + 0x0000000A + + + DMMU_TABLE10 + 0 + 7 + read-write + + + + + DMMU_TABLE11 + 0x570 + 0x20 + 0x0000000B + + + DMMU_TABLE11 + 0 + 7 + read-write + + + + + DMMU_TABLE12 + 0x574 + 0x20 + 0x0000000C + + + DMMU_TABLE12 + 0 + 7 + read-write + + + + + DMMU_TABLE13 + 0x578 + 0x20 + 0x0000000D + + + DMMU_TABLE13 + 0 + 7 + read-write + + + + + DMMU_TABLE14 + 0x57C + 0x20 + 0x0000000E + + + DMMU_TABLE14 + 0 + 7 + read-write + + + + + DMMU_TABLE15 + 0x580 + 0x20 + 0x0000000F + + + DMMU_TABLE15 + 0 + 7 + read-write + + + + + PRO_INTRUSION_CTRL + 0x584 + 0x20 + 0x00000001 + + + PRO_INTRUSION_RECORD_RESET_N + 0 + 1 + read-write + + + + + PRO_INTRUSION_STATUS + 0x588 + 0x20 + + + PRO_INTRUSION_RECORD + 0 + 4 + read-only + + + + + APP_INTRUSION_CTRL + 0x58C + 0x20 + 0x00000001 + + + APP_INTRUSION_RECORD_RESET_N + 0 + 1 + read-write + + + + + APP_INTRUSION_STATUS + 0x590 + 0x20 + + + APP_INTRUSION_RECORD + 0 + 4 + read-only + + + + + FRONT_END_MEM_PD + 0x594 + 0x20 + 0x00000005 + + + AGC_MEM_FORCE_PU + 0 + 1 + read-write + + + AGC_MEM_FORCE_PD + 1 + 1 + read-write + + + PBUS_MEM_FORCE_PU + 2 + 1 + read-write + + + PBUS_MEM_FORCE_PD + 3 + 1 + read-write + + + + + MMU_IA_INT_EN + 0x598 + 0x20 + + + MMU_IA_INT_EN + 0 + 24 + read-write + + + + + MPU_IA_INT_EN + 0x59C + 0x20 + + + MPU_IA_INT_EN + 0 + 17 + read-write + + + + + CACHE_IA_INT_EN + 0x5A0 + 0x20 + + + CACHE_IA_INT_EN + Interrupt enable bits for various invalid cache access reasons + 0 + 28 + read-write + + + CACHE_IA_INT_APP_DROM0 + APP CPU invalid access to DROM0 when cache is disabled + 0 + 1 + read-write + + + CACHE_IA_INT_APP_IRAM0 + APP CPU invalid access to IRAM0 when cache is disabled + 1 + 1 + read-write + + + CACHE_IA_INT_APP_IRAM1 + APP CPU invalid access to IRAM1 when cache is disabled + 2 + 1 + read-write + + + CACHE_IA_INT_APP_IROM0 + APP CPU invalid access to IROM0 when cache is disabled + 3 + 1 + read-write + + + CACHE_IA_INT_APP_DRAM1 + APP CPU invalid access to DRAM1 when cache is disabled + 4 + 1 + read-write + + + CACHE_IA_INT_APP_OPPOSITE + APP CPU invalid access to APP CPU cache when cache disabled + 5 + 1 + read-write + + + CACHE_IA_INT_PRO_DROM0 + PRO CPU invalid access to DROM0 when cache is disabled + 14 + 1 + read-write + + + CACHE_IA_INT_PRO_IRAM0 + PRO CPU invalid access to IRAM0 when cache is disabled + 15 + 1 + read-write + + + CACHE_IA_INT_PRO_IRAM1 + PRO CPU invalid access to IRAM1 when cache is disabled + 16 + 1 + read-write + + + CACHE_IA_INT_PRO_IROM0 + PRO CPU invalid access to IROM0 when cache is disabled + 17 + 1 + read-write + + + CACHE_IA_INT_PRO_DRAM1 + PRO CPU invalid access to DRAM1 when cache is disabled + 18 + 1 + read-write + + + CACHE_IA_INT_PRO_OPPOSITE + PRO CPU invalid access to APP CPU cache when cache disabled + 19 + 1 + read-write + + + + + SECURE_BOOT_CTRL + 0x5A4 + 0x20 + + + SW_BOOTLOADER_SEL + 0 + 1 + read-write + + + + + SPI_DMA_CHAN_SEL + 0x5A8 + 0x20 + + + SPI1_DMA_CHAN_SEL + 0 + 2 + read-write + + + SPI2_DMA_CHAN_SEL + 2 + 2 + read-write + + + SPI3_DMA_CHAN_SEL + 4 + 2 + read-write + + + + + PRO_VECBASE_CTRL + 0x5AC + 0x20 + + + PRO_OUT_VECBASE_SEL + 0 + 2 + read-write + + + + + PRO_VECBASE_SET + 0x5B0 + 0x20 + + + PRO_OUT_VECBASE + 0 + 22 + read-write + + + + + APP_VECBASE_CTRL + 0x5B4 + 0x20 + + + APP_OUT_VECBASE_SEL + 0 + 2 + read-write + + + + + APP_VECBASE_SET + 0x5B8 + 0x20 + + + APP_OUT_VECBASE + 0 + 22 + read-write + + + + + DATE + 0xFFC + 0x20 + 0x01605190 + + + DATE + 0 + 28 + read-write + + + + + + + EFUSE + eFuse Controller + EFUSE + 0x3FF5A000 + + 0x0 + 0x124 + registers + + + EFUSE + 44 + + + + BLK0_RDATA0 + 0x0 + 0x20 + + + RD_EFUSE_WR_DIS + read for efuse_wr_disable + 0 + 16 + read-only + + + RD_EFUSE_RD_DIS + read for efuse_rd_disable + 16 + 4 + read-only + + + RD_FLASH_CRYPT_CNT + read for flash_crypt_cnt + 20 + 7 + read-only + + + + + BLK0_RDATA1 + 0x4 + 0x20 + + + RD_WIFI_MAC_CRC_LOW + read for low 32bit WIFI_MAC_Address + 0 + 32 + read-only + + + + + BLK0_RDATA2 + 0x8 + 0x20 + + + RD_WIFI_MAC_CRC_HIGH + read for high 24bit WIFI_MAC_Address + 0 + 24 + read-only + + + + + BLK0_RDATA3 + 0xC + 0x20 + + + RD_CHIP_VER_DIS_APP_CPU + 0 + 1 + read-only + + + RD_CHIP_VER_DIS_BT + 1 + 1 + read-only + + + RD_CHIP_VER_PKG_4BIT + most significant bit of chip package + 2 + 1 + read-only + + + RD_CHIP_VER_DIS_CACHE + 3 + 1 + read-only + + + RD_SPI_PAD_CONFIG_HD + read for SPI_pad_config_hd + 4 + 5 + read-only + + + RD_CHIP_VER_PKG + least significant bits of chip package + 9 + 3 + read-write + + + RD_CHIP_CPU_FREQ_LOW + If set alongside EFUSE_RD_CHIP_CPU_FREQ_RATED, the ESP32's max CPU frequency is rated for 160MHz. 240MHz otherwise + 12 + 1 + read-write + + + RD_CHIP_CPU_FREQ_RATED + If set, the ESP32's maximum CPU frequency has been rated + 13 + 1 + read-write + + + RD_BLK3_PART_RESERVE + If set, this bit indicates that BLOCK3[143:96] is reserved for internal use + 14 + 1 + read-write + + + RD_CHIP_VER_REV1 + bit is set to 1 for rev1 silicon + 15 + 1 + read-write + + + + + BLK0_RDATA4 + 0x10 + 0x20 + + + RD_CK8M_FREQ + 0 + 8 + read-only + + + RD_ADC_VREF + True ADC reference voltage + 8 + 5 + read-write + + + RD_SDIO_DREFH + 8 + 2 + read-only + + + RD_SDIO_DREFM + 10 + 2 + read-only + + + RD_SDIO_DREFL + 12 + 2 + read-only + + + RD_XPD_SDIO + read for XPD_SDIO_REG + 14 + 1 + read-only + + + RD_SDIO_TIEH + read for SDIO_TIEH + 15 + 1 + read-only + + + RD_SDIO_FORCE + read for sdio_force + 16 + 1 + read-only + + + + + BLK0_RDATA5 + 0x14 + 0x20 + + + RD_SPI_PAD_CONFIG_CLK + read for SPI_pad_config_clk + 0 + 5 + read-only + + + RD_SPI_PAD_CONFIG_Q + read for SPI_pad_config_q + 5 + 5 + read-only + + + RD_SPI_PAD_CONFIG_D + read for SPI_pad_config_d + 10 + 5 + read-only + + + RD_SPI_PAD_CONFIG_CS0 + read for SPI_pad_config_cs0 + 15 + 5 + read-only + + + RD_CHIP_VER_REV2 + 20 + 1 + read-only + + + RD_VOL_LEVEL_HP_INV + This field stores the voltage level for CPU to run at 240 MHz, or for flash/PSRAM to run at 80 MHz.0x0: level 7; 0x1: level 6; 0x2: level 5; 0x3: level 4. (RO) + 22 + 2 + read-only + + + RD_WAFER_VERSION_MINOR + 24 + 2 + read-only + + + RD_FLASH_CRYPT_CONFIG + read for flash_crypt_config + 28 + 4 + read-only + + + + + BLK0_RDATA6 + 0x18 + 0x20 + + + RD_CODING_SCHEME + read for coding_scheme + 0 + 2 + read-only + + + RD_CONSOLE_DEBUG_DISABLE + read for console_debug_disable + 2 + 1 + read-only + + + RD_DISABLE_SDIO_HOST + 3 + 1 + read-only + + + RD_ABS_DONE_0 + read for abstract_done_0 + 4 + 1 + read-only + + + RD_ABS_DONE_1 + read for abstract_done_1 + 5 + 1 + read-only + + + RD_DISABLE_JTAG + read for JTAG_disable + 6 + 1 + read-only + + + RD_DISABLE_DL_ENCRYPT + read for download_dis_encrypt + 7 + 1 + read-only + + + RD_DISABLE_DL_DECRYPT + read for download_dis_decrypt + 8 + 1 + read-only + + + RD_DISABLE_DL_CACHE + read for download_dis_cache + 9 + 1 + read-only + + + RD_KEY_STATUS + read for key_status + 10 + 1 + read-only + + + + + BLK0_WDATA0 + 0x1C + 0x20 + + + WR_DIS + program for efuse_wr_disable + 0 + 16 + read-write + + + RD_DIS + program for efuse_rd_disable + 16 + 4 + read-write + + + FLASH_CRYPT_CNT + program for flash_crypt_cnt + 20 + 7 + read-write + + + + + BLK0_WDATA1 + 0x20 + 0x20 + + + WIFI_MAC_CRC_LOW + program for low 32bit WIFI_MAC_Address + 0 + 32 + read-write + + + + + BLK0_WDATA2 + 0x24 + 0x20 + + + WIFI_MAC_CRC_HIGH + program for high 24bit WIFI_MAC_Address + 0 + 24 + read-write + + + + + BLK0_WDATA3 + 0x28 + 0x20 + + + CHIP_VER_DIS_APP_CPU + 0 + 1 + read-write + + + CHIP_VER_DIS_BT + 1 + 1 + read-write + + + CHIP_VER_PKG_4BIT + most significant bit of chip package + 2 + 1 + read-only + + + CHIP_VER_DIS_CACHE + 3 + 1 + read-write + + + SPI_PAD_CONFIG_HD + program for SPI_pad_config_hd + 4 + 5 + read-write + + + CHIP_VER_PKG + least significant bits of chip package + 9 + 3 + read-write + + + CHIP_CPU_FREQ_LOW + If set alongside EFUSE_CHIP_CPU_FREQ_RATED, the ESP32's max CPU frequency is rated for 160MHz. 240MHz otherwise + 12 + 1 + read-write + + + CHIP_CPU_FREQ_RATED + If set, the ESP32's maximum CPU frequency has been rated + 13 + 1 + read-write + + + BLK3_PART_RESERVE + If set, this bit indicates that BLOCK3[143:96] is reserved for internal use + 14 + 1 + read-write + + + CHIP_VER_REV1 + 15 + 1 + read-write + + + + + BLK0_WDATA4 + 0x2C + 0x20 + + + CK8M_FREQ + 0 + 8 + read-write + + + ADC_VREF + True ADC reference voltage + 8 + 5 + read-write + + + SDIO_DREFH + 8 + 2 + read-write + + + SDIO_DREFM + 10 + 2 + read-write + + + SDIO_DREFL + 12 + 2 + read-write + + + XPD_SDIO + program for XPD_SDIO_REG + 14 + 1 + read-write + + + SDIO_TIEH + program for SDIO_TIEH + 15 + 1 + read-write + + + SDIO_FORCE + program for sdio_force + 16 + 1 + read-write + + + + + BLK0_WDATA5 + 0x30 + 0x20 + + + SPI_PAD_CONFIG_CLK + program for SPI_pad_config_clk + 0 + 5 + read-write + + + SPI_PAD_CONFIG_Q + program for SPI_pad_config_q + 5 + 5 + read-write + + + SPI_PAD_CONFIG_D + program for SPI_pad_config_d + 10 + 5 + read-write + + + SPI_PAD_CONFIG_CS0 + program for SPI_pad_config_cs0 + 15 + 5 + read-write + + + INST_CONFIG + 20 + 8 + read-write + + + VOL_LEVEL_HP_INV + This field stores the voltage level for CPU to run at 240 MHz, or for flash/PSRAM to run at 80 MHz.0x0: level 7; 0x1: level 6; 0x2: level 5; 0x3: level 4. (R/W) + 22 + 2 + read-write + + + DIG_VOL_L6 + 24 + 4 + read-write + + + FLASH_CRYPT_CONFIG + program for flash_crypt_config + 28 + 4 + read-write + + + + + BLK0_WDATA6 + 0x34 + 0x20 + + + CODING_SCHEME + program for coding_scheme + 0 + 2 + read-write + + + CONSOLE_DEBUG_DISABLE + program for console_debug_disable + 2 + 1 + read-write + + + DISABLE_SDIO_HOST + 3 + 1 + read-write + + + ABS_DONE_0 + program for abstract_done_0 + 4 + 1 + read-write + + + ABS_DONE_1 + program for abstract_done_1 + 5 + 1 + read-write + + + DISABLE_JTAG + program for JTAG_disable + 6 + 1 + read-write + + + DISABLE_DL_ENCRYPT + program for download_dis_encrypt + 7 + 1 + read-write + + + DISABLE_DL_DECRYPT + program for download_dis_decrypt + 8 + 1 + read-write + + + DISABLE_DL_CACHE + program for download_dis_cache + 9 + 1 + read-write + + + KEY_STATUS + program for key_status + 10 + 1 + read-write + + + + + BLK1_RDATA0 + 0x38 + 0x20 + + + BLK1_DOUT0 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK1_RDATA1 + 0x3C + 0x20 + + + BLK1_DOUT1 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK1_RDATA2 + 0x40 + 0x20 + + + BLK1_DOUT2 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK1_RDATA3 + 0x44 + 0x20 + + + BLK1_DOUT3 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK1_RDATA4 + 0x48 + 0x20 + + + BLK1_DOUT4 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK1_RDATA5 + 0x4C + 0x20 + + + BLK1_DOUT5 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK1_RDATA6 + 0x50 + 0x20 + + + BLK1_DOUT6 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK1_RDATA7 + 0x54 + 0x20 + + + BLK1_DOUT7 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK2_RDATA0 + 0x58 + 0x20 + + + BLK2_DOUT0 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK2_RDATA1 + 0x5C + 0x20 + + + BLK2_DOUT1 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK2_RDATA2 + 0x60 + 0x20 + + + BLK2_DOUT2 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK2_RDATA3 + 0x64 + 0x20 + + + BLK2_DOUT3 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK2_RDATA4 + 0x68 + 0x20 + + + BLK2_DOUT4 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK2_RDATA5 + 0x6C + 0x20 + + + BLK2_DOUT5 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK2_RDATA6 + 0x70 + 0x20 + + + BLK2_DOUT6 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK2_RDATA7 + 0x74 + 0x20 + + + BLK2_DOUT7 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK3_RDATA0 + 0x78 + 0x20 + + + BLK3_DOUT0 + read for BLOCK3 + 0 + 32 + read-only + + + + + BLK3_RDATA1 + 0x7C + 0x20 + + + BLK3_DOUT1 + read for BLOCK3 + 0 + 32 + read-only + + + + + BLK3_RDATA2 + 0x80 + 0x20 + + + BLK3_DOUT2 + read for BLOCK3 + 0 + 32 + read-only + + + + + BLK3_RDATA3 + 0x84 + 0x20 + + + BLK3_DOUT3 + read for BLOCK3 + 0 + 32 + read-only + + + RD_ADC1_TP_LOW + ADC1 Two Point calibration low point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 0 + 7 + read-write + + + RD_ADC1_TP_HIGH + ADC1 Two Point calibration high point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 7 + 9 + read-write + + + RD_ADC2_TP_LOW + ADC2 Two Point calibration low point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 16 + 7 + read-write + + + RD_ADC2_TP_HIGH + ADC2 Two Point calibration high point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 23 + 9 + read-write + + + + + BLK3_RDATA4 + 0x88 + 0x20 + + + BLK3_DOUT4 + read for BLOCK3 + 0 + 32 + read-only + + + RD_CAL_RESERVED + Reserved for future calibration use. Indicated by EFUSE_RD_BLK3_PART_RESERVE + 0 + 16 + read-write + + + + + BLK3_RDATA5 + 0x8C + 0x20 + + + BLK3_DOUT5 + read for BLOCK3 + 0 + 32 + read-only + + + + + BLK3_RDATA6 + 0x90 + 0x20 + + + BLK3_DOUT6 + read for BLOCK3 + 0 + 32 + read-only + + + + + BLK3_RDATA7 + 0x94 + 0x20 + + + BLK3_DOUT7 + read for BLOCK3 + 0 + 32 + read-only + + + + + BLK1_WDATA0 + 0x98 + 0x20 + + + BLK1_DIN0 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK1_WDATA1 + 0x9C + 0x20 + + + BLK1_DIN1 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK1_WDATA2 + 0xA0 + 0x20 + + + BLK1_DIN2 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK1_WDATA3 + 0xA4 + 0x20 + + + BLK1_DIN3 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK1_WDATA4 + 0xA8 + 0x20 + + + BLK1_DIN4 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK1_WDATA5 + 0xAC + 0x20 + + + BLK1_DIN5 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK1_WDATA6 + 0xB0 + 0x20 + + + BLK1_DIN6 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK1_WDATA7 + 0xB4 + 0x20 + + + BLK1_DIN7 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK2_WDATA0 + 0xB8 + 0x20 + + + BLK2_DIN0 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK2_WDATA1 + 0xBC + 0x20 + + + BLK2_DIN1 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK2_WDATA2 + 0xC0 + 0x20 + + + BLK2_DIN2 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK2_WDATA3 + 0xC4 + 0x20 + + + BLK2_DIN3 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK2_WDATA4 + 0xC8 + 0x20 + + + BLK2_DIN4 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK2_WDATA5 + 0xCC + 0x20 + + + BLK2_DIN5 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK2_WDATA6 + 0xD0 + 0x20 + + + BLK2_DIN6 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK2_WDATA7 + 0xD4 + 0x20 + + + BLK2_DIN7 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK3_WDATA0 + 0xD8 + 0x20 + + + BLK3_DIN0 + program for BLOCK3 + 0 + 32 + read-write + + + + + BLK3_WDATA1 + 0xDC + 0x20 + + + BLK3_DIN1 + program for BLOCK3 + 0 + 32 + read-write + + + + + BLK3_WDATA2 + 0xE0 + 0x20 + + + BLK3_DIN2 + program for BLOCK3 + 0 + 32 + read-write + + + + + BLK3_WDATA3 + 0xE4 + 0x20 + + + BLK3_DIN3 + program for BLOCK3 + 0 + 32 + read-write + + + ADC1_TP_LOW + ADC1 Two Point calibration low point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 0 + 7 + read-write + + + ADC1_TP_HIGH + ADC1 Two Point calibration high point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 7 + 9 + read-write + + + ADC2_TP_LOW + ADC2 Two Point calibration low point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 16 + 7 + read-write + + + ADC2_TP_HIGH + ADC2 Two Point calibration high point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 23 + 9 + read-write + + + + + BLK3_WDATA4 + 0xE8 + 0x20 + + + BLK3_DIN4 + program for BLOCK3 + 0 + 32 + read-write + + + CAL_RESERVED + Reserved for future calibration use. Indicated by EFUSE_BLK3_PART_RESERVE + 0 + 16 + read-write + + + + + BLK3_WDATA5 + 0xEC + 0x20 + + + BLK3_DIN5 + program for BLOCK3 + 0 + 32 + read-write + + + + + BLK3_WDATA6 + 0xF0 + 0x20 + + + BLK3_DIN6 + program for BLOCK3 + 0 + 32 + read-write + + + + + BLK3_WDATA7 + 0xF4 + 0x20 + + + BLK3_DIN7 + program for BLOCK3 + 0 + 32 + read-write + + + + + CLK + 0xF8 + 0x20 + 0x00004052 + + + SEL0 + efuse timing configure + 0 + 8 + read-write + + + SEL1 + efuse timing configure + 8 + 8 + read-write + + + EN + 16 + 1 + read-write + + + + + CONF + 0xFC + 0x20 + 0x00010000 + + + OP_CODE + efuse operation code + 0 + 16 + read-write + + + FORCE_NO_WR_RD_DIS + 16 + 1 + read-write + + + + + STATUS + 0x100 + 0x20 + + + DEBUG + 0 + 32 + read-only + + + + + CMD + 0x104 + 0x20 + + + READ_CMD + command for read + 0 + 1 + read-write + + + PGM_CMD + command for program + 1 + 1 + read-write + + + + + INT_RAW + 0x108 + 0x20 + + + READ_DONE_INT_RAW + read done interrupt raw status + 0 + 1 + read-only + + + PGM_DONE_INT_RAW + program done interrupt raw status + 1 + 1 + read-only + + + + + INT_ST + 0x10C + 0x20 + + + READ_DONE_INT_ST + read done interrupt status + 0 + 1 + read-only + + + PGM_DONE_INT_ST + program done interrupt status + 1 + 1 + read-only + + + + + INT_ENA + 0x110 + 0x20 + + + READ_DONE_INT_ENA + read done interrupt enable + 0 + 1 + read-write + + + PGM_DONE_INT_ENA + program done interrupt enable + 1 + 1 + read-write + + + + + INT_CLR + 0x114 + 0x20 + + + READ_DONE_INT_CLR + read done interrupt clear + 0 + 1 + write-only + + + PGM_DONE_INT_CLR + program done interrupt clear + 1 + 1 + write-only + + + + + DAC_CONF + 0x118 + 0x20 + 0x00000028 + + + DAC_CLK_DIV + efuse timing configure + 0 + 8 + read-write + + + DAC_CLK_PAD_SEL + 8 + 1 + read-write + + + + + DEC_STATUS + 0x11C + 0x20 + + + DEC_WARNINGS + the decode result of 3/4 coding scheme has warning + 0 + 12 + read-only + + + + + DATE + 0x1FC + 0x20 + 0x16042600 + + + DATE + 0 + 32 + read-write + + + + + + + FLASH_ENCRYPTION + Flash Encryption Peripheral + FLASH_ENCRYPTION + 0x3FF46000 + + 0x0 + 0x2C + registers + + + + 8 + 0x4 + BUFFER_%s + 0x0 + 0x20 + + + BUFFER + Data buffers for encryption. + 0 + 8 + write-only + + + + + START + 0x20 + 0x20 + + + FLASH_START + Set this bit to start encryption operation on data buffer. + 0 + 8 + write-only + + + + + ADDRESS + 0x24 + 0x20 + + + ADDRESS + The physical address on the off-chip flash must be 8-word boundary aligned. + 0 + 8 + write-only + + + + + DONE + 0x28 + 0x20 + + + FLASH_DONE + Set this bit when encryption operation is complete. + 0 + 1 + read-only + + + + + + + FRC_TIMER + Peripheral FRC_TIMER + FRC + 0x3FF47000 + + 0x0 + 0x14 + registers + + + + TIMER_LOAD + 0x0 + 0x20 + + + VALUE + 0 + 8 + read-write + + + + + TIMER_COUNT + 0x4 + 0x20 + + + TIMER_COUNT + 0 + 8 + read-write + + + + + TIMER_CTRL + 0x8 + 0x20 + + + TIMER_PRESCALER + 1 + 8 + read-write + + + + + TIMER_INT + 0xC + 0x20 + + + CLR + 0 + 1 + read-write + + + + + TIMER_ALARM + 0x10 + 0x20 + + + TIMER_ALARM + 0 + 8 + read-write + + + + + + + GPIO + General Purpose Input/Output + GPIO + 0x3FF44000 + + 0x0 + 0x5CC + registers + + + GPIO + 22 + + + GPIO_NMI + 23 + + + + BT_SELECT + 0x0 + 0x20 + + + BT_SEL + NA + 0 + 32 + read-write + + + + + OUT + 0x4 + 0x20 + + + DATA + GPIO0~31 output value + 0 + 32 + read-write + + + + + OUT_W1TS + 0x8 + 0x20 + + + OUT_DATA_W1TS + GPIO0~31 output value write 1 to set + 0 + 32 + read-write + + + + + OUT_W1TC + 0xC + 0x20 + + + OUT_DATA_W1TC + GPIO0~31 output value write 1 to clear + 0 + 32 + read-write + + + + + OUT1 + 0x10 + 0x20 + + + DATA + GPIO32~39 output value + 0 + 8 + read-write + + + + + OUT1_W1TS + 0x14 + 0x20 + + + OUT1_DATA_W1TS + GPIO32~39 output value write 1 to set + 0 + 8 + read-write + + + + + OUT1_W1TC + 0x18 + 0x20 + + + OUT1_DATA_W1TC + GPIO32~39 output value write 1 to clear + 0 + 8 + read-write + + + + + SDIO_SELECT + 0x1C + 0x20 + + + SDIO_SEL + SDIO PADS on/off control from outside + 0 + 8 + read-write + + + + + ENABLE + 0x20 + 0x20 + + + DATA + GPIO0~31 output enable + 0 + 32 + read-write + + + + + ENABLE_W1TS + 0x24 + 0x20 + + + ENABLE_DATA_W1TS + GPIO0~31 output enable write 1 to set + 0 + 32 + read-write + + + + + ENABLE_W1TC + 0x28 + 0x20 + + + ENABLE_DATA_W1TC + GPIO0~31 output enable write 1 to clear + 0 + 32 + read-write + + + + + ENABLE1 + 0x2C + 0x20 + + + DATA + GPIO32~39 output enable + 0 + 8 + read-write + + + + + ENABLE1_W1TS + 0x30 + 0x20 + + + ENABLE1_DATA_W1TS + GPIO32~39 output enable write 1 to set + 0 + 8 + read-write + + + + + ENABLE1_W1TC + 0x34 + 0x20 + + + ENABLE1_DATA_W1TC + GPIO32~39 output enable write 1 to clear + 0 + 8 + read-write + + + + + STRAP + 0x38 + 0x20 + + + STRAPPING + {10'b0, MTDI, GPIO0, GPIO2, GPIO4, MTDO, GPIO5} + 0 + 16 + read-only + + + + + IN + 0x3C + 0x20 + + + DATA_NEXT + GPIO0~31 input value + 0 + 32 + read-write + + + + + IN1 + 0x40 + 0x20 + + + DATA_NEXT + GPIO32~39 input value + 0 + 8 + read-write + + + + + STATUS + 0x44 + 0x20 + + + INT + GPIO0~31 interrupt status + 0 + 32 + read-write + + + + + STATUS_W1TS + 0x48 + 0x20 + + + STATUS_INT_W1TS + GPIO0~31 interrupt status write 1 to set + 0 + 32 + read-write + + + + + STATUS_W1TC + 0x4C + 0x20 + + + STATUS_INT_W1TC + GPIO0~31 interrupt status write 1 to clear + 0 + 32 + read-write + + + + + STATUS1 + 0x50 + 0x20 + + + INT + GPIO32~39 interrupt status + 0 + 8 + read-write + + + + + STATUS1_W1TS + 0x54 + 0x20 + + + STATUS1_INT_W1TS + GPIO32~39 interrupt status write 1 to set + 0 + 8 + read-write + + + + + STATUS1_W1TC + 0x58 + 0x20 + + + STATUS1_INT_W1TC + GPIO32~39 interrupt status write 1 to clear + 0 + 8 + read-write + + + + + ACPU_INT + 0x60 + 0x20 + + + APPCPU_INT + GPIO0~31 APP CPU interrupt status + 0 + 32 + read-only + + + + + ACPU_NMI_INT + 0x64 + 0x20 + + + APPCPU_NMI_INT + GPIO0~31 APP CPU non-maskable interrupt status + 0 + 32 + read-only + + + + + PCPU_INT + 0x68 + 0x20 + + + PROCPU_INT + GPIO0~31 PRO CPU interrupt status + 0 + 32 + read-only + + + + + PCPU_NMI_INT + 0x6C + 0x20 + + + PROCPU_NMI_INT + GPIO0~31 PRO CPU non-maskable interrupt status + 0 + 32 + read-only + + + + + CPUSDIO_INT + 0x70 + 0x20 + + + SDIO_INT + SDIO's extent GPIO0~31 interrupt + 0 + 32 + read-only + + + + + ACPU_INT1 + 0x74 + 0x20 + + + APPCPU_INT_H + GPIO32~39 APP CPU interrupt status + 0 + 8 + read-only + + + + + ACPU_NMI_INT1 + 0x78 + 0x20 + + + APPCPU_NMI_INT_H + GPIO32~39 APP CPU non-maskable interrupt status + 0 + 8 + read-only + + + + + PCPU_INT1 + 0x7C + 0x20 + + + PROCPU_INT_H + GPIO32~39 PRO CPU interrupt status + 0 + 8 + read-only + + + + + PCPU_NMI_INT1 + 0x80 + 0x20 + + + PROCPU_NMI_INT_H + GPIO32~39 PRO CPU non-maskable interrupt status + 0 + 8 + read-only + + + + + CPUSDIO_INT1 + 0x84 + 0x20 + + + SDIO_INT_H + SDIO's extent GPIO32~39 interrupt + 0 + 8 + read-only + + + PIN_PAD_DRIVER + 2 + 1 + read-write + + + PIN_INT_TYPE + 7 + 3 + read-write + + + PIN_WAKEUP_ENABLE + 10 + 1 + read-write + + + PIN_CONFIG + 11 + 2 + read-write + + + PIN_INT_ENA + 13 + 5 + read-write + + + + + 40 + 0x4 + 0-39 + PIN%s + 0x88 + 0x20 + + + PAD_DRIVER + if set to 0: normal output if set to 1: open drain + 2 + 1 + read-write + + + INT_TYPE + if set to 0: GPIO interrupt disable if set to 1: rising edge trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger + 7 + 3 + read-write + + + WAKEUP_ENABLE + GPIO wake up enable only available in light sleep + 10 + 1 + read-write + + + CONFIG + NA + 11 + 2 + read-write + + + INT_ENA + bit0: APP CPU interrupt enable bit1: APP CPU non-maskable interrupt enable bit3: PRO CPU interrupt enable bit4: PRO CPU non-maskable interrupt enable bit5: SDIO's extent interrupt enable + 13 + 5 + read-write + + + + + cali_conf + 0x128 + 0x20 + + + CALI_RTC_MAX + 0 + 10 + read-write + + + CALI_START + 31 + 1 + read-write + + + + + cali_data + 0x12C + 0x20 + + + CALI_VALUE_SYNC2 + 0 + 20 + read-only + + + CALI_RDY_REAL + 30 + 1 + read-only + + + CALI_RDY_SYNC2 + 31 + 1 + read-only + + + + + 256 + 0x4 + 0-255 + FUNC%s_IN_SEL_CFG + 0x130 + 0x20 + + + IN_SEL + select one of the 256 inputs + 0 + 6 + read-write + + + IN_INV_SEL + revert the value of the input if you want to revert please set the value to 1 + 6 + 1 + read-write + + + SEL + if the slow signal bypass the io matrix or not if you want setting the value to 1 + 7 + 1 + read-write + + + + + 40 + 0x4 + 0-39 + FUNC%s_OUT_SEL_CFG + 0x530 + 0x20 + + + OUT_SEL + select one of the 256 output to 40 GPIO + 0 + 9 + read-write + + + INV_SEL + invert the output value if you want to revert the output value setting the value to 1 + 9 + 1 + read-write + + + OEN_SEL + weather using the logical oen signal or not using the value setting by the register + 10 + 1 + read-write + + + OEN_INV_SEL + invert the output enable value if you want to revert the output enable value setting the value to 1 + 11 + 1 + read-write + + + + + + + GPIO_SD + Sigma-Delta Modulation + GPIO_SIGMADELTA + 0x3FF44F00 + + 0x0 + 0x2C + registers + + + + SIGMADELTA0 + 0x0 + 0x20 + 0x0000FF00 + + + SD0_IN + 0 + 8 + read-write + + + SD0_PRESCALE + 8 + 8 + read-write + + + + + SIGMADELTA1 + 0x4 + 0x20 + 0x0000FF00 + + + SD1_IN + 0 + 8 + read-write + + + SD1_PRESCALE + 8 + 8 + read-write + + + + + SIGMADELTA2 + 0x8 + 0x20 + 0x0000FF00 + + + SD2_IN + 0 + 8 + read-write + + + SD2_PRESCALE + 8 + 8 + read-write + + + + + SIGMADELTA3 + 0xC + 0x20 + 0x0000FF00 + + + SD3_IN + 0 + 8 + read-write + + + SD3_PRESCALE + 8 + 8 + read-write + + + + + SIGMADELTA4 + 0x10 + 0x20 + 0x0000FF00 + + + SD4_IN + 0 + 8 + read-write + + + SD4_PRESCALE + 8 + 8 + read-write + + + + + SIGMADELTA5 + 0x14 + 0x20 + 0x0000FF00 + + + SD5_IN + 0 + 8 + read-write + + + SD5_PRESCALE + 8 + 8 + read-write + + + + + SIGMADELTA6 + 0x18 + 0x20 + 0x0000FF00 + + + SD6_IN + 0 + 8 + read-write + + + SD6_PRESCALE + 8 + 8 + read-write + + + + + SIGMADELTA7 + 0x1C + 0x20 + 0x0000FF00 + + + SD7_IN + 0 + 8 + read-write + + + SD7_PRESCALE + 8 + 8 + read-write + + + + + CG + 0x20 + 0x20 + + + SD_CLK_EN + 31 + 1 + read-write + + + + + MISC + 0x24 + 0x20 + + + SPI_SWAP + 31 + 1 + read-write + + + + + VERSION + 0x28 + 0x20 + 0x01506190 + + + SD_DATE + 0 + 28 + read-write + + + + + + + HINF + Peripheral HINF + HINF + 0x3FF4B000 + + 0x0 + 0x34 + registers + + + + CFG_DATA0 + 0x0 + 0x20 + 0x22226666 + + + USER_ID_FN1 + 0 + 16 + read-write + + + DEVICE_ID_FN1 + 16 + 16 + read-write + + + + + CFG_DATA1 + 0x4 + 0x20 + 0x01110011 + + + SDIO_ENABLE + 0 + 1 + read-write + + + SDIO_IOREADY1 + 1 + 1 + read-write + + + HIGHSPEED_ENABLE + 2 + 1 + read-write + + + HIGHSPEED_MODE + 3 + 1 + read-only + + + SDIO_CD_ENABLE + 4 + 1 + read-write + + + SDIO_IOREADY2 + 5 + 1 + read-write + + + SDIO_INT_MASK + 6 + 1 + read-write + + + IOENABLE2 + 7 + 1 + read-only + + + CD_DISABLE + 8 + 1 + read-only + + + FUNC1_EPS + 9 + 1 + read-only + + + EMP + 10 + 1 + read-only + + + IOENABLE1 + 11 + 1 + read-only + + + SDIO20_CONF0 + 12 + 4 + read-write + + + SDIO_VER + 16 + 12 + read-write + + + FUNC2_EPS + 28 + 1 + read-only + + + SDIO20_CONF1 + 29 + 3 + read-write + + + + + CFG_DATA7 + 0x1C + 0x20 + 0x00020000 + + + PIN_STATE + 0 + 8 + read-write + + + CHIP_STATE + 8 + 8 + read-write + + + SDIO_RST + 16 + 1 + read-write + + + SDIO_IOREADY0 + 17 + 1 + read-write + + + + + CIS_CONF0 + 0x20 + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W0 + 0 + 32 + read-write + + + + + CIS_CONF1 + 0x24 + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W1 + 0 + 32 + read-write + + + + + CIS_CONF2 + 0x28 + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W2 + 0 + 32 + read-write + + + + + CIS_CONF3 + 0x2C + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W3 + 0 + 32 + read-write + + + + + CIS_CONF4 + 0x30 + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W4 + 0 + 32 + read-write + + + + + CIS_CONF5 + 0x34 + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W5 + 0 + 32 + read-write + + + + + CIS_CONF6 + 0x38 + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W6 + 0 + 32 + read-write + + + + + CIS_CONF7 + 0x3C + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W7 + 0 + 32 + read-write + + + + + CFG_DATA16 + 0x40 + 0x20 + 0x33336666 + + + USER_ID_FN2 + 0 + 16 + read-write + + + DEVICE_ID_FN2 + 16 + 16 + read-write + + + + + DATE + 0xFC + 0x20 + 0x15030200 + + + SDIO_DATE + 0 + 32 + read-write + + + + + + + I2C0 + I2C (Inter-Integrated Circuit) Controller + I2C + 0x3FF53000 + + 0x0 + 0x9C + registers + + + I2C_EXT0 + 49 + + + + SCL_LOW_PERIOD + 0x0 + 0x20 + + + SCL_LOW_PERIOD + This register is used to configure the low level width of SCL clock. + 0 + 14 + read-write + + + + + CTR + 0x4 + 0x20 + 0x00000003 + + + SDA_FORCE_OUT + 1: normally ouput sda data 0: exchange the function of sda_o and sda_oe (sda_o is the original internal output sda signal sda_oe is the enable bit for the internal output sda signal) + 0 + 1 + read-write + + + SCL_FORCE_OUT + 1: normally ouput scl clock 0: exchange the function of scl_o and scl_oe (scl_o is the original internal output scl signal scl_oe is the enable bit for the internal output scl signal) + 1 + 1 + read-write + + + SAMPLE_SCL_LEVEL + Set this bit to sample data in SCL low level. clear this bit to sample data in SCL high level. + 2 + 1 + read-write + + + MS_MODE + Set this bit to configure the module as i2c master clear this bit to configure the module as i2c slave. + 4 + 1 + read-write + + + TRANS_START + Set this bit to start sending data in txfifo. + 5 + 1 + read-write + + + TX_LSB_FIRST + This bit is used to control the sending mode for data need to be send. 1: receive data from most significant bit 0: receive data from least significant bit + 6 + 1 + read-write + + + RX_LSB_FIRST + This bit is used to control the storage mode for received datas. 1: receive data from most significant bit 0: receive data from least significant bit + 7 + 1 + read-write + + + CLK_EN + This is the clock gating control bit for reading or writing registers. + 8 + 1 + read-write + + + + + SR + 0x8 + 0x20 + + + ACK_REC + This register stores the value of ACK bit. + 0 + 1 + read-only + + + SLAVE_RW + when in slave mode 1: master read slave 0: master write slave. + 1 + 1 + read-only + + + TIME_OUT + when I2C takes more than time_out_reg clocks to receive a data then this register changes to high level. + 2 + 1 + read-only + + + ARB_LOST + when I2C lost control of SDA line this register changes to high level. + 3 + 1 + read-only + + + BUS_BUSY + 1:I2C bus is busy transferring data. 0:I2C bus is in idle state. + 4 + 1 + read-only + + + SLAVE_ADDRESSED + when configured as i2c slave and the address send by master is equal to slave's address then this bit will be high level. + 5 + 1 + read-only + + + BYTE_TRANS + This register changes to high level when one byte is transferred. + 6 + 1 + read-only + + + RXFIFO_CNT + This register represent the amount of data need to send. + 8 + 6 + read-only + + + TXFIFO_CNT + This register stores the amount of received data in ram. + 18 + 6 + read-only + + + SCL_MAIN_STATE_LAST + This register stores the value of state machine for i2c module. 3'h0: SCL_MAIN_IDLE 3'h1: SCL_ADDRESS_SHIFT 3'h2: SCL_ACK_ADDRESS 3'h3: SCL_RX_DATA 3'h4 SCL_TX_DATA 3'h5:SCL_SEND_ACK 3'h6:SCL_WAIT_ACK + 24 + 3 + read-only + + + SCL_STATE_LAST + This register stores the value of state machine to produce SCL. 3'h0: SCL_IDLE 3'h1:SCL_START 3'h2:SCL_LOW_EDGE 3'h3: SCL_LOW 3'h4:SCL_HIGH_EDGE 3'h5:SCL_HIGH 3'h6:SCL_STOP + 28 + 3 + read-only + + + + + TO + 0xC + 0x20 + + + TIME_OUT + This register is used to configure the max clock number of receiving a data. + 0 + 20 + read-write + + + + + SLAVE_ADDR + 0x10 + 0x20 + + + SLAVE_ADDR + when configured as i2c slave this register is used to configure slave's address. + 0 + 15 + read-write + + + ADDR_10BIT_EN + This register is used to enable slave 10bit address mode. + 31 + 1 + read-write + + + + + RXFIFO_ST + 0x14 + 0x20 + + + RXFIFO_START_ADDR + This is the offset address of the last receiving data as described in nonfifo_rx_thres_register. + 0 + 5 + read-only + + + RXFIFO_END_ADDR + This is the offset address of the first receiving data as described in nonfifo_rx_thres_register. + 5 + 5 + read-only + + + TXFIFO_START_ADDR + This is the offset address of the first sending data as described in nonfifo_tx_thres register. + 10 + 5 + read-only + + + TXFIFO_END_ADDR + This is the offset address of the last sending data as described in nonfifo_tx_thres register. + 15 + 5 + read-only + + + + + FIFO_CONF + 0x18 + 0x20 + 0x0155408B + + + RXFIFO_FULL_THRHD + 0 + 5 + read-write + + + TXFIFO_EMPTY_THRHD + Config txfifo empty threhd value when using apb fifo access + 5 + 5 + read-write + + + NONFIFO_EN + Set this bit to enble apb nonfifo access. + 10 + 1 + read-write + + + FIFO_ADDR_CFG_EN + When this bit is set to 1 then the byte after address represent the offset address of I2C Slave's ram. + 11 + 1 + read-write + + + RX_FIFO_RST + Set this bit to reset rx fifo when using apb fifo access. + 12 + 1 + read-write + + + TX_FIFO_RST + Set this bit to reset tx fifo when using apb fifo access. + 13 + 1 + read-write + + + NONFIFO_RX_THRES + when I2C receives more than nonfifo_rx_thres data it will produce rx_send_full_int_raw interrupt and update the current offset address of the receiving data. + 14 + 6 + read-write + + + NONFIFO_TX_THRES + when I2C sends more than nonfifo_tx_thres data it will produce tx_send_empty_int_raw interrupt and update the current offset address of the sending data. + 20 + 6 + read-write + + + + + DATA + 0x1C + 0x20 + + + FIFO_RDATA + The register represent the byte data read from rxfifo when use apb fifo access + 0 + 8 + read-only + + + + + INT_RAW + 0x20 + 0x20 + + + RXFIFO_FULL_INT_RAW + The raw interrupt status bit for rxfifo full when use apb fifo access. + 0 + 1 + read-only + + + TXFIFO_EMPTY_INT_RAW + The raw interrupt status bit for txfifo empty when use apb fifo access. + 1 + 1 + read-only + + + RXFIFO_OVF_INT_RAW + The raw interrupt status bit for receiving data overflow when use apb fifo access. + 2 + 1 + read-only + + + END_DETECT_INT_RAW + The raw interrupt status bit for end_detect_int interrupt. when I2C deals with the END command it will produce end_detect_int interrupt. + 3 + 1 + read-only + + + SLAVE_TRAN_COMP_INT_RAW + The raw interrupt status bit for slave_tran_comp_int interrupt. when I2C Slave detectsthe STOP bit it will produce slave_tran_comp_int interrupt. + 4 + 1 + read-only + + + ARBITRATION_LOST_INT_RAW + The raw interrupt status bit for arbitration_lost_int interrupt.when I2C lost the usage right of I2C BUS it will produce arbitration_lost_int interrupt. + 5 + 1 + read-only + + + MASTER_TRAN_COMP_INT_RAW + The raw interrupt status bit for master_tra_comp_int interrupt. when I2C Master sends or receives a byte it will produce master_tran_comp_int interrupt. + 6 + 1 + read-only + + + TRANS_COMPLETE_INT_RAW + The raw interrupt status bit for trans_complete_int interrupt. when I2C Master finished STOP command it will produce trans_complete_int interrupt. + 7 + 1 + read-only + + + TIME_OUT_INT_RAW + The raw interrupt status bit for time_out_int interrupt. when I2C takes a lot of time to receive a data it will produce time_out_int interrupt. + 8 + 1 + read-only + + + TRANS_START_INT_RAW + The raw interrupt status bit for trans_start_int interrupt. when I2C sends the START bit it will produce trans_start_int interrupt. + 9 + 1 + read-only + + + ACK_ERR_INT_RAW + The raw interrupt status bit for ack_err_int interrupt. when I2C receives a wrong ACK bit it will produce ack_err_int interrupt.. + 10 + 1 + read-only + + + RX_REC_FULL_INT_RAW + The raw interrupt status bit for rx_rec_full_int interrupt. when I2C receives more data than nonfifo_rx_thres it will produce rx_rec_full_int interrupt. + 11 + 1 + read-only + + + TX_SEND_EMPTY_INT_RAW + The raw interrupt status bit for tx_send_empty_int interrupt.when I2C sends more data than nonfifo_tx_thres it will produce tx_send_empty_int interrupt.. + 12 + 1 + read-only + + + + + INT_CLR + 0x24 + 0x20 + + + RXFIFO_FULL_INT_CLR + Set this bit to clear the rxfifo_full_int interrupt. + 0 + 1 + write-only + + + TXFIFO_EMPTY_INT_CLR + Set this bit to clear the txfifo_empty_int interrupt. + 1 + 1 + write-only + + + RXFIFO_OVF_INT_CLR + Set this bit to clear the rxfifo_ovf_int interrupt. + 2 + 1 + write-only + + + END_DETECT_INT_CLR + Set this bit to clear the end_detect_int interrupt. + 3 + 1 + write-only + + + SLAVE_TRAN_COMP_INT_CLR + Set this bit to clear the slave_tran_comp_int interrupt. + 4 + 1 + write-only + + + ARBITRATION_LOST_INT_CLR + Set this bit to clear the arbitration_lost_int interrupt. + 5 + 1 + write-only + + + MASTER_TRAN_COMP_INT_CLR + Set this bit to clear the master_tran_comp interrupt. + 6 + 1 + write-only + + + TRANS_COMPLETE_INT_CLR + Set this bit to clear the trans_complete_int interrupt. + 7 + 1 + write-only + + + TIME_OUT_INT_CLR + Set this bit to clear the time_out_int interrupt. + 8 + 1 + write-only + + + TRANS_START_INT_CLR + Set this bit to clear the trans_start_int interrupt. + 9 + 1 + write-only + + + ACK_ERR_INT_CLR + Set this bit to clear the ack_err_int interrupt. + 10 + 1 + write-only + + + RX_REC_FULL_INT_CLR + Set this bit to clear the rx_rec_full_int interrupt. + 11 + 1 + write-only + + + TX_SEND_EMPTY_INT_CLR + Set this bit to clear the tx_send_empty_int interrupt. + 12 + 1 + write-only + + + + + INT_ENA + 0x28 + 0x20 + + + RXFIFO_FULL_INT_ENA + The enable bit for rxfifo_full_int interrupt. + 0 + 1 + read-write + + + TXFIFO_EMPTY_INT_ENA + The enable bit for txfifo_empty_int interrupt. + 1 + 1 + read-write + + + RXFIFO_OVF_INT_ENA + The enable bit for rxfifo_ovf_int interrupt. + 2 + 1 + read-write + + + END_DETECT_INT_ENA + The enable bit for end_detect_int interrupt. + 3 + 1 + read-write + + + SLAVE_TRAN_COMP_INT_ENA + The enable bit for slave_tran_comp_int interrupt. + 4 + 1 + read-write + + + ARBITRATION_LOST_INT_ENA + The enable bit for arbitration_lost_int interrupt. + 5 + 1 + read-write + + + MASTER_TRAN_COMP_INT_ENA + The enable bit for master_tran_comp_int interrupt. + 6 + 1 + read-write + + + TRANS_COMPLETE_INT_ENA + The enable bit for trans_complete_int interrupt. + 7 + 1 + read-write + + + TIME_OUT_INT_ENA + The enable bit for time_out_int interrupt. + 8 + 1 + read-write + + + TRANS_START_INT_ENA + The enable bit for trans_start_int interrupt. + 9 + 1 + read-write + + + ACK_ERR_INT_ENA + The enable bit for ack_err_int interrupt. + 10 + 1 + read-write + + + RX_REC_FULL_INT_ENA + The enable bit for rx_rec_full_int interrupt. + 11 + 1 + read-write + + + TX_SEND_EMPTY_INT_ENA + The enable bit for tx_send_empty_int interrupt. + 12 + 1 + read-write + + + + + INT_STATUS + 0x2C + 0x20 + + + RXFIFO_FULL_INT_ST + The masked interrupt status for rxfifo_full_int interrupt. + 0 + 1 + read-only + + + TXFIFO_EMPTY_INT_ST + The masked interrupt status for txfifo_empty_int interrupt. + 1 + 1 + read-only + + + RXFIFO_OVF_INT_ST + The masked interrupt status for rxfifo_ovf_int interrupt. + 2 + 1 + read-only + + + END_DETECT_INT_ST + The masked interrupt status for end_detect_int interrupt. + 3 + 1 + read-only + + + SLAVE_TRAN_COMP_INT_ST + The masked interrupt status for slave_tran_comp_int interrupt. + 4 + 1 + read-only + + + ARBITRATION_LOST_INT_ST + The masked interrupt status for arbitration_lost_int interrupt. + 5 + 1 + read-only + + + MASTER_TRAN_COMP_INT_ST + The masked interrupt status for master_tran_comp_int interrupt. + 6 + 1 + read-only + + + TRANS_COMPLETE_INT_ST + The masked interrupt status for trans_complete_int interrupt. + 7 + 1 + read-only + + + TIME_OUT_INT_ST + The masked interrupt status for time_out_int interrupt. + 8 + 1 + read-only + + + TRANS_START_INT_ST + The masked interrupt status for trans_start_int interrupt. + 9 + 1 + read-only + + + ACK_ERR_INT_ST + The masked interrupt status for ack_err_int interrupt. + 10 + 1 + read-only + + + RX_REC_FULL_INT_ST + The masked interrupt status for rx_rec_full_int interrupt. + 11 + 1 + read-only + + + TX_SEND_EMPTY_INT_ST + The masked interrupt status for tx_send_empty_int interrupt. + 12 + 1 + read-only + + + + + SDA_HOLD + 0x30 + 0x20 + + + TIME + This register is used to configure the clock num I2C used to hold the data after the negedge of SCL. + 0 + 10 + read-write + + + + + SDA_SAMPLE + 0x34 + 0x20 + + + TIME + This register is used to configure the clock num I2C used to sample data on SDA after the posedge of SCL + 0 + 10 + read-write + + + + + SCL_HIGH_PERIOD + 0x38 + 0x20 + + + SCL_HIGH_PERIOD + This register is used to configure the clock num during SCL is low level. + 0 + 14 + read-write + + + + + SCL_START_HOLD + 0x40 + 0x20 + 0x00000008 + + + TIME + This register is used to configure the clock num between the negedge of SDA and negedge of SCL for start mark. + 0 + 10 + read-write + + + + + SCL_RSTART_SETUP + 0x44 + 0x20 + 0x00000008 + + + TIME + This register is used to configure the clock num between the posedge of SCL and the negedge of SDA for restart mark. + 0 + 10 + read-write + + + + + SCL_STOP_HOLD + 0x48 + 0x20 + + + TIME + This register is used to configure the clock num after the STOP bit's posedge. + 0 + 14 + read-write + + + + + SCL_STOP_SETUP + 0x4C + 0x20 + + + TIME + This register is used to configure the clock num between the posedge of SCL and the posedge of SDA. + 0 + 10 + read-write + + + + + SCL_FILTER_CFG + 0x50 + 0x20 + 0x00000008 + + + SCL_FILTER_THRES + When input SCL's pulse width is smaller than this register value I2C ignores this pulse. + 0 + 3 + read-write + + + SCL_FILTER_EN + This is the filter enable bit for SCL. + 3 + 1 + read-write + + + + + SDA_FILTER_CFG + 0x54 + 0x20 + 0x00000008 + + + SDA_FILTER_THRES + When input SCL's pulse width is smaller than this register value I2C ignores this pulse. + 0 + 3 + read-write + + + SDA_FILTER_EN + This is the filter enable bit for SDA. + 3 + 1 + read-write + + + + + 16 + 0x4 + 0-15 + COMD%s + 0x58 + 0x20 + + + COMMAND + This is the content of command0. It consists of three part. op_code is the command 0: RSTART 1: WRITE 2: READ 3: STOP . 4:END. Byte_num represent the number of data need to be send or data need to be received. ack_check_en ack_exp and ack value are used to control the ack bit. + 0 + 14 + read-write + + + COMMAND_DONE + When command0 is done in I2C Master mode this bit changes to high level. + 31 + 1 + read-write + + + + + DATE + 0xF8 + 0x20 + 0x16042000 + + + DATE + 0 + 32 + read-write + + + + + FIFO_START_ADDR + 0x100 + 0x20 + + + + + I2C1 + I2C (Inter-Integrated Circuit) Controller + 0x3FF67000 + + I2C_EXT1 + 50 + + + + I2S0 + I2S (Inter-IC Sound) Controller + I2S + 0x3FF4F000 + + 0x0 + 0xB4 + registers + + + I2S0 + 32 + + + + CONF + 0x8 + 0x20 + 0x00030300 + + + TX_RESET + 0 + 1 + read-write + + + RX_RESET + 1 + 1 + read-write + + + TX_FIFO_RESET + 2 + 1 + read-write + + + RX_FIFO_RESET + 3 + 1 + read-write + + + TX_START + 4 + 1 + read-write + + + RX_START + 5 + 1 + read-write + + + TX_SLAVE_MOD + 6 + 1 + read-write + + + RX_SLAVE_MOD + 7 + 1 + read-write + + + TX_RIGHT_FIRST + 8 + 1 + read-write + + + RX_RIGHT_FIRST + 9 + 1 + read-write + + + TX_MSB_SHIFT + 10 + 1 + read-write + + + RX_MSB_SHIFT + 11 + 1 + read-write + + + TX_SHORT_SYNC + 12 + 1 + read-write + + + RX_SHORT_SYNC + 13 + 1 + read-write + + + TX_MONO + 14 + 1 + read-write + + + RX_MONO + 15 + 1 + read-write + + + TX_MSB_RIGHT + 16 + 1 + read-write + + + RX_MSB_RIGHT + 17 + 1 + read-write + + + SIG_LOOPBACK + 18 + 1 + read-write + + + + + INT_RAW + 0xC + 0x20 + + + RX_TAKE_DATA_INT_RAW + 0 + 1 + read-only + + + TX_PUT_DATA_INT_RAW + 1 + 1 + read-only + + + RX_WFULL_INT_RAW + 2 + 1 + read-only + + + RX_REMPTY_INT_RAW + 3 + 1 + read-only + + + TX_WFULL_INT_RAW + 4 + 1 + read-only + + + TX_REMPTY_INT_RAW + 5 + 1 + read-only + + + RX_HUNG_INT_RAW + 6 + 1 + read-only + + + TX_HUNG_INT_RAW + 7 + 1 + read-only + + + IN_DONE_INT_RAW + 8 + 1 + read-only + + + IN_SUC_EOF_INT_RAW + 9 + 1 + read-only + + + IN_ERR_EOF_INT_RAW + 10 + 1 + read-only + + + OUT_DONE_INT_RAW + 11 + 1 + read-only + + + OUT_EOF_INT_RAW + 12 + 1 + read-only + + + IN_DSCR_ERR_INT_RAW + 13 + 1 + read-only + + + OUT_DSCR_ERR_INT_RAW + 14 + 1 + read-only + + + IN_DSCR_EMPTY_INT_RAW + 15 + 1 + read-only + + + OUT_TOTAL_EOF_INT_RAW + 16 + 1 + read-only + + + + + INT_ST + 0x10 + 0x20 + + + RX_TAKE_DATA_INT_ST + 0 + 1 + read-only + + + TX_PUT_DATA_INT_ST + 1 + 1 + read-only + + + RX_WFULL_INT_ST + 2 + 1 + read-only + + + RX_REMPTY_INT_ST + 3 + 1 + read-only + + + TX_WFULL_INT_ST + 4 + 1 + read-only + + + TX_REMPTY_INT_ST + 5 + 1 + read-only + + + RX_HUNG_INT_ST + 6 + 1 + read-only + + + TX_HUNG_INT_ST + 7 + 1 + read-only + + + IN_DONE_INT_ST + 8 + 1 + read-only + + + IN_SUC_EOF_INT_ST + 9 + 1 + read-only + + + IN_ERR_EOF_INT_ST + 10 + 1 + read-only + + + OUT_DONE_INT_ST + 11 + 1 + read-only + + + OUT_EOF_INT_ST + 12 + 1 + read-only + + + IN_DSCR_ERR_INT_ST + 13 + 1 + read-only + + + OUT_DSCR_ERR_INT_ST + 14 + 1 + read-only + + + IN_DSCR_EMPTY_INT_ST + 15 + 1 + read-only + + + OUT_TOTAL_EOF_INT_ST + 16 + 1 + read-only + + + + + INT_ENA + 0x14 + 0x20 + + + RX_TAKE_DATA_INT_ENA + 0 + 1 + read-write + + + TX_PUT_DATA_INT_ENA + 1 + 1 + read-write + + + RX_WFULL_INT_ENA + 2 + 1 + read-write + + + RX_REMPTY_INT_ENA + 3 + 1 + read-write + + + TX_WFULL_INT_ENA + 4 + 1 + read-write + + + TX_REMPTY_INT_ENA + 5 + 1 + read-write + + + RX_HUNG_INT_ENA + 6 + 1 + read-write + + + TX_HUNG_INT_ENA + 7 + 1 + read-write + + + IN_DONE_INT_ENA + 8 + 1 + read-write + + + IN_SUC_EOF_INT_ENA + 9 + 1 + read-write + + + IN_ERR_EOF_INT_ENA + 10 + 1 + read-write + + + OUT_DONE_INT_ENA + 11 + 1 + read-write + + + OUT_EOF_INT_ENA + 12 + 1 + read-write + + + IN_DSCR_ERR_INT_ENA + 13 + 1 + read-write + + + OUT_DSCR_ERR_INT_ENA + 14 + 1 + read-write + + + IN_DSCR_EMPTY_INT_ENA + 15 + 1 + read-write + + + OUT_TOTAL_EOF_INT_ENA + 16 + 1 + read-write + + + + + INT_CLR + 0x18 + 0x20 + + + TAKE_DATA_INT_CLR + 0 + 1 + write-only + + + PUT_DATA_INT_CLR + 1 + 1 + write-only + + + RX_WFULL_INT_CLR + 2 + 1 + write-only + + + RX_REMPTY_INT_CLR + 3 + 1 + write-only + + + TX_WFULL_INT_CLR + 4 + 1 + write-only + + + TX_REMPTY_INT_CLR + 5 + 1 + write-only + + + RX_HUNG_INT_CLR + 6 + 1 + write-only + + + TX_HUNG_INT_CLR + 7 + 1 + write-only + + + IN_DONE_INT_CLR + 8 + 1 + write-only + + + IN_SUC_EOF_INT_CLR + 9 + 1 + write-only + + + IN_ERR_EOF_INT_CLR + 10 + 1 + write-only + + + OUT_DONE_INT_CLR + 11 + 1 + write-only + + + OUT_EOF_INT_CLR + 12 + 1 + write-only + + + IN_DSCR_ERR_INT_CLR + 13 + 1 + write-only + + + OUT_DSCR_ERR_INT_CLR + 14 + 1 + write-only + + + IN_DSCR_EMPTY_INT_CLR + 15 + 1 + write-only + + + OUT_TOTAL_EOF_INT_CLR + 16 + 1 + write-only + + + + + TIMING + 0x1C + 0x20 + + + TX_BCK_IN_DELAY + 0 + 2 + read-write + + + TX_WS_IN_DELAY + 2 + 2 + read-write + + + RX_BCK_IN_DELAY + 4 + 2 + read-write + + + RX_WS_IN_DELAY + 6 + 2 + read-write + + + RX_SD_IN_DELAY + 8 + 2 + read-write + + + TX_BCK_OUT_DELAY + 10 + 2 + read-write + + + TX_WS_OUT_DELAY + 12 + 2 + read-write + + + TX_SD_OUT_DELAY + 14 + 2 + read-write + + + RX_WS_OUT_DELAY + 16 + 2 + read-write + + + RX_BCK_OUT_DELAY + 18 + 2 + read-write + + + TX_DSYNC_SW + 20 + 1 + read-write + + + RX_DSYNC_SW + 21 + 1 + read-write + + + DATA_ENABLE_DELAY + 22 + 2 + read-write + + + TX_BCK_IN_INV + 24 + 1 + read-write + + + + + FIFO_CONF + 0x20 + 0x20 + 0x00001820 + + + RX_DATA_NUM + 0 + 6 + read-write + + + TX_DATA_NUM + 6 + 6 + read-write + + + DSCR_EN + 12 + 1 + read-write + + + TX_FIFO_MOD + 13 + 3 + read-write + + + RX_FIFO_MOD + 16 + 3 + read-write + + + TX_FIFO_MOD_FORCE_EN + 19 + 1 + read-write + + + RX_FIFO_MOD_FORCE_EN + 20 + 1 + read-write + + + + + RXEOF_NUM + 0x24 + 0x20 + 0x00000040 + + + RX_EOF_NUM + 0 + 32 + read-write + + + + + CONF_SIGLE_DATA + 0x28 + 0x20 + + + SIGLE_DATA + 0 + 32 + read-write + + + + + CONF_CHAN + 0x2C + 0x20 + + + TX_CHAN_MOD + 0 + 3 + read-write + + + RX_CHAN_MOD + 3 + 2 + read-write + + + + + OUT_LINK + 0x30 + 0x20 + + + OUTLINK_ADDR + 0 + 20 + read-write + + + OUTLINK_STOP + 28 + 1 + read-write + + + OUTLINK_START + 29 + 1 + read-write + + + OUTLINK_RESTART + 30 + 1 + read-write + + + OUTLINK_PARK + 31 + 1 + read-only + + + + + IN_LINK + 0x34 + 0x20 + + + INLINK_ADDR + 0 + 20 + read-write + + + INLINK_STOP + 28 + 1 + read-write + + + INLINK_START + 29 + 1 + read-write + + + INLINK_RESTART + 30 + 1 + read-write + + + INLINK_PARK + 31 + 1 + read-only + + + + + OUT_EOF_DES_ADDR + 0x38 + 0x20 + + + OUT_EOF_DES_ADDR + 0 + 32 + read-only + + + + + IN_EOF_DES_ADDR + 0x3C + 0x20 + + + IN_SUC_EOF_DES_ADDR + 0 + 32 + read-only + + + + + OUT_EOF_BFR_DES_ADDR + 0x40 + 0x20 + + + OUT_EOF_BFR_DES_ADDR + 0 + 32 + read-only + + + + + AHB_TEST + 0x44 + 0x20 + + + AHB_TESTMODE + 0 + 3 + read-write + + + AHB_TESTADDR + 4 + 2 + read-write + + + + + INLINK_DSCR + 0x48 + 0x20 + + + INLINK_DSCR + 0 + 32 + read-only + + + + + INLINK_DSCR_BF0 + 0x4C + 0x20 + + + INLINK_DSCR_BF0 + 0 + 32 + read-only + + + + + INLINK_DSCR_BF1 + 0x50 + 0x20 + + + INLINK_DSCR_BF1 + 0 + 32 + read-only + + + + + OUTLINK_DSCR + 0x54 + 0x20 + + + OUTLINK_DSCR + 0 + 32 + read-only + + + + + OUTLINK_DSCR_BF0 + 0x58 + 0x20 + + + OUTLINK_DSCR_BF0 + 0 + 32 + read-only + + + + + OUTLINK_DSCR_BF1 + 0x5C + 0x20 + + + OUTLINK_DSCR_BF1 + 0 + 32 + read-only + + + + + LC_CONF + 0x60 + 0x20 + 0x00000100 + + + IN_RST + 0 + 1 + read-write + + + OUT_RST + 1 + 1 + read-write + + + AHBM_FIFO_RST + 2 + 1 + read-write + + + AHBM_RST + 3 + 1 + read-write + + + OUT_LOOP_TEST + 4 + 1 + read-write + + + IN_LOOP_TEST + 5 + 1 + read-write + + + OUT_AUTO_WRBACK + 6 + 1 + read-write + + + OUT_NO_RESTART_CLR + 7 + 1 + read-write + + + OUT_EOF_MODE + 8 + 1 + read-write + + + OUTDSCR_BURST_EN + 9 + 1 + read-write + + + INDSCR_BURST_EN + 10 + 1 + read-write + + + OUT_DATA_BURST_EN + 11 + 1 + read-write + + + CHECK_OWNER + 12 + 1 + read-write + + + MEM_TRANS_EN + 13 + 1 + read-write + + + + + OUTFIFO_PUSH + 0x64 + 0x20 + + + OUTFIFO_WDATA + 0 + 9 + read-write + + + OUTFIFO_PUSH + 16 + 1 + read-write + + + + + INFIFO_POP + 0x68 + 0x20 + + + INFIFO_RDATA + 0 + 12 + read-only + + + INFIFO_POP + 16 + 1 + read-write + + + + + LC_STATE0 + 0x6C + 0x20 + + + LC_STATE0 + 0 + 32 + read-only + + + + + LC_STATE1 + 0x70 + 0x20 + + + LC_STATE1 + 0 + 32 + read-only + + + + + LC_HUNG_CONF + 0x74 + 0x20 + 0x00000810 + + + LC_FIFO_TIMEOUT + 0 + 8 + read-write + + + LC_FIFO_TIMEOUT_SHIFT + 8 + 3 + read-write + + + LC_FIFO_TIMEOUT_ENA + 11 + 1 + read-write + + + + + CVSD_CONF0 + 0x80 + 0x20 + 0x80007FFF + + + CVSD_Y_MAX + 0 + 16 + read-write + + + CVSD_Y_MIN + 16 + 16 + read-write + + + + + CVSD_CONF1 + 0x84 + 0x20 + 0x000A0500 + + + CVSD_SIGMA_MAX + 0 + 16 + read-write + + + CVSD_SIGMA_MIN + 16 + 16 + read-write + + + + + CVSD_CONF2 + 0x88 + 0x20 + 0x000502A4 + + + CVSD_K + 0 + 3 + read-write + + + CVSD_J + 3 + 3 + read-write + + + CVSD_BETA + 6 + 10 + read-write + + + CVSD_H + 16 + 3 + read-write + + + + + PLC_CONF0 + 0x8C + 0x20 + 0x08A80339 + + + GOOD_PACK_MAX + 0 + 6 + read-write + + + N_ERR_SEG + 6 + 3 + read-write + + + SHIFT_RATE + 9 + 3 + read-write + + + MAX_SLIDE_SAMPLE + 12 + 8 + read-write + + + PACK_LEN_8K + 20 + 5 + read-write + + + N_MIN_ERR + 25 + 3 + read-write + + + + + PLC_CONF1 + 0x90 + 0x20 + 0xA0178A05 + + + BAD_CEF_ATTEN_PARA + 0 + 8 + read-write + + + BAD_CEF_ATTEN_PARA_SHIFT + 8 + 4 + read-write + + + BAD_OLA_WIN2_PARA_SHIFT + 12 + 4 + read-write + + + BAD_OLA_WIN2_PARA + 16 + 8 + read-write + + + SLIDE_WIN_LEN + 24 + 8 + read-write + + + + + PLC_CONF2 + 0x94 + 0x20 + 0x00000028 + + + CVSD_SEG_MOD + 0 + 2 + read-write + + + MIN_PERIOD + 2 + 5 + read-write + + + + + ESCO_CONF0 + 0x98 + 0x20 + + + ESCO_EN + 0 + 1 + read-write + + + ESCO_CHAN_MOD + 1 + 1 + read-write + + + ESCO_CVSD_DEC_PACK_ERR + 2 + 1 + read-write + + + ESCO_CVSD_PACK_LEN_8K + 3 + 5 + read-write + + + ESCO_CVSD_INF_EN + 8 + 1 + read-write + + + CVSD_DEC_START + 9 + 1 + read-write + + + CVSD_DEC_RESET + 10 + 1 + read-write + + + PLC_EN + 11 + 1 + read-write + + + PLC2DMA_EN + 12 + 1 + read-write + + + + + SCO_CONF0 + 0x9C + 0x20 + + + SCO_WITH_I2S_EN + 0 + 1 + read-write + + + SCO_NO_I2S_EN + 1 + 1 + read-write + + + CVSD_ENC_START + 2 + 1 + read-write + + + CVSD_ENC_RESET + 3 + 1 + read-write + + + + + CONF1 + 0xA0 + 0x20 + 0x00000089 + + + TX_PCM_CONF + 0 + 3 + read-write + + + TX_PCM_BYPASS + 3 + 1 + read-write + + + RX_PCM_CONF + 4 + 3 + read-write + + + RX_PCM_BYPASS + 7 + 1 + read-write + + + TX_STOP_EN + 8 + 1 + read-write + + + TX_ZEROS_RM_EN + 9 + 1 + read-write + + + + + PD_CONF + 0xA4 + 0x20 + 0x0000000A + + + FIFO_FORCE_PD + 0 + 1 + read-write + + + FIFO_FORCE_PU + 1 + 1 + read-write + + + PLC_MEM_FORCE_PD + 2 + 1 + read-write + + + PLC_MEM_FORCE_PU + 3 + 1 + read-write + + + + + CONF2 + 0xA8 + 0x20 + + + CAMERA_EN + 0 + 1 + read-write + + + LCD_TX_WRX2_EN + 1 + 1 + read-write + + + LCD_TX_SDX2_EN + 2 + 1 + read-write + + + DATA_ENABLE_TEST_EN + 3 + 1 + read-write + + + DATA_ENABLE + 4 + 1 + read-write + + + LCD_EN + 5 + 1 + read-write + + + EXT_ADC_START_EN + 6 + 1 + read-write + + + INTER_VALID_EN + 7 + 1 + read-write + + + + + CLKM_CONF + 0xAC + 0x20 + 0x00000004 + + + CLKM_DIV_NUM + 0 + 8 + read-write + + + CLKM_DIV_B + 8 + 6 + read-write + + + CLKM_DIV_A + 14 + 6 + read-write + + + CLK_EN + 20 + 1 + read-write + + + CLKA_ENA + 21 + 1 + read-write + + + + + SAMPLE_RATE_CONF + 0xB0 + 0x20 + 0x00410186 + + + TX_BCK_DIV_NUM + 0 + 6 + read-write + + + RX_BCK_DIV_NUM + 6 + 6 + read-write + + + TX_BITS_MOD + 12 + 6 + read-write + + + RX_BITS_MOD + 18 + 6 + read-write + + + + + PDM_CONF + 0xB4 + 0x20 + 0x01550020 + + + TX_PDM_EN + 0 + 1 + read-write + + + RX_PDM_EN + 1 + 1 + read-write + + + PCM2PDM_CONV_EN + 2 + 1 + read-write + + + PDM2PCM_CONV_EN + 3 + 1 + read-write + + + TX_PDM_SINC_OSR2 + 4 + 4 + read-write + + + TX_PDM_PRESCALE + 8 + 8 + read-write + + + TX_PDM_HP_IN_SHIFT + 16 + 2 + read-write + + + TX_PDM_LP_IN_SHIFT + 18 + 2 + read-write + + + TX_PDM_SINC_IN_SHIFT + 20 + 2 + read-write + + + TX_PDM_SIGMADELTA_IN_SHIFT + 22 + 2 + read-write + + + RX_PDM_SINC_DSR_16_EN + 24 + 1 + read-write + + + TX_PDM_HP_BYPASS + 25 + 1 + read-write + + + + + PDM_FREQ_CONF + 0xB8 + 0x20 + 0x000F01E0 + + + TX_PDM_FS + 0 + 10 + read-write + + + TX_PDM_FP + 10 + 10 + read-write + + + + + STATE + 0xBC + 0x20 + 0x00000007 + + + TX_IDLE + 0 + 1 + read-only + + + TX_FIFO_RESET_BACK + 1 + 1 + read-only + + + RX_FIFO_RESET_BACK + 2 + 1 + read-only + + + + + DATE + 0xFC + 0x20 + 0x01604201 + + + I2SDATE + 0 + 32 + read-write + + + + + + + I2S1 + I2S (Inter-IC Sound) Controller + 0x3FF6D000 + + I2S1 + 33 + + + + IO_MUX + Input/Output Multiplexer + IO_MUX + 0x3FF49000 + + 0x0 + 0x94 + registers + + + + PIN_CTRL + 0x0 + 0x20 + + + CLK1 + If you want to output clock for I2S0 to: CLK_OUT1, then set PIN_CTRL[3:0] = 0x0; CLK_OUT2, then set PIN_CTRL[3:0] = 0x0 and PIN_CTRL[7:4] = 0x0; CLK_OUT3, then set PIN_CTRL[3:0] = 0x0 and PIN_CTRL[11:8] = 0x0. If you want to output clock for I2S1 to: CLK_OUT1, then set PIN_CTRL[3:0] = 0xF; CLK_OUT2, then set PIN_CTRL[3:0] = 0xF and PIN_CTRL[7:4] = 0x0; CLK_OUT3, then set PIN_CTRL[3:0] = 0xF and PIN_CTRL[11:8] = 0x0. + 0 + 4 + read-write + + + CLK2 + If you want to output clock for I2S0 to: CLK_OUT1, then set PIN_CTRL[3:0] = 0x0; CLK_OUT2, then set PIN_CTRL[3:0] = 0x0 and PIN_CTRL[7:4] = 0x0; CLK_OUT3, then set PIN_CTRL[3:0] = 0x0 and PIN_CTRL[11:8] = 0x0. If you want to output clock for I2S1 to: CLK_OUT1, then set PIN_CTRL[3:0] = 0xF; CLK_OUT2, then set PIN_CTRL[3:0] = 0xF and PIN_CTRL[7:4] = 0x0; CLK_OUT3, then set PIN_CTRL[3:0] = 0xF and PIN_CTRL[11:8] = 0x0. + 4 + 4 + read-write + + + CLK3 + If you want to output clock for I2S0 to: CLK_OUT1, then set PIN_CTRL[3:0] = 0x0; CLK_OUT2, then set PIN_CTRL[3:0] = 0x0 and PIN_CTRL[7:4] = 0x0; CLK_OUT3, then set PIN_CTRL[3:0] = 0x0 and PIN_CTRL[11:8] = 0x0. If you want to output clock for I2S1 to: CLK_OUT1, then set PIN_CTRL[3:0] = 0xF; CLK_OUT2, then set PIN_CTRL[3:0] = 0xF and PIN_CTRL[7:4] = 0x0; CLK_OUT3, then set PIN_CTRL[3:0] = 0xF and PIN_CTRL[11:8] = 0x0. + 8 + 4 + read-write + + + + + GPIO36 + 0x4 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO37 + 0x8 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO38 + 0xC + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO39 + 0x10 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO34 + 0x14 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO35 + 0x18 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO32 + 0x1C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO33 + 0x20 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO25 + 0x24 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO26 + 0x28 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO27 + 0x2C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO14 + 0x30 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO12 + 0x34 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO13 + 0x38 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO15 + 0x3C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO2 + 0x40 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO0 + 0x44 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO4 + 0x48 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO16 + 0x4C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO17 + 0x50 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO9 + 0x54 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO10 + 0x58 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO11 + 0x5C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO6 + 0x60 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO7 + 0x64 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO8 + 0x68 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO5 + 0x6C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO18 + 0x70 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO19 + 0x74 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO20 + 0x78 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO21 + 0x7C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO22 + 0x80 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO3 + 0x84 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO1 + 0x88 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO23 + 0x8C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO24 + 0x90 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + + + LEDC + LED Control PWM (Pulse Width Modulation) + LEDC + 0x3FF59000 + + 0x0 + 0x198 + registers + + + LEDC + 43 + + + TIMER1 + 56 + + + TIMER2 + 57 + + + + 8 + 0x14 + 0-7 + HSCH%s_CONF0 + 0x0 + 0x20 + + + TIMER_SEL + There are four high speed timers the two bits are used to select one of them for high speed channel0. 2'b00: seletc hstimer0. 2'b01: select hstimer1. 2'b10: select hstimer2. 2'b11: select hstimer3. + 0 + 2 + read-write + + + SIG_OUT_EN + This is the output enable control bit for high speed channel0 + 2 + 1 + read-write + + + IDLE_LV + This bit is used to control the output value when high speed channel0 is off. + 3 + 1 + read-write + + + + + 8 + 0x14 + 0-7 + HSCH%s_HPOINT + 0x4 + 0x20 + + + HPOINT + The output value changes to high when htimerx(x=[0 3]) selected by high speed channel0 has reached reg_hpoint_hsch0[19:0] + 0 + 20 + read-write + + + + + 8 + 0x14 + 0-7 + HSCH%s_DUTY + 0x8 + 0x20 + + + DUTY + This register represents the current duty of the output signal for high speed channel0. + 0 + 25 + read-write + + + + + 8 + 0x14 + 0-7 + HSCH%s_CONF1 + 0xC + 0x20 + 0x40000000 + + + DUTY_SCALE + This register controls the increase or decrease step scale for high speed channel0. + 0 + 10 + read-write + + + DUTY_CYCLE + This register is used to increase or decrease the duty every reg_duty_cycle_hsch0 cycles for high speed channel0. + 10 + 10 + read-write + + + DUTY_NUM + This register is used to control the num of increased or decreased times for high speed channel0. + 20 + 10 + read-write + + + DUTY_INC + This register is used to increase the duty of output signal or decrease the duty of output signal for high speed channel0. + 30 + 1 + read-write + + + DUTY_START + When reg_duty_num_hsch0 reg_duty_cycle_hsch0 and reg_duty_scale_hsch0 has been configured. these register won't take effect until set reg_duty_start_hsch0. this bit is automatically cleared by hardware. + 31 + 1 + read-write + + + + + 8 + 0x14 + 0-7 + HSCH%s_DUTY_R + 0x10 + 0x20 + + + DUTY_R + This register represents the current duty cycle of the output signal for high-speed channel %s + 0 + 25 + read-only + + + + + 8 + 0x14 + 0-7 + LSCH%s_CONF0 + 0xA0 + 0x20 + + + TIMER_SEL + There are four low speed timers the two bits are used to select one of them for low speed channel0. 2'b00: seletc lstimer0. 2'b01: select lstimer1. 2'b10: select lstimer2. 2'b11: select lstimer3. + 0 + 2 + read-write + + + SIG_OUT_EN + This is the output enable control bit for low speed channel0. + 2 + 1 + read-write + + + IDLE_LV + This bit is used to control the output value when low speed channel0 is off. + 3 + 1 + read-write + + + PARA_UP + This bit is used to update register LEDC_LSCH0_HPOINT and LEDC_LSCH0_DUTY for low speed channel0. + 4 + 1 + read-write + + + + + 8 + 0x14 + 0-7 + LSCH%s_HPOINT + 0xA4 + 0x20 + + + HPOINT + The output value changes to high when lstimerx(x=[0 3]) selected by low speed channel0 has reached reg_hpoint_lsch0[19:0] + 0 + 20 + read-write + + + + + 8 + 0x14 + 0-7 + LSCH%s_DUTY + 0xA8 + 0x20 + read-write + + + DUTY + This register represents the current duty of the output signal for low speed channel0. + 0 + 25 + read-write + + + + + 8 + 0x14 + 0-7 + LSCH%s_CONF1 + 0xAC + 0x20 + 0x40000000 + + + DUTY_SCALE + This register controls the increase or decrease step scale for low speed channel0. + 0 + 10 + read-write + + + DUTY_CYCLE + This register is used to increase or decrease the duty every reg_duty_cycle_lsch0 cycles for low speed channel0. + 10 + 10 + read-write + + + DUTY_NUM + This register is used to control the num of increased or decreased times for low speed channel6. + 20 + 10 + read-write + + + DUTY_INC + This register is used to increase the duty of output signal or decrease the duty of output signal for low speed channel6. + 30 + 1 + read-write + + + DUTY_START + When reg_duty_num_hsch1 reg_duty_cycle_hsch1 and reg_duty_scale_hsch1 has been configured. these register won't take effect until set reg_duty_start_hsch1. this bit is automatically cleared by hardware. + 31 + 1 + read-write + + + + + 8 + 0x14 + 0-7 + LSCH%s_DUTY_R + 0xB0 + 0x20 + + + DUTY_R + This register represents the current duty cycle of the output signal for low-speed channel %s + 0 + 25 + read-only + + + + + 4 + 0x8 + 0-3 + HSTIMER%s_CONF + 0x140 + 0x20 + 0x01000000 + + + DUTY_RES + This register controls the range of the counter in high speed timer0. the counter range is [0 2**reg_hstimer0_lim] the max bit width for counter is 20. + 0 + 5 + read-write + + + DIV_NUM + This register is used to configure parameter for divider in high speed timer0 the least significant eight bits represent the decimal part. + 5 + 18 + read-write + + + PAUSE + This bit is used to pause the counter in high speed timer0 + 23 + 1 + read-write + + + RST + This bit is used to reset high speed timer0 the counter will be 0 after reset. + 24 + 1 + read-write + + + TICK_SEL + This bit is used to choose apb_clk or ref_tick for high speed timer0. 1'b1:apb_clk 0:ref_tick + 25 + 1 + read-write + + + LIM + 31 + 5 + read-write + + + + + 4 + 0x8 + 0-3 + HSTIMER%s_VALUE + 0x144 + 0x20 + + + CNT + software can read this register to get the current counter value in high speed timer0 + 0 + 20 + read-only + + + + + 4 + 0x8 + 0-3 + LSTIMER%s_CONF + 0x160 + 0x20 + 0x01000000 + + + DUTY_RES + This register controls the range of the counter in low speed timer0. the counter range is [0 2**reg_lstimer0_lim] the max bit width for counter is 20. + 0 + 5 + read-write + + + DIV_NUM + This register is used to configure parameter for divider in low speed timer0 the least significant eight bits represent the decimal part. + 5 + 18 + read-write + + + PAUSE + This bit is used to pause the counter in low speed timer0. + 23 + 1 + read-write + + + RST + This bit is used to reset low speed timer0 the counter will be 0 after reset. + 24 + 1 + read-write + + + TICK_SEL + This bit is used to choose slow_clk or ref_tick for low speed timer0. 1'b1:slow_clk 0:ref_tick + 25 + 1 + read-write + + + PARA_UP + Set this bit to update reg_div_num_lstime0 and reg_lstimer0_lim. + 26 + 1 + read-write + + + LIM + 31 + 5 + read-write + + + + + 4 + 0x8 + 0-3 + LSTIMER%s_VALUE + 0x164 + 0x20 + + + CNT + software can read this register to get the current counter value in low speed timer0. + 0 + 20 + read-only + + + + + INT_RAW + 0x180 + 0x20 + + + HSTIMER0_OVF_INT_RAW + The interrupt raw bit for high speed channel0 counter overflow. + 0 + 1 + read-only + + + HSTIMER1_OVF_INT_RAW + The interrupt raw bit for high speed channel1 counter overflow. + 1 + 1 + read-only + + + HSTIMER2_OVF_INT_RAW + The interrupt raw bit for high speed channel2 counter overflow. + 2 + 1 + read-only + + + HSTIMER3_OVF_INT_RAW + The interrupt raw bit for high speed channel3 counter overflow. + 3 + 1 + read-only + + + LSTIMER0_OVF_INT_RAW + The interrupt raw bit for low speed channel0 counter overflow. + 4 + 1 + read-only + + + LSTIMER1_OVF_INT_RAW + The interrupt raw bit for low speed channel1 counter overflow. + 5 + 1 + read-only + + + LSTIMER2_OVF_INT_RAW + The interrupt raw bit for low speed channel2 counter overflow. + 6 + 1 + read-only + + + LSTIMER3_OVF_INT_RAW + The interrupt raw bit for low speed channel3 counter overflow. + 7 + 1 + read-only + + + DUTY_CHNG_END_HSCH0_INT_RAW + The interrupt raw bit for high speed channel 0 duty change done. + 8 + 1 + read-only + + + DUTY_CHNG_END_HSCH1_INT_RAW + The interrupt raw bit for high speed channel 1 duty change done. + 9 + 1 + read-only + + + DUTY_CHNG_END_HSCH2_INT_RAW + The interrupt raw bit for high speed channel 2 duty change done. + 10 + 1 + read-only + + + DUTY_CHNG_END_HSCH3_INT_RAW + The interrupt raw bit for high speed channel 3 duty change done. + 11 + 1 + read-only + + + DUTY_CHNG_END_HSCH4_INT_RAW + The interrupt raw bit for high speed channel 4 duty change done. + 12 + 1 + read-only + + + DUTY_CHNG_END_HSCH5_INT_RAW + The interrupt raw bit for high speed channel 5 duty change done. + 13 + 1 + read-only + + + DUTY_CHNG_END_HSCH6_INT_RAW + The interrupt raw bit for high speed channel 6 duty change done. + 14 + 1 + read-only + + + DUTY_CHNG_END_HSCH7_INT_RAW + The interrupt raw bit for high speed channel 7 duty change done. + 15 + 1 + read-only + + + DUTY_CHNG_END_LSCH0_INT_RAW + The interrupt raw bit for low speed channel 0 duty change done. + 16 + 1 + read-only + + + DUTY_CHNG_END_LSCH1_INT_RAW + The interrupt raw bit for low speed channel 1 duty change done. + 17 + 1 + read-only + + + DUTY_CHNG_END_LSCH2_INT_RAW + The interrupt raw bit for low speed channel 2 duty change done. + 18 + 1 + read-only + + + DUTY_CHNG_END_LSCH3_INT_RAW + The interrupt raw bit for low speed channel 3 duty change done. + 19 + 1 + read-only + + + DUTY_CHNG_END_LSCH4_INT_RAW + The interrupt raw bit for low speed channel 4 duty change done. + 20 + 1 + read-only + + + DUTY_CHNG_END_LSCH5_INT_RAW + The interrupt raw bit for low speed channel 5 duty change done. + 21 + 1 + read-only + + + DUTY_CHNG_END_LSCH6_INT_RAW + The interrupt raw bit for low speed channel 6 duty change done. + 22 + 1 + read-only + + + DUTY_CHNG_END_LSCH7_INT_RAW + The interrupt raw bit for low speed channel 7 duty change done. + 23 + 1 + read-only + + + + + INT_ST + 0x184 + 0x20 + + + HSTIMER0_OVF_INT_ST + The interrupt status bit for high speed channel0 counter overflow event. + 0 + 1 + read-only + + + HSTIMER1_OVF_INT_ST + The interrupt status bit for high speed channel1 counter overflow event. + 1 + 1 + read-only + + + HSTIMER2_OVF_INT_ST + The interrupt status bit for high speed channel2 counter overflow event. + 2 + 1 + read-only + + + HSTIMER3_OVF_INT_ST + The interrupt status bit for high speed channel3 counter overflow event. + 3 + 1 + read-only + + + LSTIMER0_OVF_INT_ST + The interrupt status bit for low speed channel0 counter overflow event. + 4 + 1 + read-only + + + LSTIMER1_OVF_INT_ST + The interrupt status bit for low speed channel1 counter overflow event. + 5 + 1 + read-only + + + LSTIMER2_OVF_INT_ST + The interrupt status bit for low speed channel2 counter overflow event. + 6 + 1 + read-only + + + LSTIMER3_OVF_INT_ST + The interrupt status bit for low speed channel3 counter overflow event. + 7 + 1 + read-only + + + DUTY_CHNG_END_HSCH0_INT_ST + The interrupt status bit for high speed channel 0 duty change done event. + 8 + 1 + read-only + + + DUTY_CHNG_END_HSCH1_INT_ST + The interrupt status bit for high speed channel 1 duty change done event. + 9 + 1 + read-only + + + DUTY_CHNG_END_HSCH2_INT_ST + The interrupt status bit for high speed channel 2 duty change done event. + 10 + 1 + read-only + + + DUTY_CHNG_END_HSCH3_INT_ST + The interrupt status bit for high speed channel 3 duty change done event. + 11 + 1 + read-only + + + DUTY_CHNG_END_HSCH4_INT_ST + The interrupt status bit for high speed channel 4 duty change done event. + 12 + 1 + read-only + + + DUTY_CHNG_END_HSCH5_INT_ST + The interrupt status bit for high speed channel 5 duty change done event. + 13 + 1 + read-only + + + DUTY_CHNG_END_HSCH6_INT_ST + The interrupt status bit for high speed channel 6 duty change done event. + 14 + 1 + read-only + + + DUTY_CHNG_END_HSCH7_INT_ST + The interrupt status bit for high speed channel 7 duty change done event. + 15 + 1 + read-only + + + DUTY_CHNG_END_LSCH0_INT_ST + The interrupt status bit for low speed channel 0 duty change done event. + 16 + 1 + read-only + + + DUTY_CHNG_END_LSCH1_INT_ST + The interrupt status bit for low speed channel 1 duty change done event. + 17 + 1 + read-only + + + DUTY_CHNG_END_LSCH2_INT_ST + The interrupt status bit for low speed channel 2 duty change done event. + 18 + 1 + read-only + + + DUTY_CHNG_END_LSCH3_INT_ST + The interrupt status bit for low speed channel 3 duty change done event. + 19 + 1 + read-only + + + DUTY_CHNG_END_LSCH4_INT_ST + The interrupt status bit for low speed channel 4 duty change done event. + 20 + 1 + read-only + + + DUTY_CHNG_END_LSCH5_INT_ST + The interrupt status bit for low speed channel 5 duty change done event. + 21 + 1 + read-only + + + DUTY_CHNG_END_LSCH6_INT_ST + The interrupt status bit for low speed channel 6 duty change done event. + 22 + 1 + read-only + + + DUTY_CHNG_END_LSCH7_INT_ST + The interrupt status bit for low speed channel 7 duty change done event + 23 + 1 + read-only + + + + + INT_ENA + 0x188 + 0x20 + + + HSTIMER0_OVF_INT_ENA + The interrupt enable bit for high speed channel0 counter overflow interrupt. + 0 + 1 + read-write + + + HSTIMER1_OVF_INT_ENA + The interrupt enable bit for high speed channel1 counter overflow interrupt. + 1 + 1 + read-write + + + HSTIMER2_OVF_INT_ENA + The interrupt enable bit for high speed channel2 counter overflow interrupt. + 2 + 1 + read-write + + + HSTIMER3_OVF_INT_ENA + The interrupt enable bit for high speed channel3 counter overflow interrupt. + 3 + 1 + read-write + + + LSTIMER0_OVF_INT_ENA + The interrupt enable bit for low speed channel0 counter overflow interrupt. + 4 + 1 + read-write + + + LSTIMER1_OVF_INT_ENA + The interrupt enable bit for low speed channel1 counter overflow interrupt. + 5 + 1 + read-write + + + LSTIMER2_OVF_INT_ENA + The interrupt enable bit for low speed channel2 counter overflow interrupt. + 6 + 1 + read-write + + + LSTIMER3_OVF_INT_ENA + The interrupt enable bit for low speed channel3 counter overflow interrupt. + 7 + 1 + read-write + + + DUTY_CHNG_END_HSCH0_INT_ENA + The interrupt enable bit for high speed channel 0 duty change done interrupt. + 8 + 1 + read-write + + + DUTY_CHNG_END_HSCH1_INT_ENA + The interrupt enable bit for high speed channel 1 duty change done interrupt. + 9 + 1 + read-write + + + DUTY_CHNG_END_HSCH2_INT_ENA + The interrupt enable bit for high speed channel 2 duty change done interrupt. + 10 + 1 + read-write + + + DUTY_CHNG_END_HSCH3_INT_ENA + The interrupt enable bit for high speed channel 3 duty change done interrupt. + 11 + 1 + read-write + + + DUTY_CHNG_END_HSCH4_INT_ENA + The interrupt enable bit for high speed channel 4 duty change done interrupt. + 12 + 1 + read-write + + + DUTY_CHNG_END_HSCH5_INT_ENA + The interrupt enable bit for high speed channel 5 duty change done interrupt. + 13 + 1 + read-write + + + DUTY_CHNG_END_HSCH6_INT_ENA + The interrupt enable bit for high speed channel 6 duty change done interrupt. + 14 + 1 + read-write + + + DUTY_CHNG_END_HSCH7_INT_ENA + The interrupt enable bit for high speed channel 7 duty change done interrupt. + 15 + 1 + read-write + + + DUTY_CHNG_END_LSCH0_INT_ENA + The interrupt enable bit for low speed channel 0 duty change done interrupt. + 16 + 1 + read-write + + + DUTY_CHNG_END_LSCH1_INT_ENA + The interrupt enable bit for low speed channel 1 duty change done interrupt. + 17 + 1 + read-write + + + DUTY_CHNG_END_LSCH2_INT_ENA + The interrupt enable bit for low speed channel 2 duty change done interrupt. + 18 + 1 + read-write + + + DUTY_CHNG_END_LSCH3_INT_ENA + The interrupt enable bit for low speed channel 3 duty change done interrupt. + 19 + 1 + read-write + + + DUTY_CHNG_END_LSCH4_INT_ENA + The interrupt enable bit for low speed channel 4 duty change done interrupt. + 20 + 1 + read-write + + + DUTY_CHNG_END_LSCH5_INT_ENA + The interrupt enable bit for low speed channel 5 duty change done interrupt. + 21 + 1 + read-write + + + DUTY_CHNG_END_LSCH6_INT_ENA + The interrupt enable bit for low speed channel 6 duty change done interrupt. + 22 + 1 + read-write + + + DUTY_CHNG_END_LSCH7_INT_ENA + The interrupt enable bit for low speed channel 7 duty change done interrupt. + 23 + 1 + read-write + + + + + INT_CLR + 0x18C + 0x20 + + + HSTIMER0_OVF_INT_CLR + Set this bit to clear high speed channel0 counter overflow interrupt. + 0 + 1 + write-only + + + HSTIMER1_OVF_INT_CLR + Set this bit to clear high speed channel1 counter overflow interrupt. + 1 + 1 + write-only + + + HSTIMER2_OVF_INT_CLR + Set this bit to clear high speed channel2 counter overflow interrupt. + 2 + 1 + write-only + + + HSTIMER3_OVF_INT_CLR + Set this bit to clear high speed channel3 counter overflow interrupt. + 3 + 1 + write-only + + + LSTIMER0_OVF_INT_CLR + Set this bit to clear low speed channel0 counter overflow interrupt. + 4 + 1 + write-only + + + LSTIMER1_OVF_INT_CLR + Set this bit to clear low speed channel1 counter overflow interrupt. + 5 + 1 + write-only + + + LSTIMER2_OVF_INT_CLR + Set this bit to clear low speed channel2 counter overflow interrupt. + 6 + 1 + write-only + + + LSTIMER3_OVF_INT_CLR + Set this bit to clear low speed channel3 counter overflow interrupt. + 7 + 1 + write-only + + + DUTY_CHNG_END_HSCH0_INT_CLR + Set this bit to clear high speed channel 0 duty change done interrupt. + 8 + 1 + write-only + + + DUTY_CHNG_END_HSCH1_INT_CLR + Set this bit to clear high speed channel 1 duty change done interrupt. + 9 + 1 + write-only + + + DUTY_CHNG_END_HSCH2_INT_CLR + Set this bit to clear high speed channel 2 duty change done interrupt. + 10 + 1 + write-only + + + DUTY_CHNG_END_HSCH3_INT_CLR + Set this bit to clear high speed channel 3 duty change done interrupt. + 11 + 1 + write-only + + + DUTY_CHNG_END_HSCH4_INT_CLR + Set this bit to clear high speed channel 4 duty change done interrupt. + 12 + 1 + write-only + + + DUTY_CHNG_END_HSCH5_INT_CLR + Set this bit to clear high speed channel 5 duty change done interrupt. + 13 + 1 + write-only + + + DUTY_CHNG_END_HSCH6_INT_CLR + Set this bit to clear high speed channel 6 duty change done interrupt. + 14 + 1 + write-only + + + DUTY_CHNG_END_HSCH7_INT_CLR + Set this bit to clear high speed channel 7 duty change done interrupt. + 15 + 1 + write-only + + + DUTY_CHNG_END_LSCH0_INT_CLR + Set this bit to clear low speed channel 0 duty change done interrupt. + 16 + 1 + write-only + + + DUTY_CHNG_END_LSCH1_INT_CLR + Set this bit to clear low speed channel 1 duty change done interrupt. + 17 + 1 + write-only + + + DUTY_CHNG_END_LSCH2_INT_CLR + Set this bit to clear low speed channel 2 duty change done interrupt. + 18 + 1 + write-only + + + DUTY_CHNG_END_LSCH3_INT_CLR + Set this bit to clear low speed channel 3 duty change done interrupt. + 19 + 1 + write-only + + + DUTY_CHNG_END_LSCH4_INT_CLR + Set this bit to clear low speed channel 4 duty change done interrupt. + 20 + 1 + write-only + + + DUTY_CHNG_END_LSCH5_INT_CLR + Set this bit to clear low speed channel 5 duty change done interrupt. + 21 + 1 + write-only + + + DUTY_CHNG_END_LSCH6_INT_CLR + Set this bit to clear low speed channel 6 duty change done interrupt. + 22 + 1 + write-only + + + DUTY_CHNG_END_LSCH7_INT_CLR + Set this bit to clear low speed channel 7 duty change done interrupt. + 23 + 1 + write-only + + + + + CONF + 0x190 + 0x20 + + + APB_CLK_SEL + This bit is used to set the frequency of slow_clk. 1'b1:80mhz 1'b0:8mhz + 0 + 1 + read-write + + + + + DATE + 0x1FC + 0x20 + 0x16031700 + + + DATE + This register represents the version . + 0 + 32 + read-write + + + + + + + PWM0 + Motor Control Pulse-Width Modulation + MCPWM + 0x3FF5E000 + + 0x0 + 0x128 + registers + + + PWM0 + 39 + + + + CLK_CFG + 0x0 + 0x20 + + + CLK_PRESCALE + 0 + 8 + read-write + + + + + TIMER0_CFG0 + 0x4 + 0x20 + 0x0000FF00 + + + TIMER0_PRESCALE + 0 + 8 + read-write + + + TIMER0_PERIOD + 8 + 16 + read-write + + + TIMER0_PERIOD_UPMETHOD + 24 + 2 + read-write + + + + + TIMER0_CFG1 + 0x8 + 0x20 + + + TIMER0_START + 0 + 3 + read-write + + + TIMER0_MOD + 3 + 2 + read-write + + + + + TIMER0_SYNC + 0xC + 0x20 + + + TIMER0_SYNCI_EN + 0 + 1 + read-write + + + SW + 1 + 1 + read-write + + + TIMER0_SYNCO_SEL + 2 + 2 + read-write + + + TIMER0_PHASE + 4 + 16 + read-write + + + TIMER0_PHASE_DIRECTION + 20 + 1 + read-write + + + + + TIMER0_STATUS + 0x10 + 0x20 + + + TIMER0_VALUE + 0 + 16 + read-only + + + TIMER0_DIRECTION + 16 + 1 + read-only + + + + + TIMER1_CFG0 + 0x14 + 0x20 + 0x0000FF00 + + + TIMER1_PRESCALE + 0 + 8 + read-write + + + TIMER1_PERIOD + 8 + 16 + read-write + + + TIMER1_PERIOD_UPMETHOD + 24 + 2 + read-write + + + + + TIMER1_CFG1 + 0x18 + 0x20 + + + TIMER1_START + 0 + 3 + read-write + + + TIMER1_MOD + 3 + 2 + read-write + + + + + TIMER1_SYNC + 0x1C + 0x20 + + + TIMER1_SYNCI_EN + 0 + 1 + read-write + + + SW + 1 + 1 + read-write + + + TIMER1_SYNCO_SEL + 2 + 2 + read-write + + + TIMER1_PHASE + 4 + 16 + read-write + + + TIMER1_PHASE_DIRECTION + 20 + 1 + read-write + + + + + TIMER1_STATUS + 0x20 + 0x20 + + + TIMER1_VALUE + 0 + 16 + read-only + + + TIMER1_DIRECTION + 16 + 1 + read-only + + + + + TIMER2_CFG0 + 0x24 + 0x20 + 0x0000FF00 + + + TIMER2_PRESCALE + 0 + 8 + read-write + + + TIMER2_PERIOD + 8 + 16 + read-write + + + TIMER2_PERIOD_UPMETHOD + 24 + 2 + read-write + + + + + TIMER2_CFG1 + 0x28 + 0x20 + + + TIMER2_START + 0 + 3 + read-write + + + TIMER2_MOD + 3 + 2 + read-write + + + + + TIMER2_SYNC + 0x2C + 0x20 + + + TIMER2_SYNCI_EN + 0 + 1 + read-write + + + SW + 1 + 1 + read-write + + + TIMER2_SYNCO_SEL + 2 + 2 + read-write + + + TIMER2_PHASE + 4 + 16 + read-write + + + TIMER2_PHASE_DIRECTION + 20 + 1 + read-write + + + + + TIMER2_STATUS + 0x30 + 0x20 + + + TIMER2_VALUE + 0 + 16 + read-only + + + TIMER2_DIRECTION + 16 + 1 + read-only + + + + + TIMER_SYNCI_CFG + 0x34 + 0x20 + + + TIMER0_SYNCISEL + 0 + 3 + read-write + + + TIMER1_SYNCISEL + 3 + 3 + read-write + + + TIMER2_SYNCISEL + 6 + 3 + read-write + + + EXTERNAL_SYNCI0_INVERT + 9 + 1 + read-write + + + EXTERNAL_SYNCI1_INVERT + 10 + 1 + read-write + + + EXTERNAL_SYNCI2_INVERT + 11 + 1 + read-write + + + + + OPERATOR_TIMERSEL + 0x38 + 0x20 + + + OPERATOR0_TIMERSEL + 0 + 2 + read-write + + + OPERATOR1_TIMERSEL + 2 + 2 + read-write + + + OPERATOR2_TIMERSEL + 4 + 2 + read-write + + + + + GEN0_STMP_CFG + 0x3C + 0x20 + + + GEN0_A_UPMETHOD + 0 + 4 + read-write + + + GEN0_B_UPMETHOD + 4 + 4 + read-write + + + GEN0_A_SHDW_FULL + 8 + 1 + read-write + + + GEN0_B_SHDW_FULL + 9 + 1 + read-write + + + + + GEN0_TSTMP_A + 0x40 + 0x20 + + + GEN0_A + 0 + 16 + read-write + + + + + GEN0_TSTMP_B + 0x44 + 0x20 + + + GEN0_B + 0 + 16 + read-write + + + + + GEN0_CFG0 + 0x48 + 0x20 + + + GEN0_CFG_UPMETHOD + 0 + 4 + read-write + + + GEN0_T0_SEL + 4 + 3 + read-write + + + GEN0_T1_SEL + 7 + 3 + read-write + + + + + GEN0_FORCE + 0x4C + 0x20 + 0x00000020 + + + GEN0_CNTUFORCE_UPMETHOD + 0 + 6 + read-write + + + GEN0_A_CNTUFORCE_MODE + 6 + 2 + read-write + + + GEN0_B_CNTUFORCE_MODE + 8 + 2 + read-write + + + GEN0_A_NCIFORCE + 10 + 1 + read-write + + + GEN0_A_NCIFORCE_MODE + 11 + 2 + read-write + + + GEN0_B_NCIFORCE + 13 + 1 + read-write + + + GEN0_B_NCIFORCE_MODE + 14 + 2 + read-write + + + + + GEN0_A + 0x50 + 0x20 + + + UTEZ + 0 + 2 + read-write + + + UTEP + 2 + 2 + read-write + + + UTEA + 4 + 2 + read-write + + + UTEB + 6 + 2 + read-write + + + UT0 + 8 + 2 + read-write + + + UT1 + 10 + 2 + read-write + + + DTEZ + 12 + 2 + read-write + + + DTEP + 14 + 2 + read-write + + + DTEA + 16 + 2 + read-write + + + DTEB + 18 + 2 + read-write + + + DT0 + 20 + 2 + read-write + + + DT1 + 22 + 2 + read-write + + + + + GEN0_B + 0x54 + 0x20 + + + UTEZ + 0 + 2 + read-write + + + UTEP + 2 + 2 + read-write + + + UTEA + 4 + 2 + read-write + + + UTEB + 6 + 2 + read-write + + + UT0 + 8 + 2 + read-write + + + UT1 + 10 + 2 + read-write + + + DTEZ + 12 + 2 + read-write + + + DTEP + 14 + 2 + read-write + + + DTEA + 16 + 2 + read-write + + + DTEB + 18 + 2 + read-write + + + DT0 + 20 + 2 + read-write + + + DT1 + 22 + 2 + read-write + + + + + DT0_CFG + 0x58 + 0x20 + 0x00018000 + + + DT0_FED_UPMETHOD + 0 + 4 + read-write + + + DT0_RED_UPMETHOD + 4 + 4 + read-write + + + DT0_DEB_MODE + 8 + 1 + read-write + + + DT0_A_OUTSWAP + 9 + 1 + read-write + + + DT0_B_OUTSWAP + 10 + 1 + read-write + + + DT0_RED_INSEL + 11 + 1 + read-write + + + DT0_FED_INSEL + 12 + 1 + read-write + + + DT0_RED_OUTINVERT + 13 + 1 + read-write + + + DT0_FED_OUTINVERT + 14 + 1 + read-write + + + DT0_A_OUTBYPASS + 15 + 1 + read-write + + + DT0_B_OUTBYPASS + 16 + 1 + read-write + + + DT0_CLK_SEL + 17 + 1 + read-write + + + + + DT0_FED_CFG + 0x5C + 0x20 + + + DT0_FED + 0 + 16 + read-write + + + + + DT0_RED_CFG + 0x60 + 0x20 + + + DT0_RED + 0 + 16 + read-write + + + + + CARRIER0_CFG + 0x64 + 0x20 + + + CARRIER0_EN + 0 + 1 + read-write + + + CARRIER0_PRESCALE + 1 + 4 + read-write + + + CARRIER0_DUTY + 5 + 3 + read-write + + + CARRIER0_OSHTWTH + 8 + 4 + read-write + + + CARRIER0_OUT_INVERT + 12 + 1 + read-write + + + CARRIER0_IN_INVERT + 13 + 1 + read-write + + + + + FH0_CFG0 + 0x68 + 0x20 + + + FH0_SW_CBC + 0 + 1 + read-write + + + FH0_F2_CBC + 1 + 1 + read-write + + + FH0_F1_CBC + 2 + 1 + read-write + + + FH0_F0_CBC + 3 + 1 + read-write + + + FH0_SW_OST + 4 + 1 + read-write + + + FH0_F2_OST + 5 + 1 + read-write + + + FH0_F1_OST + 6 + 1 + read-write + + + FH0_F0_OST + 7 + 1 + read-write + + + FH0_A_CBC_D + 8 + 2 + read-write + + + FH0_A_CBC_U + 10 + 2 + read-write + + + FH0_A_OST_D + 12 + 2 + read-write + + + FH0_A_OST_U + 14 + 2 + read-write + + + FH0_B_CBC_D + 16 + 2 + read-write + + + FH0_B_CBC_U + 18 + 2 + read-write + + + FH0_B_OST_D + 20 + 2 + read-write + + + FH0_B_OST_U + 22 + 2 + read-write + + + + + FH0_CFG1 + 0x6C + 0x20 + + + FH0_CLR_OST + 0 + 1 + read-write + + + FH0_CBCPULSE + 1 + 2 + read-write + + + FH0_FORCE_CBC + 3 + 1 + read-write + + + FH0_FORCE_OST + 4 + 1 + read-write + + + + + FH0_STATUS + 0x70 + 0x20 + + + FH0_CBC_ON + 0 + 1 + read-only + + + FH0_OST_ON + 1 + 1 + read-only + + + + + GEN1_STMP_CFG + 0x74 + 0x20 + + + GEN1_A_UPMETHOD + 0 + 4 + read-write + + + GEN1_B_UPMETHOD + 4 + 4 + read-write + + + GEN1_A_SHDW_FULL + 8 + 1 + read-write + + + GEN1_B_SHDW_FULL + 9 + 1 + read-write + + + + + GEN1_TSTMP_A + 0x78 + 0x20 + + + GEN1_A + 0 + 16 + read-write + + + + + GEN1_TSTMP_B + 0x7C + 0x20 + + + GEN1_B + 0 + 16 + read-write + + + + + GEN1_CFG0 + 0x80 + 0x20 + + + GEN1_CFG_UPMETHOD + 0 + 4 + read-write + + + GEN1_T0_SEL + 4 + 3 + read-write + + + GEN1_T1_SEL + 7 + 3 + read-write + + + + + GEN1_FORCE + 0x84 + 0x20 + 0x00000020 + + + GEN1_CNTUFORCE_UPMETHOD + 0 + 6 + read-write + + + GEN1_A_CNTUFORCE_MODE + 6 + 2 + read-write + + + GEN1_B_CNTUFORCE_MODE + 8 + 2 + read-write + + + GEN1_A_NCIFORCE + 10 + 1 + read-write + + + GEN1_A_NCIFORCE_MODE + 11 + 2 + read-write + + + GEN1_B_NCIFORCE + 13 + 1 + read-write + + + GEN1_B_NCIFORCE_MODE + 14 + 2 + read-write + + + + + GEN1_A + 0x88 + 0x20 + + + UTEZ + 0 + 2 + read-write + + + UTEP + 2 + 2 + read-write + + + UTEA + 4 + 2 + read-write + + + UTEB + 6 + 2 + read-write + + + UT0 + 8 + 2 + read-write + + + UT1 + 10 + 2 + read-write + + + DTEZ + 12 + 2 + read-write + + + DTEP + 14 + 2 + read-write + + + DTEA + 16 + 2 + read-write + + + DTEB + 18 + 2 + read-write + + + DT0 + 20 + 2 + read-write + + + DT1 + 22 + 2 + read-write + + + + + GEN1_B + 0x8C + 0x20 + + + UTEZ + 0 + 2 + read-write + + + UTEP + 2 + 2 + read-write + + + UTEA + 4 + 2 + read-write + + + UTEB + 6 + 2 + read-write + + + UT0 + 8 + 2 + read-write + + + UT1 + 10 + 2 + read-write + + + DTEZ + 12 + 2 + read-write + + + DTEP + 14 + 2 + read-write + + + DTEA + 16 + 2 + read-write + + + DTEB + 18 + 2 + read-write + + + DT0 + 20 + 2 + read-write + + + DT1 + 22 + 2 + read-write + + + + + DT1_CFG + 0x90 + 0x20 + 0x00018000 + + + DT1_FED_UPMETHOD + 0 + 4 + read-write + + + DT1_RED_UPMETHOD + 4 + 4 + read-write + + + DT1_DEB_MODE + 8 + 1 + read-write + + + DT1_A_OUTSWAP + 9 + 1 + read-write + + + DT1_B_OUTSWAP + 10 + 1 + read-write + + + DT1_RED_INSEL + 11 + 1 + read-write + + + DT1_FED_INSEL + 12 + 1 + read-write + + + DT1_RED_OUTINVERT + 13 + 1 + read-write + + + DT1_FED_OUTINVERT + 14 + 1 + read-write + + + DT1_A_OUTBYPASS + 15 + 1 + read-write + + + DT1_B_OUTBYPASS + 16 + 1 + read-write + + + DT1_CLK_SEL + 17 + 1 + read-write + + + + + DT1_FED_CFG + 0x94 + 0x20 + + + DT1_FED + 0 + 16 + read-write + + + + + DT1_RED_CFG + 0x98 + 0x20 + + + DT1_RED + 0 + 16 + read-write + + + + + CARRIER1_CFG + 0x9C + 0x20 + + + CARRIER1_EN + 0 + 1 + read-write + + + CARRIER1_PRESCALE + 1 + 4 + read-write + + + CARRIER1_DUTY + 5 + 3 + read-write + + + CARRIER1_OSHTWTH + 8 + 4 + read-write + + + CARRIER1_OUT_INVERT + 12 + 1 + read-write + + + CARRIER1_IN_INVERT + 13 + 1 + read-write + + + + + FH1_CFG0 + 0xA0 + 0x20 + + + FH1_SW_CBC + 0 + 1 + read-write + + + FH1_F2_CBC + 1 + 1 + read-write + + + FH1_F1_CBC + 2 + 1 + read-write + + + FH1_F0_CBC + 3 + 1 + read-write + + + FH1_SW_OST + 4 + 1 + read-write + + + FH1_F2_OST + 5 + 1 + read-write + + + FH1_F1_OST + 6 + 1 + read-write + + + FH1_F0_OST + 7 + 1 + read-write + + + FH1_A_CBC_D + 8 + 2 + read-write + + + FH1_A_CBC_U + 10 + 2 + read-write + + + FH1_A_OST_D + 12 + 2 + read-write + + + FH1_A_OST_U + 14 + 2 + read-write + + + FH1_B_CBC_D + 16 + 2 + read-write + + + FH1_B_CBC_U + 18 + 2 + read-write + + + FH1_B_OST_D + 20 + 2 + read-write + + + FH1_B_OST_U + 22 + 2 + read-write + + + + + FH1_CFG1 + 0xA4 + 0x20 + + + FH1_CLR_OST + 0 + 1 + read-write + + + FH1_CBCPULSE + 1 + 2 + read-write + + + FH1_FORCE_CBC + 3 + 1 + read-write + + + FH1_FORCE_OST + 4 + 1 + read-write + + + + + FH1_STATUS + 0xA8 + 0x20 + + + FH1_CBC_ON + 0 + 1 + read-only + + + FH1_OST_ON + 1 + 1 + read-only + + + + + GEN2_STMP_CFG + 0xAC + 0x20 + + + GEN2_A_UPMETHOD + 0 + 4 + read-write + + + GEN2_B_UPMETHOD + 4 + 4 + read-write + + + GEN2_A_SHDW_FULL + 8 + 1 + read-write + + + GEN2_B_SHDW_FULL + 9 + 1 + read-write + + + + + GEN2_TSTMP_A + 0xB0 + 0x20 + + + GEN2_A + 0 + 16 + read-write + + + + + GEN2_TSTMP_B + 0xB4 + 0x20 + + + GEN2_B + 0 + 16 + read-write + + + + + GEN2_CFG0 + 0xB8 + 0x20 + + + GEN2_CFG_UPMETHOD + 0 + 4 + read-write + + + GEN2_T0_SEL + 4 + 3 + read-write + + + GEN2_T1_SEL + 7 + 3 + read-write + + + + + GEN2_FORCE + 0xBC + 0x20 + 0x00000020 + + + GEN2_CNTUFORCE_UPMETHOD + 0 + 6 + read-write + + + GEN2_A_CNTUFORCE_MODE + 6 + 2 + read-write + + + GEN2_B_CNTUFORCE_MODE + 8 + 2 + read-write + + + GEN2_A_NCIFORCE + 10 + 1 + read-write + + + GEN2_A_NCIFORCE_MODE + 11 + 2 + read-write + + + GEN2_B_NCIFORCE + 13 + 1 + read-write + + + GEN2_B_NCIFORCE_MODE + 14 + 2 + read-write + + + + + GEN2_A + 0xC0 + 0x20 + + + UTEZ + 0 + 2 + read-write + + + UTEP + 2 + 2 + read-write + + + UTEA + 4 + 2 + read-write + + + UTEB + 6 + 2 + read-write + + + UT0 + 8 + 2 + read-write + + + UT1 + 10 + 2 + read-write + + + DTEZ + 12 + 2 + read-write + + + DTEP + 14 + 2 + read-write + + + DTEA + 16 + 2 + read-write + + + DTEB + 18 + 2 + read-write + + + DT0 + 20 + 2 + read-write + + + DT1 + 22 + 2 + read-write + + + + + GEN2_B + 0xC4 + 0x20 + + + UTEZ + 0 + 2 + read-write + + + UTEP + 2 + 2 + read-write + + + UTEA + 4 + 2 + read-write + + + UTEB + 6 + 2 + read-write + + + UT0 + 8 + 2 + read-write + + + UT1 + 10 + 2 + read-write + + + DTEZ + 12 + 2 + read-write + + + DTEP + 14 + 2 + read-write + + + DTEA + 16 + 2 + read-write + + + DTEB + 18 + 2 + read-write + + + DT0 + 20 + 2 + read-write + + + DT1 + 22 + 2 + read-write + + + + + DT2_CFG + 0xC8 + 0x20 + 0x00018000 + + + DT2_FED_UPMETHOD + 0 + 4 + read-write + + + DT2_RED_UPMETHOD + 4 + 4 + read-write + + + DT2_DEB_MODE + 8 + 1 + read-write + + + DT2_A_OUTSWAP + 9 + 1 + read-write + + + DT2_B_OUTSWAP + 10 + 1 + read-write + + + DT2_RED_INSEL + 11 + 1 + read-write + + + DT2_FED_INSEL + 12 + 1 + read-write + + + DT2_RED_OUTINVERT + 13 + 1 + read-write + + + DT2_FED_OUTINVERT + 14 + 1 + read-write + + + DT2_A_OUTBYPASS + 15 + 1 + read-write + + + DT2_B_OUTBYPASS + 16 + 1 + read-write + + + DT2_CLK_SEL + 17 + 1 + read-write + + + + + DT2_FED_CFG + 0xCC + 0x20 + + + DT2_FED + 0 + 16 + read-write + + + + + DT2_RED_CFG + 0xD0 + 0x20 + + + DT2_RED + 0 + 16 + read-write + + + + + CARRIER2_CFG + 0xD4 + 0x20 + + + CARRIER2_EN + 0 + 1 + read-write + + + CARRIER2_PRESCALE + 1 + 4 + read-write + + + CARRIER2_DUTY + 5 + 3 + read-write + + + CARRIER2_OSHTWTH + 8 + 4 + read-write + + + CARRIER2_OUT_INVERT + 12 + 1 + read-write + + + CARRIER2_IN_INVERT + 13 + 1 + read-write + + + + + FH2_CFG0 + 0xD8 + 0x20 + + + FH2_SW_CBC + 0 + 1 + read-write + + + FH2_F2_CBC + 1 + 1 + read-write + + + FH2_F1_CBC + 2 + 1 + read-write + + + FH2_F0_CBC + 3 + 1 + read-write + + + FH2_SW_OST + 4 + 1 + read-write + + + FH2_F2_OST + 5 + 1 + read-write + + + FH2_F1_OST + 6 + 1 + read-write + + + FH2_F0_OST + 7 + 1 + read-write + + + FH2_A_CBC_D + 8 + 2 + read-write + + + FH2_A_CBC_U + 10 + 2 + read-write + + + FH2_A_OST_D + 12 + 2 + read-write + + + FH2_A_OST_U + 14 + 2 + read-write + + + FH2_B_CBC_D + 16 + 2 + read-write + + + FH2_B_CBC_U + 18 + 2 + read-write + + + FH2_B_OST_D + 20 + 2 + read-write + + + FH2_B_OST_U + 22 + 2 + read-write + + + + + FH2_CFG1 + 0xDC + 0x20 + + + FH2_CLR_OST + 0 + 1 + read-write + + + FH2_CBCPULSE + 1 + 2 + read-write + + + FH2_FORCE_CBC + 3 + 1 + read-write + + + FH2_FORCE_OST + 4 + 1 + read-write + + + + + FH2_STATUS + 0xE0 + 0x20 + + + FH2_CBC_ON + 0 + 1 + read-only + + + FH2_OST_ON + 1 + 1 + read-only + + + + + FAULT_DETECT + 0xE4 + 0x20 + + + F0_EN + 0 + 1 + read-write + + + F1_EN + 1 + 1 + read-write + + + F2_EN + 2 + 1 + read-write + + + F0_POLE + 3 + 1 + read-write + + + F1_POLE + 4 + 1 + read-write + + + F2_POLE + 5 + 1 + read-write + + + EVENT_F0 + 6 + 1 + read-only + + + EVENT_F1 + 7 + 1 + read-only + + + EVENT_F2 + 8 + 1 + read-only + + + + + CAP_TIMER_CFG + 0xE8 + 0x20 + + + CAP_TIMER_EN + 0 + 1 + read-write + + + CAP_SYNCI_EN + 1 + 1 + read-write + + + CAP_SYNCI_SEL + 2 + 3 + read-write + + + CAP_SYNC_SW + 5 + 1 + write-only + + + + + CAP_TIMER_PHASE + 0xEC + 0x20 + + + CAP_TIMER_PHASE + 0 + 32 + read-write + + + + + CAP_CH0_CFG + 0xF0 + 0x20 + + + CAP0_EN + 0 + 1 + read-write + + + CAP0_MODE + 1 + 2 + read-write + + + CAP0_PRESCALE + 3 + 8 + read-write + + + CAP0_IN_INVERT + 11 + 1 + read-write + + + CAP0_SW + 12 + 1 + write-only + + + + + CAP_CH1_CFG + 0xF4 + 0x20 + + + CAP1_EN + 0 + 1 + read-write + + + CAP1_MODE + 1 + 2 + read-write + + + CAP1_PRESCALE + 3 + 8 + read-write + + + CAP1_IN_INVERT + 11 + 1 + read-write + + + CAP1_SW + 12 + 1 + write-only + + + + + CAP_CH2_CFG + 0xF8 + 0x20 + + + CAP2_EN + 0 + 1 + read-write + + + CAP2_MODE + 1 + 2 + read-write + + + CAP2_PRESCALE + 3 + 8 + read-write + + + CAP2_IN_INVERT + 11 + 1 + read-write + + + CAP2_SW + 12 + 1 + write-only + + + + + CAP_CH0 + 0xFC + 0x20 + + + CAP0_VALUE + 0 + 32 + read-only + + + + + CAP_CH1 + 0x100 + 0x20 + + + CAP1_VALUE + 0 + 32 + read-only + + + + + CAP_CH2 + 0x104 + 0x20 + + + CAP2_VALUE + 0 + 32 + read-only + + + + + CAP_STATUS + 0x108 + 0x20 + + + CAP0_EDGE + 0 + 1 + read-only + + + CAP1_EDGE + 1 + 1 + read-only + + + CAP2_EDGE + 2 + 1 + read-only + + + + + UPDATE_CFG + 0x10C + 0x20 + 0x00000055 + + + GLOBAL_UP_EN + 0 + 1 + read-write + + + GLOBAL_FORCE_UP + 1 + 1 + read-write + + + OP0_UP_EN + 2 + 1 + read-write + + + OP0_FORCE_UP + 3 + 1 + read-write + + + OP1_UP_EN + 4 + 1 + read-write + + + OP1_FORCE_UP + 5 + 1 + read-write + + + OP2_UP_EN + 6 + 1 + read-write + + + OP2_FORCE_UP + 7 + 1 + read-write + + + + + INT_ENA + 0x110 + 0x20 + + + TIMER0_STOP_INT_ENA + 0 + 1 + read-write + + + TIMER1_STOP_INT_ENA + 1 + 1 + read-write + + + TIMER2_STOP_INT_ENA + 2 + 1 + read-write + + + TIMER0_TEZ_INT_ENA + 3 + 1 + read-write + + + TIMER1_TEZ_INT_ENA + 4 + 1 + read-write + + + TIMER2_TEZ_INT_ENA + 5 + 1 + read-write + + + TIMER0_TEP_INT_ENA + 6 + 1 + read-write + + + TIMER1_TEP_INT_ENA + 7 + 1 + read-write + + + TIMER2_TEP_INT_ENA + 8 + 1 + read-write + + + FAULT0_INT_ENA + 9 + 1 + read-write + + + FAULT1_INT_ENA + 10 + 1 + read-write + + + FAULT2_INT_ENA + 11 + 1 + read-write + + + FAULT0_CLR_INT_ENA + 12 + 1 + read-write + + + FAULT1_CLR_INT_ENA + 13 + 1 + read-write + + + FAULT2_CLR_INT_ENA + 14 + 1 + read-write + + + OP0_TEA_INT_ENA + 15 + 1 + read-write + + + OP1_TEA_INT_ENA + 16 + 1 + read-write + + + OP2_TEA_INT_ENA + 17 + 1 + read-write + + + OP0_TEB_INT_ENA + 18 + 1 + read-write + + + OP1_TEB_INT_ENA + 19 + 1 + read-write + + + OP2_TEB_INT_ENA + 20 + 1 + read-write + + + FH0_CBC_INT_ENA + 21 + 1 + read-write + + + FH1_CBC_INT_ENA + 22 + 1 + read-write + + + FH2_CBC_INT_ENA + 23 + 1 + read-write + + + FH0_OST_INT_ENA + 24 + 1 + read-write + + + FH1_OST_INT_ENA + 25 + 1 + read-write + + + FH2_OST_INT_ENA + 26 + 1 + read-write + + + CAP0_INT_ENA + 27 + 1 + read-write + + + CAP1_INT_ENA + 28 + 1 + read-write + + + CAP2_INT_ENA + 29 + 1 + read-write + + + + + INT_RAW + 0x114 + 0x20 + + + TIMER0_STOP_INT_RAW + 0 + 1 + read-only + + + TIMER1_STOP_INT_RAW + 1 + 1 + read-only + + + TIMER2_STOP_INT_RAW + 2 + 1 + read-only + + + TIMER0_TEZ_INT_RAW + 3 + 1 + read-only + + + TIMER1_TEZ_INT_RAW + 4 + 1 + read-only + + + TIMER2_TEZ_INT_RAW + 5 + 1 + read-only + + + TIMER0_TEP_INT_RAW + 6 + 1 + read-only + + + TIMER1_TEP_INT_RAW + 7 + 1 + read-only + + + TIMER2_TEP_INT_RAW + 8 + 1 + read-only + + + FAULT0_INT_RAW + 9 + 1 + read-only + + + FAULT1_INT_RAW + 10 + 1 + read-only + + + FAULT2_INT_RAW + 11 + 1 + read-only + + + FAULT0_CLR_INT_RAW + 12 + 1 + read-only + + + FAULT1_CLR_INT_RAW + 13 + 1 + read-only + + + FAULT2_CLR_INT_RAW + 14 + 1 + read-only + + + OP0_TEA_INT_RAW + 15 + 1 + read-only + + + OP1_TEA_INT_RAW + 16 + 1 + read-only + + + OP2_TEA_INT_RAW + 17 + 1 + read-only + + + OP0_TEB_INT_RAW + 18 + 1 + read-only + + + OP1_TEB_INT_RAW + 19 + 1 + read-only + + + OP2_TEB_INT_RAW + 20 + 1 + read-only + + + FH0_CBC_INT_RAW + 21 + 1 + read-only + + + FH1_CBC_INT_RAW + 22 + 1 + read-only + + + FH2_CBC_INT_RAW + 23 + 1 + read-only + + + FH0_OST_INT_RAW + 24 + 1 + read-only + + + FH1_OST_INT_RAW + 25 + 1 + read-only + + + FH2_OST_INT_RAW + 26 + 1 + read-only + + + CAP0_INT_RAW + 27 + 1 + read-only + + + CAP1_INT_RAW + 28 + 1 + read-only + + + CAP2_INT_RAW + 29 + 1 + read-only + + + + + INT_ST + 0x118 + 0x20 + + + TIMER0_STOP_INT_ST + 0 + 1 + read-only + + + TIMER1_STOP_INT_ST + 1 + 1 + read-only + + + TIMER2_STOP_INT_ST + 2 + 1 + read-only + + + TIMER0_TEZ_INT_ST + 3 + 1 + read-only + + + TIMER1_TEZ_INT_ST + 4 + 1 + read-only + + + TIMER2_TEZ_INT_ST + 5 + 1 + read-only + + + TIMER0_TEP_INT_ST + 6 + 1 + read-only + + + TIMER1_TEP_INT_ST + 7 + 1 + read-only + + + TIMER2_TEP_INT_ST + 8 + 1 + read-only + + + FAULT0_INT_ST + 9 + 1 + read-only + + + FAULT1_INT_ST + 10 + 1 + read-only + + + FAULT2_INT_ST + 11 + 1 + read-only + + + FAULT0_CLR_INT_ST + 12 + 1 + read-only + + + FAULT1_CLR_INT_ST + 13 + 1 + read-only + + + FAULT2_CLR_INT_ST + 14 + 1 + read-only + + + OP0_TEA_INT_ST + 15 + 1 + read-only + + + OP1_TEA_INT_ST + 16 + 1 + read-only + + + OP2_TEA_INT_ST + 17 + 1 + read-only + + + OP0_TEB_INT_ST + 18 + 1 + read-only + + + OP1_TEB_INT_ST + 19 + 1 + read-only + + + OP2_TEB_INT_ST + 20 + 1 + read-only + + + FH0_CBC_INT_ST + 21 + 1 + read-only + + + FH1_CBC_INT_ST + 22 + 1 + read-only + + + FH2_CBC_INT_ST + 23 + 1 + read-only + + + FH0_OST_INT_ST + 24 + 1 + read-only + + + FH1_OST_INT_ST + 25 + 1 + read-only + + + FH2_OST_INT_ST + 26 + 1 + read-only + + + CAP0_INT_ST + 27 + 1 + read-only + + + CAP1_INT_ST + 28 + 1 + read-only + + + CAP2_INT_ST + 29 + 1 + read-only + + + + + INT_CLR + 0x11C + 0x20 + + + TIMER0_STOP_INT_CLR + 0 + 1 + write-only + + + TIMER1_STOP_INT_CLR + 1 + 1 + write-only + + + TIMER2_STOP_INT_CLR + 2 + 1 + write-only + + + TIMER0_TEZ_INT_CLR + 3 + 1 + write-only + + + TIMER1_TEZ_INT_CLR + 4 + 1 + write-only + + + TIMER2_TEZ_INT_CLR + 5 + 1 + write-only + + + TIMER0_TEP_INT_CLR + 6 + 1 + write-only + + + TIMER1_TEP_INT_CLR + 7 + 1 + write-only + + + TIMER2_TEP_INT_CLR + 8 + 1 + write-only + + + FAULT0_INT_CLR + 9 + 1 + write-only + + + FAULT1_INT_CLR + 10 + 1 + write-only + + + FAULT2_INT_CLR + 11 + 1 + write-only + + + FAULT0_CLR_INT_CLR + 12 + 1 + write-only + + + FAULT1_CLR_INT_CLR + 13 + 1 + write-only + + + FAULT2_CLR_INT_CLR + 14 + 1 + write-only + + + OP0_TEA_INT_CLR + 15 + 1 + write-only + + + OP1_TEA_INT_CLR + 16 + 1 + write-only + + + OP2_TEA_INT_CLR + 17 + 1 + write-only + + + OP0_TEB_INT_CLR + 18 + 1 + write-only + + + OP1_TEB_INT_CLR + 19 + 1 + write-only + + + OP2_TEB_INT_CLR + 20 + 1 + write-only + + + FH0_CBC_INT_CLR + 21 + 1 + write-only + + + FH1_CBC_INT_CLR + 22 + 1 + write-only + + + FH2_CBC_INT_CLR + 23 + 1 + write-only + + + FH0_OST_INT_CLR + 24 + 1 + write-only + + + FH1_OST_INT_CLR + 25 + 1 + write-only + + + FH2_OST_INT_CLR + 26 + 1 + write-only + + + CAP0_INT_CLR + 27 + 1 + write-only + + + CAP1_INT_CLR + 28 + 1 + write-only + + + CAP2_INT_CLR + 29 + 1 + write-only + + + + + CLK + 0x120 + 0x20 + + + EN + 0 + 1 + read-write + + + + + VERSION + 0x124 + 0x20 + 0x02107230 + + + DATE + 0 + 28 + read-write + + + + + + + PWM1 + Motor Control Pulse-Width Modulation + 0x3FF6C000 + + PWM1 + 40 + + + + NRX + Peripheral NRX + NRX + 0x3FF5CC00 + + 0x0 + 0x4 + registers + + + + NRXPD_CTRL + WiFi RX control register + 0xD4 + 0x20 + + + DEMAP_FORCE_PD + 0 + 1 + read-write + + + DEMAP_FORCE_PU + 1 + 1 + read-write + + + VIT_FORCE_PD + 2 + 1 + read-write + + + VIT_FORCE_PU + 3 + 1 + read-write + + + RX_ROT_FORCE_PD + 4 + 1 + read-write + + + RX_ROT_FORCE_PU + 5 + 1 + read-write + + + CHAN_EST_FORCE_PD + 6 + 1 + read-write + + + CHAN_EST_FORCE_PU + 7 + 1 + read-write + + + + + + + PCNT + Pulse Count Controller + PCNT + 0x3FF57000 + + 0x0 + 0xB8 + registers + + + PCNT + 48 + + + + U0_CONF0 + 0x0 + 0x20 + 0x00003C10 + + + FILTER_THRES_U0 + This register is used to filter pluse whose width is smaller than this value for unit0. + 0 + 10 + read-write + + + FILTER_EN_U0 + This is the enable bit for filtering input signals for unit0. + 10 + 1 + read-write + + + THR_ZERO_EN_U0 + This is the enable bit for comparing unit0's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U0 + This is the enable bit for comparing unit0's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U0 + This is the enable bit for comparing unit0's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U0 + This is the enable bit for comparing unit0's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U0 + This is the enable bit for comparing unit0's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U0 + This register is used to control the mode of channel0's input negedge signal for unit0. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U0 + This register is used to control the mode of channel0's input posedge signal for unit0. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U0 + This register is used to control the mode of channel0's high control signal for unit0. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U0 + This register is used to control the mode of channel0's low control signal for unit0. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U0 + This register is used to control the mode of channel1's input negedge signal for unit0. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U0 + This register is used to control the mode of channel1's input posedge signal for unit0. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U0 + This register is used to control the mode of channel1's high control signal for unit0. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U0 + This register is used to control the mode of channel1's low control signal for unit0. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U0_CONF1 + 0x4 + 0x20 + + + CNT_THRES0_U0 + This register is used to configure thres0 value for unit0. + 0 + 16 + read-write + + + CNT_THRES1_U0 + This register is used to configure thres1 value for unit0. + 16 + 16 + read-write + + + + + U0_CONF2 + 0x8 + 0x20 + + + CNT_H_LIM_U0 + This register is used to configure thr_h_lim value for unit0. + 0 + 16 + read-write + + + CNT_L_LIM_U0 + This register is used to confiugre thr_l_lim value for unit0. + 16 + 16 + read-write + + + + + U1_CONF0 + 0xC + 0x20 + 0x00003C10 + + + FILTER_THRES_U1 + This register is used to filter pluse whose width is smaller than this value for unit1. + 0 + 10 + read-write + + + FILTER_EN_U1 + This is the enable bit for filtering input signals for unit1. + 10 + 1 + read-write + + + THR_ZERO_EN_U1 + This is the enable bit for comparing unit1's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U1 + This is the enable bit for comparing unit1's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U1 + This is the enable bit for comparing unit1's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U1 + This is the enable bit for comparing unit1's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U1 + This is the enable bit for comparing unit1's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U1 + This register is used to control the mode of channel0's input negedge signal for unit1. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U1 + This register is used to control the mode of channel0's input posedge signal for unit1. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U1 + This register is used to control the mode of channel0's high control signal for unit1. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U1 + This register is used to control the mode of channel0's low control signal for unit1. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U1 + This register is used to control the mode of channel1's input negedge signal for unit1. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U1 + This register is used to control the mode of channel1's input posedge signal for unit1. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U1 + This register is used to control the mode of channel1's high control signal for unit1. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U1 + This register is used to control the mode of channel1's low control signal for unit1. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U1_CONF1 + 0x10 + 0x20 + + + CNT_THRES0_U1 + This register is used to configure thres0 value for unit1. + 0 + 16 + read-write + + + CNT_THRES1_U1 + This register is used to configure thres1 value for unit1. + 16 + 16 + read-write + + + + + U1_CONF2 + 0x14 + 0x20 + + + CNT_H_LIM_U1 + This register is used to configure thr_h_lim value for unit1. + 0 + 16 + read-write + + + CNT_L_LIM_U1 + This register is used to confiugre thr_l_lim value for unit1. + 16 + 16 + read-write + + + + + U2_CONF0 + 0x18 + 0x20 + 0x00003C10 + + + FILTER_THRES_U2 + This register is used to filter pluse whose width is smaller than this value for unit2. + 0 + 10 + read-write + + + FILTER_EN_U2 + This is the enable bit for filtering input signals for unit2. + 10 + 1 + read-write + + + THR_ZERO_EN_U2 + This is the enable bit for comparing unit2's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U2 + This is the enable bit for comparing unit2's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U2 + This is the enable bit for comparing unit2's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U2 + This is the enable bit for comparing unit2's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U2 + This is the enable bit for comparing unit2's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U2 + This register is used to control the mode of channel0's input negedge signal for unit2. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U2 + This register is used to control the mode of channel0's input posedge signal for unit2. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U2 + This register is used to control the mode of channel0's high control signal for unit2. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U2 + This register is used to control the mode of channel0's low control signal for unit2. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U2 + This register is used to control the mode of channel1's input negedge signal for unit2. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U2 + This register is used to control the mode of channel1's input posedge signal for unit2. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U2 + This register is used to control the mode of channel1's high control signal for unit2. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U2 + This register is used to control the mode of channel1's low control signal for unit2. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U2_CONF1 + 0x1C + 0x20 + + + CNT_THRES0_U2 + This register is used to configure thres0 value for unit2. + 0 + 16 + read-write + + + CNT_THRES1_U2 + This register is used to configure thres1 value for unit2. + 16 + 16 + read-write + + + + + U2_CONF2 + 0x20 + 0x20 + + + CNT_H_LIM_U2 + This register is used to configure thr_h_lim value for unit2. + 0 + 16 + read-write + + + CNT_L_LIM_U2 + This register is used to confiugre thr_l_lim value for unit2. + 16 + 16 + read-write + + + + + U3_CONF0 + 0x24 + 0x20 + 0x00003C10 + + + FILTER_THRES_U3 + This register is used to filter pluse whose width is smaller than this value for unit3. + 0 + 10 + read-write + + + FILTER_EN_U3 + This is the enable bit for filtering input signals for unit3. + 10 + 1 + read-write + + + THR_ZERO_EN_U3 + This is the enable bit for comparing unit3's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U3 + This is the enable bit for comparing unit3's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U3 + This is the enable bit for comparing unit3's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U3 + This is the enable bit for comparing unit3's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U3 + This is the enable bit for comparing unit3's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U3 + This register is used to control the mode of channel0's input negedge signal for unit3. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U3 + This register is used to control the mode of channel0's input posedge signal for unit3. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U3 + This register is used to control the mode of channel0's high control signal for unit3. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U3 + This register is used to control the mode of channel0's low control signal for unit3. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U3 + This register is used to control the mode of channel1's input negedge signal for unit3. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U3 + This register is used to control the mode of channel1's input posedge signal for unit3. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U3 + This register is used to control the mode of channel1's high control signal for unit3. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U3 + This register is used to control the mode of channel1's low control signal for unit3. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U3_CONF1 + 0x28 + 0x20 + + + CNT_THRES0_U3 + This register is used to configure thres0 value for unit3. + 0 + 16 + read-write + + + CNT_THRES1_U3 + This register is used to configure thres1 value for unit3. + 16 + 16 + read-write + + + + + U3_CONF2 + 0x2C + 0x20 + + + CNT_H_LIM_U3 + This register is used to configure thr_h_lim value for unit3. + 0 + 16 + read-write + + + CNT_L_LIM_U3 + This register is used to confiugre thr_l_lim value for unit3. + 16 + 16 + read-write + + + + + U4_CONF0 + 0x30 + 0x20 + 0x00003C10 + + + FILTER_THRES_U4 + This register is used to filter pluse whose width is smaller than this value for unit4. + 0 + 10 + read-write + + + FILTER_EN_U4 + This is the enable bit for filtering input signals for unit4. + 10 + 1 + read-write + + + THR_ZERO_EN_U4 + This is the enable bit for comparing unit4's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U4 + This is the enable bit for comparing unit4's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U4 + This is the enable bit for comparing unit4's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U4 + This is the enable bit for comparing unit4's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U4 + This is the enable bit for comparing unit4's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U4 + This register is used to control the mode of channel0's input negedge signal for unit4. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U4 + This register is used to control the mode of channel0's input posedge signal for unit4. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U4 + This register is used to control the mode of channel0's high control signal for unit4. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U4 + This register is used to control the mode of channel0's low control signal for unit4. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U4 + This register is used to control the mode of channel1's input negedge signal for unit4. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U4 + This register is used to control the mode of channel1's input posedge signal for unit4. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U4 + This register is used to control the mode of channel1's high control signal for unit4. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U4 + This register is used to control the mode of channel1's low control signal for unit4. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U4_CONF1 + 0x34 + 0x20 + + + CNT_THRES0_U4 + This register is used to configure thres0 value for unit4. + 0 + 16 + read-write + + + CNT_THRES1_U4 + This register is used to configure thres1 value for unit4. + 16 + 16 + read-write + + + + + U4_CONF2 + 0x38 + 0x20 + + + CNT_H_LIM_U4 + This register is used to configure thr_h_lim value for unit4. + 0 + 16 + read-write + + + CNT_L_LIM_U4 + This register is used to confiugre thr_l_lim value for unit4. + 16 + 16 + read-write + + + + + U5_CONF0 + 0x3C + 0x20 + 0x00003C10 + + + FILTER_THRES_U5 + This register is used to filter pluse whose width is smaller than this value for unit5. + 0 + 10 + read-write + + + FILTER_EN_U5 + This is the enable bit for filtering input signals for unit5. + 10 + 1 + read-write + + + THR_ZERO_EN_U5 + This is the enable bit for comparing unit5's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U5 + This is the enable bit for comparing unit5's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U5 + This is the enable bit for comparing unit5's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U5 + This is the enable bit for comparing unit5's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U5 + This is the enable bit for comparing unit5's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U5 + This register is used to control the mode of channel0's input negedge signal for unit5. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U5 + This register is used to control the mode of channel0's input posedge signal for unit5. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U5 + This register is used to control the mode of channel0's high control signal for unit5. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U5 + This register is used to control the mode of channel0's low control signal for unit5. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U5 + This register is used to control the mode of channel1's input negedge signal for unit5. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U5 + This register is used to control the mode of channel1's input posedge signal for unit5. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U5 + This register is used to control the mode of channel1's high control signal for unit5. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U5 + This register is used to control the mode of channel1's low control signal for unit5. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U5_CONF1 + 0x40 + 0x20 + + + CNT_THRES0_U5 + This register is used to configure thres0 value for unit5. + 0 + 16 + read-write + + + CNT_THRES1_U5 + This register is used to configure thres1 value for unit5. + 16 + 16 + read-write + + + + + U5_CONF2 + 0x44 + 0x20 + + + CNT_H_LIM_U5 + This register is used to configure thr_h_lim value for unit5. + 0 + 16 + read-write + + + CNT_L_LIM_U5 + This register is used to confiugre thr_l_lim value for unit5. + 16 + 16 + read-write + + + + + U6_CONF0 + 0x48 + 0x20 + 0x00003C10 + + + FILTER_THRES_U6 + This register is used to filter pluse whose width is smaller than this value for unit6. + 0 + 10 + read-write + + + FILTER_EN_U6 + This is the enable bit for filtering input signals for unit6. + 10 + 1 + read-write + + + THR_ZERO_EN_U6 + This is the enable bit for comparing unit6's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U6 + This is the enable bit for comparing unit6's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U6 + This is the enable bit for comparing unit6's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U6 + This is the enable bit for comparing unit6's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U6 + This is the enable bit for comparing unit6's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U6 + This register is used to control the mode of channel0's input negedge signal for unit6. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U6 + This register is used to control the mode of channel0's input posedge signal for unit6. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U6 + This register is used to control the mode of channel0's high control signal for unit6. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U6 + This register is used to control the mode of channel0's low control signal for unit6. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U6 + This register is used to control the mode of channel1's input negedge signal for unit6. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U6 + This register is used to control the mode of channel1's input posedge signal for unit6. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U6 + This register is used to control the mode of channel1's high control signal for unit6. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U6 + This register is used to control the mode of channel1's low control signal for unit6. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U6_CONF1 + 0x4C + 0x20 + + + CNT_THRES0_U6 + This register is used to configure thres0 value for unit6. + 0 + 16 + read-write + + + CNT_THRES1_U6 + This register is used to configure thres1 value for unit6. + 16 + 16 + read-write + + + + + U6_CONF2 + 0x50 + 0x20 + + + CNT_H_LIM_U6 + This register is used to configure thr_h_lim value for unit6. + 0 + 16 + read-write + + + CNT_L_LIM_U6 + This register is used to confiugre thr_l_lim value for unit6. + 16 + 16 + read-write + + + + + U7_CONF0 + 0x54 + 0x20 + 0x00003C10 + + + FILTER_THRES_U7 + This register is used to filter pluse whose width is smaller than this value for unit7. + 0 + 10 + read-write + + + FILTER_EN_U7 + This is the enable bit for filtering input signals for unit7. + 10 + 1 + read-write + + + THR_ZERO_EN_U7 + This is the enable bit for comparing unit7's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U7 + This is the enable bit for comparing unit7's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U7 + This is the enable bit for comparing unit7's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U7 + This is the enable bit for comparing unit7's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U7 + This is the enable bit for comparing unit7's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U7 + This register is used to control the mode of channel0's input negedge signal for unit7. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U7 + This register is used to control the mode of channel0's input posedge signal for unit7. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U7 + This register is used to control the mode of channel0's high control signal for unit7. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U7 + This register is used to control the mode of channel0's low control signal for unit7. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U7 + This register is used to control the mode of channel1's input negedge signal for unit7. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U7 + This register is used to control the mode of channel1's input posedge signal for unit7. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U7 + This register is used to control the mode of channel1's high control signal for unit7. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U7 + This register is used to control the mode of channel1's low control signal for unit7. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U7_CONF1 + 0x58 + 0x20 + + + CNT_THRES0_U7 + This register is used to configure thres0 value for unit7. + 0 + 16 + read-write + + + CNT_THRES1_U7 + This register is used to configure thres1 value for unit7. + 16 + 16 + read-write + + + + + U7_CONF2 + 0x5C + 0x20 + + + CNT_H_LIM_U7 + This register is used to configure thr_h_lim value for unit7. + 0 + 16 + read-write + + + CNT_L_LIM_U7 + This register is used to confiugre thr_l_lim value for unit7. + 16 + 16 + read-write + + + + + U0_CNT + 0x60 + 0x20 + + + PLUS_CNT_U0 + This register stores the current pulse count value for unit0. + 0 + 16 + read-only + + + + + U1_CNT + 0x64 + 0x20 + + + PLUS_CNT_U1 + This register stores the current pulse count value for unit1. + 0 + 16 + read-only + + + + + U2_CNT + 0x68 + 0x20 + + + PLUS_CNT_U2 + This register stores the current pulse count value for unit2. + 0 + 16 + read-only + + + + + U3_CNT + 0x6C + 0x20 + + + PLUS_CNT_U3 + This register stores the current pulse count value for unit3. + 0 + 16 + read-only + + + + + U4_CNT + 0x70 + 0x20 + + + PLUS_CNT_U4 + This register stores the current pulse count value for unit4. + 0 + 16 + read-only + + + + + U5_CNT + 0x74 + 0x20 + + + PLUS_CNT_U5 + This register stores the current pulse count value for unit5. + 0 + 16 + read-only + + + + + U6_CNT + 0x78 + 0x20 + + + PLUS_CNT_U6 + This register stores the current pulse count value for unit6. + 0 + 16 + read-only + + + + + U7_CNT + 0x7C + 0x20 + + + PLUS_CNT_U7 + This register stores the current pulse count value for unit7. + 0 + 16 + read-only + + + + + INT_RAW + 0x80 + 0x20 + + + CNT_THR_EVENT_U0_INT_RAW + This is the interrupt raw bit for channel0 event. + 0 + 1 + read-only + + + CNT_THR_EVENT_U1_INT_RAW + This is the interrupt raw bit for channel1 event. + 1 + 1 + read-only + + + CNT_THR_EVENT_U2_INT_RAW + This is the interrupt raw bit for channel2 event. + 2 + 1 + read-only + + + CNT_THR_EVENT_U3_INT_RAW + This is the interrupt raw bit for channel3 event. + 3 + 1 + read-only + + + CNT_THR_EVENT_U4_INT_RAW + This is the interrupt raw bit for channel4 event. + 4 + 1 + read-only + + + CNT_THR_EVENT_U5_INT_RAW + This is the interrupt raw bit for channel5 event. + 5 + 1 + read-only + + + CNT_THR_EVENT_U6_INT_RAW + This is the interrupt raw bit for channel6 event. + 6 + 1 + read-only + + + CNT_THR_EVENT_U7_INT_RAW + This is the interrupt raw bit for channel7 event. + 7 + 1 + read-only + + + + + INT_ST + 0x84 + 0x20 + + + CNT_THR_EVENT_U0_INT_ST + This is the interrupt status bit for channel0 event. + 0 + 1 + read-only + + + CNT_THR_EVENT_U1_INT_ST + This is the interrupt status bit for channel1 event. + 1 + 1 + read-only + + + CNT_THR_EVENT_U2_INT_ST + This is the interrupt status bit for channel2 event. + 2 + 1 + read-only + + + CNT_THR_EVENT_U3_INT_ST + This is the interrupt status bit for channel3 event. + 3 + 1 + read-only + + + CNT_THR_EVENT_U4_INT_ST + This is the interrupt status bit for channel4 event. + 4 + 1 + read-only + + + CNT_THR_EVENT_U5_INT_ST + This is the interrupt status bit for channel5 event. + 5 + 1 + read-only + + + CNT_THR_EVENT_U6_INT_ST + This is the interrupt status bit for channel6 event. + 6 + 1 + read-only + + + CNT_THR_EVENT_U7_INT_ST + This is the interrupt status bit for channel7 event. + 7 + 1 + read-only + + + + + INT_ENA + 0x88 + 0x20 + + + CNT_THR_EVENT_U0_INT_ENA + This is the interrupt enable bit for channel0 event. + 0 + 1 + read-write + + + CNT_THR_EVENT_U1_INT_ENA + This is the interrupt enable bit for channel1 event. + 1 + 1 + read-write + + + CNT_THR_EVENT_U2_INT_ENA + This is the interrupt enable bit for channel2 event. + 2 + 1 + read-write + + + CNT_THR_EVENT_U3_INT_ENA + This is the interrupt enable bit for channel3 event. + 3 + 1 + read-write + + + CNT_THR_EVENT_U4_INT_ENA + This is the interrupt enable bit for channel4 event. + 4 + 1 + read-write + + + CNT_THR_EVENT_U5_INT_ENA + This is the interrupt enable bit for channel5 event. + 5 + 1 + read-write + + + CNT_THR_EVENT_U6_INT_ENA + This is the interrupt enable bit for channel6 event. + 6 + 1 + read-write + + + CNT_THR_EVENT_U7_INT_ENA + This is the interrupt enable bit for channel7 event. + 7 + 1 + read-write + + + + + INT_CLR + 0x8C + 0x20 + + + CNT_THR_EVENT_U0_INT_CLR + Set this bit to clear channel0 event interrupt. + 0 + 1 + write-only + + + CNT_THR_EVENT_U1_INT_CLR + Set this bit to clear channel1 event interrupt. + 1 + 1 + write-only + + + CNT_THR_EVENT_U2_INT_CLR + Set this bit to clear channel2 event interrupt. + 2 + 1 + write-only + + + CNT_THR_EVENT_U3_INT_CLR + Set this bit to clear channel3 event interrupt. + 3 + 1 + write-only + + + CNT_THR_EVENT_U4_INT_CLR + Set this bit to clear channel4 event interrupt. + 4 + 1 + write-only + + + CNT_THR_EVENT_U5_INT_CLR + Set this bit to clear channel5 event interrupt. + 5 + 1 + write-only + + + CNT_THR_EVENT_U6_INT_CLR + Set this bit to clear channel6 event interrupt. + 6 + 1 + write-only + + + CNT_THR_EVENT_U7_INT_CLR + Set this bit to clear channel7 event interrupt. + 7 + 1 + write-only + + + + + U0_STATUS + 0x90 + 0x20 + + + CORE_STATUS_U0 + 0 + 32 + read-only + + + STATUS_CNT_MODE + 0 + 2 + read-write + + + STATUS_THRES1 + 2 + 1 + read-write + + + STATUS_THRES0 + 3 + 1 + read-write + + + STATUS_L_LIM + 4 + 1 + read-write + + + STATUS_H_LIM + 5 + 1 + read-write + + + STATUS_ZERO + 6 + 1 + read-write + + + + + U1_STATUS + 0x94 + 0x20 + + + CORE_STATUS_U1 + 0 + 32 + read-only + + + + + U2_STATUS + 0x98 + 0x20 + + + CORE_STATUS_U2 + 0 + 32 + read-only + + + + + U3_STATUS + 0x9C + 0x20 + + + CORE_STATUS_U3 + 0 + 32 + read-only + + + + + U4_STATUS + 0xA0 + 0x20 + + + CORE_STATUS_U4 + 0 + 32 + read-only + + + + + U5_STATUS + 0xA4 + 0x20 + + + CORE_STATUS_U5 + 0 + 32 + read-only + + + + + U6_STATUS + 0xA8 + 0x20 + + + CORE_STATUS_U6 + 0 + 32 + read-only + + + + + U7_STATUS + 0xAC + 0x20 + + + CORE_STATUS_U7 + 0 + 32 + read-only + + + + + CTRL + 0xB0 + 0x20 + 0x00005555 + + + PLUS_CNT_RST_U0 + Set this bit to clear unit0's counter. + 0 + 1 + read-write + + + CNT_PAUSE_U0 + Set this bit to pause unit0's counter. + 1 + 1 + read-write + + + PLUS_CNT_RST_U1 + Set this bit to clear unit1's counter. + 2 + 1 + read-write + + + CNT_PAUSE_U1 + Set this bit to pause unit1's counter. + 3 + 1 + read-write + + + PLUS_CNT_RST_U2 + Set this bit to clear unit2's counter. + 4 + 1 + read-write + + + CNT_PAUSE_U2 + Set this bit to pause unit2's counter. + 5 + 1 + read-write + + + PLUS_CNT_RST_U3 + Set this bit to clear unit3's counter. + 6 + 1 + read-write + + + CNT_PAUSE_U3 + Set this bit to pause unit3's counter. + 7 + 1 + read-write + + + PLUS_CNT_RST_U4 + Set this bit to clear unit4's counter. + 8 + 1 + read-write + + + CNT_PAUSE_U4 + Set this bit to pause unit4's counter. + 9 + 1 + read-write + + + PLUS_CNT_RST_U5 + Set this bit to clear unit5's counter. + 10 + 1 + read-write + + + CNT_PAUSE_U5 + Set this bit to pause unit5's counter. + 11 + 1 + read-write + + + PLUS_CNT_RST_U6 + Set this bit to clear unit6's counter. + 12 + 1 + read-write + + + CNT_PAUSE_U6 + Set this bit to pause unit6's counter. + 13 + 1 + read-write + + + PLUS_CNT_RST_U7 + Set this bit to clear unit7's counter. + 14 + 1 + read-write + + + CNT_PAUSE_U7 + Set this bit to pause unit7's counter. + 15 + 1 + read-write + + + CLK_EN + 16 + 1 + read-write + + + + + DATE + 0xFC + 0x20 + 0x14122600 + + + DATE + 0 + 32 + read-write + + + + + + + RMT + Remote Control Peripheral + RMT + 0x3FF56000 + + 0x0 + 0xF8 + registers + + + RMT + 47 + + + + CH0DATA + 0x0 + 0x20 + + + CH1DATA + 0x4 + 0x20 + + + CH2DATA + 0x8 + 0x20 + + + CH3DATA + 0xC + 0x20 + + + CH4DATA + 0x10 + 0x20 + + + CH5DATA + 0x14 + 0x20 + + + CH6DATA + 0x18 + 0x20 + + + CH7DATA + 0x1C + 0x20 + + + 8 + 0x8 + 0-7 + CH%sCONF0 + 0x20 + 0x20 + 0x31100002 + + + DIV_CNT + This register is used to configure the frequency divider's factor in channel0. + 0 + 8 + read-write + + + IDLE_THRES + In receive mode when no edge is detected on the input signal for longer than reg_idle_thres_ch0 then the receive process is done. + 8 + 16 + read-write + + + MEM_SIZE + This register is used to configure the the amount of memory blocks allocated to channel0. + 24 + 4 + read-write + + + CARRIER_EN + This is the carrier modulation enable control bit for channel0. + 28 + 1 + read-write + + + CARRIER_OUT_LV + This bit is used to configure the way carrier wave is modulated for channel0.1'b1:transmit on low output level 1'b0:transmit on high output level. + 29 + 1 + read-write + + + MEM_PD + This bit is used to reduce power consumed by mem. 1:mem is in low power state. + 30 + 1 + read-write + + + CLK_EN + This bit is used to control clock.when software config RMT internal registers it controls the register clock. + 31 + 1 + read-write + + + + + 8 + 0x8 + 0-7 + CH%sCONF1 + 0x24 + 0x20 + 0x00000F20 + + + TX_START + Set this bit to start sending data for channel0. + 0 + 1 + read-write + + + RX_EN + Set this bit to enbale receving data for channel0. + 1 + 1 + read-write + + + MEM_WR_RST + Set this bit to reset write ram address for channel0 by receiver access. + 2 + 1 + read-write + + + MEM_RD_RST + Set this bit to reset read ram address for channel0 by transmitter access. + 3 + 1 + read-write + + + APB_MEM_RST + Set this bit to reset W/R ram address for channel0 by apb fifo access + 4 + 1 + read-write + + + MEM_OWNER + This is the mark of channel0's ram usage right.1'b1:receiver uses the ram 0:transmitter uses the ram + 5 + 1 + read-write + + + TX_CONTI_MODE + Set this bit to continue sending from the first data to the last data in channel0 again and again. + 6 + 1 + read-write + + + RX_FILTER_EN + This is the receive filter enable bit for channel0. + 7 + 1 + read-write + + + RX_FILTER_THRES + in receive mode channel0 ignore input pulse when the pulse width is smaller then this value. + 8 + 8 + read-write + + + REF_CNT_RST + This bit is used to reset divider in channel0. + 16 + 1 + read-write + + + REF_ALWAYS_ON + This bit is used to select base clock. 1'b1:clk_apb 1'b0:clk_ref + 17 + 1 + read-write + + + IDLE_OUT_LV + This bit configures the output signal's level for channel0 in IDLE state. + 18 + 1 + read-write + + + IDLE_OUT_EN + This is the output enable control bit for channel0 in IDLE state. + 19 + 1 + read-write + + + + + CH0STATUS + 0x60 + 0x20 + + + STATUS + The status for channel0 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel0. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel0. + 12 + 10 + read-only + + + STATE + The channel0 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel0 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel0 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel0. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel0 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel0 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH1STATUS + 0x64 + 0x20 + + + STATUS + The status for channel1 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel1. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel1. + 12 + 10 + read-only + + + STATE + The channel1 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel1 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel1 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel1. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel1 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel1 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH2STATUS + 0x68 + 0x20 + + + STATUS + The status for channel2 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel2. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel2. + 12 + 10 + read-only + + + STATE + The channel2 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel2 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel2 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel2. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel2 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel2 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH3STATUS + 0x6C + 0x20 + + + STATUS + The status for channel3 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel3. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel3. + 12 + 10 + read-only + + + STATE + The channel3 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel3 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel3 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel3. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel3 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel3 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH4STATUS + 0x70 + 0x20 + + + STATUS + The status for channel4 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel4. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel4. + 12 + 10 + read-only + + + STATE + The channel4 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel4 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel4 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel4. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel4 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel4 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH5STATUS + 0x74 + 0x20 + + + STATUS + The status for channel5 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel5. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel5. + 12 + 10 + read-only + + + STATE + The channel5 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel5 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel5 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel5. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel5 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel5 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH6STATUS + 0x78 + 0x20 + + + STATUS + The status for channel6 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel6. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel6. + 12 + 10 + read-only + + + STATE + The channel6 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel6 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel6 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel6. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel6 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel6 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH7STATUS + 0x7C + 0x20 + + + STATUS + The status for channel7 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel7. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel7. + 12 + 10 + read-only + + + STATE + The channel7 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel7 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel7 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel7. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel7 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel7 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH0ADDR + 0x80 + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel0 by apb fifo access + 0 + 32 + read-only + + + + + CH1ADDR + 0x84 + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel1 by apb fifo access + 0 + 32 + read-only + + + + + CH2ADDR + 0x88 + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel2 by apb fifo access + 0 + 32 + read-only + + + + + CH3ADDR + 0x8C + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel3 by apb fifo access + 0 + 32 + read-only + + + + + CH4ADDR + 0x90 + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel4 by apb fifo access + 0 + 32 + read-only + + + + + CH5ADDR + 0x94 + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel5 by apb fifo access + 0 + 32 + read-only + + + + + CH6ADDR + 0x98 + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel6 by apb fifo access + 0 + 32 + read-only + + + + + CH7ADDR + 0x9C + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel7 by apb fifo access + 0 + 32 + read-only + + + + + INT_RAW + 0xA0 + 0x20 + + + 8 + 0x3 + 0-7 + CH%s_TX_END_INT_RAW + The interrupt raw bit for channel %s turns to high level when the transmit process is done. + 0 + 1 + read-only + + + 8 + 0x3 + 0-7 + CH%s_RX_END_INT_RAW + The interrupt raw bit for channel %s turns to high level when the receive process is done. + 1 + 1 + read-only + + + 8 + 0x3 + 0-7 + CH%s_ERR_INT_RAW + The interrupt raw bit for channel %s turns to high level when channle %s detects some errors. + 2 + 1 + read-only + + + 8 + 0x1 + 0-7 + CH%s_TX_THR_EVENT_INT_RAW + The interrupt raw bit for channel %s turns to high level when transmitter in channle%s have send datas more than reg_rmt_tx_lim_ch%s after detecting this interrupt software can updata the old datas with new datas. + 24 + 1 + read-only + + + + + INT_ST + 0xA4 + 0x20 + + + 8 + 0x3 + 0-7 + CH%s_TX_END_INT_ST + The interrupt state bit for channel %s's mt_ch%s_tx_end_int_raw when mt_ch%s_tx_end_int_ena is set to %s. + 0 + 1 + read-only + + + 8 + 0x3 + 0-7 + CH%s_RX_END_INT_ST + The interrupt state bit for channel %s's rmt_ch%s_rx_end_int_raw when rmt_ch%s_rx_end_int_ena is set to %s. + 1 + 1 + read-only + + + 8 + 0x3 + 0-7 + CH%s_ERR_INT_ST + The interrupt state bit for channel %s's rmt_ch%s_err_int_raw when rmt_ch%s_err_int_ena is set to %s. + 2 + 1 + read-only + + + 8 + 0x1 + 0-7 + CH%s_TX_THR_EVENT_INT_ST + The interrupt state bit for channel %s's rmt_ch%s_tx_thr_event_int_raw when mt_ch%s_tx_thr_event_int_ena is set to 1. + 24 + 1 + read-only + + + + + INT_ENA + 0xA8 + 0x20 + + + 8 + 0x3 + 0-7 + CH%s_TX_END_INT_ENA + Set this bit to enable rmt_ch%s_tx_end_int_st. + 0 + 1 + read-write + + + 8 + 0x3 + 0-7 + CH%s_RX_END_INT_ENA + Set this bit to enable rmt_ch%s_rx_end_int_st. + 1 + 1 + read-write + + + 8 + 0x3 + 0-7 + CH%s_ERR_INT_ENA + Set this bit to enable rmt_ch%s_err_int_st. + 2 + 1 + read-write + + + 8 + 0x1 + 0-7 + CH%s_TX_THR_EVENT_INT_ENA + Set this bit to enable rmt_ch%s_tx_thr_event_int_st. + 24 + 1 + read-write + + + + + INT_CLR + 0xAC + 0x20 + + + 8 + 0x3 + 0-7 + CH%s_TX_END_INT_CLR + Set this bit to clear the rmt_ch%s_rx_end_int_raw.. + 0 + 1 + write-only + + + 8 + 0x3 + 0-7 + CH%s_RX_END_INT_CLR + Set this bit to clear the rmt_ch%s_tx_end_int_raw. + 1 + 1 + write-only + + + 8 + 0x3 + 0-7 + CH%s_ERR_INT_CLR + Set this bit to clear the rmt_ch%s_err_int_raw. + 2 + 1 + write-only + + + 8 + 0x1 + 0-7 + CH%s_TX_THR_EVENT_INT_CLR + Set this bit to clear the rmt_ch%s_tx_thr_event_int_raw interrupt. + 24 + 1 + write-only + + + + + CH0CARRIER_DUTY + 0xB0 + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel0. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel0. + 16 + 16 + read-write + + + + + CH1CARRIER_DUTY + 0xB4 + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel1. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel1. + 16 + 16 + read-write + + + + + CH2CARRIER_DUTY + 0xB8 + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel2. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel2. + 16 + 16 + read-write + + + + + CH3CARRIER_DUTY + 0xBC + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel3. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel3. + 16 + 16 + read-write + + + + + CH4CARRIER_DUTY + 0xC0 + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel4. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel4. + 16 + 16 + read-write + + + + + CH5CARRIER_DUTY + 0xC4 + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel5. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel5. + 16 + 16 + read-write + + + + + CH6CARRIER_DUTY + 0xC8 + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel6. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel6. + 16 + 16 + read-write + + + + + CH7CARRIER_DUTY + 0xCC + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel7. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel7. + 16 + 16 + read-write + + + + + 8 + 0x4 + 0-7 + CH%s_TX_LIM + 0xD0 + 0x20 + 0x00000080 + + + TX_LIM + When channel0 sends more than reg_rmt_tx_lim_ch0 datas then channel0 produce the relative interrupt. + 0 + 9 + read-write + + + + + APB_CONF + 0xF0 + 0x20 + + + APB_FIFO_MASK + Set this bit to disable apb fifo access + 0 + 1 + read-write + + + MEM_TX_WRAP_EN + when datas need to be send is more than channel's mem can store then set this bit to enable reusage of mem this bit is used together with reg_rmt_tx_lim_chn. + 1 + 1 + read-write + + + + + DATE + 0xFC + 0x20 + 0x16022600 + + + DATE + This is the version register. + 0 + 32 + read-write + + + + + + + RNG + Hardware random number generator + RNG + 0x60035000 + + 0x0 + 0x4 + registers + + + + DATA + Random number data + 0x144 + 0x20 + + + + + RSA + RSA (Rivest Shamir Adleman) Accelerator + RSA + 0x3FF02000 + + 0x0 + 0x1C + registers + + + RSA + 51 + + + + M_PRIME + 0x0 + 0x20 + + + M_PRIME + This register contains M’. + 0 + 8 + read-write + + + + + MODEXP_MODE + 0x4 + 0x20 + + + MODEXP_MODE + This register contains the mode of modular exponentiation. + 0 + 2 + read-write + + + + + MODEXP_START + 0x8 + 0x20 + + + MODEXP_START + Write 1 to start modular exponentiation. + 0 + 1 + write-only + + + + + MULT_MODE + 0xC + 0x20 + + + MULT_MODE + This register contains the mode of modular multiplication and multiplication. + 0 + 1 + read-write + + + + + MULT_START + 0x10 + 0x20 + + + MULT_START + Write 1 to start modular multiplication or multiplication. + 0 + 1 + write-only + + + + + INTERRUPT + 0x14 + 0x20 + + + INTERRUPT + RSA interrupt status register. Will read 1 once an operation has completed. + 0 + 1 + read-write + + + + + CLEAN + 0x18 + 0x20 + + + CLEAN + This bit will read 1 once the memory initialization is completed. + 0 + 1 + read-only + + + + + + + RTC_CNTL + Real-Time Clock Control + RTC_CNTL + 0x3FF48000 + + 0x0 + 0xDC + registers + + + RTC_CORE + 46 + + + + OPTIONS0 + 0x0 + 0x20 + 0x1C492000 + + + SW_STALL_APPCPU_C0 + {reg_sw_stall_appcpu_c1[5:0] reg_sw_stall_appcpu_c0[1:0]} == 0x86 will stall APP CPU + 0 + 2 + read-write + + + SW_STALL_PROCPU_C0 + {reg_sw_stall_procpu_c1[5:0] reg_sw_stall_procpu_c0[1:0]} == 0x86 will stall PRO CPU + 2 + 2 + read-write + + + SW_APPCPU_RST + APP CPU SW reset + 4 + 1 + write-only + + + SW_PROCPU_RST + PRO CPU SW reset + 5 + 1 + write-only + + + BB_I2C_FORCE_PD + BB_I2C force power down + 6 + 1 + read-write + + + BB_I2C_FORCE_PU + BB_I2C force power up + 7 + 1 + read-write + + + BBPLL_I2C_FORCE_PD + BB_PLL _I2C force power down + 8 + 1 + read-write + + + BBPLL_I2C_FORCE_PU + BB_PLL_I2C force power up + 9 + 1 + read-write + + + BBPLL_FORCE_PD + BB_PLL force power down + 10 + 1 + read-write + + + BBPLL_FORCE_PU + BB_PLL force power up + 11 + 1 + read-write + + + XTL_FORCE_PD + crystall force power down + 12 + 1 + read-write + + + XTL_FORCE_PU + crystall force power up + 13 + 1 + read-write + + + BIAS_SLEEP_FOLW_8M + BIAS_SLEEP follow CK8M + 14 + 1 + read-write + + + BIAS_FORCE_SLEEP + BIAS_SLEEP force sleep + 15 + 1 + read-write + + + BIAS_FORCE_NOSLEEP + BIAS_SLEEP force no sleep + 16 + 1 + read-write + + + BIAS_I2C_FOLW_8M + BIAS_I2C follow CK8M + 17 + 1 + read-write + + + BIAS_I2C_FORCE_PD + BIAS_I2C force power down + 18 + 1 + read-write + + + BIAS_I2C_FORCE_PU + BIAS_I2C force power up + 19 + 1 + read-write + + + BIAS_CORE_FOLW_8M + BIAS_CORE follow CK8M + 20 + 1 + read-write + + + BIAS_CORE_FORCE_PD + BIAS_CORE force power down + 21 + 1 + read-write + + + BIAS_CORE_FORCE_PU + BIAS_CORE force power up + 22 + 1 + read-write + + + XTL_FORCE_ISO + 23 + 1 + read-write + + + PLL_FORCE_ISO + 24 + 1 + read-write + + + ANALOG_FORCE_ISO + 25 + 1 + read-write + + + XTL_FORCE_NOISO + 26 + 1 + read-write + + + PLL_FORCE_NOISO + 27 + 1 + read-write + + + ANALOG_FORCE_NOISO + 28 + 1 + read-write + + + DG_WRAP_FORCE_RST + digital wrap force reset in deep sleep + 29 + 1 + read-write + + + DG_WRAP_FORCE_NORST + digital core force no reset in deep sleep + 30 + 1 + read-write + + + SW_SYS_RST + SW system reset + 31 + 1 + write-only + + + + + SLP_TIMER0 + 0x4 + 0x20 + + + SLP_VAL_LO + RTC sleep timer low 32 bits + 0 + 32 + read-write + + + + + SLP_TIMER1 + 0x8 + 0x20 + + + SLP_VAL_HI + RTC sleep timer high 16 bits + 0 + 16 + read-write + + + MAIN_TIMER_ALARM_EN + timer alarm enable bit + 16 + 1 + read-write + + + + + TIME_UPDATE + 0xC + 0x20 + + + TIME_VALID + To indicate the register is updated + 30 + 1 + read-only + + + TIME_UPDATE + Set 1: to update register with RTC timer + 31 + 1 + write-only + + + + + TIME0 + 0x10 + 0x20 + + + TIME_LO + RTC timer low 32 bits + 0 + 32 + read-only + + + + + TIME1 + 0x14 + 0x20 + + + TIME_HI + RTC timer high 16 bits + 0 + 16 + read-only + + + + + STATE0 + 0x18 + 0x20 + 0x00300000 + + + TOUCH_WAKEUP_FORCE_EN + touch controller force wake up + 20 + 1 + read-write + + + ULP_CP_WAKEUP_FORCE_EN + ULP-coprocessor force wake up + 21 + 1 + read-write + + + APB2RTC_BRIDGE_SEL + 1: APB to RTC using bridge 0: APB to RTC using sync + 22 + 1 + read-write + + + TOUCH_SLP_TIMER_EN + touch timer enable bit + 23 + 1 + read-write + + + ULP_CP_SLP_TIMER_EN + ULP-coprocessor timer enable bit + 24 + 1 + read-write + + + SDIO_ACTIVE_IND + SDIO active indication + 28 + 1 + read-only + + + SLP_WAKEUP + sleep wakeup bit + 29 + 1 + read-write + + + SLP_REJECT + sleep reject bit + 30 + 1 + read-write + + + SLEEP_EN + sleep enable bit + 31 + 1 + read-write + + + + + TIMER1 + 0x1C + 0x20 + 0x28140403 + + + CPU_STALL_EN + CPU stall enable bit + 0 + 1 + read-write + + + CPU_STALL_WAIT + CPU stall wait cycles in fast_clk_rtc + 1 + 5 + read-write + + + CK8M_WAIT + CK8M wait cycles in slow_clk_rtc + 6 + 8 + read-write + + + XTL_BUF_WAIT + XTAL wait cycles in slow_clk_rtc + 14 + 10 + read-write + + + PLL_BUF_WAIT + PLL wait cycles in slow_clk_rtc + 24 + 8 + read-write + + + + + TIMER2 + 0x20 + 0x20 + 0x01080000 + + + ULPCP_TOUCH_START_WAIT + wait cycles in slow_clk_rtc before ULP-coprocessor / touch controller start to work + 15 + 9 + read-write + + + MIN_TIME_CK8M_OFF + minimal cycles in slow_clk_rtc for CK8M in power down state + 24 + 8 + read-write + + + + + TIMER3 + 0x24 + 0x20 + 0x14160A08 + + + WIFI_WAIT_TIMER + 0 + 9 + read-write + + + WIFI_POWERUP_TIMER + 9 + 7 + read-write + + + ROM_RAM_WAIT_TIMER + 16 + 9 + read-write + + + ROM_RAM_POWERUP_TIMER + 25 + 7 + read-write + + + + + TIMER4 + 0x28 + 0x20 + 0x10200A08 + + + WAIT_TIMER + 0 + 9 + read-write + + + POWERUP_TIMER + 9 + 7 + read-write + + + DG_WRAP_WAIT_TIMER + 16 + 9 + read-write + + + DG_WRAP_POWERUP_TIMER + 25 + 7 + read-write + + + + + TIMER5 + 0x2C + 0x20 + 0x12148001 + + + ULP_CP_SUBTIMER_PREDIV + 0 + 8 + read-write + + + MIN_SLP_VAL + minimal sleep cycles in slow_clk_rtc + 8 + 8 + read-write + + + RTCMEM_WAIT_TIMER + 16 + 9 + read-write + + + RTCMEM_POWERUP_TIMER + 25 + 7 + read-write + + + + + ANA_CONF + 0x30 + 0x20 + 0x00800000 + + + PLLA_FORCE_PD + PLLA force power down + 23 + 1 + read-write + + + PLLA_FORCE_PU + PLLA force power up + 24 + 1 + read-write + + + BBPLL_CAL_SLP_START + start BBPLL calibration during sleep + 25 + 1 + read-write + + + PVTMON_PU + 1: PVTMON power up otherwise power down + 26 + 1 + read-write + + + TXRF_I2C_PU + 1: TXRF_I2C power up otherwise power down + 27 + 1 + read-write + + + RFRX_PBUS_PU + 1: RFRX_PBUS power up otherwise power down + 28 + 1 + read-write + + + CKGEN_I2C_PU + 1: CKGEN_I2C power up otherwise power down + 30 + 1 + read-write + + + PLL_I2C_PU + 1: PLL_I2C power up otherwise power down + 31 + 1 + read-write + + + + + RESET_STATE + 0x34 + 0x20 + 0x00003000 + + + RESET_CAUSE_PROCPU + reset cause of PRO CPU + 0 + 6 + read-only + + + RESET_CAUSE_APPCPU + reset cause of APP CPU + 6 + 6 + read-only + + + APPCPU_STAT_VECTOR_SEL + APP CPU state vector sel + 12 + 1 + read-write + + + PROCPU_STAT_VECTOR_SEL + PRO CPU state vector sel + 13 + 1 + read-write + + + + + WAKEUP_STATE + 0x38 + 0x20 + 0x00006000 + + + WAKEUP_CAUSE + wakeup cause + 0 + 11 + read-only + + + WAKEUP_ENA + wakeup enable bitmap + 11 + 11 + read-write + + + GPIO_WAKEUP_FILTER + enable filter for gpio wakeup event + 22 + 1 + read-write + + + + + INT_ENA + 0x3C + 0x20 + + + SLP_WAKEUP_INT_ENA + enable sleep wakeup interrupt + 0 + 1 + read-write + + + SLP_REJECT_INT_ENA + enable sleep reject interrupt + 1 + 1 + read-write + + + SDIO_IDLE_INT_ENA + enable SDIO idle interrupt + 2 + 1 + read-write + + + WDT_INT_ENA + enable RTC WDT interrupt + 3 + 1 + read-write + + + TIME_VALID_INT_ENA + enable RTC time valid interrupt + 4 + 1 + read-write + + + ULP_CP_INT_ENA + enable ULP-coprocessor interrupt + 5 + 1 + read-write + + + TOUCH_INT_ENA + enable touch interrupt + 6 + 1 + read-write + + + BROWN_OUT_INT_ENA + enable brown out interrupt + 7 + 1 + read-write + + + MAIN_TIMER_INT_ENA + enable RTC main timer interrupt + 8 + 1 + read-write + + + + + INT_RAW + 0x40 + 0x20 + + + SLP_WAKEUP_INT_RAW + sleep wakeup interrupt raw + 0 + 1 + read-only + + + SLP_REJECT_INT_RAW + sleep reject interrupt raw + 1 + 1 + read-only + + + SDIO_IDLE_INT_RAW + SDIO idle interrupt raw + 2 + 1 + read-only + + + WDT_INT_RAW + RTC WDT interrupt raw + 3 + 1 + read-only + + + TIME_VALID_INT_RAW + RTC time valid interrupt raw + 4 + 1 + read-only + + + ULP_CP_INT_RAW + ULP-coprocessor interrupt raw + 5 + 1 + read-only + + + TOUCH_INT_RAW + touch interrupt raw + 6 + 1 + read-only + + + BROWN_OUT_INT_RAW + brown out interrupt raw + 7 + 1 + read-only + + + MAIN_TIMER_INT_RAW + RTC main timer interrupt raw + 8 + 1 + read-only + + + + + INT_ST + 0x44 + 0x20 + + + SLP_WAKEUP_INT_ST + sleep wakeup interrupt state + 0 + 1 + read-only + + + SLP_REJECT_INT_ST + sleep reject interrupt state + 1 + 1 + read-only + + + SDIO_IDLE_INT_ST + SDIO idle interrupt state + 2 + 1 + read-only + + + WDT_INT_ST + RTC WDT interrupt state + 3 + 1 + read-only + + + TIME_VALID_INT_ST + RTC time valid interrupt state + 4 + 1 + read-only + + + SAR_INT_ST + ULP-coprocessor interrupt state + 5 + 1 + read-only + + + TOUCH_INT_ST + touch interrupt state + 6 + 1 + read-only + + + BROWN_OUT_INT_ST + brown out interrupt state + 7 + 1 + read-only + + + MAIN_TIMER_INT_ST + RTC main timer interrupt state + 8 + 1 + read-only + + + + + INT_CLR + 0x48 + 0x20 + + + SLP_WAKEUP_INT_CLR + Clear sleep wakeup interrupt state + 0 + 1 + write-only + + + SLP_REJECT_INT_CLR + Clear sleep reject interrupt state + 1 + 1 + write-only + + + SDIO_IDLE_INT_CLR + Clear SDIO idle interrupt state + 2 + 1 + write-only + + + WDT_INT_CLR + Clear RTC WDT interrupt state + 3 + 1 + write-only + + + TIME_VALID_INT_CLR + Clear RTC time valid interrupt state + 4 + 1 + write-only + + + SAR_INT_CLR + Clear ULP-coprocessor interrupt state + 5 + 1 + write-only + + + TOUCH_INT_CLR + Clear touch interrupt state + 6 + 1 + write-only + + + BROWN_OUT_INT_CLR + Clear brown out interrupt state + 7 + 1 + write-only + + + MAIN_TIMER_INT_CLR + Clear RTC main timer interrupt state + 8 + 1 + write-only + + + + + STORE0 + 0x4C + 0x20 + + + SCRATCH0 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + STORE1 + 0x50 + 0x20 + + + SCRATCH1 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + STORE2 + 0x54 + 0x20 + + + SCRATCH2 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + STORE3 + 0x58 + 0x20 + + + SCRATCH3 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + EXT_XTL_CONF + 0x5C + 0x20 + + + XTL_EXT_CTR_LV + 0: power down XTAL at high level 1: power down XTAL at low level + 30 + 1 + read-write + + + XTL_EXT_CTR_EN + enable control XTAL by external pads + 31 + 1 + read-write + + + + + EXT_WAKEUP_CONF + 0x60 + 0x20 + + + EXT_WAKEUP0_LV + 0: external wakeup at low level 1: external wakeup at high level + 30 + 1 + read-write + + + EXT_WAKEUP1_LV + 0: external wakeup at low level 1: external wakeup at high level + 31 + 1 + read-write + + + + + SLP_REJECT_CONF + 0x64 + 0x20 + + + GPIO_REJECT_EN + enable GPIO reject + 24 + 1 + read-write + + + SDIO_REJECT_EN + enable SDIO reject + 25 + 1 + read-write + + + LIGHT_SLP_REJECT_EN + enable reject for light sleep + 26 + 1 + read-write + + + DEEP_SLP_REJECT_EN + enable reject for deep sleep + 27 + 1 + read-write + + + REJECT_CAUSE + sleep reject cause + 28 + 4 + read-only + + + + + CPU_PERIOD_CONF + 0x68 + 0x20 + + + CPUSEL_CONF + CPU sel option + 29 + 1 + read-write + + + CPUPERIOD_SEL + CPU period sel + 30 + 2 + read-write + + + + + SDIO_ACT_CONF + 0x6C + 0x20 + + + SDIO_ACT_DNUM + 22 + 10 + read-write + + + + + CLK_CONF + 0x70 + 0x20 + 0x00002210 + + + CK8M_DIV + CK8M_D256_OUT divider. 00: div128 01: div256 10: div512 11: div1024. + 4 + 2 + read-write + + CK8M_DIV + read-write + + DIV128 + DIV128 + 0 + + + DIV256 + DIV256 + 1 + + + DIV512 + DIV512 + 2 + + + DIV1024 + DIV1024 + 3 + + + + + ENB_CK8M + disable CK8M and CK8M_D256_OUT + 6 + 1 + read-write + + + ENB_CK8M_DIV + 1: CK8M_D256_OUT is actually CK8M 0: CK8M_D256_OUT is CK8M divided by 256 + 7 + 1 + read-write + + ENB_CK8M_DIV + read-write + + CK8M_DIV_256 + CK8M_DIV_256 + 0 + + + CK8M + CK8M + 1 + + + + + DIG_XTAL32K_EN + enable CK_XTAL_32K for digital core (no relationship with RTC core) + 8 + 1 + read-write + + + DIG_CLK8M_D256_EN + enable CK8M_D256_OUT for digital core (no relationship with RTC core) + 9 + 1 + read-write + + + DIG_CLK8M_EN + enable CK8M for digital core (no relationship with RTC core) + 10 + 1 + read-write + + + CK8M_DFREQ_FORCE + 11 + 1 + read-write + + + CK8M_DIV_SEL + divider = reg_ck8m_div_sel + 1 + 12 + 3 + read-write + + + XTAL_FORCE_NOGATING + XTAL force no gating during sleep + 15 + 1 + read-write + + + CK8M_FORCE_NOGATING + CK8M force no gating during sleep + 16 + 1 + read-write + + + CK8M_DFREQ + CK8M_DFREQ + 17 + 8 + read-write + + + CK8M_FORCE_PD + CK8M force power down + 25 + 1 + read-write + + + CK8M_FORCE_PU + CK8M force power up + 26 + 1 + read-write + + + SOC_CLK_SEL + SOC clock sel. 0: XTAL 1: PLL 2: CK8M 3: APLL + 27 + 2 + read-write + + SOC_CLK_SEL + read-write + + XTAL + XTAL + 0 + + + PLL + PLL + 1 + + + CK8M + CK8M + 2 + + + APLL + APLL + 3 + + + + + FAST_CLK_RTC_SEL + fast_clk_rtc sel. 0: XTAL div 4 1: CK8M + 29 + 1 + read-write + + FAST_CLK_RTC_SEL + read-write + + XTAL_DIV_4 + XTAL_DIV_4 + 0 + + + CK8M + CK8M + 1 + + + + + ANA_CLK_RTC_SEL + slow_clk_rtc sel. 0: SLOW_CK 1: CK_XTAL_32K 2: CK8M_D256_OUT + 30 + 2 + read-write + + ANA_CLK_RTC_SEL + read-write + + SLOW_CK + SLOW_CK + 0 + + + CK_XTAL_32K + CK_XTAL_32K + 1 + + + CK8M_D256_OUT + CK8M_D256_OUT + 2 + + + + + + + SDIO_CONF + 0x74 + 0x20 + 0x02A00000 + + + SDIO_PD_EN + power down SDIO_REG in sleep. Only active when reg_sdio_force = 0 + 21 + 1 + read-write + + + SDIO_FORCE + 1: use SW option to control SDIO_REG 0: use state machine + 22 + 1 + read-write + + + SDIO_TIEH + SW option for SDIO_TIEH. Only active when reg_sdio_force = 1 + 23 + 1 + read-write + + + REG1P8_READY + read only register for REG1P8_READY + 24 + 1 + read-only + + + DREFL_SDIO + SW option for DREFL_SDIO. Only active when reg_sdio_force = 1 + 25 + 2 + read-write + + + DREFM_SDIO + SW option for DREFM_SDIO. Only active when reg_sdio_force = 1 + 27 + 2 + read-write + + + DREFH_SDIO + SW option for DREFH_SDIO. Only active when reg_sdio_force = 1 + 29 + 2 + read-write + + + XPD_SDIO + SW option for XPD_SDIO_REG. Only active when reg_sdio_force = 1 + 31 + 1 + read-write + + + + + BIAS_CONF + 0x78 + 0x20 + + + DBG_ATTEN + DBG_ATTEN + 24 + 2 + read-write + + + ENB_SCK_XTAL + ENB_SCK_XTAL + 26 + 1 + read-write + + + INC_HEARTBEAT_REFRESH + INC_HEARTBEAT_REFRESH + 27 + 1 + read-write + + + DEC_HEARTBEAT_PERIOD + DEC_HEARTBEAT_PERIOD + 28 + 1 + read-write + + + INC_HEARTBEAT_PERIOD + INC_HEARTBEAT_PERIOD + 29 + 1 + read-write + + + DEC_HEARTBEAT_WIDTH + DEC_HEARTBEAT_WIDTH + 30 + 1 + read-write + + + RST_BIAS_I2C + RST_BIAS_I2C + 31 + 1 + read-write + + + + + REG + 0x7C + 0x20 + 0x29002400 + + + SCK_DCAP_FORCE + N/A + 7 + 1 + read-write + + + DIG_DBIAS_SLP + DIG_REG_DBIAS during sleep + 8 + 3 + read-write + + + DIG_DBIAS_WAK + DIG_REG_DBIAS during wakeup + 11 + 3 + read-write + + + SCK_DCAP + SCK_DCAP + 14 + 8 + read-write + + + DBIAS_SLP + RTC_DBIAS during sleep + 22 + 3 + read-write + + + DBIAS_WAK + RTC_DBIAS during wakeup + 25 + 3 + read-write + + + DBOOST_FORCE_PD + RTC_DBOOST force power down + 28 + 1 + read-write + + + DBOOST_FORCE_PU + RTC_DBOOST force power up + 29 + 1 + read-write + + + FORCE_PD + RTC_REG force power down (for RTC_REG power down means decrease the voltage to 0.8v or lower ) + 30 + 1 + read-write + + + FORCE_PU + RTC_REG force power up + 31 + 1 + read-write + + + + + PWC + 0x80 + 0x20 + 0x00012925 + + + FASTMEM_FORCE_NOISO + Fast RTC memory force no ISO + 0 + 1 + read-write + + + FASTMEM_FORCE_ISO + Fast RTC memory force ISO + 1 + 1 + read-write + + + SLOWMEM_FORCE_NOISO + RTC memory force no ISO + 2 + 1 + read-write + + + SLOWMEM_FORCE_ISO + RTC memory force ISO + 3 + 1 + read-write + + + FORCE_ISO + rtc_peri force ISO + 4 + 1 + read-write + + + FORCE_NOISO + rtc_peri force no ISO + 5 + 1 + read-write + + + FASTMEM_FOLW_CPU + 1: Fast RTC memory PD following CPU 0: fast RTC memory PD following RTC state machine + 6 + 1 + read-write + + + FASTMEM_FORCE_LPD + Fast RTC memory force PD + 7 + 1 + read-write + + + FASTMEM_FORCE_LPU + Fast RTC memory force no PD + 8 + 1 + read-write + + + SLOWMEM_FOLW_CPU + 1: RTC memory PD following CPU 0: RTC memory PD following RTC state machine + 9 + 1 + read-write + + + SLOWMEM_FORCE_LPD + RTC memory force PD + 10 + 1 + read-write + + + SLOWMEM_FORCE_LPU + RTC memory force no PD + 11 + 1 + read-write + + + FASTMEM_FORCE_PD + Fast RTC memory force power down + 12 + 1 + read-write + + + FASTMEM_FORCE_PU + Fast RTC memory force power up + 13 + 1 + read-write + + + FASTMEM_PD_EN + enable power down fast RTC memory in sleep + 14 + 1 + read-write + + + SLOWMEM_FORCE_PD + RTC memory force power down + 15 + 1 + read-write + + + SLOWMEM_FORCE_PU + RTC memory force power up + 16 + 1 + read-write + + + SLOWMEM_PD_EN + enable power down RTC memory in sleep + 17 + 1 + read-write + + + FORCE_PD + rtc_peri force power down + 18 + 1 + read-write + + + FORCE_PU + rtc_peri force power up + 19 + 1 + read-write + + + PD_EN + enable power down rtc_peri in sleep + 20 + 1 + read-write + + + + + DIG_PWC + 0x84 + 0x20 + 0x00155550 + + + LSLP_MEM_FORCE_PD + memories in digital core force PD in sleep + 3 + 1 + read-write + + + LSLP_MEM_FORCE_PU + memories in digital core force no PD in sleep + 4 + 1 + read-write + + + ROM0_FORCE_PD + ROM force power down + 5 + 1 + read-write + + + ROM0_FORCE_PU + ROM force power up + 6 + 1 + read-write + + + INTER_RAM0_FORCE_PD + internal SRAM 0 force power down + 7 + 1 + read-write + + + INTER_RAM0_FORCE_PU + internal SRAM 0 force power up + 8 + 1 + read-write + + + INTER_RAM1_FORCE_PD + internal SRAM 1 force power down + 9 + 1 + read-write + + + INTER_RAM1_FORCE_PU + internal SRAM 1 force power up + 10 + 1 + read-write + + + INTER_RAM2_FORCE_PD + internal SRAM 2 force power down + 11 + 1 + read-write + + + INTER_RAM2_FORCE_PU + internal SRAM 2 force power up + 12 + 1 + read-write + + + INTER_RAM3_FORCE_PD + internal SRAM 3 force power down + 13 + 1 + read-write + + + INTER_RAM3_FORCE_PU + internal SRAM 3 force power up + 14 + 1 + read-write + + + INTER_RAM4_FORCE_PD + internal SRAM 4 force power down + 15 + 1 + read-write + + + INTER_RAM4_FORCE_PU + internal SRAM 4 force power up + 16 + 1 + read-write + + + WIFI_FORCE_PD + wifi force power down + 17 + 1 + read-write + + + WIFI_FORCE_PU + wifi force power up + 18 + 1 + read-write + + + DG_WRAP_FORCE_PD + digital core force power down + 19 + 1 + read-write + + + DG_WRAP_FORCE_PU + digital core force power up + 20 + 1 + read-write + + + ROM0_PD_EN + enable power down ROM in sleep + 24 + 1 + read-write + + + INTER_RAM0_PD_EN + enable power down internal SRAM 0 in sleep + 25 + 1 + read-write + + + INTER_RAM1_PD_EN + enable power down internal SRAM 1 in sleep + 26 + 1 + read-write + + + INTER_RAM2_PD_EN + enable power down internal SRAM 2 in sleep + 27 + 1 + read-write + + + INTER_RAM3_PD_EN + enable power down internal SRAM 3 in sleep + 28 + 1 + read-write + + + INTER_RAM4_PD_EN + enable power down internal SRAM 4 in sleep + 29 + 1 + read-write + + + WIFI_PD_EN + enable power down wifi in sleep + 30 + 1 + read-write + + + DG_WRAP_PD_EN + enable power down digital core in sleep + 31 + 1 + read-write + + + + + DIG_ISO + 0x88 + 0x20 + 0xAAAA5000 + + + FORCE_OFF + 7 + 1 + read-write + + + FORCE_ON + 8 + 1 + read-write + + + DG_PAD_AUTOHOLD + read only register to indicate digital pad auto-hold status + 9 + 1 + read-only + + + CLR_DG_PAD_AUTOHOLD + wtite only register to clear digital pad auto-hold + 10 + 1 + write-only + + + DG_PAD_AUTOHOLD_EN + digital pad enable auto-hold + 11 + 1 + read-write + + + DG_PAD_FORCE_NOISO + digital pad force no ISO + 12 + 1 + read-write + + + DG_PAD_FORCE_ISO + digital pad force ISO + 13 + 1 + read-write + + + DG_PAD_FORCE_UNHOLD + digital pad force un-hold + 14 + 1 + read-write + + + DG_PAD_FORCE_HOLD + digital pad force hold + 15 + 1 + read-write + + + ROM0_FORCE_ISO + ROM force ISO + 16 + 1 + read-write + + + ROM0_FORCE_NOISO + ROM force no ISO + 17 + 1 + read-write + + + INTER_RAM0_FORCE_ISO + internal SRAM 0 force ISO + 18 + 1 + read-write + + + INTER_RAM0_FORCE_NOISO + internal SRAM 0 force no ISO + 19 + 1 + read-write + + + INTER_RAM1_FORCE_ISO + internal SRAM 1 force ISO + 20 + 1 + read-write + + + INTER_RAM1_FORCE_NOISO + internal SRAM 1 force no ISO + 21 + 1 + read-write + + + INTER_RAM2_FORCE_ISO + internal SRAM 2 force ISO + 22 + 1 + read-write + + + INTER_RAM2_FORCE_NOISO + internal SRAM 2 force no ISO + 23 + 1 + read-write + + + INTER_RAM3_FORCE_ISO + internal SRAM 3 force ISO + 24 + 1 + read-write + + + INTER_RAM3_FORCE_NOISO + internal SRAM 3 force no ISO + 25 + 1 + read-write + + + INTER_RAM4_FORCE_ISO + internal SRAM 4 force ISO + 26 + 1 + read-write + + + INTER_RAM4_FORCE_NOISO + internal SRAM 4 force no ISO + 27 + 1 + read-write + + + WIFI_FORCE_ISO + wifi force ISO + 28 + 1 + read-write + + + WIFI_FORCE_NOISO + wifi force no ISO + 29 + 1 + read-write + + + DG_WRAP_FORCE_ISO + digital core force ISO + 30 + 1 + read-write + + + DG_WRAP_FORCE_NOISO + digital core force no ISO + 31 + 1 + read-write + + + + + WDTCONFIG0 + 0x8C + 0x20 + 0x00004C80 + + + WDT_PAUSE_IN_SLP + pause WDT in sleep + 7 + 1 + read-write + + + WDT_APPCPU_RESET_EN + enable WDT reset APP CPU + 8 + 1 + read-write + + + WDT_PROCPU_RESET_EN + enable WDT reset PRO CPU + 9 + 1 + read-write + + + WDT_FLASHBOOT_MOD_EN + enable WDT in flash boot + 10 + 1 + read-write + + + WDT_SYS_RESET_LENGTH + system reset counter length + 11 + 3 + read-write + + + WDT_CPU_RESET_LENGTH + CPU reset counter length + 14 + 3 + read-write + + + WDT_LEVEL_INT_EN + N/A + 17 + 1 + read-write + + + WDT_EDGE_INT_EN + N/A + 18 + 1 + read-write + + + WDT_STG3 + 1: interrupt stage en 2: CPU reset stage en 3: system reset stage en 4: RTC reset stage en + 19 + 3 + read-write + + + WDT_STG2 + 1: interrupt stage en 2: CPU reset stage en 3: system reset stage en 4: RTC reset stage en + 22 + 3 + read-write + + + WDT_STG1 + 1: interrupt stage en 2: CPU reset stage en 3: system reset stage en 4: RTC reset stage en + 25 + 3 + read-write + + + WDT_STG0 + 1: interrupt stage en 2: CPU reset stage en 3: system reset stage en 4: RTC reset stage en + 28 + 3 + read-write + + + WDT_EN + enable RTC WDT + 31 + 1 + read-write + + + + + WDTCONFIG1 + 0x90 + 0x20 + 0x0001F400 + + + WDT_STG0_HOLD + 0 + 32 + read-write + + + + + WDTCONFIG2 + 0x94 + 0x20 + 0x00013880 + + + WDT_STG1_HOLD + 0 + 32 + read-write + + + + + WDTCONFIG3 + 0x98 + 0x20 + 0x00000FFF + + + WDT_STG2_HOLD + 0 + 32 + read-write + + + + + WDTCONFIG4 + 0x9C + 0x20 + 0x00000FFF + + + WDT_STG3_HOLD + 0 + 32 + read-write + + + + + WDTFEED + 0xA0 + 0x20 + + + WDT_FEED + 31 + 1 + write-only + + + + + WDTWPROTECT + 0xA4 + 0x20 + 0x50D83AA1 + + + WDT_WKEY + 0 + 32 + read-write + + + + + TEST_MUX + 0xA8 + 0x20 + + + ENT_RTC + ENT_RTC + 29 + 1 + read-write + + + DTEST_RTC + DTEST_RTC + 30 + 2 + read-write + + + + + SW_CPU_STALL + 0xAC + 0x20 + + + SW_STALL_APPCPU_C1 + {reg_sw_stall_appcpu_c1[5:0] reg_sw_stall_appcpu_c0[1:0]} == 0x86 will stall APP CPU + 20 + 6 + read-write + + + SW_STALL_PROCPU_C1 + {reg_sw_stall_procpu_c1[5:0] reg_sw_stall_procpu_c0[1:0]} == 0x86 will stall PRO CPU + 26 + 6 + read-write + + + + + STORE4 + 0xB0 + 0x20 + + + SCRATCH4 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + STORE5 + 0xB4 + 0x20 + + + SCRATCH5 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + STORE6 + 0xB8 + 0x20 + + + SCRATCH6 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + STORE7 + 0xBC + 0x20 + + + SCRATCH7 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + LOW_POWER_ST + 0xC0 + 0x20 + + + LOW_POWER_DIAG0 + 0 + 32 + read-only + + + RDY_FOR_WAKEUP + 1 if RTC controller is ready to execute WAKE instruction, 0 otherwise + 19 + 1 + read-only + + + + + DIAG1 + 0xC4 + 0x20 + + + LOW_POWER_DIAG1 + 0 + 32 + read-only + + + + + HOLD_FORCE + 0xC8 + 0x20 + + + ADC1_HOLD_FORCE + 0 + 1 + read-write + + + ADC2_HOLD_FORCE + 1 + 1 + read-write + + + PDAC1_HOLD_FORCE + 2 + 1 + read-write + + + PDAC2_HOLD_FORCE + 3 + 1 + read-write + + + SENSE1_HOLD_FORCE + 4 + 1 + read-write + + + SENSE2_HOLD_FORCE + 5 + 1 + read-write + + + SENSE3_HOLD_FORCE + 6 + 1 + read-write + + + SENSE4_HOLD_FORCE + 7 + 1 + read-write + + + TOUCH_PAD0_HOLD_FORCE + 8 + 1 + read-write + + + TOUCH_PAD1_HOLD_FORCE + 9 + 1 + read-write + + + TOUCH_PAD2_HOLD_FORCE + 10 + 1 + read-write + + + TOUCH_PAD3_HOLD_FORCE + 11 + 1 + read-write + + + TOUCH_PAD4_HOLD_FORCE + 12 + 1 + read-write + + + TOUCH_PAD5_HOLD_FORCE + 13 + 1 + read-write + + + TOUCH_PAD6_HOLD_FORCE + 14 + 1 + read-write + + + TOUCH_PAD7_HOLD_FORCE + 15 + 1 + read-write + + + X32P_HOLD_FORCE + 16 + 1 + read-write + + + X32N_HOLD_FORCE + 17 + 1 + read-write + + + + + EXT_WAKEUP1 + 0xCC + 0x20 + + + SEL + Bitmap to select RTC pads for ext wakeup1 + 0 + 18 + read-write + + + STATUS_CLR + clear ext wakeup1 status + 18 + 1 + write-only + + + + + EXT_WAKEUP1_STATUS + 0xD0 + 0x20 + + + EXT_WAKEUP1_STATUS + ext wakeup1 status + 0 + 18 + read-only + + + + + BROWN_OUT + 0xD4 + 0x20 + 0x13FF0000 + + + RTC_MEM_PID_CONF + 0 + 8 + read-write + + + RTC_MEM_CRC_START + 8 + 1 + read-write + + + RTC_MEM_CRC_ADDR + 9 + 11 + read-write + + + CLOSE_FLASH_ENA + enable close flash when brown out happens + 14 + 1 + read-write + + + PD_RF_ENA + enable power down RF when brown out happens + 15 + 1 + read-write + + + RST_WAIT + brown out reset wait cycles + 16 + 10 + read-write + + + RTC_MEM_CRC_LEN + 20 + 11 + read-write + + + RST_ENA + enable brown out reset + 26 + 1 + read-write + + + DBROWN_OUT_THRES + brown out threshold + 27 + 3 + read-write + + + ENA + enable brown out + 30 + 1 + read-write + + + DET + brown out detect + 31 + 1 + read-only + + + RTC_MEM_CRC_FINISH + 31 + 1 + read-write + + + + + DATE + 0x13C + 0x20 + 0x01604280 + + + CNTL_DATE + 0 + 28 + read-write + + + + + + + RTCIO + Peripheral RTCIO + RTC_GPIO + 0x3FF48400 + + 0x0 + 0xCC + registers + + + + OUT + 0x0 + 0x20 + + + DATA + GPIO0~17 output value + 14 + 18 + read-write + + + + + OUT_W1TS + 0x4 + 0x20 + + + OUT_DATA_W1TS + GPIO0~17 output value write 1 to set + 14 + 18 + write-only + + + + + OUT_W1TC + 0x8 + 0x20 + + + OUT_DATA_W1TC + GPIO0~17 output value write 1 to clear + 14 + 18 + write-only + + + + + ENABLE + 0xC + 0x20 + + + ENABLE + GPIO0~17 output enable + 14 + 18 + read-write + + + + + ENABLE_W1TS + 0x10 + 0x20 + + + ENABLE_W1TS + GPIO0~17 output enable write 1 to set + 14 + 18 + write-only + + + + + ENABLE_W1TC + 0x14 + 0x20 + + + ENABLE_W1TC + GPIO0~17 output enable write 1 to clear + 14 + 18 + write-only + + + + + STATUS + 0x18 + 0x20 + + + INT + GPIO0~17 interrupt status + 14 + 18 + read-write + + + + + STATUS_W1TS + 0x1C + 0x20 + + + STATUS_INT_W1TS + GPIO0~17 interrupt status write 1 to set + 14 + 18 + write-only + + + + + STATUS_W1TC + 0x20 + 0x20 + + + STATUS_INT_W1TC + GPIO0~17 interrupt status write 1 to clear + 14 + 18 + write-only + + + + + IN + 0x24 + 0x20 + + + NEXT + GPIO0~17 input value + 14 + 18 + read-only + + + + + 18 + 0x4 + 0-17 + PIN%s + 0x28 + 0x20 + + + PAD_DRIVER + if set to 0: normal output if set to 1: open drain + 2 + 1 + read-write + + + INT_TYPE + if set to 0: GPIO interrupt disable if set to 1: rising edge trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger + 7 + 3 + read-write + + + WAKEUP_ENABLE + GPIO wake up enable only available in light sleep + 10 + 1 + read-write + + + + + RTC_DEBUG_SEL + 0x70 + 0x20 + + + DEBUG_SEL0 + 0 + 5 + read-write + + + DEBUG_SEL1 + 5 + 5 + read-write + + + DEBUG_SEL2 + 10 + 5 + read-write + + + DEBUG_SEL3 + 15 + 5 + read-write + + + DEBUG_SEL4 + 20 + 5 + read-write + + + DEBUG_12M_NO_GATING + 25 + 1 + read-write + + + + + DIG_PAD_HOLD + 0x74 + 0x20 + + + DIG_PAD_HOLD + select the digital pad hold value. + 0 + 32 + read-write + + + + + HALL_SENS + 0x78 + 0x20 + + + HALL_PHASE + Reverse phase of hall sensor + 30 + 1 + read-write + + + XPD_HALL + Power on hall sensor and connect to VP and VN + 31 + 1 + read-write + + + + + SENSOR_PADS + 0x7C + 0x20 + + + SENSE4_FUN_IE + the input enable of the pad + 4 + 1 + read-write + + + SENSE4_SLP_IE + the input enable of the pad in sleep status + 5 + 1 + read-write + + + SENSE4_SLP_SEL + the sleep status selection signal of the pad + 6 + 1 + read-write + + + SENSE4_FUN_SEL + the functional selection signal of the pad + 7 + 2 + read-write + + + SENSE3_FUN_IE + the input enable of the pad + 9 + 1 + read-write + + + SENSE3_SLP_IE + the input enable of the pad in sleep status + 10 + 1 + read-write + + + SENSE3_SLP_SEL + the sleep status selection signal of the pad + 11 + 1 + read-write + + + SENSE3_FUN_SEL + the functional selection signal of the pad + 12 + 2 + read-write + + + SENSE2_FUN_IE + the input enable of the pad + 14 + 1 + read-write + + + SENSE2_SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SENSE2_SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + SENSE2_FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + SENSE1_FUN_IE + the input enable of the pad + 19 + 1 + read-write + + + SENSE1_SLP_IE + the input enable of the pad in sleep status + 20 + 1 + read-write + + + SENSE1_SLP_SEL + the sleep status selection signal of the pad + 21 + 1 + read-write + + + SENSE1_FUN_SEL + the functional selection signal of the pad + 22 + 2 + read-write + + + SENSE4_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 24 + 1 + read-write + + + SENSE3_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 25 + 1 + read-write + + + SENSE2_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 26 + 1 + read-write + + + SENSE1_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 27 + 1 + read-write + + + SENSE4_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 28 + 1 + read-write + + + SENSE3_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 29 + 1 + read-write + + + SENSE2_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 30 + 1 + read-write + + + SENSE1_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + ADC_PAD + 0x80 + 0x20 + + + ADC2_FUN_IE + the input enable of the pad + 18 + 1 + read-write + + + ADC2_SLP_IE + the input enable of the pad in sleep status + 19 + 1 + read-write + + + ADC2_SLP_SEL + the sleep status selection signal of the pad + 20 + 1 + read-write + + + ADC2_FUN_SEL + the functional selection signal of the pad + 21 + 2 + read-write + + + ADC1_FUN_IE + the input enable of the pad + 23 + 1 + read-write + + + ADC1_SLP_IE + the input enable of the pad in sleep status + 24 + 1 + read-write + + + ADC1_SLP_SEL + the sleep status selection signal of the pad + 25 + 1 + read-write + + + ADC1_FUN_SEL + the functional selection signal of the pad + 26 + 2 + read-write + + + ADC2_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 28 + 1 + read-write + + + ADC1_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 29 + 1 + read-write + + + ADC2_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 30 + 1 + read-write + + + ADC1_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + PAD_DAC1 + 0x84 + 0x20 + 0x80000000 + + + PDAC1_DAC_XPD_FORCE + Power on DAC1. Usually we need to tristate PDAC1 if we power on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0 + 10 + 1 + read-write + + + PDAC1_FUN_IE + the input enable of the pad + 11 + 1 + read-write + + + PDAC1_SLP_OE + the output enable of the pad in sleep status + 12 + 1 + read-write + + + PDAC1_SLP_IE + the input enable of the pad in sleep status + 13 + 1 + read-write + + + PDAC1_SLP_SEL + the sleep status selection signal of the pad + 14 + 1 + read-write + + + PDAC1_FUN_SEL + the functional selection signal of the pad + 15 + 2 + read-write + + + PDAC1_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 17 + 1 + read-write + + + PDAC1_XPD_DAC + Power on DAC1. Usually we need to tristate PDAC1 if we power on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0 + 18 + 1 + read-write + + + PDAC1_DAC + PAD DAC1 control code. + 19 + 8 + read-write + + + PDAC1_RUE + the pull up enable of the pad + 27 + 1 + read-write + + + PDAC1_RDE + the pull down enable of the pad + 28 + 1 + read-write + + + PDAC1_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 29 + 1 + read-write + + + PDAC1_DRV + the driver strength of the pad + 30 + 2 + read-write + + + + + PAD_DAC2 + 0x88 + 0x20 + 0x80000000 + + + PDAC2_DAC_XPD_FORCE + Power on DAC2. Usually we need to tristate PDAC2 if we power on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0 + 10 + 1 + read-write + + + PDAC2_FUN_IE + the input enable of the pad + 11 + 1 + read-write + + + PDAC2_SLP_OE + the output enable of the pad in sleep status + 12 + 1 + read-write + + + PDAC2_SLP_IE + the input enable of the pad in sleep status + 13 + 1 + read-write + + + PDAC2_SLP_SEL + the sleep status selection signal of the pad + 14 + 1 + read-write + + + PDAC2_FUN_SEL + the functional selection signal of the pad + 15 + 2 + read-write + + + PDAC2_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 17 + 1 + read-write + + + PDAC2_XPD_DAC + Power on DAC2. Usually we need to tristate PDAC1 if we power on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0 + 18 + 1 + read-write + + + PDAC2_DAC + PAD DAC2 control code. + 19 + 8 + read-write + + + PDAC2_RUE + the pull up enable of the pad + 27 + 1 + read-write + + + PDAC2_RDE + the pull down enable of the pad + 28 + 1 + read-write + + + PDAC2_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 29 + 1 + read-write + + + PDAC2_DRV + the driver strength of the pad + 30 + 2 + read-write + + + + + XTAL_32K_PAD + 0x8C + 0x20 + 0x84100010 + + + DBIAS_XTAL_32K + 32K XTAL self-bias reference control. + 1 + 2 + read-write + + + DRES_XTAL_32K + 32K XTAL resistor bias control. + 3 + 2 + read-write + + + X32P_FUN_IE + the input enable of the pad + 5 + 1 + read-write + + + X32P_SLP_OE + the output enable of the pad in sleep status + 6 + 1 + read-write + + + X32P_SLP_IE + the input enable of the pad in sleep status + 7 + 1 + read-write + + + X32P_SLP_SEL + the sleep status selection signal of the pad + 8 + 1 + read-write + + + X32P_FUN_SEL + the functional selection signal of the pad + 9 + 2 + read-write + + + X32N_FUN_IE + the input enable of the pad + 11 + 1 + read-write + + + X32N_SLP_OE + the output enable of the pad in sleep status + 12 + 1 + read-write + + + X32N_SLP_IE + the input enable of the pad in sleep status + 13 + 1 + read-write + + + X32N_SLP_SEL + the sleep status selection signal of the pad + 14 + 1 + read-write + + + X32N_FUN_SEL + the functional selection signal of the pad + 15 + 2 + read-write + + + X32P_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 17 + 1 + read-write + + + X32N_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 18 + 1 + read-write + + + XPD_XTAL_32K + Power up 32kHz crystal oscillator + 19 + 1 + read-write + + + DAC_XTAL_32K + 32K XTAL bias current DAC. + 20 + 2 + read-write + + + X32P_RUE + the pull up enable of the pad + 22 + 1 + read-write + + + X32P_RDE + the pull down enable of the pad + 23 + 1 + read-write + + + X32P_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 24 + 1 + read-write + + + X32P_DRV + the driver strength of the pad + 25 + 2 + read-write + + + X32N_RUE + the pull up enable of the pad + 27 + 1 + read-write + + + X32N_RDE + the pull down enable of the pad + 28 + 1 + read-write + + + X32N_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 29 + 1 + read-write + + + X32N_DRV + the driver strength of the pad + 30 + 2 + read-write + + + + + TOUCH_CFG + 0x90 + 0x20 + 0x66000000 + + + TOUCH_DCUR + touch sensor bias current. Should have option to tie with BIAS_SLEEP(When BIAS_SLEEP this setting is available + 23 + 2 + read-write + + + TOUCH_DRANGE + touch sensor saw wave voltage range. + 25 + 2 + read-write + + + TOUCH_DREFL + touch sensor saw wave bottom voltage. + 27 + 2 + read-write + + + TOUCH_DREFH + touch sensor saw wave top voltage. + 29 + 2 + read-write + + + TOUCH_XPD_BIAS + touch sensor bias power on. + 31 + 1 + read-write + + + + + TOUCH_PAD0 + 0x94 + 0x20 + 0x52000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale GPIO4 + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + TOUCH_PAD1 + 0x98 + 0x20 + 0x4A000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale.GPIO0 + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + 31 + 1 + read-write + + + + + TOUCH_PAD2 + 0x9C + 0x20 + 0x52000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale.GPIO2 + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + TOUCH_PAD3 + 0xA0 + 0x20 + 0x4A000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale.MTDO + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + TOUCH_PAD4 + 0xA4 + 0x20 + 0x52000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale.MTCK + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + TOUCH_PAD5 + 0xA8 + 0x20 + 0x52000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale.MTDI + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + TOUCH_PAD6 + 0xAC + 0x20 + 0x4A000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale.MTMS + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + TOUCH_PAD7 + 0xB0 + 0x20 + 0x42000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale.GPIO27 + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + TOUCH_PAD8 + 0xB4 + 0x20 + 0x02000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + + + TOUCH_PAD9 + 0xB8 + 0x20 + 0x02000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + + + EXT_WAKEUP0 + 0xBC + 0x20 + + + SEL + select the wakeup source Ó0Ó select GPIO0 Ó1Ó select GPIO2 ...Ò17Ó select GPIO17 + 27 + 5 + read-write + + + + + XTL_EXT_CTR + 0xC0 + 0x20 + + + SEL + select the external xtl power source Ó0Ó select GPIO0 Ó1Ó select GPIO2 ...Ò17Ó select GPIO17 + 27 + 5 + read-write + + + + + SAR_I2C_IO + 0xC4 + 0x20 + + + SAR_DEBUG_BIT_SEL + 23 + 5 + read-write + + + SAR_I2C_SCL_SEL + Ò0Ó using TOUCH_PAD[0] as i2c clk Ò1Ó using TOUCH_PAD[2] as i2c clk + 28 + 2 + read-write + + + SAR_I2C_SDA_SEL + Ò0Ó using TOUCH_PAD[1] as i2c sda Ò1Ó using TOUCH_PAD[3] as i2c sda + 30 + 2 + read-write + + + + + DATE + 0xC8 + 0x20 + 0x01603160 + + + IO_DATE + date + 0 + 28 + read-write + + + + + + + RTC_I2C + Peripheral RTC_I2C + RTC_I2C + 0x3FF48C00 + + 0x0 + 0x3C + registers + + + + SCL_LOW_PERIOD + 0x0 + 0x20 + + + SCL_LOW_PERIOD + number of cycles that scl == 0 + 0 + 25 + read-write + + + + + CTRL + 0x4 + 0x20 + + + SDA_FORCE_OUT + SDA is push-pull (1) or open-drain (0) + 0 + 1 + read-write + + + SCL_FORCE_OUT + SCL is push-pull (1) or open-drain (0) + 1 + 1 + read-write + + + MS_MODE + Master (1) or slave (0) + 4 + 1 + read-write + + + TRANS_START + Force to generate start condition + 5 + 1 + read-write + + + TX_LSB_FIRST + Send LSB first + 6 + 1 + read-write + + + RX_LSB_FIRST + Receive LSB first + 7 + 1 + read-write + + + + + DEBUG_STATUS + 0x8 + 0x20 + + + ACK_VAL + The value of an acknowledge signal on the bus + 0 + 1 + read-write + + + SLAVE_RW + When working as a slave, the value of R/W bit received + 1 + 1 + read-write + + + TIMED_OUT + Transfer has timed out + 2 + 1 + read-write + + + ARB_LOST + When working as a master, lost control of I2C bus + 3 + 1 + read-write + + + BUS_BUSY + operation is in progress + 4 + 1 + read-write + + + SLAVE_ADDR_MATCH + When working as a slave, whether address was matched + 5 + 1 + read-write + + + BYTE_TRANS + 8 bit transmit done + 6 + 1 + read-write + + + MAIN_STATE + state of the main state machine + 25 + 3 + read-write + + + SCL_STATE + state of SCL state machine + 28 + 3 + read-write + + + + + TIMEOUT + 0xC + 0x20 + + + TIMEOUT + Maximum number of FAST_CLK cycles that the transmission can take + 0 + 20 + read-write + + + + + SLAVE_ADDR + 0x10 + 0x20 + + + SLAVE_ADDR + local slave address + 0 + 15 + read-write + + + _10BIT + Set if local slave address is 10-bit + 31 + 1 + read-write + + + + + DATA + 0x1C + 0x20 + + + INT_RAW + 0x20 + 0x20 + + + SLAVE_TRANS_COMPLETE_INT_RAW + Slave accepted 1 byte and address matched + 3 + 1 + read-write + + + ARBITRATION_LOST_INT_RAW + Master lost arbitration + 4 + 1 + read-write + + + MASTER_TRANS_COMPLETE_INT_RAW + 5 + 1 + read-write + + + TRANS_COMPLETE_INT_RAW + Stop condition has been detected interrupt raw status + 6 + 1 + read-write + + + TIME_OUT_INT_RAW + time out interrupt raw status + 7 + 1 + read-only + + + + + INT_CLR + 0x24 + 0x20 + + + SLAVE_TRANS_COMPLETE_INT_CLR + 4 + 1 + read-write + + + ARBITRATION_LOST_INT_CLR + 5 + 1 + read-write + + + MASTER_TRANS_COMPLETE_INT_CLR + 6 + 1 + read-write + + + TRANS_COMPLETE_INT_CLR + 7 + 1 + read-write + + + TIME_OUT_INT_CLR + 8 + 1 + write-only + + + + + INT_EN + 0x28 + 0x20 + + + INT_ST + 0x2C + 0x20 + + + SDA_DUTY + 0x30 + 0x20 + + + SDA_DUTY + Number of FAST_CLK cycles SDA will switch after falling edge of SCL + 0 + 20 + read-write + + + + + SCL_HIGH_PERIOD + 0x38 + 0x20 + + + SCL_HIGH_PERIOD + Number of FAST_CLK cycles for SCL to be high + 0 + 20 + read-write + + + + + SCL_START_PERIOD + 0x40 + 0x20 + + + SCL_START_PERIOD + Number of FAST_CLK cycles to wait before generating start condition + 0 + 20 + read-write + + + + + SCL_STOP_PERIOD + 0x44 + 0x20 + + + SCL_STOP_PERIOD + Number of FAST_CLK cycles to wait before generating stop condition + 0 + 20 + read-write + + + + + CMD + 0x48 + 0x20 + + + VAL + Command content + 0 + 14 + read-write + + + DONE + Bit is set by HW when command is done + 31 + 1 + read-write + + + + + + + SDMMC + SD/MMC Host Controller + SDHOST + 0x3FF68000 + + 0x0 + 0xA4 + registers + + + + CTRL + Control register + 0x0 + 0x20 + + + CONTROLLER_RESET + To reset controller, firmware should set this bit. This bit is auto-cleared after two AHB and two sdhost_cclk_in clock cycles. + 0 + 1 + read-write + + + FIFO_RESET + To reset FIFO, firmware should set bit to 1. This bit is auto-cleared after completion of reset operation. +Note: FIFO pointers will be out of reset after 2 cycles of system clocks in addition to synchronization delay (2 cycles of card clock), after the fifo_reset is cleared. + 1 + 1 + read-write + + + DMA_RESET + To reset DMA interface, firmware should set bit to 1. This bit is auto-cleared after two AHB clocks. + 2 + 1 + read-write + + + INT_ENABLE + Global interrupt enable/disable bit. 0: Disable; 1: Enable. + 4 + 1 + read-write + + + READ_WAIT + For sending read-wait to SDIO cards. + 6 + 1 + read-write + + + SEND_IRQ_RESPONSE + Bit automatically clears once response is sent. To wait for MMC card interrupts, host issues CMD40 and waits for interrupt response from MMC card(s). In the meantime, if host wants SD/MMC to exit waiting for interrupt state, it can set this bit, at which time SD/MMC command state-machine sends CMD40 response on bus and returns to idle state. + 7 + 1 + read-write + + + ABORT_READ_DATA + After a suspend-command is issued during a read-operation, software polls the card to find when the suspend-event occurred. Once the suspend-event has occurred, software sets the bit which will reset the data state machine that is waiting for the next block of data. This bit is automatically cleared once the data state machine is reset to idle. + 8 + 1 + read-write + + + SEND_CCSD + When set, SD/MMC sends CCSD to the CE-ATA device. Software sets this bit only if the current command is expecting CCS (that is, RW_BLK), and if interrupts are enabled for the CE-ATA device. Once the CCSD pattern is sent to the device, SD/MMC automatically clears the SDHOST_SEND_CCSD bit. It also sets the Command Done (CD) bit in the SDHOST_RINTSTS_REG register, and generates an interrupt for the host, in case the Command Done interrupt is not masked. +NOTE: Once the SDHOST_SEND_CCSD bit is set, it takes two card clock cycles to drive the CCSD on the CMD line. Due to this, within the boundary conditions the CCSD may be sent to the CE-ATA device, even if the device has signalled CCS. + 9 + 1 + read-write + + + SEND_AUTO_STOP_CCSD + Always Set SDHOST_SEND_AUTO_STOP_CCSD and SDHOST_SEND_CCSD bits together; SDHOST_SEND_AUTO_STOP_CCSD should not be set independently of send_ccsd. When set, SD/MMC automatically sends an internally-generated STOP command (CMD12) to the CE-ATA device. After sending this internally-generated STOP command, the Auto Command Done (ACD) bit in SDHOST_RINTSTS_REG is set and an interrupt is generated for the host, in case the ACD interrupt is not masked. After sending the Command Completion Signal Disable (CCSD), SD/MMC automatically clears the SDHOST_SEND_AUTO_STOP_CCSD bit. + 10 + 1 + read-write + + + CEATA_DEVICE_INTERRUPT_STATUS + Software should appropriately write to this bit after the power-on reset or any other reset to the CE-ATA device. After reset, the CE-ATA device's interrupt is usually disabled (nIEN = 1). If the host enables the CE-ATA device's interrupt, then software should set this bit. + 11 + 1 + read-write + + + + + CLKDIV + Clock divider configuration register + 0x8 + 0x20 + + + CLK_DIVIDER0 + Clock divider0 value. Clock divisor is 2*n, where n = 0 bypasses the divider (divisor of 1). For example, a value of 1 means divided by 2*1 = 2, a value of 0xFF means divided by 2*255 = 510, and so on. + 0 + 8 + read-write + + + CLK_DIVIDER1 + Clock divider1 value. Clock divisor is 2*n, where n = 0 bypasses the divider (divisor of 1). For example, a value of 1 means divided by 2*1 = 2, a value of 0xFF means divided by 2*255 = 510, and so on. + 8 + 8 + read-write + + + CLK_DIVIDER2 + Clock divider2 value. Clock divisor is 2*n, where n = 0 bypasses the divider (divisor of 1). For example, a value of 1 means divided by 2*1 = 2, a value of 0xFF means divided by 2*255 = 510, and so on. + 16 + 8 + read-write + + + CLK_DIVIDER3 + Clock divider3 value. Clock divisor is 2*n, where n = 0 bypasses the divider (divisor of 1). For example, a value of 1 means divided by 2*1 = 2, a value of 0xFF means divided by 2*255 = 510, and so on. + 24 + 8 + read-write + + + + + CLKSRC + Clock source selection register + 0xC + 0x20 + + + CLKSRC + Clock divider source for two SD cards is supported. Each card has two bits assigned to it. For example, bit[1:0] are assigned for card 0, bit[3:2] are assigned for card 1. Card 0 maps and internally routes clock divider[0:3] outputs to cclk_out[1:0] pins, depending on bit value. +00 : Clock divider 0; +01 : Clock divider 1; +10 : Clock divider 2; +11 : Clock divider 3. + 0 + 4 + read-write + + + + + CLKENA + Clock enable register + 0x10 + 0x20 + + + CCLK_ENABLE + Clock-enable control for two SD card clocks and one MMC card clock is supported. One bit per card. +0: Clock disabled; +1: Clock enabled. + 0 + 2 + read-write + + + LP_ENABLE + Disable clock when the card is in IDLE state. One bit per card. +0: clock disabled; +1: clock enabled. + 16 + 2 + read-write + + + + + TMOUT + Data and response timeout configuration register + 0x14 + 0x20 + 0xFFFFFF40 + + + RESPONSE_TIMEOUT + Response timeout value. Value is specified in terms of number of card output clocks, i.e., sdhost_cclk_out. + 0 + 8 + read-write + + + DATA_TIMEOUT + Value for card data read timeout. This value is also used for data starvation by host timeout. The timeout counter is started only after the card clock is stopped. This value is specified in number of card output clocks, i.e. sdhost_cclk_out of the selected card. +NOTE: The software timer should be used if the timeout value is in the order of 100 ms. In this case, read data timeout interrupt needs to be disabled. + 8 + 24 + read-write + + + + + CTYPE + Card bus width configuration register + 0x18 + 0x20 + + + CARD_WIDTH4 + One bit per card indicates if card is 1-bit or 4-bit mode. +0: 1-bit mode; +1: 4-bit mode. +Bit[1:0] correspond to card[1:0] respectively. + 0 + 2 + read-write + + + CARD_WIDTH8 + One bit per card indicates if card is in 8-bit mode. +0: Non 8-bit mode; +1: 8-bit mode. +Bit[17:16] correspond to card[1:0] respectively. + 16 + 2 + read-write + + + + + BLKSIZ + Card data block size configuration register + 0x1C + 0x20 + 0x00000200 + + + BLOCK_SIZE + Block size. + 0 + 16 + read-write + + + + + BYTCNT + Data transfer length configuration register + 0x20 + 0x20 + 0x00000200 + + + BYTE_COUNT + Number of bytes to be transferred, should be an integral multiple of Block Size for block transfers. For data transfers of undefined byte lengths, byte count should be set to 0. When byte count is set to 0, it is the responsibility of host to explicitly send stop/abort command to terminate data transfer. + 0 + 32 + read-write + + + + + INTMASK + SDIO interrupt mask register + 0x24 + 0x20 + + + INT_MASK + These bits used to mask unwanted interrupts. A value of 0 masks interrupt, and a value of 1 enables the interrupt. +Bit 15 (EBE): End-bit error/no CRC error; +Bit 14 (ACD): Auto command done; +Bit 13 (SBE/BCI): Rx Start Bit Error; +Bit 12 (HLE): Hardware locked write error; +Bit 11 (FRUN): FIFO underrun/overrun error; +Bit 10 (HTO): Data starvation-by-host timeout; +Bit 9 (DRTO): Data read timeout; +Bit 8 (RTO): Response timeout; +Bit 7 (DCRC): Data CRC error; +Bit 6 (RCRC): Response CRC error; +Bit 5 (RXDR): Receive FIFO data request; +Bit 4 (TXDR): Transmit FIFO data request; +Bit 3 (DTO): Data transfer over; +Bit 2 (CD): Command done; +Bit 1 (RE): Response error; +Bit 0 (CD): Card detect. + 0 + 16 + read-write + + + SDIO_INT_MASK + SDIO interrupt mask, one bit for each card. Bit[17:16] correspond to card[15:0] respectively. When masked, SDIO interrupt detection for that card is disabled. 0 masks an interrupt, and 1 enables an interrupt. + 16 + 2 + read-write + + + + + CMDARG + Command argument data register + 0x28 + 0x20 + + + CMDARG + Value indicates command argument to be passed to the card. + 0 + 32 + read-write + + + + + CMD + Command and boot configuration register + 0x2C + 0x20 + 0x20000000 + + + INDEX + Command index. + 0 + 6 + read-write + + + RESPONSE_EXPECT + 0: No response expected from card; 1: Response expected from card. + 6 + 1 + read-write + + + RESPONSE_LENGTH + 0: Short response expected from card; 1: Long response expected from card. + 7 + 1 + read-write + + + CHECK_RESPONSE_CRC + 0: Do not check; 1: Check response CRC. +Some of command responses do not return valid CRC bits. Software should disable CRC checks for those commands in order to disable CRC checking by controller. + 8 + 1 + read-write + + + DATA_EXPECTED + 0: No data transfer expected; 1: Data transfer expected. + 9 + 1 + read-write + + + READ_WRITE + 0: Read from card; 1: Write to card. +Don't care if no data is expected from card. + 10 + 1 + read-write + + + TRANSFER_MODE + Block data transfer command; 1: Stream data transfer command. +Don't care if no data expected. + 11 + 1 + read-write + + + SEND_AUTO_STOP + 0: No stop command is sent at the end of data transfer; 1: Send stop command at the end of data transfer. + 12 + 1 + read-write + + + WAIT_PRVDATA_COMPLETE + 0: Send command at once, even if previous data transfer has not completed; 1: Wait for previous data transfer to complete before sending Command. +The SDHOST_WAIT_PRVDATA_COMPLETE] = 0 option is typically used to query status of card during data transfer or to stop current data transfer. SDHOST_CARD_NUMBERr should be same as in previous command. + 13 + 1 + read-write + + + STOP_ABORT_CMD + 0: Neither stop nor abort command can stop current data transfer. If abort is sent to function-number currently selected or not in data-transfer mode, then bit should be set to 0; 1: Stop or abort command intended to stop current data transfer in progress. +When open-ended or predefined data transfer is in progress, and host issues stop or abort command to stop data transfer, bit should be set so that command/data state-machines of CIU can return correctly to idle state. + 14 + 1 + read-write + + + SEND_INITIALIZATION + 0: Do not send initialization sequence (80 clocks of 1) before sending this command; 1: Send initialization sequence before sending this command. +After powered on, 80 clocks must be sent to card for initialization before sending any commands to card. Bit should be set while sending first command to card so that controller will initialize clocks before sending command to card. + 15 + 1 + read-write + + + CARD_NUMBER + Card number in use. Represents physical slot number of card being accessed. In SD-only mode, up to two cards are supported. + 16 + 5 + read-write + + + UPDATE_CLOCK_REGISTERS_ONLY + 0: Normal command sequence; 1: Do not send commands, just update clock register value into card clock domain. +Following register values are transferred into card clock domain: CLKDIV, CLRSRC, and CLKENA. +Changes card clocks (change frequency, truncate off or on, and set low-frequency mode). This is provided in order to change clock frequency or stop clock without having to send command to cards. During normal command sequence, when sdhost_update_clock_registers_only = 0, following control registers are transferred from BIU to CIU: CMD, CMDARG, TMOUT, CTYPE, BLKSIZ, and BYTCNT. CIU uses new register values for new command sequence to card(s). When bit is set, there are no Command Done interrupts because no command is sent to SD_MMC_CEATA cards. + 21 + 1 + read-write + + + READ_CEATA_DEVICE + Read access flag. +0: Host is not performing read access (RW_REG or RW_BLK)towards CE-ATA device; +1: Host is performing read access (RW_REG or RW_BLK) towards CE-ATA device. +Software should set this bit to indicate that CE-ATA device is being accessed for read transfer. This bit is used to disable read data timeout indication while performing CE-ATA read transfers. Maximum value of I/O transmission delay can be no less than 10 seconds. SD/MMC should not indicate read data timeout while waiting for data from CE-ATA device. + 22 + 1 + read-write + + + CCS_EXPECTED + Expected Command Completion Signal (CCS) configuration. +0: Interrupts are not enabled in CE-ATA device (nIEN = 1 in ATA control register), or command does not expect CCS from device; +1: Interrupts are enabled in CE-ATA device (nIEN = 0), and RW_BLK command expects command completion signal from CE-ATA device. +If the command expects Command Completion Signal (CCS) from the CE-ATA device, the software should set this control bit. SD/MMC sets Data Transfer Over (DTO) bit in RINTSTS register and generates interrupt to host if Data Transfer Over interrupt is not masked. + 23 + 1 + read-write + + + USE_HOLE + Use Hold Register. +0: CMD and DATA sent to card bypassing HOLD Register; +1: CMD and DATA sent to card through the HOLD Register. + 29 + 1 + read-write + + + START_CMD + Start command. Once command is served by the CIU, this bit is automatically cleared. When this bit is set, host should not attempt to write to any command registers. If a write is attempted, hardware lock error is set in raw interrupt register. Once command is sent and a response is received from SD_MMC_CEATA cards, Command Done bit is set in the raw interrupt Register. + 31 + 1 + read-write + + + + + RESP0 + Response data register + 0x30 + 0x20 + + + RESPONSE0 + Bit[31:0] of response. + 0 + 32 + read-only + + + + + RESP1 + Long response data register + 0x34 + 0x20 + + + RESPONSE1 + Bit[63:32] of long response. + 0 + 32 + read-only + + + + + RESP2 + Long response data register + 0x38 + 0x20 + + + RESPONSE2 + Bit[95:64] of long response. + 0 + 32 + read-only + + + + + RESP3 + Long response data register + 0x3C + 0x20 + + + RESPONSE3 + Bit[127:96] of long response. + 0 + 32 + read-only + + + + + MINTSTS + Masked interrupt status register + 0x40 + 0x20 + + + INT_STATUS_MSK + Interrupt enabled only if corresponding bit in interrupt mask register is set. +Bit 15 (EBE): End-bit error/no CRC error; +Bit 14 (ACD): Auto command done; +Bit 13 (SBE/BCI): RX Start Bit Error; +Bit 12 (HLE): Hardware locked write error; +Bit 11 (FRUN): FIFO underrun/overrun error; +Bit 10 (HTO): Data starvation by host timeout (HTO); +Bit 9 (DTRO): Data read timeout; +Bit 8 (RTO): Response timeout; +Bit 7 (DCRC): Data CRC error; +Bit 6 (RCRC): Response CRC error; +Bit 5 (RXDR): Receive FIFO data request; +Bit 4 (TXDR): Transmit FIFO data request; +Bit 3 (DTO): Data transfer over; +Bit 2 (CD): Command done; +Bit 1 (RE): Response error; +Bit 0 (CD): Card detect. + 0 + 16 + read-only + + + SDIO_INTERRUPT_MSK + Interrupt from SDIO card, one bit for each card. Bit[17:16] correspond to card1 and card0, respectively. SDIO interrupt for card is enabled only if corresponding sdhost_sdio_int_mask bit is set in Interrupt mask register (Setting mask bit enables interrupt). + 16 + 2 + read-only + + + + + RINTSTS + Raw interrupt status register + 0x44 + 0x20 + + + INT_STATUS_RAW + Setting a bit clears the corresponding interrupt and writing 0 has no effect. Bits are logged regardless of interrupt mask status. +Bit 15 (EBE): End-bit error/no CRC error; +Bit 14 (ACD): Auto command done; +Bit 13 (SBE/BCI): RX Start Bit Error; +Bit 12 (HLE): Hardware locked write error; +Bit 11 (FRUN): FIFO underrun/overrun error; +Bit 10 (HTO): Data starvation by host timeout (HTO); +Bit 9 (DTRO): Data read timeout; +Bit 8 (RTO): Response timeout; +Bit 7 (DCRC): Data CRC error; +Bit 6 (RCRC): Response CRC error; +Bit 5 (RXDR): Receive FIFO data request; +Bit 4 (TXDR): Transmit FIFO data request; +Bit 3 (DTO): Data transfer over; +Bit 2 (CD): Command done; +Bit 1 (RE): Response error; +Bit 0 (CD): Card detect. + 0 + 16 + read-write + + + SDIO_INTERRUPT_RAW + Interrupt from SDIO card, one bit for each card. Bit[17:16] correspond to card1 and card0, respectively. Setting a bit clears the corresponding interrupt bit and writing 0 has no effect. +0: No SDIO interrupt from card; +1: SDIO interrupt from card. + 16 + 2 + read-write + + + + + STATUS + SD/MMC status register + 0x48 + 0x20 + 0x00000716 + + + FIFO_RX_WATERMARK + FIFO reached Receive watermark level, not qualified with data transfer. + 0 + 1 + read-only + + + FIFO_TX_WATERMARK + FIFO reached Transmit watermark level, not qualified with data transfer. + 1 + 1 + read-only + + + FIFO_EMPTY + FIFO is empty status. + 2 + 1 + read-only + + + FIFO_FULL + FIFO is full status. + 3 + 1 + read-only + + + COMMAND_FSM_STATES + Command FSM states. +0: Idle; +1: Send init sequence; +2: Send cmd start bit; +3: Send cmd tx bit; +4: Send cmd index + arg; +5: Send cmd crc7; +6: Send cmd end bit; +7: Receive resp start bit; +8: Receive resp IRQ response; +9: Receive resp tx bit; +10: Receive resp cmd idx; +11: Receive resp data; +12: Receive resp crc7; +13: Receive resp end bit; +14: Cmd path wait NCC; +15: Wait, cmd-to-response turnaround. + 4 + 4 + read-only + + + DATA_3_STATUS + Raw selected sdhost_card_data[3], checks whether card is present. +0: card not present; +1: card present. + 8 + 1 + read-only + + + DATA_BUSY + Inverted version of raw selected sdhost_card_data[0]. +0: Card data not busy; +1: Card data busy. + 9 + 1 + read-only + + + DATA_STATE_MC_BUSY + Data transmit or receive state-machine is busy. + 10 + 1 + read-only + + + RESPONSE_INDEX + Index of previous response, including any auto-stop sent by core. + 11 + 6 + read-only + + + FIFO_COUNT + FIFO count, number of filled locations in FIFO. + 17 + 13 + read-only + + + + + FIFOTH + FIFO configuration register + 0x4C + 0x20 + + + TX_WMARK + FIFO threshold watermark level when transmitting data to card. When FIFO data count is less than or equal to this number, DMA/FIFO request is raised. If Interrupt is enabled, then interrupt occurs. During end of packet, request or interrupt is generated, regardless of threshold programming.In non-DMA mode, when transmit FIFO threshold (TXDR) interrupt is enabled, then interrupt is generated instead of DMA request. During end of packet, on last interrupt, host is responsible for filling FIFO with only required remaining bytes (not before FIFO is full or after CIU completes data transfers, because FIFO may not be empty). In DMA mode, at end of packet, if last transfer is less than burst size, DMA controller does single cycles until required bytes are transferred. + 0 + 12 + read-write + + + RX_WMARK + FIFO threshold watermark level when receiving data to card.When FIFO data count reaches greater than this number , DMA/FIFO request is raised. During end of packet, request is generated regardless of threshold programming in order to complete any remaining data.In non-DMA mode, when receiver FIFO threshold (RXDR) interrupt is enabled, then interrupt is generated instead of DMA request.During end of packet, interrupt is not generated if threshold programming is larger than any remaining data. It is responsibility of host to read remaining bytes on seeing Data Transfer Done interrupt.In DMA mode, at end of packet, even if remaining bytes are less than threshold, DMA request does single transfers to flush out any remaining bytes before Data Transfer Done interrupt is set. + 16 + 11 + read-write + + + DMA_MULTIPLE_TRANSACTION_SIZE + Burst size of multiple transaction, should be programmed same as DMA controller multiple-transaction-size SDHOST_SRC/DEST_MSIZE. +000: 1-byte transfer; +001: 4-byte transfer; +010: 8-byte transfer; +011: 16-byte transfer; +100: 32-byte transfer; +101: 64-byte transfer; +110: 128-byte transfer; +111: 256-byte transfer. + 28 + 3 + read-write + + + + + CDETECT + Card detect register + 0x50 + 0x20 + + + CARD_DETECT_N + Value on sdhost_card_detect_n input ports (1 bit per card), read-only bits. 0 represents presence of card. Only NUM_CARDS number of bits are implemented. + 0 + 2 + read-only + + + + + WRTPRT + Card write protection (WP) status register + 0x54 + 0x20 + + + WRITE_PROTECT + Value on sdhost_card_write_prt input ports (1 bit per card). 1 represents write protection. Only NUM_CARDS number of bits are implemented. + 0 + 2 + read-only + + + + + TCBCNT + Transferred byte count register + 0x5C + 0x20 + + + TCBCNT + Number of bytes transferred by CIU unit to card. + 0 + 32 + read-only + + + + + TBBCNT + Transferred byte count register + 0x60 + 0x20 + + + TBBCNT + Number of bytes transferred between Host/DMA memory and BIU FIFO. + 0 + 32 + read-only + + + + + DEBNCE + Debounce filter time configuration register + 0x64 + 0x20 + + + DEBOUNCE_COUNT + Number of host clocks (clk) used by debounce filter logic. The typical debounce time is 5 \verb+~+ 25 ms to prevent the card instability when the card is inserted or removed. + 0 + 24 + read-write + + + + + USRID + User ID (scratchpad) register + 0x68 + 0x20 + + + USRID + User identification register, value set by user. Can also be used as a scratchpad register by user. + 0 + 32 + read-write + + + + + VERID + Version ID (scratchpad) register + 0x6C + 0x20 + 0x5432270A + + + VERSIONID + Hardware version register. Can also be read by fireware. + 0 + 32 + read-only + + + + + HCON + Hardware feature register + 0x70 + 0x20 + 0x03444CC3 + + + CARD_TYPE + Hardware support SDIO and MMC. + 0 + 1 + read-only + + + CARD_NUM + Support card number is 2. + 1 + 5 + read-only + + + BUS_TYPE + Register config is APB bus. + 6 + 1 + read-only + + + DATA_WIDTH + Regisger data widht is 32. + 7 + 3 + read-only + + + ADDR_WIDTH + Register address width is 32. + 10 + 6 + read-only + + + DMA_WIDTH + DMA data witdth is 32. + 18 + 3 + read-only + + + RAM_INDISE + Inside RAM in SDMMC module. + 21 + 1 + read-only + + + HOLD + Have a hold regiser in data path . + 22 + 1 + read-only + + + NUM_CLK_DIV + Have 4 clk divider in design . + 24 + 2 + read-only + + + + + UHS + UHS-1 register + 0x74 + 0x20 + + + DDR + DDR mode selecton,1 bit for each card. +0-Non-DDR mdoe. +1-DDR mdoe. + 16 + 2 + read-write + + + + + RST_N + Card reset register + 0x78 + 0x20 + 0x00000001 + + + CARD_RESET + Hardware reset. +1: Active mode; +0: Reset. +These bits cause the cards to enter pre-idle state, which requires them to be re-initialized. SDHOST_RST_CARD_RESET[0] should be set to 1'b0 to reset card0, SDHOST_RST_CARD_RESET[1] should be set to 1'b0 to reset card1. + 0 + 2 + read-write + + + + + BMOD + Burst mode transfer configuration register + 0x80 + 0x20 + + + SWR + Software Reset. When set, the DMA Controller resets all its internal registers. It is automatically cleared after one clock cycle. + 0 + 1 + read-write + + + FB + Fixed Burst. Controls whether the AHB Master interface performs fixed burst transfers or not. When set, the AHB will use only SINGLE, INCR4, INCR8 or INCR16 during start of normal burst transfers. When reset, the AHB will use SINGLE and INCR burst transfer operations. + 1 + 1 + read-write + + + DE + IDMAC Enable. When set, the IDMAC is enabled. + 7 + 1 + read-write + + + PBL + Programmable Burst Length. These bits indicate the maximum number of beats to be performed in one IDMAC???Internal DMA Control???transaction. The IDMAC will always attempt to burst as specified in PBL each time it starts a burst transfer on the host bus. The permissible values are 1, 4, 8, 16, 32, 64, 128 and 256. This value is the mirror of MSIZE of FIFOTH register. In order to change this value, write the required value to FIFOTH register. This is an encode value as follows: +000: 1-byte transfer; +001: 4-byte transfer; +010: 8-byte transfer; +011: 16-byte transfer; +100: 32-byte transfer; +101: 64-byte transfer; +110: 128-byte transfer; +111: 256-byte transfer. +PBL is a read-only value and is applicable only for data access, it does not apply to descriptor access. + 8 + 3 + read-write + + + + + PLDMND + Poll demand configuration register + 0x84 + 0x20 + + + PD + Poll Demand. If the OWNER bit of a descriptor is not set, the FSM goes to the Suspend state. The host needs to write any value into this register for the IDMAC FSM to resume normal descriptor fetch operation. This is a write only . + 0 + 32 + write-only + + + + + DBADDR + Descriptor base address register + 0x88 + 0x20 + + + DBADDR + Start of Descriptor List. Contains the base address of the First Descriptor. The LSB bits [1:0] are ignored and taken as all-zero by the IDMAC internally. Hence these LSB bits may be treated as read-only. + 0 + 32 + read-write + + + + + IDSTS + IDMAC status register + 0x8C + 0x20 + + + TI + Transmit Interrupt. Indicates that data transmission is finished for a descriptor. Writing 1 clears this bit. + 0 + 1 + read-write + + + RI + Receive Interrupt. Indicates the completion of data reception for a descriptor. Writing 1 clears this bit. + 1 + 1 + read-write + + + FBE + Fatal Bus Error Interrupt. Indicates that a Bus Error occurred (IDSTS[12:10]) . When this bit is set, the DMA disables all its bus accesses. Writing 1 clears this bit. + 2 + 1 + read-write + + + DU + Descriptor Unavailable Interrupt. This bit is set when the descriptor is unavailable due to OWNER bit = 0 (DES0[31] = 0). Writing 1 clears this bit. + 4 + 1 + read-write + + + CES + Card Error Summary. Indicates the status of the transaction to/from the card, also present in RINTSTS. Indicates the logical OR of the following bits: +EBE : End Bit Error; +RTO : Response Timeout/Boot Ack Timeout; +RCRC : Response CRC; +SBE : Start Bit Error; +DRTO : Data Read Timeout/BDS timeout; +DCRC : Data CRC for Receive; +RE : Response Error. +Writing 1 clears this bit. The abort condition of the IDMAC depends on the setting of this CES bit. If the CES bit is enabled, then the IDMAC aborts on a response error. + 5 + 1 + read-write + + + NIS + Normal Interrupt Summary. Logical OR of the following: IDSTS[0] : Transmit Interrupt, IDSTS[1] : Receive Interrupt. Only unmasked bits affect this bit. This is a sticky bit and must be cleared each time a corresponding bit that causes NIS to be set is cleared. Writing 1 clears this bit. + 8 + 1 + read-write + + + AIS + Abnormal Interrupt Summary. Logical OR of the following: IDSTS[2] : Fatal Bus Interrupt, IDSTS[4] : DU bit Interrupt. Only unmasked bits affect this bit. This is a sticky bit and must be cleared each time a corresponding bit that causes AIS to be set is cleared. Writing 1 clears this bit. + 9 + 1 + read-write + + + FBE_CODE + Fatal Bus Error Code. Indicates the type of error that caused a Bus Error. Valid only when the Fatal Bus Error bit IDSTS[2] is set. This field does not generate an interrupt. +001: Host Abort received during transmission; +010: Host Abort received during reception; +Others: Reserved. + 10 + 3 + read-write + + + FSM + DMAC FSM present state. +0: DMA_IDLE (idle state); +1: DMA_SUSPEND (suspend state); +2: DESC_RD (descriptor reading state); +3: DESC_CHK (descriptor checking state); +4: DMA_RD_REQ_WAIT (read-data request waiting state); +5: DMA_WR_REQ_WAIT (write-data request waiting state); +6: DMA_RD (data-read state); +7: DMA_WR (data-write state); +8: DESC_CLOSE (descriptor close state). + 13 + 4 + read-write + + + + + IDINTEN + IDMAC interrupt enable register + 0x90 + 0x20 + + + TI + Transmit Interrupt Enable. When set with Normal Interrupt Summary Enable, Transmit Interrupt is enabled. When reset, Transmit Interrupt is disabled. + 0 + 1 + read-write + + + RI + Receive Interrupt Enable. When set with Normal Interrupt Summary Enable, Receive Interrupt is enabled. When reset, Receive Interrupt is disabled. + 1 + 1 + read-write + + + FBE + Fatal Bus Error Enable. When set with Abnormal Interrupt Summary Enable, the Fatal Bus Error Interrupt is enabled. When reset, Fatal Bus Error Enable Interrupt is disabled. + 2 + 1 + read-write + + + DU + Descriptor Unavailable Interrupt. When set along with Abnormal Interrupt Summary Enable, the DU interrupt is enabled. + 4 + 1 + read-write + + + CES + Card Error summary Interrupt Enable. When set, it enables the Card Interrupt summary. + 5 + 1 + read-write + + + NI + Normal Interrupt Summary Enable. When set, a normal interrupt is enabled. When reset, a normal interrupt is disabled. This bit enables the following bits: +IDINTEN[0]: Transmit Interrupt; +IDINTEN[1]: Receive Interrupt. + 8 + 1 + read-write + + + AI + Abnormal Interrupt Summary Enable. When set, an abnormal interrupt is enabled. This bit enables the following bits: +IDINTEN[2]: Fatal Bus Error Interrupt; +IDINTEN[4]: DU Interrupt. + 9 + 1 + read-write + + + + + DSCADDR + Host descriptor address pointer + 0x94 + 0x20 + + + DSCADDR + Host Descriptor Address Pointer, updated by IDMAC during operation and cleared on reset. This register points to the start address of the current descriptor read by the IDMAC. + 0 + 32 + read-only + + + + + BUFADDR + Host buffer address pointer register + 0x98 + 0x20 + + + BUFADDR + Host Buffer Address Pointer, updated by IDMAC during operation and cleared on reset. This register points to the current Data Buffer Address being accessed by the IDMAC. + 0 + 32 + read-only + + + + + CARDTHRCTL + Card Threshold Control register + 0x100 + 0x20 + + + CARDRDTHREN + Card read threshold enable. +1'b0-Card read threshold disabled. +1'b1-Card read threshold enabled. + 0 + 1 + read-write + + + CARDCLRINTEN + Busy clear interrupt generation: +1'b0-Busy clear interrypt disabled. +1'b1-Busy clear interrypt enabled. + 1 + 1 + read-write + + + CARDWRTHREN + Applicable when HS400 mode is enabled. +1'b0-Card write Threshold disabled. +1'b1-Card write Threshold enabled. + 2 + 1 + read-write + + + CARDTHRESHOLD + The inside FIFO size is 512,This register is applicable when SDHOST_CARDERTHREN_REG is set to 1 or SDHOST_CARDRDTHREN_REG set to 1. + 16 + 16 + read-write + + + + + EMMCDDR + eMMC DDR register + 0x10C + 0x20 + + + HALFSTARTBIT + Control for start bit detection mechanism duration of start bit.Each bit refers to one slot.Set this bit to 1 for eMMC4.5 and above,set to 0 for SD applications.For eMMC4.5,start bit can be: +1'b0-Full cycle. +1'b1-less than one full cycle. + 0 + 2 + read-write + + + HS400_MODE + Set 1 to enable HS400 mode. + 31 + 1 + read-write + + + + + ENSHIFT + Enable Phase Shift register + 0x110 + 0x20 + + + ENABLE_SHIFT + Control for the amount of phase shift provided on the default enables in the design.Two bits assigned for each card. +2'b00-Default phase shift. +2'b01-Enables shifted to next immediate positive edge. +2'b10-Enables shifted to next immediate negative edge. +2'b11-Reserved. + 0 + 4 + read-write + + + + + BUFFIFO + CPU write and read transmit data by FIFO + 0x200 + 0x20 + + + BUFFIFO + CPU write and read transmit data by FIFO. This register points to the current Data FIFO . + 0 + 32 + read-write + + + + + CLK_EDGE_SEL + SDIO control register. + 0x800 + 0x20 + 0x00820200 + + + CCLKIN_EDGE_DRV_SEL + It's used to select the clock phase of the output signal from phase 0, phase 90, phase 180, phase 270. + 0 + 3 + read-write + + + CCLKIN_EDGE_SAM_SEL + It's used to select the clock phase of the input signal from phase 0, phase 90, phase 180, phase 270. + 3 + 3 + read-write + + + CCLKIN_EDGE_SLF_SEL + It's used to select the clock phase of the internal signal from phase 0, phase 90, phase 180, phase 270. + 6 + 3 + read-write + + + CCLLKIN_EDGE_H + The high level of the divider clock. The value should be smaller than CCLKIN_EDGE_L. + 9 + 4 + read-write + + + CCLLKIN_EDGE_L + The low level of the divider clock. The value should be larger than CCLKIN_EDGE_H. + 13 + 4 + read-write + + + CCLLKIN_EDGE_N + The value should be equal to CCLKIN_EDGE_L. + 17 + 4 + read-write + + + ESDIO_MODE + Enable esdio mode. + 21 + 1 + read-write + + + ESD_MODE + Enable esd mode. + 22 + 1 + read-write + + + CCLK_EN + Sdio clock enable + 23 + 1 + read-write + + + + + + + SENS + Peripheral SENS + SENS + 0x3FF48800 + + 0x0 + 0xA8 + registers + + + + SAR_READ_CTRL + 0x0 + 0x20 + 0x00070902 + + + SAR1_CLK_DIV + clock divider + 0 + 8 + read-write + + + SAR1_SAMPLE_CYCLE + sample cycles for SAR ADC1 + 8 + 8 + read-write + + + SAR1_SAMPLE_BIT + 00: for 9-bit width 01: for 10-bit width 10: for 11-bit width 11: for 12-bit width + 16 + 2 + read-write + + + SAR1_CLK_GATED + 18 + 1 + read-write + + + SAR1_SAMPLE_NUM + 19 + 8 + read-write + + + SAR1_DIG_FORCE + 1: SAR ADC1 controlled by DIG ADC1 CTRL 0: SAR ADC1 controlled by RTC ADC1 CTRL + 27 + 1 + read-write + + + SAR1_DATA_INV + Invert SAR ADC1 data + 28 + 1 + read-write + + + + + SAR_READ_STATUS1 + 0x4 + 0x20 + + + SAR1_READER_STATUS + 0 + 32 + read-only + + + + + SAR_MEAS_WAIT1 + 0x8 + 0x20 + 0x000A000A + + + SAR_AMP_WAIT1 + 0 + 16 + read-write + + + SAR_AMP_WAIT2 + 16 + 16 + read-write + + + + + SAR_MEAS_WAIT2 + 0xC + 0x20 + 0x0020000A + + + FORCE_XPD_SAR_SW + 0 + 1 + read-write + + + SAR_AMP_WAIT3 + 0 + 16 + read-write + + + FORCE_XPD_AMP + 16 + 2 + read-write + + + FORCE_XPD_SAR + 18 + 2 + read-write + + + SAR2_RSTB_WAIT + 20 + 8 + read-write + + + + + SAR_MEAS_CTRL + 0x10 + 0x20 + 0x0707338F + + + XPD_SAR_AMP_FSM + 0 + 4 + read-write + + + AMP_RST_FB_FSM + 4 + 4 + read-write + + + AMP_SHORT_REF_FSM + 8 + 4 + read-write + + + AMP_SHORT_REF_GND_FSM + 12 + 4 + read-write + + + XPD_SAR_FSM + 16 + 4 + read-write + + + SAR_RSTB_FSM + 20 + 4 + read-write + + + SAR2_XPD_WAIT + 24 + 8 + read-write + + + + + SAR_READ_STATUS2 + 0x14 + 0x20 + + + SAR2_READER_STATUS + 0 + 32 + read-only + + + + + ULP_CP_SLEEP_CYC0 + 0x18 + 0x20 + 0x000000C8 + + + SLEEP_CYCLES_S0 + sleep cycles for ULP-coprocessor timer + 0 + 32 + read-write + + + + + ULP_CP_SLEEP_CYC1 + 0x1C + 0x20 + 0x00000064 + + + SLEEP_CYCLES_S1 + 0 + 32 + read-write + + + + + ULP_CP_SLEEP_CYC2 + 0x20 + 0x20 + 0x00000032 + + + SLEEP_CYCLES_S2 + 0 + 32 + read-write + + + + + ULP_CP_SLEEP_CYC3 + 0x24 + 0x20 + 0x00000028 + + + SLEEP_CYCLES_S3 + 0 + 32 + read-write + + + + + ULP_CP_SLEEP_CYC4 + 0x28 + 0x20 + 0x00000014 + + + SLEEP_CYCLES_S4 + 0 + 32 + read-write + + + + + SAR_START_FORCE + 0x2C + 0x20 + 0x0000000F + + + SAR1_BIT_WIDTH + 00: 9 bit 01: 10 bits 10: 11bits 11: 12bits + 0 + 2 + read-write + + + SAR2_BIT_WIDTH + 00: 9 bit 01: 10 bits 10: 11bits 11: 12bits + 2 + 2 + read-write + + + SAR2_EN_TEST + SAR2_EN_TEST only active when reg_sar2_dig_force = 0 + 4 + 1 + read-write + + + SAR2_PWDET_CCT + SAR2_PWDET_CCT PA power detector capacitance tuning. + 5 + 3 + read-write + + + ULP_CP_FORCE_START_TOP + 1: ULP-coprocessor is started by SW 0: ULP-coprocessor is started by timer + 8 + 1 + read-write + + + ULP_CP_START_TOP + Write 1 to start ULP-coprocessor only active when reg_ulp_cp_force_start_top = 1 + 9 + 1 + read-write + + + SARCLK_EN + 10 + 1 + read-write + + + PC_INIT + initialized PC for ULP-coprocessor + 11 + 11 + read-write + + + SAR2_STOP + stop SAR ADC2 conversion + 22 + 1 + read-write + + + SAR1_STOP + stop SAR ADC1 conversion + 23 + 1 + read-write + + + SAR2_PWDET_EN + N/A + 24 + 1 + read-write + + + + + SAR_MEM_WR_CTRL + 0x30 + 0x20 + 0x00100200 + + + MEM_WR_ADDR_INIT + 0 + 11 + read-write + + + MEM_WR_ADDR_SIZE + 11 + 11 + read-write + + + RTC_MEM_WR_OFFST_CLR + 22 + 1 + write-only + + + + + SAR_ATTEN1 + 0x34 + 0x20 + 0xFFFFFFFF + + + SAR1_ATTEN + 2-bit attenuation for each pad 11:1dB 10:6dB 01:3dB 00:0dB + 0 + 32 + read-write + + + + + SAR_ATTEN2 + 0x38 + 0x20 + 0xFFFFFFFF + + + SAR2_ATTEN + 2-bit attenuation for each pad 11:1dB 10:6dB 01:3dB 00:0dB + 0 + 32 + read-write + + + + + SAR_SLAVE_ADDR1 + 0x3C + 0x20 + + + I2C_SLAVE_ADDR1 + 0 + 11 + read-write + + + I2C_SLAVE_ADDR0 + 11 + 11 + read-write + + + MEAS_STATUS + 22 + 8 + read-only + + + + + SAR_SLAVE_ADDR2 + 0x40 + 0x20 + + + I2C_SLAVE_ADDR3 + 0 + 11 + read-write + + + I2C_SLAVE_ADDR2 + 11 + 11 + read-write + + + + + SAR_SLAVE_ADDR3 + 0x44 + 0x20 + + + I2C_SLAVE_ADDR5 + 0 + 11 + read-write + + + I2C_SLAVE_ADDR4 + 11 + 11 + read-write + + + TSENS_OUT + temperature sensor data out + 22 + 8 + read-only + + + TSENS_RDY_OUT + indicate temperature sensor out ready + 30 + 1 + read-only + + + + + SAR_SLAVE_ADDR4 + 0x48 + 0x20 + + + I2C_SLAVE_ADDR7 + 0 + 11 + read-write + + + I2C_SLAVE_ADDR6 + 11 + 11 + read-write + + + I2C_RDATA + I2C read data + 22 + 8 + read-only + + + I2C_DONE + indicate I2C done + 30 + 1 + read-only + + + + + SAR_TSENS_CTRL + 0x4C + 0x20 + 0x00066002 + + + TSENS_XPD_WAIT + 0 + 12 + read-write + + + TSENS_XPD_FORCE + 12 + 1 + read-write + + + TSENS_CLK_INV + 13 + 1 + read-write + + + TSENS_CLK_GATED + 14 + 1 + read-write + + + TSENS_IN_INV + invert temperature sensor data + 15 + 1 + read-write + + + TSENS_CLK_DIV + temperature sensor clock divider + 16 + 8 + read-write + + + TSENS_POWER_UP + temperature sensor power up + 24 + 1 + read-write + + + TSENS_POWER_UP_FORCE + 1: dump out & power up controlled by SW 0: by FSM + 25 + 1 + read-write + + + TSENS_DUMP_OUT + temperature sensor dump out only active when reg_tsens_power_up_force = 1 + 26 + 1 + read-write + + + + + SAR_I2C_CTRL + 0x50 + 0x20 + + + SAR_I2C_CTRL + I2C control data only active when reg_sar_i2c_start_force = 1 + 0 + 28 + read-write + + + SAR_I2C_START + start I2C only active when reg_sar_i2c_start_force = 1 + 28 + 1 + read-write + + + SAR_I2C_START_FORCE + 1: I2C started by SW 0: I2C started by FSM + 29 + 1 + read-write + + + + + SAR_MEAS_START1 + 0x54 + 0x20 + + + MEAS1_DATA_SAR + SAR ADC1 data + 0 + 16 + read-only + + + MEAS1_DONE_SAR + SAR ADC1 conversion done indication + 16 + 1 + read-only + + + MEAS1_START_SAR + SAR ADC1 controller (in RTC) starts conversion only active when reg_meas1_start_force = 1 + 17 + 1 + read-write + + + MEAS1_START_FORCE + 1: SAR ADC1 controller (in RTC) is started by SW 0: SAR ADC1 controller is started by ULP-coprocessor + 18 + 1 + read-write + + + SAR1_EN_PAD + SAR ADC1 pad enable bitmap only active when reg_sar1_en_pad_force = 1 + 19 + 12 + read-write + + + SAR1_EN_PAD_FORCE + 1: SAR ADC1 pad enable bitmap is controlled by SW 0: SAR ADC1 pad enable bitmap is controlled by ULP-coprocessor + 31 + 1 + read-write + + + + + SAR_TOUCH_CTRL1 + 0x58 + 0x20 + 0x02041000 + + + TOUCH_MEAS_DELAY + the meas length (in 8MHz) + 0 + 16 + read-write + + + TOUCH_XPD_WAIT + the waiting cycles (in 8MHz) between TOUCH_START and TOUCH_XPD + 16 + 8 + read-write + + + TOUCH_OUT_SEL + 1: when the counter is greater then the threshold the touch pad is considered as "touched" 0: when the counter is less than the threshold the touch pad is considered as "touched" + 24 + 1 + read-write + + + TOUCH_OUT_1EN + 1: wakeup interrupt is generated if SET1 is "touched" 0: wakeup interrupt is generated only if SET1 & SET2 is both "touched" + 25 + 1 + read-write + + + XPD_HALL_FORCE + 1: XPD HALL is controlled by SW. 0: XPD HALL is controlled by FSM in ULP-coprocessor + 26 + 1 + read-write + + + HALL_PHASE_FORCE + 1: HALL PHASE is controlled by SW 0: HALL PHASE is controlled by FSM in ULP-coprocessor + 27 + 1 + read-write + + + + + SAR_TOUCH_THRES1 + 0x5C + 0x20 + + + TOUCH_OUT_TH1 + the threshold for touch pad 1 + 0 + 16 + read-write + + + TOUCH_OUT_TH0 + the threshold for touch pad 0 + 16 + 16 + read-write + + + + + SAR_TOUCH_THRES2 + 0x60 + 0x20 + + + TOUCH_OUT_TH3 + the threshold for touch pad 3 + 0 + 16 + read-write + + + TOUCH_OUT_TH2 + the threshold for touch pad 2 + 16 + 16 + read-write + + + + + SAR_TOUCH_THRES3 + 0x64 + 0x20 + + + TOUCH_OUT_TH5 + the threshold for touch pad 5 + 0 + 16 + read-write + + + TOUCH_OUT_TH4 + the threshold for touch pad 4 + 16 + 16 + read-write + + + + + SAR_TOUCH_THRES4 + 0x68 + 0x20 + + + TOUCH_OUT_TH7 + the threshold for touch pad 7 + 0 + 16 + read-write + + + TOUCH_OUT_TH6 + the threshold for touch pad 6 + 16 + 16 + read-write + + + + + SAR_TOUCH_THRES5 + 0x6C + 0x20 + + + TOUCH_OUT_TH9 + the threshold for touch pad 9 + 0 + 16 + read-write + + + TOUCH_OUT_TH8 + the threshold for touch pad 8 + 16 + 16 + read-write + + + + + SAR_TOUCH_OUT1 + 0x70 + 0x20 + + + TOUCH_MEAS_OUT1 + the counter for touch pad 1 + 0 + 16 + read-only + + + TOUCH_MEAS_OUT0 + the counter for touch pad 0 + 16 + 16 + read-only + + + + + SAR_TOUCH_OUT2 + 0x74 + 0x20 + + + TOUCH_MEAS_OUT3 + the counter for touch pad 3 + 0 + 16 + read-only + + + TOUCH_MEAS_OUT2 + the counter for touch pad 2 + 16 + 16 + read-only + + + + + SAR_TOUCH_OUT3 + 0x78 + 0x20 + + + TOUCH_MEAS_OUT5 + the counter for touch pad 5 + 0 + 16 + read-only + + + TOUCH_MEAS_OUT4 + the counter for touch pad 4 + 16 + 16 + read-only + + + + + SAR_TOUCH_OUT4 + 0x7C + 0x20 + + + TOUCH_MEAS_OUT7 + the counter for touch pad 7 + 0 + 16 + read-only + + + TOUCH_MEAS_OUT6 + the counter for touch pad 6 + 16 + 16 + read-only + + + + + SAR_TOUCH_OUT5 + 0x80 + 0x20 + + + TOUCH_MEAS_OUT9 + the counter for touch pad 9 + 0 + 16 + read-only + + + TOUCH_MEAS_OUT8 + the counter for touch pad 8 + 16 + 16 + read-only + + + + + SAR_TOUCH_CTRL2 + 0x84 + 0x20 + 0x00400800 + + + TOUCH_MEAS_EN + 10-bit register to indicate which pads are "touched" + 0 + 10 + read-only + + + TOUCH_MEAS_DONE + fsm set 1 to indicate touch touch meas is done + 10 + 1 + read-only + + + TOUCH_START_FSM_EN + 1: TOUCH_START & TOUCH_XPD is controlled by touch fsm 0: TOUCH_START & TOUCH_XPD is controlled by registers + 11 + 1 + read-write + + + TOUCH_START_EN + 1: start touch fsm valid when reg_touch_start_force is set + 12 + 1 + read-write + + + TOUCH_START_FORCE + 1: to start touch fsm by SW 0: to start touch fsm by timer + 13 + 1 + read-write + + + TOUCH_SLEEP_CYCLES + sleep cycles for timer + 14 + 16 + read-write + + + TOUCH_MEAS_EN_CLR + to clear reg_touch_meas_en + 30 + 1 + write-only + + + + + SAR_TOUCH_ENABLE + 0x8C + 0x20 + 0x3FFFFFFF + + + TOUCH_PAD_WORKEN + Bitmap defining the working set during the measurement. + 0 + 10 + read-write + + + TOUCH_PAD_OUTEN2 + Bitmap defining SET2 for generating wakeup interrupt. SET2 is "touched" only if at least one of touch pad in SET2 is "touched". + 10 + 10 + read-write + + + TOUCH_PAD_OUTEN1 + Bitmap defining SET1 for generating wakeup interrupt. SET1 is "touched" only if at least one of touch pad in SET1 is "touched". + 20 + 10 + read-write + + + + + SAR_READ_CTRL2 + 0x90 + 0x20 + 0x00070902 + + + SAR2_CLK_DIV + clock divider + 0 + 8 + read-write + + + SAR2_SAMPLE_CYCLE + sample cycles for SAR ADC2 + 8 + 8 + read-write + + + SAR2_SAMPLE_BIT + 00: for 9-bit width 01: for 10-bit width 10: for 11-bit width 11: for 12-bit width + 16 + 2 + read-write + + + SAR2_CLK_GATED + 18 + 1 + read-write + + + SAR2_SAMPLE_NUM + 19 + 8 + read-write + + + SAR2_PWDET_FORCE + 27 + 1 + read-write + + + SAR2_DIG_FORCE + 1: SAR ADC2 controlled by DIG ADC2 CTRL or PWDET CTRL 0: SAR ADC2 controlled by RTC ADC2 CTRL + 28 + 1 + read-write + + + SAR2_DATA_INV + Invert SAR ADC2 data + 29 + 1 + read-write + + + + + SAR_MEAS_START2 + 0x94 + 0x20 + + + MEAS2_DATA_SAR + SAR ADC2 data + 0 + 16 + read-only + + + MEAS2_DONE_SAR + SAR ADC2 conversion done indication + 16 + 1 + read-only + + + MEAS2_START_SAR + SAR ADC2 controller (in RTC) starts conversion only active when reg_meas2_start_force = 1 + 17 + 1 + read-write + + + MEAS2_START_FORCE + 1: SAR ADC2 controller (in RTC) is started by SW 0: SAR ADC2 controller is started by ULP-coprocessor + 18 + 1 + read-write + + + SAR2_EN_PAD + SAR ADC2 pad enable bitmap only active when reg_sar2_en_pad_force = 1 + 19 + 12 + read-write + + + SAR2_EN_PAD_FORCE + 1: SAR ADC2 pad enable bitmap is controlled by SW 0: SAR ADC2 pad enable bitmap is controlled by ULP-coprocessor + 31 + 1 + read-write + + + + + SAR_DAC_CTRL1 + 0x98 + 0x20 + + + SW_FSTEP + frequency step for CW generator can be used to adjust the frequency + 0 + 16 + read-write + + + SW_TONE_EN + 1: enable CW generator 0: disable CW generator + 16 + 1 + read-write + + + DEBUG_BIT_SEL + 17 + 5 + read-write + + + DAC_DIG_FORCE + 1: DAC1 & DAC2 use DMA 0: DAC1 & DAC2 do not use DMA + 22 + 1 + read-write + + + DAC_CLK_FORCE_LOW + 1: force PDAC_CLK to low + 23 + 1 + read-write + + + DAC_CLK_FORCE_HIGH + 1: force PDAC_CLK to high + 24 + 1 + read-write + + + DAC_CLK_INV + 1: invert PDAC_CLK + 25 + 1 + read-write + + + + + SAR_DAC_CTRL2 + 0x9C + 0x20 + 0x03000000 + + + DAC_DC1 + DC offset for DAC1 CW generator + 0 + 8 + read-write + + + DAC_DC2 + DC offset for DAC2 CW generator + 8 + 8 + read-write + + + DAC_SCALE1 + 00: no scale 01: scale to 1/2 10: scale to 1/4 scale to 1/8 + 16 + 2 + read-write + + + DAC_SCALE2 + 00: no scale 01: scale to 1/2 10: scale to 1/4 scale to 1/8 + 18 + 2 + read-write + + + DAC_INV1 + 00: do not invert any bits 01: invert all bits 10: invert MSB 11: invert all bits except MSB + 20 + 2 + read-write + + + DAC_INV2 + 00: do not invert any bits 01: invert all bits 10: invert MSB 11: invert all bits except MSB + 22 + 2 + read-write + + + DAC_CW_EN1 + 1: to select CW generator as source to PDAC1_DAC[7:0] 0: to select register reg_pdac1_dac[7:0] as source to PDAC1_DAC[7:0] + 24 + 1 + read-write + + + DAC_CW_EN2 + 1: to select CW generator as source to PDAC2_DAC[7:0] 0: to select register reg_pdac2_dac[7:0] as source to PDAC2_DAC[7:0] + 25 + 1 + read-write + + + + + SAR_MEAS_CTRL2 + 0xA0 + 0x20 + 0x00000003 + + + SAR1_DAC_XPD_FSM + 0 + 4 + read-write + + + SAR1_DAC_XPD_FSM_IDLE + 4 + 1 + read-write + + + XPD_SAR_AMP_FSM_IDLE + 5 + 1 + read-write + + + AMP_RST_FB_FSM_IDLE + 6 + 1 + read-write + + + AMP_SHORT_REF_FSM_IDLE + 7 + 1 + read-write + + + AMP_SHORT_REF_GND_FSM_IDLE + 8 + 1 + read-write + + + XPD_SAR_FSM_IDLE + 9 + 1 + read-write + + + SAR_RSTB_FSM_IDLE + 10 + 1 + read-write + + + SAR2_RSTB_FORCE + 11 + 2 + read-write + + + AMP_RST_FB_FORCE + 13 + 2 + read-write + + + AMP_SHORT_REF_FORCE + 15 + 2 + read-write + + + AMP_SHORT_REF_GND_FORCE + 17 + 2 + read-write + + + + + SAR_NOUSE + 0xF8 + 0x20 + + + SAR_NOUSE + 0 + 32 + read-write + + + + + SARDATE + 0xFC + 0x20 + 0x01605180 + + + SAR_DATE + 0 + 28 + read-write + + + + + + + SHA + SHA (Secure Hash Algorithm) Accelerator + SHA + 0x3FF03000 + + 0x0 + 0xC0 + registers + + + + 32 + 0x4 + TEXT_%s + 0x0 + 0x20 + + + TEXT + SHA Message block and hash result register. + 0 + 8 + read-write + + + + + SHA1_START + 0x80 + 0x20 + + + SHA1_START + Write 1 to start an SHA-1 operation on the first message block. + 0 + 1 + write-only + + + + + SHA1_CONTINUE + 0x80 + 0x20 + + + SHA1_CONTINUE + Write 1 to continue the SHA-1 operation with subsequent blocks. + 0 + 1 + write-only + + + + + SHA1_LOAD + 0x88 + 0x20 + + + SHA1_LOAD + Write 1 to finish the SHA-1 operation to calculate the final message hash. + 0 + 1 + write-only + + + + + SHA1_BUSY + 0x8C + 0x20 + + + SHA1_BUSY + SHA-1 operation status: 1 if the SHA accelerator is processing data, 0 if it is idle. + 0 + 1 + write-only + + + + + SHA256_START + 0x90 + 0x20 + + + SHA256_START + Write 1 to start an SHA-256 operation on the first message block. + 0 + 1 + write-only + + + + + SHA256_LOAD + 0x90 + 0x20 + + + SHA256_LOAD + Write 1 to finish the SHA-256 operation to calculate the final message hash. + 0 + 1 + write-only + + + + + SHA256_CONTINUE + 0x94 + 0x20 + + + SHA256_CONTINUE + Write 1 to continue the SHA-256 operation with subsequent blocks. + 0 + 1 + write-only + + + + + SHA256_BUSY + 0x9C + 0x20 + + + SHA256_BUSY + SHA-256 operation status: 1 if the SHA accelerator is processing data, 0 if it is idle. + 0 + 1 + read-only + + + + + SHA384_START + 0xA0 + 0x20 + + + SHA384_START + Write 1 to start an SHA-384 operation on the first message block. + 0 + 1 + write-only + + + + + SHA384_CONTINUE + 0xA4 + 0x20 + + + SHA384_CONTINUE + Write 1 to continue the SHA-384 operation with subsequent blocks. + 0 + 1 + write-only + + + + + SHA384_LOAD + 0xA8 + 0x20 + + + SHA384_LOAD + Write 1 to finish the SHA-384 operation to calculate the final message hash. + 0 + 1 + write-only + + + + + SHA384_BUSY + 0xAC + 0x20 + + + SHA384_BUSY + SHA-384 operation status: 1 if the SHA accelerator is processing data, 0 if it is idle. + 0 + 1 + read-only + + + + + SHA512_START + 0xB0 + 0x20 + + + SHA512_START + Write 1 to start an SHA-512 operation on the first message block. + 0 + 1 + write-only + + + + + SHA512_CONTINUE + 0xB4 + 0x20 + + + SHA512_CONTINUE + Write 1 to continue the SHA-512 operation with subsequent blocks. + 0 + 1 + write-only + + + + + SHA512_LOAD + 0xB8 + 0x20 + + + SHA512_LOAD + Write 1 to finish the SHA-512 operation to calculate the final message hash. + 0 + 1 + write-only + + + + + SHA512_BUSY + 0xBC + 0x20 + + + SHA512_BUSY + SHA-512 operation status: 1 if the SHA accelerator is processing data, 0 if it is idle. + 0 + 1 + read-only + + + + + + + SLC + Peripheral SLC + SLC + 0x3FF58000 + + 0x0 + 0x14C + registers + + + + CONF0 + 0x0 + 0x20 + 0xFF3CFF30 + + + SLC0_TX_RST + 0 + 1 + read-write + + + SLC0_RX_RST + 1 + 1 + read-write + + + AHBM_FIFO_RST + 2 + 1 + read-write + + + AHBM_RST + 3 + 1 + read-write + + + SLC0_TX_LOOP_TEST + 4 + 1 + read-write + + + SLC0_RX_LOOP_TEST + 5 + 1 + read-write + + + SLC0_RX_AUTO_WRBACK + 6 + 1 + read-write + + + SLC0_RX_NO_RESTART_CLR + 7 + 1 + read-write + + + SLC0_RXDSCR_BURST_EN + 8 + 1 + read-write + + + SLC0_RXDATA_BURST_EN + 9 + 1 + read-write + + + SLC0_RXLINK_AUTO_RET + 10 + 1 + read-write + + + SLC0_TXLINK_AUTO_RET + 11 + 1 + read-write + + + SLC0_TXDSCR_BURST_EN + 12 + 1 + read-write + + + SLC0_TXDATA_BURST_EN + 13 + 1 + read-write + + + SLC0_TOKEN_AUTO_CLR + 14 + 1 + read-write + + + SLC0_TOKEN_SEL + 15 + 1 + read-write + + + SLC1_TX_RST + 16 + 1 + read-write + + + SLC1_RX_RST + 17 + 1 + read-write + + + SLC0_WR_RETRY_MASK_EN + 18 + 1 + read-write + + + SLC1_WR_RETRY_MASK_EN + 19 + 1 + read-write + + + SLC1_TX_LOOP_TEST + 20 + 1 + read-write + + + SLC1_RX_LOOP_TEST + 21 + 1 + read-write + + + SLC1_RX_AUTO_WRBACK + 22 + 1 + read-write + + + SLC1_RX_NO_RESTART_CLR + 23 + 1 + read-write + + + SLC1_RXDSCR_BURST_EN + 24 + 1 + read-write + + + SLC1_RXDATA_BURST_EN + 25 + 1 + read-write + + + SLC1_RXLINK_AUTO_RET + 26 + 1 + read-write + + + SLC1_TXLINK_AUTO_RET + 27 + 1 + read-write + + + SLC1_TXDSCR_BURST_EN + 28 + 1 + read-write + + + SLC1_TXDATA_BURST_EN + 29 + 1 + read-write + + + SLC1_TOKEN_AUTO_CLR + 30 + 1 + read-write + + + SLC1_TOKEN_SEL + 31 + 1 + read-write + + + + + _0INT_RAW + 0x4 + 0x20 + + + FRHOST_BIT0_INT_RAW + 0 + 1 + read-only + + + FRHOST_BIT1_INT_RAW + 1 + 1 + read-only + + + FRHOST_BIT2_INT_RAW + 2 + 1 + read-only + + + FRHOST_BIT3_INT_RAW + 3 + 1 + read-only + + + FRHOST_BIT4_INT_RAW + 4 + 1 + read-only + + + FRHOST_BIT5_INT_RAW + 5 + 1 + read-only + + + FRHOST_BIT6_INT_RAW + 6 + 1 + read-only + + + FRHOST_BIT7_INT_RAW + 7 + 1 + read-only + + + SLC0_RX_START_INT_RAW + 8 + 1 + read-only + + + SLC0_TX_START_INT_RAW + 9 + 1 + read-only + + + SLC0_RX_UDF_INT_RAW + 10 + 1 + read-only + + + SLC0_TX_OVF_INT_RAW + 11 + 1 + read-only + + + SLC0_TOKEN0_1TO0_INT_RAW + 12 + 1 + read-only + + + SLC0_TOKEN1_1TO0_INT_RAW + 13 + 1 + read-only + + + SLC0_TX_DONE_INT_RAW + 14 + 1 + read-only + + + SLC0_TX_SUC_EOF_INT_RAW + 15 + 1 + read-only + + + SLC0_RX_DONE_INT_RAW + 16 + 1 + read-only + + + SLC0_RX_EOF_INT_RAW + 17 + 1 + read-only + + + SLC0_TOHOST_INT_RAW + 18 + 1 + read-only + + + SLC0_TX_DSCR_ERR_INT_RAW + 19 + 1 + read-only + + + SLC0_RX_DSCR_ERR_INT_RAW + 20 + 1 + read-only + + + SLC0_TX_DSCR_EMPTY_INT_RAW + 21 + 1 + read-only + + + SLC0_HOST_RD_ACK_INT_RAW + 22 + 1 + read-only + + + SLC0_WR_RETRY_DONE_INT_RAW + 23 + 1 + read-only + + + SLC0_TX_ERR_EOF_INT_RAW + 24 + 1 + read-only + + + CMD_DTC_INT_RAW + 25 + 1 + read-only + + + SLC0_RX_QUICK_EOF_INT_RAW + 26 + 1 + read-only + + + + + _0INT_ST + 0x8 + 0x20 + + + FRHOST_BIT0_INT_ST + 0 + 1 + read-only + + + FRHOST_BIT1_INT_ST + 1 + 1 + read-only + + + FRHOST_BIT2_INT_ST + 2 + 1 + read-only + + + FRHOST_BIT3_INT_ST + 3 + 1 + read-only + + + FRHOST_BIT4_INT_ST + 4 + 1 + read-only + + + FRHOST_BIT5_INT_ST + 5 + 1 + read-only + + + FRHOST_BIT6_INT_ST + 6 + 1 + read-only + + + FRHOST_BIT7_INT_ST + 7 + 1 + read-only + + + SLC0_RX_START_INT_ST + 8 + 1 + read-only + + + SLC0_TX_START_INT_ST + 9 + 1 + read-only + + + SLC0_RX_UDF_INT_ST + 10 + 1 + read-only + + + SLC0_TX_OVF_INT_ST + 11 + 1 + read-only + + + SLC0_TOKEN0_1TO0_INT_ST + 12 + 1 + read-only + + + SLC0_TOKEN1_1TO0_INT_ST + 13 + 1 + read-only + + + SLC0_TX_DONE_INT_ST + 14 + 1 + read-only + + + SLC0_TX_SUC_EOF_INT_ST + 15 + 1 + read-only + + + SLC0_RX_DONE_INT_ST + 16 + 1 + read-only + + + SLC0_RX_EOF_INT_ST + 17 + 1 + read-only + + + SLC0_TOHOST_INT_ST + 18 + 1 + read-only + + + SLC0_TX_DSCR_ERR_INT_ST + 19 + 1 + read-only + + + SLC0_RX_DSCR_ERR_INT_ST + 20 + 1 + read-only + + + SLC0_TX_DSCR_EMPTY_INT_ST + 21 + 1 + read-only + + + SLC0_HOST_RD_ACK_INT_ST + 22 + 1 + read-only + + + SLC0_WR_RETRY_DONE_INT_ST + 23 + 1 + read-only + + + SLC0_TX_ERR_EOF_INT_ST + 24 + 1 + read-only + + + CMD_DTC_INT_ST + 25 + 1 + read-only + + + SLC0_RX_QUICK_EOF_INT_ST + 26 + 1 + read-only + + + + + _0INT_ENA + 0xC + 0x20 + + + FRHOST_BIT0_INT_ENA + 0 + 1 + read-write + + + FRHOST_BIT1_INT_ENA + 1 + 1 + read-write + + + FRHOST_BIT2_INT_ENA + 2 + 1 + read-write + + + FRHOST_BIT3_INT_ENA + 3 + 1 + read-write + + + FRHOST_BIT4_INT_ENA + 4 + 1 + read-write + + + FRHOST_BIT5_INT_ENA + 5 + 1 + read-write + + + FRHOST_BIT6_INT_ENA + 6 + 1 + read-write + + + FRHOST_BIT7_INT_ENA + 7 + 1 + read-write + + + SLC0_RX_START_INT_ENA + 8 + 1 + read-write + + + SLC0_TX_START_INT_ENA + 9 + 1 + read-write + + + SLC0_RX_UDF_INT_ENA + 10 + 1 + read-write + + + SLC0_TX_OVF_INT_ENA + 11 + 1 + read-write + + + SLC0_TOKEN0_1TO0_INT_ENA + 12 + 1 + read-write + + + SLC0_TOKEN1_1TO0_INT_ENA + 13 + 1 + read-write + + + SLC0_TX_DONE_INT_ENA + 14 + 1 + read-write + + + SLC0_TX_SUC_EOF_INT_ENA + 15 + 1 + read-write + + + SLC0_RX_DONE_INT_ENA + 16 + 1 + read-write + + + SLC0_RX_EOF_INT_ENA + 17 + 1 + read-write + + + SLC0_TOHOST_INT_ENA + 18 + 1 + read-write + + + SLC0_TX_DSCR_ERR_INT_ENA + 19 + 1 + read-write + + + SLC0_RX_DSCR_ERR_INT_ENA + 20 + 1 + read-write + + + SLC0_TX_DSCR_EMPTY_INT_ENA + 21 + 1 + read-write + + + SLC0_HOST_RD_ACK_INT_ENA + 22 + 1 + read-write + + + SLC0_WR_RETRY_DONE_INT_ENA + 23 + 1 + read-write + + + SLC0_TX_ERR_EOF_INT_ENA + 24 + 1 + read-write + + + CMD_DTC_INT_ENA + 25 + 1 + read-write + + + SLC0_RX_QUICK_EOF_INT_ENA + 26 + 1 + read-write + + + + + _0INT_CLR + 0x10 + 0x20 + + + FRHOST_BIT0_INT_CLR + 0 + 1 + write-only + + + FRHOST_BIT1_INT_CLR + 1 + 1 + write-only + + + FRHOST_BIT2_INT_CLR + 2 + 1 + write-only + + + FRHOST_BIT3_INT_CLR + 3 + 1 + write-only + + + FRHOST_BIT4_INT_CLR + 4 + 1 + write-only + + + FRHOST_BIT5_INT_CLR + 5 + 1 + write-only + + + FRHOST_BIT6_INT_CLR + 6 + 1 + write-only + + + FRHOST_BIT7_INT_CLR + 7 + 1 + write-only + + + SLC0_RX_START_INT_CLR + 8 + 1 + write-only + + + SLC0_TX_START_INT_CLR + 9 + 1 + write-only + + + SLC0_RX_UDF_INT_CLR + 10 + 1 + write-only + + + SLC0_TX_OVF_INT_CLR + 11 + 1 + write-only + + + SLC0_TOKEN0_1TO0_INT_CLR + 12 + 1 + write-only + + + SLC0_TOKEN1_1TO0_INT_CLR + 13 + 1 + write-only + + + SLC0_TX_DONE_INT_CLR + 14 + 1 + write-only + + + SLC0_TX_SUC_EOF_INT_CLR + 15 + 1 + write-only + + + SLC0_RX_DONE_INT_CLR + 16 + 1 + write-only + + + SLC0_RX_EOF_INT_CLR + 17 + 1 + write-only + + + SLC0_TOHOST_INT_CLR + 18 + 1 + write-only + + + SLC0_TX_DSCR_ERR_INT_CLR + 19 + 1 + write-only + + + SLC0_RX_DSCR_ERR_INT_CLR + 20 + 1 + write-only + + + SLC0_TX_DSCR_EMPTY_INT_CLR + 21 + 1 + write-only + + + SLC0_HOST_RD_ACK_INT_CLR + 22 + 1 + write-only + + + SLC0_WR_RETRY_DONE_INT_CLR + 23 + 1 + write-only + + + SLC0_TX_ERR_EOF_INT_CLR + 24 + 1 + write-only + + + CMD_DTC_INT_CLR + 25 + 1 + write-only + + + SLC0_RX_QUICK_EOF_INT_CLR + 26 + 1 + write-only + + + + + _1INT_RAW + 0x14 + 0x20 + + + FRHOST_BIT8_INT_RAW + 0 + 1 + read-only + + + FRHOST_BIT9_INT_RAW + 1 + 1 + read-only + + + FRHOST_BIT10_INT_RAW + 2 + 1 + read-only + + + FRHOST_BIT11_INT_RAW + 3 + 1 + read-only + + + FRHOST_BIT12_INT_RAW + 4 + 1 + read-only + + + FRHOST_BIT13_INT_RAW + 5 + 1 + read-only + + + FRHOST_BIT14_INT_RAW + 6 + 1 + read-only + + + FRHOST_BIT15_INT_RAW + 7 + 1 + read-only + + + SLC1_RX_START_INT_RAW + 8 + 1 + read-only + + + SLC1_TX_START_INT_RAW + 9 + 1 + read-only + + + SLC1_RX_UDF_INT_RAW + 10 + 1 + read-only + + + SLC1_TX_OVF_INT_RAW + 11 + 1 + read-only + + + SLC1_TOKEN0_1TO0_INT_RAW + 12 + 1 + read-only + + + SLC1_TOKEN1_1TO0_INT_RAW + 13 + 1 + read-only + + + SLC1_TX_DONE_INT_RAW + 14 + 1 + read-only + + + SLC1_TX_SUC_EOF_INT_RAW + 15 + 1 + read-only + + + SLC1_RX_DONE_INT_RAW + 16 + 1 + read-only + + + SLC1_RX_EOF_INT_RAW + 17 + 1 + read-only + + + SLC1_TOHOST_INT_RAW + 18 + 1 + read-only + + + SLC1_TX_DSCR_ERR_INT_RAW + 19 + 1 + read-only + + + SLC1_RX_DSCR_ERR_INT_RAW + 20 + 1 + read-only + + + SLC1_TX_DSCR_EMPTY_INT_RAW + 21 + 1 + read-only + + + SLC1_HOST_RD_ACK_INT_RAW + 22 + 1 + read-only + + + SLC1_WR_RETRY_DONE_INT_RAW + 23 + 1 + read-only + + + SLC1_TX_ERR_EOF_INT_RAW + 24 + 1 + read-only + + + + + _1INT_ST + 0x18 + 0x20 + + + FRHOST_BIT8_INT_ST + 0 + 1 + read-only + + + FRHOST_BIT9_INT_ST + 1 + 1 + read-only + + + FRHOST_BIT10_INT_ST + 2 + 1 + read-only + + + FRHOST_BIT11_INT_ST + 3 + 1 + read-only + + + FRHOST_BIT12_INT_ST + 4 + 1 + read-only + + + FRHOST_BIT13_INT_ST + 5 + 1 + read-only + + + FRHOST_BIT14_INT_ST + 6 + 1 + read-only + + + FRHOST_BIT15_INT_ST + 7 + 1 + read-only + + + SLC1_RX_START_INT_ST + 8 + 1 + read-only + + + SLC1_TX_START_INT_ST + 9 + 1 + read-only + + + SLC1_RX_UDF_INT_ST + 10 + 1 + read-only + + + SLC1_TX_OVF_INT_ST + 11 + 1 + read-only + + + SLC1_TOKEN0_1TO0_INT_ST + 12 + 1 + read-only + + + SLC1_TOKEN1_1TO0_INT_ST + 13 + 1 + read-only + + + SLC1_TX_DONE_INT_ST + 14 + 1 + read-only + + + SLC1_TX_SUC_EOF_INT_ST + 15 + 1 + read-only + + + SLC1_RX_DONE_INT_ST + 16 + 1 + read-only + + + SLC1_RX_EOF_INT_ST + 17 + 1 + read-only + + + SLC1_TOHOST_INT_ST + 18 + 1 + read-only + + + SLC1_TX_DSCR_ERR_INT_ST + 19 + 1 + read-only + + + SLC1_RX_DSCR_ERR_INT_ST + 20 + 1 + read-only + + + SLC1_TX_DSCR_EMPTY_INT_ST + 21 + 1 + read-only + + + SLC1_HOST_RD_ACK_INT_ST + 22 + 1 + read-only + + + SLC1_WR_RETRY_DONE_INT_ST + 23 + 1 + read-only + + + SLC1_TX_ERR_EOF_INT_ST + 24 + 1 + read-only + + + + + _1INT_ENA + 0x1C + 0x20 + + + FRHOST_BIT8_INT_ENA + 0 + 1 + read-write + + + FRHOST_BIT9_INT_ENA + 1 + 1 + read-write + + + FRHOST_BIT10_INT_ENA + 2 + 1 + read-write + + + FRHOST_BIT11_INT_ENA + 3 + 1 + read-write + + + FRHOST_BIT12_INT_ENA + 4 + 1 + read-write + + + FRHOST_BIT13_INT_ENA + 5 + 1 + read-write + + + FRHOST_BIT14_INT_ENA + 6 + 1 + read-write + + + FRHOST_BIT15_INT_ENA + 7 + 1 + read-write + + + SLC1_RX_START_INT_ENA + 8 + 1 + read-write + + + SLC1_TX_START_INT_ENA + 9 + 1 + read-write + + + SLC1_RX_UDF_INT_ENA + 10 + 1 + read-write + + + SLC1_TX_OVF_INT_ENA + 11 + 1 + read-write + + + SLC1_TOKEN0_1TO0_INT_ENA + 12 + 1 + read-write + + + SLC1_TOKEN1_1TO0_INT_ENA + 13 + 1 + read-write + + + SLC1_TX_DONE_INT_ENA + 14 + 1 + read-write + + + SLC1_TX_SUC_EOF_INT_ENA + 15 + 1 + read-write + + + SLC1_RX_DONE_INT_ENA + 16 + 1 + read-write + + + SLC1_RX_EOF_INT_ENA + 17 + 1 + read-write + + + SLC1_TOHOST_INT_ENA + 18 + 1 + read-write + + + SLC1_TX_DSCR_ERR_INT_ENA + 19 + 1 + read-write + + + SLC1_RX_DSCR_ERR_INT_ENA + 20 + 1 + read-write + + + SLC1_TX_DSCR_EMPTY_INT_ENA + 21 + 1 + read-write + + + SLC1_HOST_RD_ACK_INT_ENA + 22 + 1 + read-write + + + SLC1_WR_RETRY_DONE_INT_ENA + 23 + 1 + read-write + + + SLC1_TX_ERR_EOF_INT_ENA + 24 + 1 + read-write + + + + + _1INT_CLR + 0x20 + 0x20 + + + FRHOST_BIT8_INT_CLR + 0 + 1 + write-only + + + FRHOST_BIT9_INT_CLR + 1 + 1 + write-only + + + FRHOST_BIT10_INT_CLR + 2 + 1 + write-only + + + FRHOST_BIT11_INT_CLR + 3 + 1 + write-only + + + FRHOST_BIT12_INT_CLR + 4 + 1 + write-only + + + FRHOST_BIT13_INT_CLR + 5 + 1 + write-only + + + FRHOST_BIT14_INT_CLR + 6 + 1 + write-only + + + FRHOST_BIT15_INT_CLR + 7 + 1 + write-only + + + SLC1_RX_START_INT_CLR + 8 + 1 + write-only + + + SLC1_TX_START_INT_CLR + 9 + 1 + write-only + + + SLC1_RX_UDF_INT_CLR + 10 + 1 + write-only + + + SLC1_TX_OVF_INT_CLR + 11 + 1 + write-only + + + SLC1_TOKEN0_1TO0_INT_CLR + 12 + 1 + write-only + + + SLC1_TOKEN1_1TO0_INT_CLR + 13 + 1 + write-only + + + SLC1_TX_DONE_INT_CLR + 14 + 1 + write-only + + + SLC1_TX_SUC_EOF_INT_CLR + 15 + 1 + write-only + + + SLC1_RX_DONE_INT_CLR + 16 + 1 + write-only + + + SLC1_RX_EOF_INT_CLR + 17 + 1 + write-only + + + SLC1_TOHOST_INT_CLR + 18 + 1 + write-only + + + SLC1_TX_DSCR_ERR_INT_CLR + 19 + 1 + write-only + + + SLC1_RX_DSCR_ERR_INT_CLR + 20 + 1 + write-only + + + SLC1_TX_DSCR_EMPTY_INT_CLR + 21 + 1 + write-only + + + SLC1_HOST_RD_ACK_INT_CLR + 22 + 1 + write-only + + + SLC1_WR_RETRY_DONE_INT_CLR + 23 + 1 + write-only + + + SLC1_TX_ERR_EOF_INT_CLR + 24 + 1 + write-only + + + + + RX_STATUS + 0x24 + 0x20 + 0x00020002 + + + SLC0_RX_FULL + 0 + 1 + read-only + + + SLC0_RX_EMPTY + 1 + 1 + read-only + + + SLC1_RX_FULL + 16 + 1 + read-only + + + SLC1_RX_EMPTY + 17 + 1 + read-only + + + + + _0RXFIFO_PUSH + 0x28 + 0x20 + + + SLC0_RXFIFO_WDATA + 0 + 9 + read-write + + + SLC0_RXFIFO_PUSH + 16 + 1 + read-write + + + + + _1RXFIFO_PUSH + 0x2C + 0x20 + + + SLC1_RXFIFO_WDATA + 0 + 9 + read-write + + + SLC1_RXFIFO_PUSH + 16 + 1 + read-write + + + + + TX_STATUS + 0x30 + 0x20 + 0x00020002 + + + SLC0_TX_FULL + 0 + 1 + read-only + + + SLC0_TX_EMPTY + 1 + 1 + read-only + + + SLC1_TX_FULL + 16 + 1 + read-only + + + SLC1_TX_EMPTY + 17 + 1 + read-only + + + + + _0TXFIFO_POP + 0x34 + 0x20 + + + SLC0_TXFIFO_RDATA + 0 + 11 + read-only + + + SLC0_TXFIFO_POP + 16 + 1 + read-write + + + + + _1TXFIFO_POP + 0x38 + 0x20 + + + SLC1_TXFIFO_RDATA + 0 + 11 + read-only + + + SLC1_TXFIFO_POP + 16 + 1 + read-write + + + + + _0RX_LINK + 0x3C + 0x20 + + + SLC0_RXLINK_ADDR + 0 + 20 + read-write + + + SLC0_RXLINK_STOP + 28 + 1 + read-write + + + SLC0_RXLINK_START + 29 + 1 + read-write + + + SLC0_RXLINK_RESTART + 30 + 1 + read-write + + + SLC0_RXLINK_PARK + 31 + 1 + read-only + + + + + _0TX_LINK + 0x40 + 0x20 + + + SLC0_TXLINK_ADDR + 0 + 20 + read-write + + + SLC0_TXLINK_STOP + 28 + 1 + read-write + + + SLC0_TXLINK_START + 29 + 1 + read-write + + + SLC0_TXLINK_RESTART + 30 + 1 + read-write + + + SLC0_TXLINK_PARK + 31 + 1 + read-only + + + + + _1RX_LINK + 0x44 + 0x20 + 0x00100000 + + + SLC1_RXLINK_ADDR + 0 + 20 + read-write + + + SLC1_BT_PACKET + 20 + 1 + read-write + + + SLC1_RXLINK_STOP + 28 + 1 + read-write + + + SLC1_RXLINK_START + 29 + 1 + read-write + + + SLC1_RXLINK_RESTART + 30 + 1 + read-write + + + SLC1_RXLINK_PARK + 31 + 1 + read-only + + + + + _1TX_LINK + 0x48 + 0x20 + + + SLC1_TXLINK_ADDR + 0 + 20 + read-write + + + SLC1_TXLINK_STOP + 28 + 1 + read-write + + + SLC1_TXLINK_START + 29 + 1 + read-write + + + SLC1_TXLINK_RESTART + 30 + 1 + read-write + + + SLC1_TXLINK_PARK + 31 + 1 + read-only + + + + + INTVEC_TOHOST + 0x4C + 0x20 + + + SLC0_TOHOST_INTVEC + 0 + 8 + write-only + + + SLC1_TOHOST_INTVEC + 16 + 8 + write-only + + + + + _0TOKEN0 + 0x50 + 0x20 + + + SLC0_TOKEN0_WDATA + 0 + 12 + write-only + + + SLC0_TOKEN0_WR + 12 + 1 + write-only + + + SLC0_TOKEN0_INC + 13 + 1 + write-only + + + SLC0_TOKEN0_INC_MORE + 14 + 1 + write-only + + + SLC0_TOKEN0 + 16 + 12 + read-only + + + + + _0TOKEN1 + 0x54 + 0x20 + + + SLC0_TOKEN1_WDATA + 0 + 12 + write-only + + + SLC0_TOKEN1_WR + 12 + 1 + write-only + + + SLC0_TOKEN1_INC + 13 + 1 + write-only + + + SLC0_TOKEN1_INC_MORE + 14 + 1 + write-only + + + SLC0_TOKEN1 + 16 + 12 + read-only + + + + + _1TOKEN0 + 0x58 + 0x20 + + + SLC1_TOKEN0_WDATA + 0 + 12 + write-only + + + SLC1_TOKEN0_WR + 12 + 1 + write-only + + + SLC1_TOKEN0_INC + 13 + 1 + write-only + + + SLC1_TOKEN0_INC_MORE + 14 + 1 + write-only + + + SLC1_TOKEN0 + 16 + 12 + read-only + + + + + _1TOKEN1 + 0x5C + 0x20 + + + SLC1_TOKEN1_WDATA + 0 + 12 + write-only + + + SLC1_TOKEN1_WR + 12 + 1 + write-only + + + SLC1_TOKEN1_INC + 13 + 1 + write-only + + + SLC1_TOKEN1_INC_MORE + 14 + 1 + write-only + + + SLC1_TOKEN1 + 16 + 12 + read-only + + + + + CONF1 + 0x60 + 0x20 + 0x00300078 + + + SLC0_CHECK_OWNER + 0 + 1 + read-write + + + SLC0_TX_CHECK_SUM_EN + 1 + 1 + read-write + + + SLC0_RX_CHECK_SUM_EN + 2 + 1 + read-write + + + CMD_HOLD_EN + 3 + 1 + read-write + + + SLC0_LEN_AUTO_CLR + 4 + 1 + read-write + + + SLC0_TX_STITCH_EN + 5 + 1 + read-write + + + SLC0_RX_STITCH_EN + 6 + 1 + read-write + + + SLC1_CHECK_OWNER + 16 + 1 + read-write + + + SLC1_TX_CHECK_SUM_EN + 17 + 1 + read-write + + + SLC1_RX_CHECK_SUM_EN + 18 + 1 + read-write + + + HOST_INT_LEVEL_SEL + 19 + 1 + read-write + + + SLC1_TX_STITCH_EN + 20 + 1 + read-write + + + SLC1_RX_STITCH_EN + 21 + 1 + read-write + + + CLK_EN + 22 + 1 + read-write + + + + + _0_STATE0 + 0x64 + 0x20 + + + SLC0_STATE0 + 0 + 32 + read-only + + + + + _0_STATE1 + 0x68 + 0x20 + + + SLC0_STATE1 + 0 + 32 + read-only + + + + + _1_STATE0 + 0x6C + 0x20 + + + SLC1_STATE0 + 0 + 32 + read-only + + + + + _1_STATE1 + 0x70 + 0x20 + + + SLC1_STATE1 + 0 + 32 + read-only + + + + + BRIDGE_CONF + 0x74 + 0x20 + 0x000A7720 + + + TXEOF_ENA + 0 + 6 + read-write + + + FIFO_MAP_ENA + 8 + 4 + read-write + + + SLC0_TX_DUMMY_MODE + 12 + 1 + read-write + + + HDA_MAP_128K + 13 + 1 + read-write + + + SLC1_TX_DUMMY_MODE + 14 + 1 + read-write + + + TX_PUSH_IDLE_NUM + 16 + 16 + read-write + + + + + _0_TO_EOF_DES_ADDR + 0x78 + 0x20 + + + SLC0_TO_EOF_DES_ADDR + 0 + 32 + read-only + + + + + _0_TX_EOF_DES_ADDR + 0x7C + 0x20 + + + SLC0_TX_SUC_EOF_DES_ADDR + 0 + 32 + read-only + + + + + _0_TO_EOF_BFR_DES_ADDR + 0x80 + 0x20 + + + SLC0_TO_EOF_BFR_DES_ADDR + 0 + 32 + read-only + + + + + _1_TO_EOF_DES_ADDR + 0x84 + 0x20 + + + SLC1_TO_EOF_DES_ADDR + 0 + 32 + read-only + + + + + _1_TX_EOF_DES_ADDR + 0x88 + 0x20 + + + SLC1_TX_SUC_EOF_DES_ADDR + 0 + 32 + read-only + + + + + _1_TO_EOF_BFR_DES_ADDR + 0x8C + 0x20 + + + SLC1_TO_EOF_BFR_DES_ADDR + 0 + 32 + read-only + + + + + AHB_TEST + 0x90 + 0x20 + + + AHB_TESTMODE + 0 + 3 + read-write + + + AHB_TESTADDR + 4 + 2 + read-write + + + + + SDIO_ST + 0x94 + 0x20 + + + CMD_ST + 0 + 3 + read-only + + + FUNC_ST + 4 + 4 + read-only + + + SDIO_WAKEUP + 8 + 1 + read-only + + + BUS_ST + 12 + 3 + read-only + + + FUNC1_ACC_STATE + 16 + 5 + read-only + + + FUNC2_ACC_STATE + 24 + 5 + read-only + + + + + RX_DSCR_CONF + 0x98 + 0x20 + 0x101B101A + + + SLC0_TOKEN_NO_REPLACE + 0 + 1 + read-write + + + SLC0_INFOR_NO_REPLACE + 1 + 1 + read-write + + + SLC0_RX_FILL_MODE + 2 + 1 + read-write + + + SLC0_RX_EOF_MODE + 3 + 1 + read-write + + + SLC0_RX_FILL_EN + 4 + 1 + read-write + + + SLC0_RD_RETRY_THRESHOLD + 5 + 11 + read-write + + + SLC1_TOKEN_NO_REPLACE + 16 + 1 + read-write + + + SLC1_INFOR_NO_REPLACE + 17 + 1 + read-write + + + SLC1_RX_FILL_MODE + 18 + 1 + read-write + + + SLC1_RX_EOF_MODE + 19 + 1 + read-write + + + SLC1_RX_FILL_EN + 20 + 1 + read-write + + + SLC1_RD_RETRY_THRESHOLD + 21 + 11 + read-write + + + + + _0_TXLINK_DSCR + 0x9C + 0x20 + + + SLC0_TXLINK_DSCR + 0 + 32 + read-only + + + + + _0_TXLINK_DSCR_BF0 + 0xA0 + 0x20 + + + SLC0_TXLINK_DSCR_BF0 + 0 + 32 + read-only + + + + + _0_TXLINK_DSCR_BF1 + 0xA4 + 0x20 + + + SLC0_TXLINK_DSCR_BF1 + 0 + 32 + read-only + + + + + _0_RXLINK_DSCR + 0xA8 + 0x20 + + + SLC0_RXLINK_DSCR + 0 + 32 + read-only + + + + + _0_RXLINK_DSCR_BF0 + 0xAC + 0x20 + + + SLC0_RXLINK_DSCR_BF0 + 0 + 32 + read-only + + + + + _0_RXLINK_DSCR_BF1 + 0xB0 + 0x20 + + + SLC0_RXLINK_DSCR_BF1 + 0 + 32 + read-only + + + + + _1_TXLINK_DSCR + 0xB4 + 0x20 + + + SLC1_TXLINK_DSCR + 0 + 32 + read-only + + + + + _1_TXLINK_DSCR_BF0 + 0xB8 + 0x20 + + + SLC1_TXLINK_DSCR_BF0 + 0 + 32 + read-only + + + + + _1_TXLINK_DSCR_BF1 + 0xBC + 0x20 + + + SLC1_TXLINK_DSCR_BF1 + 0 + 32 + read-only + + + + + _1_RXLINK_DSCR + 0xC0 + 0x20 + + + SLC1_RXLINK_DSCR + 0 + 32 + read-only + + + + + _1_RXLINK_DSCR_BF0 + 0xC4 + 0x20 + + + SLC1_RXLINK_DSCR_BF0 + 0 + 32 + read-only + + + + + _1_RXLINK_DSCR_BF1 + 0xC8 + 0x20 + + + SLC1_RXLINK_DSCR_BF1 + 0 + 32 + read-only + + + + + _0_TX_ERREOF_DES_ADDR + 0xCC + 0x20 + + + SLC0_TX_ERR_EOF_DES_ADDR + 0 + 32 + read-only + + + + + _1_TX_ERREOF_DES_ADDR + 0xD0 + 0x20 + + + SLC1_TX_ERR_EOF_DES_ADDR + 0 + 32 + read-only + + + + + TOKEN_LAT + 0xD4 + 0x20 + + + SLC0_TOKEN + 0 + 12 + read-only + + + SLC1_TOKEN + 16 + 12 + read-only + + + + + TX_DSCR_CONF + 0xD8 + 0x20 + 0x00000080 + + + WR_RETRY_THRESHOLD + 0 + 11 + read-write + + + + + CMD_INFOR0 + 0xDC + 0x20 + + + CMD_CONTENT0 + 0 + 32 + read-only + + + + + CMD_INFOR1 + 0xE0 + 0x20 + + + CMD_CONTENT1 + 0 + 32 + read-only + + + + + _0_LEN_CONF + 0xE4 + 0x20 + + + SLC0_LEN_WDATA + 0 + 20 + write-only + + + SLC0_LEN_WR + 20 + 1 + write-only + + + SLC0_LEN_INC + 21 + 1 + write-only + + + SLC0_LEN_INC_MORE + 22 + 1 + write-only + + + SLC0_RX_PACKET_LOAD_EN + 23 + 1 + read-write + + + SLC0_TX_PACKET_LOAD_EN + 24 + 1 + read-write + + + SLC0_RX_GET_USED_DSCR + 25 + 1 + write-only + + + SLC0_TX_GET_USED_DSCR + 26 + 1 + write-only + + + SLC0_RX_NEW_PKT_IND + 27 + 1 + read-only + + + SLC0_TX_NEW_PKT_IND + 28 + 1 + read-only + + + + + _0_LENGTH + 0xE8 + 0x20 + + + SLC0_LEN + 0 + 20 + read-only + + + + + _0_TXPKT_H_DSCR + 0xEC + 0x20 + + + SLC0_TX_PKT_H_DSCR_ADDR + 0 + 32 + read-write + + + + + _0_TXPKT_E_DSCR + 0xF0 + 0x20 + + + SLC0_TX_PKT_E_DSCR_ADDR + 0 + 32 + read-write + + + + + _0_RXPKT_H_DSCR + 0xF4 + 0x20 + + + SLC0_RX_PKT_H_DSCR_ADDR + 0 + 32 + read-write + + + + + _0_RXPKT_E_DSCR + 0xF8 + 0x20 + + + SLC0_RX_PKT_E_DSCR_ADDR + 0 + 32 + read-write + + + + + _0_TXPKTU_H_DSCR + 0xFC + 0x20 + + + SLC0_TX_PKT_START_DSCR_ADDR + 0 + 32 + read-only + + + + + _0_TXPKTU_E_DSCR + 0x100 + 0x20 + + + SLC0_TX_PKT_END_DSCR_ADDR + 0 + 32 + read-only + + + + + _0_RXPKTU_H_DSCR + 0x104 + 0x20 + + + SLC0_RX_PKT_START_DSCR_ADDR + 0 + 32 + read-only + + + + + _0_RXPKTU_E_DSCR + 0x108 + 0x20 + + + SLC0_RX_PKT_END_DSCR_ADDR + 0 + 32 + read-only + + + + + SEQ_POSITION + 0x114 + 0x20 + 0x00000509 + + + SLC0_SEQ_POSITION + 0 + 8 + read-write + + + SLC1_SEQ_POSITION + 8 + 8 + read-write + + + + + _0_DSCR_REC_CONF + 0x118 + 0x20 + 0x000003FF + + + SLC0_RX_DSCR_REC_LIM + 0 + 10 + read-write + + + + + SDIO_CRC_ST0 + 0x11C + 0x20 + + + DAT0_CRC_ERR_CNT + 0 + 8 + read-only + + + DAT1_CRC_ERR_CNT + 8 + 8 + read-only + + + DAT2_CRC_ERR_CNT + 16 + 8 + read-only + + + DAT3_CRC_ERR_CNT + 24 + 8 + read-only + + + + + SDIO_CRC_ST1 + 0x120 + 0x20 + + + CMD_CRC_ERR_CNT + 0 + 8 + read-only + + + ERR_CNT_CLR + 31 + 1 + read-write + + + + + _0_EOF_START_DES + 0x124 + 0x20 + + + SLC0_EOF_START_DES_ADDR + 0 + 32 + read-only + + + + + _0_PUSH_DSCR_ADDR + 0x128 + 0x20 + + + SLC0_RX_PUSH_DSCR_ADDR + 0 + 32 + read-only + + + + + _0_DONE_DSCR_ADDR + 0x12C + 0x20 + + + SLC0_RX_DONE_DSCR_ADDR + 0 + 32 + read-only + + + + + _0_SUB_START_DES + 0x130 + 0x20 + + + SLC0_SUB_PAC_START_DSCR_ADDR + 0 + 32 + read-only + + + + + _0_DSCR_CNT + 0x134 + 0x20 + + + SLC0_RX_DSCR_CNT_LAT + 0 + 10 + read-only + + + SLC0_RX_GET_EOF_OCC + 16 + 1 + read-only + + + + + _0_LEN_LIM_CONF + 0x138 + 0x20 + 0x00005400 + + + SLC0_LEN_LIM + 0 + 20 + read-write + + + + + _0INT_ST1 + 0x13C + 0x20 + + + FRHOST_BIT0_INT_ST1 + 0 + 1 + read-only + + + FRHOST_BIT1_INT_ST1 + 1 + 1 + read-only + + + FRHOST_BIT2_INT_ST1 + 2 + 1 + read-only + + + FRHOST_BIT3_INT_ST1 + 3 + 1 + read-only + + + FRHOST_BIT4_INT_ST1 + 4 + 1 + read-only + + + FRHOST_BIT5_INT_ST1 + 5 + 1 + read-only + + + FRHOST_BIT6_INT_ST1 + 6 + 1 + read-only + + + FRHOST_BIT7_INT_ST1 + 7 + 1 + read-only + + + SLC0_RX_START_INT_ST1 + 8 + 1 + read-only + + + SLC0_TX_START_INT_ST1 + 9 + 1 + read-only + + + SLC0_RX_UDF_INT_ST1 + 10 + 1 + read-only + + + SLC0_TX_OVF_INT_ST1 + 11 + 1 + read-only + + + SLC0_TOKEN0_1TO0_INT_ST1 + 12 + 1 + read-only + + + SLC0_TOKEN1_1TO0_INT_ST1 + 13 + 1 + read-only + + + SLC0_TX_DONE_INT_ST1 + 14 + 1 + read-only + + + SLC0_TX_SUC_EOF_INT_ST1 + 15 + 1 + read-only + + + SLC0_RX_DONE_INT_ST1 + 16 + 1 + read-only + + + SLC0_RX_EOF_INT_ST1 + 17 + 1 + read-only + + + SLC0_TOHOST_INT_ST1 + 18 + 1 + read-only + + + SLC0_TX_DSCR_ERR_INT_ST1 + 19 + 1 + read-only + + + SLC0_RX_DSCR_ERR_INT_ST1 + 20 + 1 + read-only + + + SLC0_TX_DSCR_EMPTY_INT_ST1 + 21 + 1 + read-only + + + SLC0_HOST_RD_ACK_INT_ST1 + 22 + 1 + read-only + + + SLC0_WR_RETRY_DONE_INT_ST1 + 23 + 1 + read-only + + + SLC0_TX_ERR_EOF_INT_ST1 + 24 + 1 + read-only + + + CMD_DTC_INT_ST1 + 25 + 1 + read-only + + + SLC0_RX_QUICK_EOF_INT_ST1 + 26 + 1 + read-only + + + + + _0INT_ENA1 + 0x140 + 0x20 + + + FRHOST_BIT0_INT_ENA1 + 0 + 1 + read-write + + + FRHOST_BIT1_INT_ENA1 + 1 + 1 + read-write + + + FRHOST_BIT2_INT_ENA1 + 2 + 1 + read-write + + + FRHOST_BIT3_INT_ENA1 + 3 + 1 + read-write + + + FRHOST_BIT4_INT_ENA1 + 4 + 1 + read-write + + + FRHOST_BIT5_INT_ENA1 + 5 + 1 + read-write + + + FRHOST_BIT6_INT_ENA1 + 6 + 1 + read-write + + + FRHOST_BIT7_INT_ENA1 + 7 + 1 + read-write + + + SLC0_RX_START_INT_ENA1 + 8 + 1 + read-write + + + SLC0_TX_START_INT_ENA1 + 9 + 1 + read-write + + + SLC0_RX_UDF_INT_ENA1 + 10 + 1 + read-write + + + SLC0_TX_OVF_INT_ENA1 + 11 + 1 + read-write + + + SLC0_TOKEN0_1TO0_INT_ENA1 + 12 + 1 + read-write + + + SLC0_TOKEN1_1TO0_INT_ENA1 + 13 + 1 + read-write + + + SLC0_TX_DONE_INT_ENA1 + 14 + 1 + read-write + + + SLC0_TX_SUC_EOF_INT_ENA1 + 15 + 1 + read-write + + + SLC0_RX_DONE_INT_ENA1 + 16 + 1 + read-write + + + SLC0_RX_EOF_INT_ENA1 + 17 + 1 + read-write + + + SLC0_TOHOST_INT_ENA1 + 18 + 1 + read-write + + + SLC0_TX_DSCR_ERR_INT_ENA1 + 19 + 1 + read-write + + + SLC0_RX_DSCR_ERR_INT_ENA1 + 20 + 1 + read-write + + + SLC0_TX_DSCR_EMPTY_INT_ENA1 + 21 + 1 + read-write + + + SLC0_HOST_RD_ACK_INT_ENA1 + 22 + 1 + read-write + + + SLC0_WR_RETRY_DONE_INT_ENA1 + 23 + 1 + read-write + + + SLC0_TX_ERR_EOF_INT_ENA1 + 24 + 1 + read-write + + + CMD_DTC_INT_ENA1 + 25 + 1 + read-write + + + SLC0_RX_QUICK_EOF_INT_ENA1 + 26 + 1 + read-write + + + + + _1INT_ST1 + 0x144 + 0x20 + + + FRHOST_BIT8_INT_ST1 + 0 + 1 + read-only + + + FRHOST_BIT9_INT_ST1 + 1 + 1 + read-only + + + FRHOST_BIT10_INT_ST1 + 2 + 1 + read-only + + + FRHOST_BIT11_INT_ST1 + 3 + 1 + read-only + + + FRHOST_BIT12_INT_ST1 + 4 + 1 + read-only + + + FRHOST_BIT13_INT_ST1 + 5 + 1 + read-only + + + FRHOST_BIT14_INT_ST1 + 6 + 1 + read-only + + + FRHOST_BIT15_INT_ST1 + 7 + 1 + read-only + + + SLC1_RX_START_INT_ST1 + 8 + 1 + read-only + + + SLC1_TX_START_INT_ST1 + 9 + 1 + read-only + + + SLC1_RX_UDF_INT_ST1 + 10 + 1 + read-only + + + SLC1_TX_OVF_INT_ST1 + 11 + 1 + read-only + + + SLC1_TOKEN0_1TO0_INT_ST1 + 12 + 1 + read-only + + + SLC1_TOKEN1_1TO0_INT_ST1 + 13 + 1 + read-only + + + SLC1_TX_DONE_INT_ST1 + 14 + 1 + read-only + + + SLC1_TX_SUC_EOF_INT_ST1 + 15 + 1 + read-only + + + SLC1_RX_DONE_INT_ST1 + 16 + 1 + read-only + + + SLC1_RX_EOF_INT_ST1 + 17 + 1 + read-only + + + SLC1_TOHOST_INT_ST1 + 18 + 1 + read-only + + + SLC1_TX_DSCR_ERR_INT_ST1 + 19 + 1 + read-only + + + SLC1_RX_DSCR_ERR_INT_ST1 + 20 + 1 + read-only + + + SLC1_TX_DSCR_EMPTY_INT_ST1 + 21 + 1 + read-only + + + SLC1_HOST_RD_ACK_INT_ST1 + 22 + 1 + read-only + + + SLC1_WR_RETRY_DONE_INT_ST1 + 23 + 1 + read-only + + + SLC1_TX_ERR_EOF_INT_ST1 + 24 + 1 + read-only + + + + + _1INT_ENA1 + 0x148 + 0x20 + + + FRHOST_BIT8_INT_ENA1 + 0 + 1 + read-write + + + FRHOST_BIT9_INT_ENA1 + 1 + 1 + read-write + + + FRHOST_BIT10_INT_ENA1 + 2 + 1 + read-write + + + FRHOST_BIT11_INT_ENA1 + 3 + 1 + read-write + + + FRHOST_BIT12_INT_ENA1 + 4 + 1 + read-write + + + FRHOST_BIT13_INT_ENA1 + 5 + 1 + read-write + + + FRHOST_BIT14_INT_ENA1 + 6 + 1 + read-write + + + FRHOST_BIT15_INT_ENA1 + 7 + 1 + read-write + + + SLC1_RX_START_INT_ENA1 + 8 + 1 + read-write + + + SLC1_TX_START_INT_ENA1 + 9 + 1 + read-write + + + SLC1_RX_UDF_INT_ENA1 + 10 + 1 + read-write + + + SLC1_TX_OVF_INT_ENA1 + 11 + 1 + read-write + + + SLC1_TOKEN0_1TO0_INT_ENA1 + 12 + 1 + read-write + + + SLC1_TOKEN1_1TO0_INT_ENA1 + 13 + 1 + read-write + + + SLC1_TX_DONE_INT_ENA1 + 14 + 1 + read-write + + + SLC1_TX_SUC_EOF_INT_ENA1 + 15 + 1 + read-write + + + SLC1_RX_DONE_INT_ENA1 + 16 + 1 + read-write + + + SLC1_RX_EOF_INT_ENA1 + 17 + 1 + read-write + + + SLC1_TOHOST_INT_ENA1 + 18 + 1 + read-write + + + SLC1_TX_DSCR_ERR_INT_ENA1 + 19 + 1 + read-write + + + SLC1_RX_DSCR_ERR_INT_ENA1 + 20 + 1 + read-write + + + SLC1_TX_DSCR_EMPTY_INT_ENA1 + 21 + 1 + read-write + + + SLC1_HOST_RD_ACK_INT_ENA1 + 22 + 1 + read-write + + + SLC1_WR_RETRY_DONE_INT_ENA1 + 23 + 1 + read-write + + + SLC1_TX_ERR_EOF_INT_ENA1 + 24 + 1 + read-write + + + + + DATE + 0x1F8 + 0x20 + 0x16022500 + + + DATE + 0 + 32 + read-write + + + + + ID + 0x1FC + 0x20 + 0x00000100 + + + ID + 0 + 32 + read-write + + + + + + + SLCHOST + Peripheral SLCHOST + SLCHOST + 0x3FF55000 + + 0x0 + 0x104 + registers + + + + HOST_SLCHOST_FUNC2_0 + 0x10 + 0x20 + + + HOST_SLC_FUNC2_INT + 24 + 1 + read-write + + + + + HOST_SLCHOST_FUNC2_1 + 0x14 + 0x20 + + + HOST_SLC_FUNC2_INT_EN + 0 + 1 + read-write + + + + + HOST_SLCHOST_FUNC2_2 + 0x20 + 0x20 + 0x00000001 + + + HOST_SLC_FUNC1_MDSTAT + 0 + 1 + read-write + + + + + HOST_SLCHOST_GPIO_STATUS0 + 0x34 + 0x20 + + + HOST_GPIO_SDIO_INT0 + 0 + 32 + read-only + + + + + HOST_SLCHOST_GPIO_STATUS1 + 0x38 + 0x20 + + + HOST_GPIO_SDIO_INT1 + 0 + 8 + read-only + + + + + HOST_SLCHOST_GPIO_IN0 + 0x3C + 0x20 + + + HOST_GPIO_SDIO_IN0 + 0 + 32 + read-only + + + + + HOST_SLCHOST_GPIO_IN1 + 0x40 + 0x20 + + + HOST_GPIO_SDIO_IN1 + 0 + 8 + read-only + + + + + HOST_SLC0HOST_TOKEN_RDATA + 0x44 + 0x20 + + + HOST_SLC0_TOKEN0 + 0 + 12 + read-only + + + HOST_SLC0_RX_PF_VALID + 12 + 1 + read-only + + + HOST_HOSTSLC0_TOKEN1 + 16 + 12 + read-only + + + HOST_SLC0_RX_PF_EOF + 28 + 4 + read-only + + + + + HOST_SLC0_HOST_PF + 0x48 + 0x20 + + + HOST_SLC0_PF_DATA + 0 + 32 + read-only + + + + + HOST_SLC1_HOST_PF + 0x4C + 0x20 + + + HOST_SLC1_PF_DATA + 0 + 32 + read-only + + + + + HOST_SLC0HOST_INT_RAW + 0x50 + 0x20 + + + HOST_SLC0_TOHOST_BIT0_INT_RAW + 0 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT1_INT_RAW + 1 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT2_INT_RAW + 2 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT3_INT_RAW + 3 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT4_INT_RAW + 4 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT5_INT_RAW + 5 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT6_INT_RAW + 6 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT7_INT_RAW + 7 + 1 + read-only + + + HOST_SLC0_TOKEN0_1TO0_INT_RAW + 8 + 1 + read-only + + + HOST_SLC0_TOKEN1_1TO0_INT_RAW + 9 + 1 + read-only + + + HOST_SLC0_TOKEN0_0TO1_INT_RAW + 10 + 1 + read-only + + + HOST_SLC0_TOKEN1_0TO1_INT_RAW + 11 + 1 + read-only + + + HOST_SLC0HOST_RX_SOF_INT_RAW + 12 + 1 + read-only + + + HOST_SLC0HOST_RX_EOF_INT_RAW + 13 + 1 + read-only + + + HOST_SLC0HOST_RX_START_INT_RAW + 14 + 1 + read-only + + + HOST_SLC0HOST_TX_START_INT_RAW + 15 + 1 + read-only + + + HOST_SLC0_RX_UDF_INT_RAW + 16 + 1 + read-only + + + HOST_SLC0_TX_OVF_INT_RAW + 17 + 1 + read-only + + + HOST_SLC0_RX_PF_VALID_INT_RAW + 18 + 1 + read-only + + + HOST_SLC0_EXT_BIT0_INT_RAW + 19 + 1 + read-only + + + HOST_SLC0_EXT_BIT1_INT_RAW + 20 + 1 + read-only + + + HOST_SLC0_EXT_BIT2_INT_RAW + 21 + 1 + read-only + + + HOST_SLC0_EXT_BIT3_INT_RAW + 22 + 1 + read-only + + + HOST_SLC0_RX_NEW_PACKET_INT_RAW + 23 + 1 + read-only + + + HOST_SLC0_HOST_RD_RETRY_INT_RAW + 24 + 1 + read-only + + + HOST_GPIO_SDIO_INT_RAW + 25 + 1 + read-only + + + + + HOST_SLC1HOST_INT_RAW + 0x54 + 0x20 + + + HOST_SLC1_TOHOST_BIT0_INT_RAW + 0 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT1_INT_RAW + 1 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT2_INT_RAW + 2 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT3_INT_RAW + 3 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT4_INT_RAW + 4 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT5_INT_RAW + 5 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT6_INT_RAW + 6 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT7_INT_RAW + 7 + 1 + read-only + + + HOST_SLC1_TOKEN0_1TO0_INT_RAW + 8 + 1 + read-only + + + HOST_SLC1_TOKEN1_1TO0_INT_RAW + 9 + 1 + read-only + + + HOST_SLC1_TOKEN0_0TO1_INT_RAW + 10 + 1 + read-only + + + HOST_SLC1_TOKEN1_0TO1_INT_RAW + 11 + 1 + read-only + + + HOST_SLC1HOST_RX_SOF_INT_RAW + 12 + 1 + read-only + + + HOST_SLC1HOST_RX_EOF_INT_RAW + 13 + 1 + read-only + + + HOST_SLC1HOST_RX_START_INT_RAW + 14 + 1 + read-only + + + HOST_SLC1HOST_TX_START_INT_RAW + 15 + 1 + read-only + + + HOST_SLC1_RX_UDF_INT_RAW + 16 + 1 + read-only + + + HOST_SLC1_TX_OVF_INT_RAW + 17 + 1 + read-only + + + HOST_SLC1_RX_PF_VALID_INT_RAW + 18 + 1 + read-only + + + HOST_SLC1_EXT_BIT0_INT_RAW + 19 + 1 + read-only + + + HOST_SLC1_EXT_BIT1_INT_RAW + 20 + 1 + read-only + + + HOST_SLC1_EXT_BIT2_INT_RAW + 21 + 1 + read-only + + + HOST_SLC1_EXT_BIT3_INT_RAW + 22 + 1 + read-only + + + HOST_SLC1_WIFI_RX_NEW_PACKET_INT_RAW + 23 + 1 + read-only + + + HOST_SLC1_HOST_RD_RETRY_INT_RAW + 24 + 1 + read-only + + + HOST_SLC1_BT_RX_NEW_PACKET_INT_RAW + 25 + 1 + read-only + + + + + HOST_SLC0HOST_INT_ST + 0x58 + 0x20 + + + HOST_SLC0_TOHOST_BIT0_INT_ST + 0 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT1_INT_ST + 1 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT2_INT_ST + 2 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT3_INT_ST + 3 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT4_INT_ST + 4 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT5_INT_ST + 5 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT6_INT_ST + 6 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT7_INT_ST + 7 + 1 + read-only + + + HOST_SLC0_TOKEN0_1TO0_INT_ST + 8 + 1 + read-only + + + HOST_SLC0_TOKEN1_1TO0_INT_ST + 9 + 1 + read-only + + + HOST_SLC0_TOKEN0_0TO1_INT_ST + 10 + 1 + read-only + + + HOST_SLC0_TOKEN1_0TO1_INT_ST + 11 + 1 + read-only + + + HOST_SLC0HOST_RX_SOF_INT_ST + 12 + 1 + read-only + + + HOST_SLC0HOST_RX_EOF_INT_ST + 13 + 1 + read-only + + + HOST_SLC0HOST_RX_START_INT_ST + 14 + 1 + read-only + + + HOST_SLC0HOST_TX_START_INT_ST + 15 + 1 + read-only + + + HOST_SLC0_RX_UDF_INT_ST + 16 + 1 + read-only + + + HOST_SLC0_TX_OVF_INT_ST + 17 + 1 + read-only + + + HOST_SLC0_RX_PF_VALID_INT_ST + 18 + 1 + read-only + + + HOST_SLC0_EXT_BIT0_INT_ST + 19 + 1 + read-only + + + HOST_SLC0_EXT_BIT1_INT_ST + 20 + 1 + read-only + + + HOST_SLC0_EXT_BIT2_INT_ST + 21 + 1 + read-only + + + HOST_SLC0_EXT_BIT3_INT_ST + 22 + 1 + read-only + + + HOST_SLC0_RX_NEW_PACKET_INT_ST + 23 + 1 + read-only + + + HOST_SLC0_HOST_RD_RETRY_INT_ST + 24 + 1 + read-only + + + HOST_GPIO_SDIO_INT_ST + 25 + 1 + read-only + + + + + HOST_SLC1HOST_INT_ST + 0x5C + 0x20 + + + HOST_SLC1_TOHOST_BIT0_INT_ST + 0 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT1_INT_ST + 1 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT2_INT_ST + 2 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT3_INT_ST + 3 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT4_INT_ST + 4 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT5_INT_ST + 5 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT6_INT_ST + 6 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT7_INT_ST + 7 + 1 + read-only + + + HOST_SLC1_TOKEN0_1TO0_INT_ST + 8 + 1 + read-only + + + HOST_SLC1_TOKEN1_1TO0_INT_ST + 9 + 1 + read-only + + + HOST_SLC1_TOKEN0_0TO1_INT_ST + 10 + 1 + read-only + + + HOST_SLC1_TOKEN1_0TO1_INT_ST + 11 + 1 + read-only + + + HOST_SLC1HOST_RX_SOF_INT_ST + 12 + 1 + read-only + + + HOST_SLC1HOST_RX_EOF_INT_ST + 13 + 1 + read-only + + + HOST_SLC1HOST_RX_START_INT_ST + 14 + 1 + read-only + + + HOST_SLC1HOST_TX_START_INT_ST + 15 + 1 + read-only + + + HOST_SLC1_RX_UDF_INT_ST + 16 + 1 + read-only + + + HOST_SLC1_TX_OVF_INT_ST + 17 + 1 + read-only + + + HOST_SLC1_RX_PF_VALID_INT_ST + 18 + 1 + read-only + + + HOST_SLC1_EXT_BIT0_INT_ST + 19 + 1 + read-only + + + HOST_SLC1_EXT_BIT1_INT_ST + 20 + 1 + read-only + + + HOST_SLC1_EXT_BIT2_INT_ST + 21 + 1 + read-only + + + HOST_SLC1_EXT_BIT3_INT_ST + 22 + 1 + read-only + + + HOST_SLC1_WIFI_RX_NEW_PACKET_INT_ST + 23 + 1 + read-only + + + HOST_SLC1_HOST_RD_RETRY_INT_ST + 24 + 1 + read-only + + + HOST_SLC1_BT_RX_NEW_PACKET_INT_ST + 25 + 1 + read-only + + + + + HOST_SLCHOST_PKT_LEN + 0x60 + 0x20 + + + HOST_HOSTSLC0_LEN + 0 + 20 + read-only + + + HOST_HOSTSLC0_LEN_CHECK + 20 + 12 + read-only + + + + + HOST_SLCHOST_STATE_W0 + 0x64 + 0x20 + + + HOST_SLCHOST_STATE0 + 0 + 8 + read-only + + + HOST_SLCHOST_STATE1 + 8 + 8 + read-only + + + HOST_SLCHOST_STATE2 + 16 + 8 + read-only + + + HOST_SLCHOST_STATE3 + 24 + 8 + read-only + + + + + HOST_SLCHOST_STATE_W1 + 0x68 + 0x20 + + + HOST_SLCHOST_STATE4 + 0 + 8 + read-only + + + HOST_SLCHOST_STATE5 + 8 + 8 + read-only + + + HOST_SLCHOST_STATE6 + 16 + 8 + read-only + + + HOST_SLCHOST_STATE7 + 24 + 8 + read-only + + + + + HOST_SLCHOST_CONF_W0 + 0x6C + 0x20 + + + HOST_SLCHOST_CONF0 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF1 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF2 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF3 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W1 + 0x70 + 0x20 + + + HOST_SLCHOST_CONF4 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF5 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF6 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF7 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W2 + 0x74 + 0x20 + + + HOST_SLCHOST_CONF8 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF9 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF10 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF11 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W3 + 0x78 + 0x20 + 0x000000C0 + + + HOST_SLCHOST_CONF12 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF13 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF14 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF15 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W4 + 0x7C + 0x20 + 0x000001FF + + + HOST_SLCHOST_CONF16 + SLC timeout value + 0 + 8 + read-write + + + HOST_SLCHOST_CONF17 + SLC timeout enable + 8 + 8 + read-write + + + HOST_SLCHOST_CONF18 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF19 + Interrupt to target CPU + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W5 + 0x80 + 0x20 + + + HOST_SLCHOST_CONF20 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF21 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF22 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF23 + 24 + 8 + read-write + + + + + HOST_SLCHOST_WIN_CMD + 0x84 + 0x20 + + + HOST_SLCHOST_CONF_W6 + 0x88 + 0x20 + + + HOST_SLCHOST_CONF24 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF25 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF26 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF27 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W7 + 0x8C + 0x20 + + + HOST_SLCHOST_CONF28 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF29 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF30 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF31 + 24 + 8 + read-write + + + + + HOST_SLCHOST_PKT_LEN0 + 0x90 + 0x20 + + + HOST_HOSTSLC0_LEN0 + 0 + 20 + read-only + + + + + HOST_SLCHOST_PKT_LEN1 + 0x94 + 0x20 + + + HOST_HOSTSLC0_LEN1 + 0 + 20 + read-only + + + + + HOST_SLCHOST_PKT_LEN2 + 0x98 + 0x20 + + + HOST_HOSTSLC0_LEN2 + 0 + 20 + read-only + + + + + HOST_SLCHOST_CONF_W8 + 0x9C + 0x20 + + + HOST_SLCHOST_CONF32 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF33 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF34 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF35 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W9 + 0xA0 + 0x20 + + + HOST_SLCHOST_CONF36 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF37 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF38 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF39 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W10 + 0xA4 + 0x20 + + + HOST_SLCHOST_CONF40 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF41 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF42 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF43 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W11 + 0xA8 + 0x20 + + + HOST_SLCHOST_CONF44 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF45 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF46 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF47 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W12 + 0xAC + 0x20 + + + HOST_SLCHOST_CONF48 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF49 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF50 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF51 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W13 + 0xB0 + 0x20 + + + HOST_SLCHOST_CONF52 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF53 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF54 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF55 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W14 + 0xB4 + 0x20 + + + HOST_SLCHOST_CONF56 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF57 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF58 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF59 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W15 + 0xB8 + 0x20 + + + HOST_SLCHOST_CONF60 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF61 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF62 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF63 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CHECK_SUM0 + 0xBC + 0x20 + + + HOST_SLCHOST_CHECK_SUM0 + 0 + 32 + read-only + + + + + HOST_SLCHOST_CHECK_SUM1 + 0xC0 + 0x20 + + + HOST_SLCHOST_CHECK_SUM1 + 0 + 32 + read-only + + + + + HOST_SLC1HOST_TOKEN_RDATA + 0xC4 + 0x20 + + + HOST_SLC1_TOKEN0 + 0 + 12 + read-only + + + HOST_SLC1_RX_PF_VALID + 12 + 1 + read-only + + + HOST_HOSTSLC1_TOKEN1 + 16 + 12 + read-only + + + HOST_SLC1_RX_PF_EOF + 28 + 4 + read-only + + + + + HOST_SLC0HOST_TOKEN_WDATA + 0xC8 + 0x20 + + + HOST_SLC0HOST_TOKEN0_WD + 0 + 12 + read-write + + + HOST_SLC0HOST_TOKEN1_WD + 16 + 12 + read-write + + + + + HOST_SLC1HOST_TOKEN_WDATA + 0xCC + 0x20 + + + HOST_SLC1HOST_TOKEN0_WD + 0 + 12 + read-write + + + HOST_SLC1HOST_TOKEN1_WD + 16 + 12 + read-write + + + + + HOST_SLCHOST_TOKEN_CON + 0xD0 + 0x20 + + + HOST_SLC0HOST_TOKEN0_DEC + 0 + 1 + write-only + + + HOST_SLC0HOST_TOKEN1_DEC + 1 + 1 + write-only + + + HOST_SLC0HOST_TOKEN0_WR + 2 + 1 + write-only + + + HOST_SLC0HOST_TOKEN1_WR + 3 + 1 + write-only + + + HOST_SLC1HOST_TOKEN0_DEC + 4 + 1 + write-only + + + HOST_SLC1HOST_TOKEN1_DEC + 5 + 1 + write-only + + + HOST_SLC1HOST_TOKEN0_WR + 6 + 1 + write-only + + + HOST_SLC1HOST_TOKEN1_WR + 7 + 1 + write-only + + + HOST_SLC0HOST_LEN_WR + 8 + 1 + write-only + + + + + HOST_SLC0HOST_INT_CLR + 0xD4 + 0x20 + + + HOST_SLC0_TOHOST_BIT0_INT_CLR + 0 + 1 + write-only + + + HOST_SLC0_TOHOST_BIT1_INT_CLR + 1 + 1 + write-only + + + HOST_SLC0_TOHOST_BIT2_INT_CLR + 2 + 1 + write-only + + + HOST_SLC0_TOHOST_BIT3_INT_CLR + 3 + 1 + write-only + + + HOST_SLC0_TOHOST_BIT4_INT_CLR + 4 + 1 + write-only + + + HOST_SLC0_TOHOST_BIT5_INT_CLR + 5 + 1 + write-only + + + HOST_SLC0_TOHOST_BIT6_INT_CLR + 6 + 1 + write-only + + + HOST_SLC0_TOHOST_BIT7_INT_CLR + 7 + 1 + write-only + + + HOST_SLC0_TOKEN0_1TO0_INT_CLR + 8 + 1 + write-only + + + HOST_SLC0_TOKEN1_1TO0_INT_CLR + 9 + 1 + write-only + + + HOST_SLC0_TOKEN0_0TO1_INT_CLR + 10 + 1 + write-only + + + HOST_SLC0_TOKEN1_0TO1_INT_CLR + 11 + 1 + write-only + + + HOST_SLC0HOST_RX_SOF_INT_CLR + 12 + 1 + write-only + + + HOST_SLC0HOST_RX_EOF_INT_CLR + 13 + 1 + write-only + + + HOST_SLC0HOST_RX_START_INT_CLR + 14 + 1 + write-only + + + HOST_SLC0HOST_TX_START_INT_CLR + 15 + 1 + write-only + + + HOST_SLC0_RX_UDF_INT_CLR + 16 + 1 + write-only + + + HOST_SLC0_TX_OVF_INT_CLR + 17 + 1 + write-only + + + HOST_SLC0_RX_PF_VALID_INT_CLR + 18 + 1 + write-only + + + HOST_SLC0_EXT_BIT0_INT_CLR + 19 + 1 + write-only + + + HOST_SLC0_EXT_BIT1_INT_CLR + 20 + 1 + write-only + + + HOST_SLC0_EXT_BIT2_INT_CLR + 21 + 1 + write-only + + + HOST_SLC0_EXT_BIT3_INT_CLR + 22 + 1 + write-only + + + HOST_SLC0_RX_NEW_PACKET_INT_CLR + 23 + 1 + write-only + + + HOST_SLC0_HOST_RD_RETRY_INT_CLR + 24 + 1 + write-only + + + HOST_GPIO_SDIO_INT_CLR + 25 + 1 + write-only + + + + + HOST_SLC1HOST_INT_CLR + 0xD8 + 0x20 + + + HOST_SLC1_TOHOST_BIT0_INT_CLR + 0 + 1 + write-only + + + HOST_SLC1_TOHOST_BIT1_INT_CLR + 1 + 1 + write-only + + + HOST_SLC1_TOHOST_BIT2_INT_CLR + 2 + 1 + write-only + + + HOST_SLC1_TOHOST_BIT3_INT_CLR + 3 + 1 + write-only + + + HOST_SLC1_TOHOST_BIT4_INT_CLR + 4 + 1 + write-only + + + HOST_SLC1_TOHOST_BIT5_INT_CLR + 5 + 1 + write-only + + + HOST_SLC1_TOHOST_BIT6_INT_CLR + 6 + 1 + write-only + + + HOST_SLC1_TOHOST_BIT7_INT_CLR + 7 + 1 + write-only + + + HOST_SLC1_TOKEN0_1TO0_INT_CLR + 8 + 1 + write-only + + + HOST_SLC1_TOKEN1_1TO0_INT_CLR + 9 + 1 + write-only + + + HOST_SLC1_TOKEN0_0TO1_INT_CLR + 10 + 1 + write-only + + + HOST_SLC1_TOKEN1_0TO1_INT_CLR + 11 + 1 + write-only + + + HOST_SLC1HOST_RX_SOF_INT_CLR + 12 + 1 + write-only + + + HOST_SLC1HOST_RX_EOF_INT_CLR + 13 + 1 + write-only + + + HOST_SLC1HOST_RX_START_INT_CLR + 14 + 1 + write-only + + + HOST_SLC1HOST_TX_START_INT_CLR + 15 + 1 + write-only + + + HOST_SLC1_RX_UDF_INT_CLR + 16 + 1 + write-only + + + HOST_SLC1_TX_OVF_INT_CLR + 17 + 1 + write-only + + + HOST_SLC1_RX_PF_VALID_INT_CLR + 18 + 1 + write-only + + + HOST_SLC1_EXT_BIT0_INT_CLR + 19 + 1 + write-only + + + HOST_SLC1_EXT_BIT1_INT_CLR + 20 + 1 + write-only + + + HOST_SLC1_EXT_BIT2_INT_CLR + 21 + 1 + write-only + + + HOST_SLC1_EXT_BIT3_INT_CLR + 22 + 1 + write-only + + + HOST_SLC1_WIFI_RX_NEW_PACKET_INT_CLR + 23 + 1 + write-only + + + HOST_SLC1_HOST_RD_RETRY_INT_CLR + 24 + 1 + write-only + + + HOST_SLC1_BT_RX_NEW_PACKET_INT_CLR + 25 + 1 + write-only + + + + + HOST_SLC0HOST_FUNC1_INT_ENA + 0xDC + 0x20 + + + HOST_FN1_SLC0_TOHOST_BIT0_INT_ENA + 0 + 1 + read-write + + + HOST_FN1_SLC0_TOHOST_BIT1_INT_ENA + 1 + 1 + read-write + + + HOST_FN1_SLC0_TOHOST_BIT2_INT_ENA + 2 + 1 + read-write + + + HOST_FN1_SLC0_TOHOST_BIT3_INT_ENA + 3 + 1 + read-write + + + HOST_FN1_SLC0_TOHOST_BIT4_INT_ENA + 4 + 1 + read-write + + + HOST_FN1_SLC0_TOHOST_BIT5_INT_ENA + 5 + 1 + read-write + + + HOST_FN1_SLC0_TOHOST_BIT6_INT_ENA + 6 + 1 + read-write + + + HOST_FN1_SLC0_TOHOST_BIT7_INT_ENA + 7 + 1 + read-write + + + HOST_FN1_SLC0_TOKEN0_1TO0_INT_ENA + 8 + 1 + read-write + + + HOST_FN1_SLC0_TOKEN1_1TO0_INT_ENA + 9 + 1 + read-write + + + HOST_FN1_SLC0_TOKEN0_0TO1_INT_ENA + 10 + 1 + read-write + + + HOST_FN1_SLC0_TOKEN1_0TO1_INT_ENA + 11 + 1 + read-write + + + HOST_FN1_SLC0HOST_RX_SOF_INT_ENA + 12 + 1 + read-write + + + HOST_FN1_SLC0HOST_RX_EOF_INT_ENA + 13 + 1 + read-write + + + HOST_FN1_SLC0HOST_RX_START_INT_ENA + 14 + 1 + read-write + + + HOST_FN1_SLC0HOST_TX_START_INT_ENA + 15 + 1 + read-write + + + HOST_FN1_SLC0_RX_UDF_INT_ENA + 16 + 1 + read-write + + + HOST_FN1_SLC0_TX_OVF_INT_ENA + 17 + 1 + read-write + + + HOST_FN1_SLC0_RX_PF_VALID_INT_ENA + 18 + 1 + read-write + + + HOST_FN1_SLC0_EXT_BIT0_INT_ENA + 19 + 1 + read-write + + + HOST_FN1_SLC0_EXT_BIT1_INT_ENA + 20 + 1 + read-write + + + HOST_FN1_SLC0_EXT_BIT2_INT_ENA + 21 + 1 + read-write + + + HOST_FN1_SLC0_EXT_BIT3_INT_ENA + 22 + 1 + read-write + + + HOST_FN1_SLC0_RX_NEW_PACKET_INT_ENA + 23 + 1 + read-write + + + HOST_FN1_SLC0_HOST_RD_RETRY_INT_ENA + 24 + 1 + read-write + + + HOST_FN1_GPIO_SDIO_INT_ENA + 25 + 1 + read-write + + + + + HOST_SLC1HOST_FUNC1_INT_ENA + 0xE0 + 0x20 + + + HOST_FN1_SLC1_TOHOST_BIT0_INT_ENA + 0 + 1 + read-write + + + HOST_FN1_SLC1_TOHOST_BIT1_INT_ENA + 1 + 1 + read-write + + + HOST_FN1_SLC1_TOHOST_BIT2_INT_ENA + 2 + 1 + read-write + + + HOST_FN1_SLC1_TOHOST_BIT3_INT_ENA + 3 + 1 + read-write + + + HOST_FN1_SLC1_TOHOST_BIT4_INT_ENA + 4 + 1 + read-write + + + HOST_FN1_SLC1_TOHOST_BIT5_INT_ENA + 5 + 1 + read-write + + + HOST_FN1_SLC1_TOHOST_BIT6_INT_ENA + 6 + 1 + read-write + + + HOST_FN1_SLC1_TOHOST_BIT7_INT_ENA + 7 + 1 + read-write + + + HOST_FN1_SLC1_TOKEN0_1TO0_INT_ENA + 8 + 1 + read-write + + + HOST_FN1_SLC1_TOKEN1_1TO0_INT_ENA + 9 + 1 + read-write + + + HOST_FN1_SLC1_TOKEN0_0TO1_INT_ENA + 10 + 1 + read-write + + + HOST_FN1_SLC1_TOKEN1_0TO1_INT_ENA + 11 + 1 + read-write + + + HOST_FN1_SLC1HOST_RX_SOF_INT_ENA + 12 + 1 + read-write + + + HOST_FN1_SLC1HOST_RX_EOF_INT_ENA + 13 + 1 + read-write + + + HOST_FN1_SLC1HOST_RX_START_INT_ENA + 14 + 1 + read-write + + + HOST_FN1_SLC1HOST_TX_START_INT_ENA + 15 + 1 + read-write + + + HOST_FN1_SLC1_RX_UDF_INT_ENA + 16 + 1 + read-write + + + HOST_FN1_SLC1_TX_OVF_INT_ENA + 17 + 1 + read-write + + + HOST_FN1_SLC1_RX_PF_VALID_INT_ENA + 18 + 1 + read-write + + + HOST_FN1_SLC1_EXT_BIT0_INT_ENA + 19 + 1 + read-write + + + HOST_FN1_SLC1_EXT_BIT1_INT_ENA + 20 + 1 + read-write + + + HOST_FN1_SLC1_EXT_BIT2_INT_ENA + 21 + 1 + read-write + + + HOST_FN1_SLC1_EXT_BIT3_INT_ENA + 22 + 1 + read-write + + + HOST_FN1_SLC1_WIFI_RX_NEW_PACKET_INT_ENA + 23 + 1 + read-write + + + HOST_FN1_SLC1_HOST_RD_RETRY_INT_ENA + 24 + 1 + read-write + + + HOST_FN1_SLC1_BT_RX_NEW_PACKET_INT_ENA + 25 + 1 + read-write + + + + + HOST_SLC0HOST_FUNC2_INT_ENA + 0xE4 + 0x20 + + + HOST_FN2_SLC0_TOHOST_BIT0_INT_ENA + 0 + 1 + read-write + + + HOST_FN2_SLC0_TOHOST_BIT1_INT_ENA + 1 + 1 + read-write + + + HOST_FN2_SLC0_TOHOST_BIT2_INT_ENA + 2 + 1 + read-write + + + HOST_FN2_SLC0_TOHOST_BIT3_INT_ENA + 3 + 1 + read-write + + + HOST_FN2_SLC0_TOHOST_BIT4_INT_ENA + 4 + 1 + read-write + + + HOST_FN2_SLC0_TOHOST_BIT5_INT_ENA + 5 + 1 + read-write + + + HOST_FN2_SLC0_TOHOST_BIT6_INT_ENA + 6 + 1 + read-write + + + HOST_FN2_SLC0_TOHOST_BIT7_INT_ENA + 7 + 1 + read-write + + + HOST_FN2_SLC0_TOKEN0_1TO0_INT_ENA + 8 + 1 + read-write + + + HOST_FN2_SLC0_TOKEN1_1TO0_INT_ENA + 9 + 1 + read-write + + + HOST_FN2_SLC0_TOKEN0_0TO1_INT_ENA + 10 + 1 + read-write + + + HOST_FN2_SLC0_TOKEN1_0TO1_INT_ENA + 11 + 1 + read-write + + + HOST_FN2_SLC0HOST_RX_SOF_INT_ENA + 12 + 1 + read-write + + + HOST_FN2_SLC0HOST_RX_EOF_INT_ENA + 13 + 1 + read-write + + + HOST_FN2_SLC0HOST_RX_START_INT_ENA + 14 + 1 + read-write + + + HOST_FN2_SLC0HOST_TX_START_INT_ENA + 15 + 1 + read-write + + + HOST_FN2_SLC0_RX_UDF_INT_ENA + 16 + 1 + read-write + + + HOST_FN2_SLC0_TX_OVF_INT_ENA + 17 + 1 + read-write + + + HOST_FN2_SLC0_RX_PF_VALID_INT_ENA + 18 + 1 + read-write + + + HOST_FN2_SLC0_EXT_BIT0_INT_ENA + 19 + 1 + read-write + + + HOST_FN2_SLC0_EXT_BIT1_INT_ENA + 20 + 1 + read-write + + + HOST_FN2_SLC0_EXT_BIT2_INT_ENA + 21 + 1 + read-write + + + HOST_FN2_SLC0_EXT_BIT3_INT_ENA + 22 + 1 + read-write + + + HOST_FN2_SLC0_RX_NEW_PACKET_INT_ENA + 23 + 1 + read-write + + + HOST_FN2_SLC0_HOST_RD_RETRY_INT_ENA + 24 + 1 + read-write + + + HOST_FN2_GPIO_SDIO_INT_ENA + 25 + 1 + read-write + + + + + HOST_SLC1HOST_FUNC2_INT_ENA + 0xE8 + 0x20 + + + HOST_FN2_SLC1_TOHOST_BIT0_INT_ENA + 0 + 1 + read-write + + + HOST_FN2_SLC1_TOHOST_BIT1_INT_ENA + 1 + 1 + read-write + + + HOST_FN2_SLC1_TOHOST_BIT2_INT_ENA + 2 + 1 + read-write + + + HOST_FN2_SLC1_TOHOST_BIT3_INT_ENA + 3 + 1 + read-write + + + HOST_FN2_SLC1_TOHOST_BIT4_INT_ENA + 4 + 1 + read-write + + + HOST_FN2_SLC1_TOHOST_BIT5_INT_ENA + 5 + 1 + read-write + + + HOST_FN2_SLC1_TOHOST_BIT6_INT_ENA + 6 + 1 + read-write + + + HOST_FN2_SLC1_TOHOST_BIT7_INT_ENA + 7 + 1 + read-write + + + HOST_FN2_SLC1_TOKEN0_1TO0_INT_ENA + 8 + 1 + read-write + + + HOST_FN2_SLC1_TOKEN1_1TO0_INT_ENA + 9 + 1 + read-write + + + HOST_FN2_SLC1_TOKEN0_0TO1_INT_ENA + 10 + 1 + read-write + + + HOST_FN2_SLC1_TOKEN1_0TO1_INT_ENA + 11 + 1 + read-write + + + HOST_FN2_SLC1HOST_RX_SOF_INT_ENA + 12 + 1 + read-write + + + HOST_FN2_SLC1HOST_RX_EOF_INT_ENA + 13 + 1 + read-write + + + HOST_FN2_SLC1HOST_RX_START_INT_ENA + 14 + 1 + read-write + + + HOST_FN2_SLC1HOST_TX_START_INT_ENA + 15 + 1 + read-write + + + HOST_FN2_SLC1_RX_UDF_INT_ENA + 16 + 1 + read-write + + + HOST_FN2_SLC1_TX_OVF_INT_ENA + 17 + 1 + read-write + + + HOST_FN2_SLC1_RX_PF_VALID_INT_ENA + 18 + 1 + read-write + + + HOST_FN2_SLC1_EXT_BIT0_INT_ENA + 19 + 1 + read-write + + + HOST_FN2_SLC1_EXT_BIT1_INT_ENA + 20 + 1 + read-write + + + HOST_FN2_SLC1_EXT_BIT2_INT_ENA + 21 + 1 + read-write + + + HOST_FN2_SLC1_EXT_BIT3_INT_ENA + 22 + 1 + read-write + + + HOST_FN2_SLC1_WIFI_RX_NEW_PACKET_INT_ENA + 23 + 1 + read-write + + + HOST_FN2_SLC1_HOST_RD_RETRY_INT_ENA + 24 + 1 + read-write + + + HOST_FN2_SLC1_BT_RX_NEW_PACKET_INT_ENA + 25 + 1 + read-write + + + + + HOST_SLC0HOST_INT_ENA + 0xEC + 0x20 + + + HOST_SLC0_TOHOST_BIT0_INT_ENA + 0 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT1_INT_ENA + 1 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT2_INT_ENA + 2 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT3_INT_ENA + 3 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT4_INT_ENA + 4 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT5_INT_ENA + 5 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT6_INT_ENA + 6 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT7_INT_ENA + 7 + 1 + read-write + + + HOST_SLC0_TOKEN0_1TO0_INT_ENA + 8 + 1 + read-write + + + HOST_SLC0_TOKEN1_1TO0_INT_ENA + 9 + 1 + read-write + + + HOST_SLC0_TOKEN0_0TO1_INT_ENA + 10 + 1 + read-write + + + HOST_SLC0_TOKEN1_0TO1_INT_ENA + 11 + 1 + read-write + + + HOST_SLC0HOST_RX_SOF_INT_ENA + 12 + 1 + read-write + + + HOST_SLC0HOST_RX_EOF_INT_ENA + 13 + 1 + read-write + + + HOST_SLC0HOST_RX_START_INT_ENA + 14 + 1 + read-write + + + HOST_SLC0HOST_TX_START_INT_ENA + 15 + 1 + read-write + + + HOST_SLC0_RX_UDF_INT_ENA + 16 + 1 + read-write + + + HOST_SLC0_TX_OVF_INT_ENA + 17 + 1 + read-write + + + HOST_SLC0_RX_PF_VALID_INT_ENA + 18 + 1 + read-write + + + HOST_SLC0_EXT_BIT0_INT_ENA + 19 + 1 + read-write + + + HOST_SLC0_EXT_BIT1_INT_ENA + 20 + 1 + read-write + + + HOST_SLC0_EXT_BIT2_INT_ENA + 21 + 1 + read-write + + + HOST_SLC0_EXT_BIT3_INT_ENA + 22 + 1 + read-write + + + HOST_SLC0_RX_NEW_PACKET_INT_ENA + 23 + 1 + read-write + + + HOST_SLC0_HOST_RD_RETRY_INT_ENA + 24 + 1 + read-write + + + HOST_GPIO_SDIO_INT_ENA + 25 + 1 + read-write + + + + + HOST_SLC1HOST_INT_ENA + 0xF0 + 0x20 + + + HOST_SLC1_TOHOST_BIT0_INT_ENA + 0 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT1_INT_ENA + 1 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT2_INT_ENA + 2 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT3_INT_ENA + 3 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT4_INT_ENA + 4 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT5_INT_ENA + 5 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT6_INT_ENA + 6 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT7_INT_ENA + 7 + 1 + read-write + + + HOST_SLC1_TOKEN0_1TO0_INT_ENA + 8 + 1 + read-write + + + HOST_SLC1_TOKEN1_1TO0_INT_ENA + 9 + 1 + read-write + + + HOST_SLC1_TOKEN0_0TO1_INT_ENA + 10 + 1 + read-write + + + HOST_SLC1_TOKEN1_0TO1_INT_ENA + 11 + 1 + read-write + + + HOST_SLC1HOST_RX_SOF_INT_ENA + 12 + 1 + read-write + + + HOST_SLC1HOST_RX_EOF_INT_ENA + 13 + 1 + read-write + + + HOST_SLC1HOST_RX_START_INT_ENA + 14 + 1 + read-write + + + HOST_SLC1HOST_TX_START_INT_ENA + 15 + 1 + read-write + + + HOST_SLC1_RX_UDF_INT_ENA + 16 + 1 + read-write + + + HOST_SLC1_TX_OVF_INT_ENA + 17 + 1 + read-write + + + HOST_SLC1_RX_PF_VALID_INT_ENA + 18 + 1 + read-write + + + HOST_SLC1_EXT_BIT0_INT_ENA + 19 + 1 + read-write + + + HOST_SLC1_EXT_BIT1_INT_ENA + 20 + 1 + read-write + + + HOST_SLC1_EXT_BIT2_INT_ENA + 21 + 1 + read-write + + + HOST_SLC1_EXT_BIT3_INT_ENA + 22 + 1 + read-write + + + HOST_SLC1_WIFI_RX_NEW_PACKET_INT_ENA + 23 + 1 + read-write + + + HOST_SLC1_HOST_RD_RETRY_INT_ENA + 24 + 1 + read-write + + + HOST_SLC1_BT_RX_NEW_PACKET_INT_ENA + 25 + 1 + read-write + + + + + HOST_SLC0HOST_RX_INFOR + 0xF4 + 0x20 + + + HOST_SLC0HOST_RX_INFOR + 0 + 20 + read-write + + + + + HOST_SLC1HOST_RX_INFOR + 0xF8 + 0x20 + + + HOST_SLC1HOST_RX_INFOR + 0 + 20 + read-write + + + + + HOST_SLC0HOST_LEN_WD + 0xFC + 0x20 + + + HOST_SLC0HOST_LEN_WD + 0 + 32 + read-write + + + + + HOST_SLC_APBWIN_WDATA + 0x100 + 0x20 + + + HOST_SLC_APBWIN_WDATA + 0 + 32 + read-write + + + + + HOST_SLC_APBWIN_CONF + 0x104 + 0x20 + + + HOST_SLC_APBWIN_ADDR + 0 + 28 + read-write + + + HOST_SLC_APBWIN_WR + 28 + 1 + read-write + + + HOST_SLC_APBWIN_START + 29 + 1 + read-write + + + + + HOST_SLC_APBWIN_RDATA + 0x108 + 0x20 + + + HOST_SLC_APBWIN_RDATA + 0 + 32 + read-only + + + + + HOST_SLCHOST_RDCLR0 + 0x10C + 0x20 + 0x0003C044 + + + HOST_SLCHOST_SLC0_BIT7_CLRADDR + 0 + 9 + read-write + + + HOST_SLCHOST_SLC0_BIT6_CLRADDR + 9 + 9 + read-write + + + + + HOST_SLCHOST_RDCLR1 + 0x110 + 0x20 + 0x0003C1E0 + + + HOST_SLCHOST_SLC1_BIT7_CLRADDR + 0 + 9 + read-write + + + HOST_SLCHOST_SLC1_BIT6_CLRADDR + 9 + 9 + read-write + + + + + HOST_SLC0HOST_INT_ENA1 + 0x114 + 0x20 + + + HOST_SLC0_TOHOST_BIT0_INT_ENA1 + 0 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT1_INT_ENA1 + 1 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT2_INT_ENA1 + 2 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT3_INT_ENA1 + 3 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT4_INT_ENA1 + 4 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT5_INT_ENA1 + 5 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT6_INT_ENA1 + 6 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT7_INT_ENA1 + 7 + 1 + read-write + + + HOST_SLC0_TOKEN0_1TO0_INT_ENA1 + 8 + 1 + read-write + + + HOST_SLC0_TOKEN1_1TO0_INT_ENA1 + 9 + 1 + read-write + + + HOST_SLC0_TOKEN0_0TO1_INT_ENA1 + 10 + 1 + read-write + + + HOST_SLC0_TOKEN1_0TO1_INT_ENA1 + 11 + 1 + read-write + + + HOST_SLC0HOST_RX_SOF_INT_ENA1 + 12 + 1 + read-write + + + HOST_SLC0HOST_RX_EOF_INT_ENA1 + 13 + 1 + read-write + + + HOST_SLC0HOST_RX_START_INT_ENA1 + 14 + 1 + read-write + + + HOST_SLC0HOST_TX_START_INT_ENA1 + 15 + 1 + read-write + + + HOST_SLC0_RX_UDF_INT_ENA1 + 16 + 1 + read-write + + + HOST_SLC0_TX_OVF_INT_ENA1 + 17 + 1 + read-write + + + HOST_SLC0_RX_PF_VALID_INT_ENA1 + 18 + 1 + read-write + + + HOST_SLC0_EXT_BIT0_INT_ENA1 + 19 + 1 + read-write + + + HOST_SLC0_EXT_BIT1_INT_ENA1 + 20 + 1 + read-write + + + HOST_SLC0_EXT_BIT2_INT_ENA1 + 21 + 1 + read-write + + + HOST_SLC0_EXT_BIT3_INT_ENA1 + 22 + 1 + read-write + + + HOST_SLC0_RX_NEW_PACKET_INT_ENA1 + 23 + 1 + read-write + + + HOST_SLC0_HOST_RD_RETRY_INT_ENA1 + 24 + 1 + read-write + + + HOST_GPIO_SDIO_INT_ENA1 + 25 + 1 + read-write + + + + + HOST_SLC1HOST_INT_ENA1 + 0x118 + 0x20 + + + HOST_SLC1_TOHOST_BIT0_INT_ENA1 + 0 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT1_INT_ENA1 + 1 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT2_INT_ENA1 + 2 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT3_INT_ENA1 + 3 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT4_INT_ENA1 + 4 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT5_INT_ENA1 + 5 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT6_INT_ENA1 + 6 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT7_INT_ENA1 + 7 + 1 + read-write + + + HOST_SLC1_TOKEN0_1TO0_INT_ENA1 + 8 + 1 + read-write + + + HOST_SLC1_TOKEN1_1TO0_INT_ENA1 + 9 + 1 + read-write + + + HOST_SLC1_TOKEN0_0TO1_INT_ENA1 + 10 + 1 + read-write + + + HOST_SLC1_TOKEN1_0TO1_INT_ENA1 + 11 + 1 + read-write + + + HOST_SLC1HOST_RX_SOF_INT_ENA1 + 12 + 1 + read-write + + + HOST_SLC1HOST_RX_EOF_INT_ENA1 + 13 + 1 + read-write + + + HOST_SLC1HOST_RX_START_INT_ENA1 + 14 + 1 + read-write + + + HOST_SLC1HOST_TX_START_INT_ENA1 + 15 + 1 + read-write + + + HOST_SLC1_RX_UDF_INT_ENA1 + 16 + 1 + read-write + + + HOST_SLC1_TX_OVF_INT_ENA1 + 17 + 1 + read-write + + + HOST_SLC1_RX_PF_VALID_INT_ENA1 + 18 + 1 + read-write + + + HOST_SLC1_EXT_BIT0_INT_ENA1 + 19 + 1 + read-write + + + HOST_SLC1_EXT_BIT1_INT_ENA1 + 20 + 1 + read-write + + + HOST_SLC1_EXT_BIT2_INT_ENA1 + 21 + 1 + read-write + + + HOST_SLC1_EXT_BIT3_INT_ENA1 + 22 + 1 + read-write + + + HOST_SLC1_WIFI_RX_NEW_PACKET_INT_ENA1 + 23 + 1 + read-write + + + HOST_SLC1_HOST_RD_RETRY_INT_ENA1 + 24 + 1 + read-write + + + HOST_SLC1_BT_RX_NEW_PACKET_INT_ENA1 + 25 + 1 + read-write + + + + + HOST_SLCHOSTDATE + 0x178 + 0x20 + 0x16022500 + + + HOST_SLCHOST_DATE + 0 + 32 + read-write + + + + + HOST_SLCHOSTID + 0x17C + 0x20 + 0x00000600 + + + HOST_SLCHOST_ID + 0 + 32 + read-write + + + + + HOST_SLCHOST_CONF + 0x1F0 + 0x20 + + + HOST_FRC_SDIO11 + 0 + 5 + read-write + + + HOST_FRC_SDIO20 + 5 + 5 + read-write + + + HOST_FRC_NEG_SAMP + 10 + 5 + read-write + + + HOST_FRC_POS_SAMP + 15 + 5 + read-write + + + HOST_FRC_QUICK_IN + 20 + 5 + read-write + + + HOST_SDIO20_INT_DELAY + 25 + 1 + read-write + + + HOST_SDIO_PAD_PULLUP + 26 + 1 + read-write + + + HOST_HSPEED_CON_EN + 27 + 1 + read-write + + + + + HOST_SLCHOST_INF_ST + 0x1F4 + 0x20 + + + HOST_SDIO20_MODE + 0 + 5 + read-only + + + HOST_SDIO_NEG_SAMP + 5 + 5 + read-only + + + HOST_SDIO_QUICK_IN + 10 + 5 + read-only + + + + + + + SPI0 + SPI (Serial Peripheral Interface) Controller + SPI + 0x3FF43000 + + 0x0 + 0x110 + registers + + + SPI0 + 28 + + + + CMD + 0x0 + 0x20 + + + FLASH_PER + program erase resume bit program erase suspend operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 16 + 1 + read-write + + + FLASH_PES + program erase suspend bit program erase suspend operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 17 + 1 + read-write + + + USR + User define command enable. An operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 18 + 1 + read-write + + + FLASH_HPM + Drive Flash into high performance mode. The bit will be cleared once the operation done.1: enable 0: disable. + 19 + 1 + read-write + + + FLASH_RES + This bit combined with reg_resandres bit releases Flash from the power-down state or high performance mode and obtains the devices ID. The bit will be cleared once the operation done.1: enable 0: disable. + 20 + 1 + read-write + + + FLASH_DP + Drive Flash into power down. An operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 21 + 1 + read-write + + + FLASH_CE + Chip erase enable. Chip erase operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 22 + 1 + read-write + + + FLASH_BE + Block erase enable. A 64KB block is erased via SPI command D8H. Block erase operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 23 + 1 + read-write + + + FLASH_SE + Sector erase enable. A 4KB sector is erased via SPI command 20H. Sector erase operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 24 + 1 + read-write + + + FLASH_PP + Page program enable(1 byte ~256 bytes data to be programmed). Page program operation will be triggered when the bit is set. The bit will be cleared once the operation done .1: enable 0: disable. + 25 + 1 + read-write + + + FLASH_WRSR + Write status register enable. Write status operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 26 + 1 + read-write + + + FLASH_RDSR + Read status register-1. Read status operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 27 + 1 + read-write + + + FLASH_RDID + Read JEDEC ID . Read ID command will be sent when the bit is set. The bit will be cleared once the operation done. 1: enable 0: disable. + 28 + 1 + read-write + + + FLASH_WRDI + Write flash disable. Write disable command will be sent when the bit is set. The bit will be cleared once the operation done. 1: enable 0: disable. + 29 + 1 + read-write + + + FLASH_WREN + Write flash enable. Write enable command will be sent when the bit is set. The bit will be cleared once the operation done. 1: enable 0: disable. + 30 + 1 + read-write + + + FLASH_READ + Read flash enable. Read flash operation will be triggered when the bit is set. The bit will be cleared once the operation done. 1: enable 0: disable. + 31 + 1 + read-write + + + + + ADDR + 0x4 + 0x20 + + + CTRL + 0x8 + 0x20 + 0x0020A400 + + + FCS_CRC_EN + For SPI1 initialize crc32 module before writing encrypted data to flash. Active low. + 10 + 1 + read-write + + + TX_CRC_EN + For SPI1 enable crc32 when writing encrypted data to flash. 1: enable 0:disable + 11 + 1 + read-write + + + WAIT_FLASH_IDLE_EN + wait flash idle when program flash or erase flash. 1: enable 0: disable. + 12 + 1 + read-write + + + FASTRD_MODE + This bit enable the bits: spi_fread_qio spi_fread_dio spi_fread_qout and spi_fread_dout. 1: enable 0: disable. + 13 + 1 + read-write + + + FREAD_DUAL + In the read operations read-data phase apply 2 signals. 1: enable 0: disable. + 14 + 1 + read-write + + + RESANDRES + The Device ID is read out to SPI_RD_STATUS register, this bit combine with spi_flash_res bit. 1: enable 0: disable. + 15 + 1 + read-write + + + FREAD_QUAD + In the read operations read-data phase apply 4 signals. 1: enable 0: disable. + 20 + 1 + read-write + + + WP + Write protect signal output when SPI is idle. 1: output high 0: output low. + 21 + 1 + read-write + + + WRSR_2B + two bytes data will be written to status register when it is set. 1: enable 0: disable. + 22 + 1 + read-write + + + FREAD_DIO + In the read operations address phase and read-data phase apply 2 signals. 1: enable 0: disable. + 23 + 1 + read-write + + + FREAD_QIO + In the read operations address phase and read-data phase apply 4 signals. 1: enable 0: disable. + 24 + 1 + read-write + + + RD_BIT_ORDER + In read-data (MISO) phase 1: LSB first 0: MSB first + 25 + 1 + read-write + + + WR_BIT_ORDER + In command address write-data (MOSI) phases 1: LSB firs 0: MSB first + 26 + 1 + read-write + + + + + CTRL1 + 0xC + 0x20 + 0x5FFF0000 + + + CS_HOLD_DELAY_RES + Delay cycles of resume Flash when resume Flash is enable by spi clock. + 16 + 12 + read-write + + + CS_HOLD_DELAY + SPI cs signal is delayed by spi clock cycles + 28 + 4 + read-write + + + + + RD_STATUS + 0x10 + 0x20 + + + STATUS + In the slave mode, it is the status for master to read out. + 0 + 16 + read-write + + + WB_MODE + Mode bits in the flash fast read mode, it is combined with spi_fastrd_mode bit. + 16 + 8 + read-write + + + STATUS_EXT + In the slave mode,it is the status for master to read out. + 24 + 8 + read-write + + + + + CTRL2 + 0x14 + 0x20 + 0x00000011 + + + SETUP_TIME + (cycles-1) of ¡°prepare¡± phase by spi clock, this bits combined with spi_cs_setup bit. + 0 + 4 + read-write + + + HOLD_TIME + delay cycles of cs pin by spi clock, this bits combined with spi_cs_hold bit. + 4 + 4 + read-write + + + CK_OUT_LOW_MODE + modify spi clock duty ratio when the value is lager than 8, the bits are combined with spi_clkcnt_N bits and spi_clkcnt_L bits. + 8 + 4 + read-write + + + CK_OUT_HIGH_MODE + modify spi clock duty ratio when the value is lager than 8, the bits are combined with spi_clkcnt_N bits and spi_clkcnt_H bits. + 12 + 4 + read-write + + + MISO_DELAY_MODE + MISO signals are delayed by spi_clk. 0: zero 1: if spi_ck_out_edge or spi_ck_i_edge is set 1 delayed by half cycle else delayed by one cycle 2: if spi_ck_out_edge or spi_ck_i_edge is set 1 delayed by one cycle else delayed by half cycle 3: delayed one cycle + 16 + 2 + read-write + + + MISO_DELAY_NUM + MISO signals are delayed by system clock cycles + 18 + 3 + read-write + + + MOSI_DELAY_MODE + MOSI signals are delayed by spi_clk. 0: zero 1: if spi_ck_out_edge or spi_ck_i_edge is set 1 delayed by half cycle else delayed by one cycle 2: if spi_ck_out_edge or spi_ck_i_edge is set 1 delayed by one cycle else delayed by half cycle 3: delayed one cycle + 21 + 2 + read-write + + + MOSI_DELAY_NUM + MOSI signals are delayed by system clock cycles + 23 + 3 + read-write + + + CS_DELAY_MODE + spi_cs signal is delayed by spi_clk . 0: zero 1: if spi_ck_out_edge or spi_ck_i_edge is set 1 delayed by half cycle else delayed by one cycle 2: if spi_ck_out_edge or spi_ck_i_edge is set 1 delayed by one cycle else delayed by half cycle 3: delayed one cycle + 26 + 2 + read-write + + + CS_DELAY_NUM + spi_cs signal is delayed by system clock cycles + 28 + 4 + read-write + + + + + CLOCK + 0x18 + 0x20 + 0x80003043 + + + CLKCNT_L + In the master mode it must be equal to spi_clkcnt_N. In the slave mode it must be 0. + 0 + 6 + read-write + + + CLKCNT_H + In the master mode it must be floor((spi_clkcnt_N+1)/2-1). In the slave mode it must be 0. + 6 + 6 + read-write + + + CLKCNT_N + In the master mode it is the divider of spi_clk. So spi_clk frequency is system/(spi_clkdiv_pre+1)/(spi_clkcnt_N+1) + 12 + 6 + read-write + + + CLKDIV_PRE + In the master mode it is pre-divider of spi_clk. + 18 + 13 + read-write + + + CLK_EQU_SYSCLK + In the master mode 1: spi_clk is eqaul to system 0: spi_clk is divided from system clock. + 31 + 1 + read-write + + + + + USER + 0x1C + 0x20 + 0x80000040 + + + DOUTDIN + Set the bit to enable full duplex communication. 1: enable 0: disable. + 0 + 1 + read-write + + + CS_HOLD + spi cs keep low when spi is in ¡°done¡± phase. 1: enable 0: disable. + 4 + 1 + read-write + + + CS_SETUP + spi cs is enable when spi is in ¡°prepare¡± phase. 1: enable 0: disable. + 5 + 1 + read-write + + + CK_I_EDGE + In the slave mode the bit is same as spi_ck_out_edge in master mode. It is combined with spi_miso_delay_mode bits. + 6 + 1 + read-write + + + CK_OUT_EDGE + the bit combined with spi_mosi_delay_mode bits to set mosi signal delay mode. + 7 + 1 + read-write + + + RD_BYTE_ORDER + In read-data (MISO) phase 1: big-endian 0: little_endian + 10 + 1 + read-write + + + WR_BYTE_ORDER + In command address write-data (MOSI) phases 1: big-endian 0: litte_endian + 11 + 1 + read-write + + + FWRITE_DUAL + In the write operations read-data phase apply 2 signals + 12 + 1 + read-write + + + FWRITE_QUAD + In the write operations read-data phase apply 4 signals + 13 + 1 + read-write + + + FWRITE_DIO + In the write operations address phase and read-data phase apply 2 signals. + 14 + 1 + read-write + + + FWRITE_QIO + In the write operations address phase and read-data phase apply 4 signals. + 15 + 1 + read-write + + + SIO + Set the bit to enable 3-line half duplex communication mosi and miso signals share the same pin. 1: enable 0: disable. + 16 + 1 + read-write + + + USR_HOLD_POL + It is combined with hold bits to set the polarity of spi hold line 1: spi will be held when spi hold line is high 0: spi will be held when spi hold line is low + 17 + 1 + read-write + + + USR_DOUT_HOLD + spi is hold at data out state the bit combined with spi_usr_hold_pol bit. + 18 + 1 + read-write + + + USR_DIN_HOLD + spi is hold at data in state the bit combined with spi_usr_hold_pol bit. + 19 + 1 + read-write + + + USR_DUMMY_HOLD + spi is hold at dummy state the bit combined with spi_usr_hold_pol bit. + 20 + 1 + read-write + + + USR_ADDR_HOLD + spi is hold at address state the bit combined with spi_usr_hold_pol bit. + 21 + 1 + read-write + + + USR_CMD_HOLD + spi is hold at command state the bit combined with spi_usr_hold_pol bit. + 22 + 1 + read-write + + + USR_PREP_HOLD + spi is hold at prepare state the bit combined with spi_usr_hold_pol bit. + 23 + 1 + read-write + + + USR_MISO_HIGHPART + read-data phase only access to high-part of the buffer spi_w8~spi_w15. 1: enable 0: disable. + 24 + 1 + read-write + + + USR_MOSI_HIGHPART + write-data phase only access to high-part of the buffer spi_w8~spi_w15. 1: enable 0: disable. + 25 + 1 + read-write + + + USR_DUMMY_IDLE + spi clock is disable in dummy phase when the bit is enable. + 26 + 1 + read-write + + + USR_MOSI + This bit enable the write-data phase of an operation. + 27 + 1 + read-write + + + USR_MISO + This bit enable the read-data phase of an operation. + 28 + 1 + read-write + + + USR_DUMMY + This bit enable the dummy phase of an operation. + 29 + 1 + read-write + + + USR_ADDR + This bit enable the address phase of an operation. + 30 + 1 + read-write + + + USR_COMMAND + This bit enable the command phase of an operation. + 31 + 1 + read-write + + + + + USER1 + 0x20 + 0x20 + 0x5C000007 + + + USR_DUMMY_CYCLELEN + The length in spi_clk cycles of dummy phase. The register value shall be (cycle_num-1). + 0 + 8 + read-write + + + USR_ADDR_BITLEN + The length in bits of address phase. The register value shall be (bit_num-1). + 26 + 6 + read-only + + + + + USER2 + 0x24 + 0x20 + 0x70000000 + + + USR_COMMAND_VALUE + The value of command. + 0 + 16 + read-write + + + USR_COMMAND_BITLEN + The length in bits of command phase. The register value shall be (bit_num-1) + 28 + 4 + read-write + + + + + MOSI_DLEN + 0x28 + 0x20 + + + USR_MOSI_DBITLEN + The length in bits of write-data. The register value shall be (bit_num-1). + 0 + 24 + read-write + + + + + MISO_DLEN + 0x2C + 0x20 + + + USR_MISO_DBITLEN + The length in bits of read-data. The register value shall be (bit_num-1). + 0 + 24 + read-write + + + + + SLV_WR_STATUS + 0x30 + 0x20 + + + SLV_WR_ST + In the slave mode this register are the status register for the master to write into. In the master mode this register are the higher 32bits in the 64 bits address condition. + 0 + 32 + read-write + + + + + PIN + 0x34 + 0x20 + 0x00000006 + + + CS0_DIS + SPI CS0 pin enable, 1: disable CS0, 0: spi_cs0 signal is from/to CS0 pin + 0 + 1 + read-write + + + CS1_DIS + SPI CS1 pin enable, 1: disable CS1, 0: spi_cs1 signal is from/to CS1 pin + 1 + 1 + read-write + + + CS2_DIS + SPI CS2 pin enable, 1: disable CS2, 0: spi_cs2 signal is from/to CS2 pin + 2 + 1 + read-write + + + CK_DIS + 1: spi clk out disable 0: spi clk out enable + 5 + 1 + read-write + + + MASTER_CS_POL + In the master mode the bits are the polarity of spi cs line the value is equivalent to spi_cs ^ spi_master_cs_pol. + 6 + 3 + read-write + + + MASTER_CK_SEL + In the master mode spi cs line is enable as spi clk it is combined with spi_cs0_dis spi_cs1_dis spi_cs2_dis. + 11 + 3 + read-write + + + CK_IDLE_EDGE + 1: spi clk line is high when idle 0: spi clk line is low when idle + 29 + 1 + read-write + + + CS_KEEP_ACTIVE + spi cs line keep low when the bit is set. + 30 + 1 + read-write + + + + + SLAVE + 0x38 + 0x20 + 0x00000020 + + + SLV_RD_BUF_DONE + The interrupt raw bit for the completion of read-buffer operation in the slave mode. + 0 + 1 + read-write + + + SLV_WR_BUF_DONE + The interrupt raw bit for the completion of write-buffer operation in the slave mode. + 1 + 1 + read-write + + + SLV_RD_STA_DONE + The interrupt raw bit for the completion of read-status operation in the slave mode. + 2 + 1 + read-write + + + SLV_WR_STA_DONE + The interrupt raw bit for the completion of write-status operation in the slave mode. + 3 + 1 + read-write + + + TRANS_DONE + The interrupt raw bit for the completion of any operation in both the master mode and the slave mode. + 4 + 1 + read-write + + + INT_EN + Interrupt enable bits for the below 5 sources + 5 + 5 + read-write + + + CS_I_MODE + In the slave mode this bits used to synchronize the input spi cs signal and eliminate spi cs jitter. + 10 + 2 + read-write + + + SLV_LAST_COMMAND + In the slave mode it is the value of command. + 17 + 3 + read-only + + + SLV_LAST_STATE + In the slave mode it is the state of spi state machine. + 20 + 3 + read-only + + + TRANS_CNT + The operations counter in both the master mode and the slave mode. 4: read-status + 23 + 4 + read-only + + + SLV_CMD_DEFINE + 1: slave mode commands are defined in SPI_SLAVE3. 0: slave mode commands are fixed as: 1: write-status 2: write-buffer and 3: read-buffer. + 27 + 1 + read-write + + + SLV_WR_RD_STA_EN + write and read status enable in the slave mode + 28 + 1 + read-write + + + SLV_WR_RD_BUF_EN + write and read buffer enable in the slave mode + 29 + 1 + read-write + + + MODE + 1: slave mode 0: master mode. + 30 + 1 + read-write + + + SYNC_RESET + Software reset enable, reset the spi clock line cs line and data lines. + 31 + 1 + read-write + + + + + SLAVE1 + 0x3C + 0x20 + 0x02000000 + + + SLV_RDBUF_DUMMY_EN + In the slave mode it is the enable bit of dummy phase for read-buffer operations. + 0 + 1 + read-write + + + SLV_WRBUF_DUMMY_EN + In the slave mode it is the enable bit of dummy phase for write-buffer operations. + 1 + 1 + read-write + + + SLV_RDSTA_DUMMY_EN + In the slave mode it is the enable bit of dummy phase for read-status operations. + 2 + 1 + read-write + + + SLV_WRSTA_DUMMY_EN + In the slave mode it is the enable bit of dummy phase for write-status operations. + 3 + 1 + read-write + + + SLV_WR_ADDR_BITLEN + In the slave mode it is the address length in bits for write-buffer operation. The register value shall be (bit_num-1). + 4 + 6 + read-write + + + SLV_RD_ADDR_BITLEN + In the slave mode it is the address length in bits for read-buffer operation. The register value shall be (bit_num-1). + 10 + 6 + read-write + + + SLV_STATUS_READBACK + In the slave mode 1:read register of SPI_SLV_WR_STATUS 0: read register of SPI_RD_STATUS. + 25 + 1 + read-write + + + SLV_STATUS_FAST_EN + In the slave mode enable fast read status. + 26 + 1 + read-write + + + SLV_STATUS_BITLEN + In the slave mode it is the length of status bit. + 27 + 5 + read-write + + + + + SLAVE2 + 0x40 + 0x20 + + + SLV_RDSTA_DUMMY_CYCLELEN + In the slave mode it is the length in spi_clk cycles of dummy phase for read-status operations. The register value shall be (cycle_num-1). + 0 + 8 + read-write + + + SLV_WRSTA_DUMMY_CYCLELEN + In the slave mode it is the length in spi_clk cycles of dummy phase for write-status operations. The register value shall be (cycle_num-1). + 8 + 8 + read-write + + + SLV_RDBUF_DUMMY_CYCLELEN + In the slave mode it is the length in spi_clk cycles of dummy phase for read-buffer operations. The register value shall be (cycle_num-1). + 16 + 8 + read-write + + + SLV_WRBUF_DUMMY_CYCLELEN + In the slave mode it is the length in spi_clk cycles of dummy phase for write-buffer operations. The register value shall be (cycle_num-1). + 24 + 8 + read-write + + + + + SLAVE3 + 0x44 + 0x20 + + + SLV_RDBUF_CMD_VALUE + In the slave mode it is the value of read-buffer command. + 0 + 8 + read-write + + + SLV_WRBUF_CMD_VALUE + In the slave mode it is the value of write-buffer command. + 8 + 8 + read-write + + + SLV_RDSTA_CMD_VALUE + In the slave mode it is the value of read-status command. + 16 + 8 + read-write + + + SLV_WRSTA_CMD_VALUE + In the slave mode it is the value of write-status command. + 24 + 8 + read-write + + + + + SLV_WRBUF_DLEN + 0x48 + 0x20 + + + SLV_WRBUF_DBITLEN + In the slave mode it is the length in bits for write-buffer operations. The register value shall be (bit_num-1). + 0 + 24 + read-write + + + + + SLV_RDBUF_DLEN + 0x4C + 0x20 + + + SLV_RDBUF_DBITLEN + In the slave mode it is the length in bits for read-buffer operations. The register value shall be (bit_num-1). + 0 + 24 + read-write + + + + + CACHE_FCTRL + 0x50 + 0x20 + + + CACHE_REQ_EN + For SPI0 Cache access enable 1: enable 0:disable. + 0 + 1 + read-write + + + CACHE_USR_CMD_4BYTE + For SPI0 cache read flash with 4 bytes command 1: enable 0:disable. + 1 + 1 + read-write + + + CACHE_FLASH_USR_CMD + For SPI0 cache read flash for user define command 1: enable 0:disable. + 2 + 1 + read-write + + + CACHE_FLASH_PES_EN + For SPI0 spi1 send suspend command before cache read flash 1: enable 0:disable. + 3 + 1 + read-write + + + + + CACHE_SCTRL + 0x54 + 0x20 + 0x15C04830 + + + USR_SRAM_DIO + For SPI0 In the spi sram mode spi dual I/O mode enable 1: enable 0:disable + 1 + 1 + read-write + + + USR_SRAM_QIO + For SPI0 In the spi sram mode spi quad I/O mode enable 1: enable 0:disable + 2 + 1 + read-write + + + USR_WR_SRAM_DUMMY + For SPI0 In the spi sram mode it is the enable bit of dummy phase for write operations. + 3 + 1 + read-write + + + USR_RD_SRAM_DUMMY + For SPI0 In the spi sram mode it is the enable bit of dummy phase for read operations. + 4 + 1 + read-write + + + CACHE_SRAM_USR_RCMD + For SPI0 In the spi sram mode cache read sram for user define command. + 5 + 1 + read-write + + + SRAM_BYTES_LEN + For SPI0 In the sram mode it is the byte length of spi read sram data. + 6 + 8 + read-write + + + SRAM_DUMMY_CYCLELEN + For SPI0 In the sram mode it is the length in bits of address phase. The register value shall be (bit_num-1). + 14 + 8 + read-write + + + SRAM_ADDR_BITLEN + For SPI0 In the sram mode it is the length in bits of address phase. The register value shall be (bit_num-1). + 22 + 6 + read-write + + + CACHE_SRAM_USR_WCMD + For SPI0 In the spi sram mode cache write sram for user define command + 28 + 1 + read-write + + + + + SRAM_CMD + 0x58 + 0x20 + + + SRAM_DIO + For SPI0 SRAM DIO mode enable . SRAM DIO enable command will be send when the bit is set. The bit will be cleared once the operation done. + 0 + 1 + read-write + + + SRAM_QIO + For SPI0 SRAM QIO mode enable . SRAM QIO enable command will be send when the bit is set. The bit will be cleared once the operation done. + 1 + 1 + read-write + + + SRAM_RSTIO + For SPI0 SRAM IO mode reset enable. SRAM IO mode reset operation will be triggered when the bit is set. The bit will be cleared once the operation done + 4 + 1 + read-write + + + + + SRAM_DRD_CMD + 0x5C + 0x20 + + + CACHE_SRAM_USR_RD_CMD_VALUE + For SPI0 When cache mode is enable it is the read command value of command phase for SRAM. + 0 + 16 + read-write + + + CACHE_SRAM_USR_RD_CMD_BITLEN + For SPI0 When cache mode is enable it is the length in bits of command phase for SRAM. The register value shall be (bit_num-1). + 28 + 4 + read-write + + + + + SRAM_DWR_CMD + 0x60 + 0x20 + + + CACHE_SRAM_USR_WR_CMD_VALUE + For SPI0 When cache mode is enable it is the write command value of command phase for SRAM. + 0 + 16 + read-write + + + CACHE_SRAM_USR_WR_CMD_BITLEN + For SPI0 When cache mode is enable it is the in bits of command phase for SRAM. The register value shall be (bit_num-1). + 28 + 4 + read-write + + + + + SLV_RD_BIT + 0x64 + 0x20 + + + SLV_RDATA_BIT + In the slave mode it is the bit length of read data. The value is the length - 1. + 0 + 24 + read-write + + + + + W0 + 0x80 + 0x20 + + + BUF0 + data buffer + 0 + 32 + read-write + + + + + W1 + 0x84 + 0x20 + + + BUF1 + data buffer + 0 + 32 + read-write + + + + + W2 + 0x88 + 0x20 + + + BUF2 + data buffer + 0 + 32 + read-write + + + + + W3 + 0x8C + 0x20 + + + BUF3 + data buffer + 0 + 32 + read-write + + + + + W4 + 0x90 + 0x20 + + + BUF4 + data buffer + 0 + 32 + read-write + + + + + W5 + 0x94 + 0x20 + + + BUF5 + data buffer + 0 + 32 + read-write + + + + + W6 + 0x98 + 0x20 + + + BUF6 + data buffer + 0 + 32 + read-write + + + + + W7 + 0x9C + 0x20 + + + BUF7 + data buffer + 0 + 32 + read-write + + + + + W8 + 0xA0 + 0x20 + + + BUF8 + data buffer + 0 + 32 + read-write + + + + + W9 + 0xA4 + 0x20 + + + BUF9 + data buffer + 0 + 32 + read-write + + + + + W10 + 0xA8 + 0x20 + + + BUF10 + data buffer + 0 + 32 + read-write + + + + + W11 + 0xAC + 0x20 + + + BUF11 + data buffer + 0 + 32 + read-write + + + + + W12 + 0xB0 + 0x20 + + + BUF12 + data buffer + 0 + 32 + read-write + + + + + W13 + 0xB4 + 0x20 + + + BUF13 + data buffer + 0 + 32 + read-write + + + + + W14 + 0xB8 + 0x20 + + + BUF14 + data buffer + 0 + 32 + read-write + + + + + W15 + 0xBC + 0x20 + + + BUF15 + data buffer + 0 + 32 + read-write + + + + + TX_CRC + 0xC0 + 0x20 + + + DATA + For SPI1 the value of crc32 for 256 bits data. + 0 + 32 + read-write + + + + + EXT0 + 0xF0 + 0x20 + 0x800A0050 + + + T_PP_TIME + page program delay time by system clock. + 0 + 12 + read-write + + + T_PP_SHIFT + page program delay time shift . + 16 + 4 + read-write + + + T_PP_ENA + page program delay enable. + 31 + 1 + read-write + + + + + EXT1 + 0xF4 + 0x20 + 0x800F0000 + + + T_ERASE_TIME + erase flash delay time by system clock. + 0 + 12 + read-write + + + T_ERASE_SHIFT + erase flash delay time shift. + 16 + 4 + read-write + + + T_ERASE_ENA + erase flash delay enable. + 31 + 1 + read-write + + + + + EXT2 + 0xF8 + 0x20 + + + ST + The status of spi state machine . + 0 + 3 + read-only + + + + + EXT3 + 0xFC + 0x20 + + + INT_HOLD_ENA + This register is for two SPI masters to share the same cs clock and data signals. The bits of one SPI are set if the other SPI is busy the SPI will be hold. 1(3): hold at ¡°idle¡± phase 2: hold at ¡°prepare¡± phase. + 0 + 2 + read-write + + + + + DMA_CONF + 0x100 + 0x20 + 0x00000200 + + + IN_RST + The bit is used to reset in dma fsm and in data fifo pointer. + 2 + 1 + read-write + + + OUT_RST + The bit is used to reset out dma fsm and out data fifo pointer. + 3 + 1 + read-write + + + AHBM_FIFO_RST + reset spi dma ahb master fifo pointer. + 4 + 1 + read-write + + + AHBM_RST + reset spi dma ahb master. + 5 + 1 + read-write + + + IN_LOOP_TEST + Set bit to test in link. + 6 + 1 + read-write + + + OUT_LOOP_TEST + Set bit to test out link. + 7 + 1 + read-write + + + OUT_AUTO_WRBACK + when the link is empty jump to next automatically. + 8 + 1 + read-write + + + OUT_EOF_MODE + out eof flag generation mode . 1: when dma pop all data from fifo 0:when ahb push all data to fifo. + 9 + 1 + read-write + + + OUTDSCR_BURST_EN + read descriptor use burst mode when read data for memory. + 10 + 1 + read-write + + + INDSCR_BURST_EN + read descriptor use burst mode when write data to memory. + 11 + 1 + read-write + + + OUT_DATA_BURST_EN + spi dma read data from memory in burst mode. + 12 + 1 + read-write + + + DMA_RX_STOP + spi dma read data stop when in continue tx/rx mode. + 14 + 1 + read-write + + + DMA_TX_STOP + spi dma write data stop when in continue tx/rx mode. + 15 + 1 + read-write + + + DMA_CONTINUE + spi dma continue tx/rx data. + 16 + 1 + read-write + + + + + DMA_OUT_LINK + 0x104 + 0x20 + + + OUTLINK_ADDR + The address of the first outlink descriptor. + 0 + 20 + read-write + + + OUTLINK_STOP + Set the bit to stop to use outlink descriptor. + 28 + 1 + read-write + + + OUTLINK_START + Set the bit to start to use outlink descriptor. + 29 + 1 + read-write + + + OUTLINK_RESTART + Set the bit to mount on new outlink descriptors. + 30 + 1 + read-write + + + + + DMA_IN_LINK + 0x108 + 0x20 + + + INLINK_ADDR + The address of the first inlink descriptor. + 0 + 20 + read-write + + + INLINK_AUTO_RET + when the bit is set inlink descriptor returns to the next descriptor while a packet is wrong + 20 + 1 + read-write + + + INLINK_STOP + Set the bit to stop to use inlink descriptor. + 28 + 1 + read-write + + + INLINK_START + Set the bit to start to use inlink descriptor. + 29 + 1 + read-write + + + INLINK_RESTART + Set the bit to mount on new inlink descriptors. + 30 + 1 + read-write + + + + + DMA_STATUS + 0x10C + 0x20 + + + DMA_RX_EN + spi dma read data status bit. + 0 + 1 + read-only + + + DMA_TX_EN + spi dma write data status bit. + 1 + 1 + read-only + + + + + DMA_INT_ENA + 0x110 + 0x20 + + + INLINK_DSCR_EMPTY_INT_ENA + The enable bit for lack of enough inlink descriptors. + 0 + 1 + read-write + + + OUTLINK_DSCR_ERROR_INT_ENA + The enable bit for outlink descriptor error. + 1 + 1 + read-write + + + INLINK_DSCR_ERROR_INT_ENA + The enable bit for inlink descriptor error. + 2 + 1 + read-write + + + IN_DONE_INT_ENA + The enable bit for completing usage of a inlink descriptor. + 3 + 1 + read-write + + + IN_ERR_EOF_INT_ENA + The enable bit for receiving error. + 4 + 1 + read-write + + + IN_SUC_EOF_INT_ENA + The enable bit for completing receiving all the packets from host. + 5 + 1 + read-write + + + OUT_DONE_INT_ENA + The enable bit for completing usage of a outlink descriptor . + 6 + 1 + read-write + + + OUT_EOF_INT_ENA + The enable bit for sending a packet to host done. + 7 + 1 + read-write + + + OUT_TOTAL_EOF_INT_ENA + The enable bit for sending all the packets to host done. + 8 + 1 + read-write + + + + + DMA_INT_RAW + 0x114 + 0x20 + + + INLINK_DSCR_EMPTY_INT_RAW + The raw bit for lack of enough inlink descriptors. + 0 + 1 + read-only + + + OUTLINK_DSCR_ERROR_INT_RAW + The raw bit for outlink descriptor error. + 1 + 1 + read-only + + + INLINK_DSCR_ERROR_INT_RAW + The raw bit for inlink descriptor error. + 2 + 1 + read-only + + + IN_DONE_INT_RAW + The raw bit for completing usage of a inlink descriptor. + 3 + 1 + read-only + + + IN_ERR_EOF_INT_RAW + The raw bit for receiving error. + 4 + 1 + read-only + + + IN_SUC_EOF_INT_RAW + The raw bit for completing receiving all the packets from host. + 5 + 1 + read-only + + + OUT_DONE_INT_RAW + The raw bit for completing usage of a outlink descriptor. + 6 + 1 + read-only + + + OUT_EOF_INT_RAW + The raw bit for sending a packet to host done. + 7 + 1 + read-only + + + OUT_TOTAL_EOF_INT_RAW + The raw bit for sending all the packets to host done. + 8 + 1 + read-only + + + + + DMA_INT_ST + 0x118 + 0x20 + + + INLINK_DSCR_EMPTY_INT_ST + The status bit for lack of enough inlink descriptors. + 0 + 1 + read-only + + + OUTLINK_DSCR_ERROR_INT_ST + The status bit for outlink descriptor error. + 1 + 1 + read-only + + + INLINK_DSCR_ERROR_INT_ST + The status bit for inlink descriptor error. + 2 + 1 + read-only + + + IN_DONE_INT_ST + The status bit for completing usage of a inlink descriptor. + 3 + 1 + read-only + + + IN_ERR_EOF_INT_ST + The status bit for receiving error. + 4 + 1 + read-only + + + IN_SUC_EOF_INT_ST + The status bit for completing receiving all the packets from host. + 5 + 1 + read-only + + + OUT_DONE_INT_ST + The status bit for completing usage of a outlink descriptor. + 6 + 1 + read-only + + + OUT_EOF_INT_ST + The status bit for sending a packet to host done. + 7 + 1 + read-only + + + OUT_TOTAL_EOF_INT_ST + The status bit for sending all the packets to host done. + 8 + 1 + read-only + + + + + DMA_INT_CLR + 0x11C + 0x20 + + + INLINK_DSCR_EMPTY_INT_CLR + The clear bit for lack of enough inlink descriptors. + 0 + 1 + read-write + + + OUTLINK_DSCR_ERROR_INT_CLR + The clear bit for outlink descriptor error. + 1 + 1 + read-write + + + INLINK_DSCR_ERROR_INT_CLR + The clear bit for inlink descriptor error. + 2 + 1 + read-write + + + IN_DONE_INT_CLR + The clear bit for completing usage of a inlink descriptor. + 3 + 1 + read-write + + + IN_ERR_EOF_INT_CLR + The clear bit for receiving error. + 4 + 1 + read-write + + + IN_SUC_EOF_INT_CLR + The clear bit for completing receiving all the packets from host. + 5 + 1 + read-write + + + OUT_DONE_INT_CLR + The clear bit for completing usage of a outlink descriptor. + 6 + 1 + read-write + + + OUT_EOF_INT_CLR + The clear bit for sending a packet to host done. + 7 + 1 + read-write + + + OUT_TOTAL_EOF_INT_CLR + The clear bit for sending all the packets to host done. + 8 + 1 + read-write + + + + + IN_ERR_EOF_DES_ADDR + 0x120 + 0x20 + + + DMA_IN_ERR_EOF_DES_ADDR + The inlink descriptor address when spi dma produce receiving error. + 0 + 32 + read-only + + + + + IN_SUC_EOF_DES_ADDR + 0x124 + 0x20 + + + DMA_IN_SUC_EOF_DES_ADDR + The last inlink descriptor address when spi dma produce from_suc_eof. + 0 + 32 + read-only + + + + + INLINK_DSCR + 0x128 + 0x20 + + + DMA_INLINK_DSCR + The content of current in descriptor pointer. + 0 + 32 + read-only + + + + + INLINK_DSCR_BF0 + 0x12C + 0x20 + + + DMA_INLINK_DSCR_BF0 + The content of next in descriptor pointer. + 0 + 32 + read-only + + + + + INLINK_DSCR_BF1 + 0x130 + 0x20 + + + DMA_INLINK_DSCR_BF1 + The content of current in descriptor data buffer pointer. + 0 + 32 + read-only + + + + + OUT_EOF_BFR_DES_ADDR + 0x134 + 0x20 + + + DMA_OUT_EOF_BFR_DES_ADDR + The address of buffer relative to the outlink descriptor that produce eof. + 0 + 32 + read-only + + + + + OUT_EOF_DES_ADDR + 0x138 + 0x20 + + + DMA_OUT_EOF_DES_ADDR + The last outlink descriptor address when spi dma produce to_eof. + 0 + 32 + read-only + + + + + OUTLINK_DSCR + 0x13C + 0x20 + + + DMA_OUTLINK_DSCR + The content of current out descriptor pointer. + 0 + 32 + read-only + + + + + OUTLINK_DSCR_BF0 + 0x140 + 0x20 + + + DMA_OUTLINK_DSCR_BF0 + The content of next out descriptor pointer. + 0 + 32 + read-only + + + + + OUTLINK_DSCR_BF1 + 0x144 + 0x20 + + + DMA_OUTLINK_DSCR_BF1 + The content of current out descriptor data buffer pointer. + 0 + 32 + read-only + + + + + DMA_RSTATUS + 0x148 + 0x20 + + + DMA_OUT_STATUS + spi dma read data from memory status. + 0 + 32 + read-only + + + + + DMA_TSTATUS + 0x14C + 0x20 + + + DMA_IN_STATUS + spi dma write data to memory status. + 0 + 32 + read-only + + + + + DATE + 0x3FC + 0x20 + 0x01604270 + + + DATE + SPI register version. + 0 + 28 + read-only + + + + + + + SPI1 + SPI (Serial Peripheral Interface) Controller + 0x3FF42000 + + SPI1 + 29 + + + SPI1_DMA + 52 + + + + SPI2 + SPI (Serial Peripheral Interface) Controller + 0x3FF64000 + + SPI2 + 30 + + + SPI2_DMA + 53 + + + + SPI3 + SPI (Serial Peripheral Interface) Controller + 0x3FF65000 + + SPI3 + 31 + + + SPI3_DMA + 54 + + + + TIMG0 + Timer Group + TIMG + 0x3FF5F000 + + 0x0 + 0xB0 + registers + + + TG0_T0_LEVEL + 14 + + + TG0_T1_LEVEL + 15 + + + TG0_WDT_LEVEL + 16 + + + TG0_LACT_LEVEL + 17 + + + TG0_T0_EDGE + 58 + + + TG0_T1_EDGE + 59 + + + TG0_WDT_EDGE + 60 + + + TG0_LACT_EDGE + 61 + + + + T0CONFIG + 0x0 + 0x20 + 0x60002000 + + + ALARM_EN + When set alarm is enabled + 10 + 1 + read-write + + + LEVEL_INT_EN + When set level type interrupt will be generated during alarm + 11 + 1 + read-write + + + EDGE_INT_EN + When set edge type interrupt will be generated during alarm + 12 + 1 + read-write + + + DIVIDER + Timer 0 clock (T0_clk) prescale value. + 13 + 16 + read-write + + + AUTORELOAD + When set timer 0 auto-reload at alarming is enabled + 29 + 1 + read-write + + + INCREASE + When set timer 0 time-base counter increment. When cleared timer 0 time-base counter decrement. + 30 + 1 + read-write + + + EN + When set timer 0 time-base counter is enabled + 31 + 1 + read-write + + + + + T0LO + 0x4 + 0x20 + + + LO + Register to store timer 0 time-base counter current value lower 32 bits. + 0 + 32 + read-only + + + + + T0HI + 0x8 + 0x20 + + + HI + Register to store timer 0 time-base counter current value higher 32 bits. + 0 + 32 + read-only + + + + + T0UPDATE + 0xC + 0x20 + + + UPDATE + Write any value will trigger a timer 0 time-base counter value update (timer 0 current value will be stored in registers above) + 0 + 32 + write-only + + + + + T0ALARMLO + 0x10 + 0x20 + + + ALARM_LO + Timer 0 time-base counter value lower 32 bits that will trigger the alarm + 0 + 32 + read-write + + + + + T0ALARMHI + 0x14 + 0x20 + + + ALARM_HI + Timer 0 time-base counter value higher 32 bits that will trigger the alarm + 0 + 32 + read-write + + + + + T0LOADLO + 0x18 + 0x20 + + + LOAD_LO + Lower 32 bits of the value that will load into timer 0 time-base counter + 0 + 32 + read-write + + + + + T0LOADHI + 0x1C + 0x20 + + + LOAD_HI + higher 32 bits of the value that will load into timer 0 time-base counter + 0 + 32 + read-write + + + + + T0LOAD + 0x20 + 0x20 + + + LOAD + Write any value will trigger timer 0 time-base counter reload + 0 + 32 + write-only + + + + + T1CONFIG + 0x24 + 0x20 + 0x60002000 + + + ALARM_EN + When set alarm is enabled + 10 + 1 + read-write + + + LEVEL_INT_EN + When set level type interrupt will be generated during alarm + 11 + 1 + read-write + + + EDGE_INT_EN + When set edge type interrupt will be generated during alarm + 12 + 1 + read-write + + + DIVIDER + Timer 1 clock (T1_clk) prescale value. + 13 + 16 + read-write + + + AUTORELOAD + When set timer 1 auto-reload at alarming is enabled + 29 + 1 + read-write + + + INCREASE + When set timer 1 time-base counter increment. When cleared timer 1 time-base counter decrement. + 30 + 1 + read-write + + + EN + When set timer 1 time-base counter is enabled + 31 + 1 + read-write + + + + + T1LO + 0x28 + 0x20 + + + LO + Register to store timer 1 time-base counter current value lower 32 bits. + 0 + 32 + read-only + + + + + T1HI + 0x2C + 0x20 + + + HI + Register to store timer 1 time-base counter current value higher 32 bits. + 0 + 32 + read-only + + + + + T1UPDATE + 0x30 + 0x20 + + + UPDATE + Write any value will trigger a timer 1 time-base counter value update (timer 1 current value will be stored in registers above) + 0 + 32 + write-only + + + + + T1ALARMLO + 0x34 + 0x20 + + + ALARM_LO + Timer 1 time-base counter value lower 32 bits that will trigger the alarm + 0 + 32 + read-write + + + + + T1ALARMHI + 0x38 + 0x20 + + + ALARM_HI + Timer 1 time-base counter value higher 32 bits that will trigger the alarm + 0 + 32 + read-write + + + + + T1LOADLO + 0x3C + 0x20 + + + LOAD_LO + Lower 32 bits of the value that will load into timer 1 time-base counter + 0 + 32 + read-write + + + + + T1LOADHI + 0x40 + 0x20 + + + LOAD_HI + higher 32 bits of the value that will load into timer 1 time-base counter + 0 + 32 + read-write + + + + + T1LOAD + 0x44 + 0x20 + + + LOAD + Write any value will trigger timer 1 time-base counter reload + 0 + 32 + write-only + + + + + WDTCONFIG0 + 0x48 + 0x20 + 0x0004C000 + + + WDT_FLASHBOOT_MOD_EN + When set flash boot protection is enabled + 14 + 1 + read-write + + + WDT_SYS_RESET_LENGTH + length of system reset selection. 0: 100ns 1: 200ns 2: 300ns 3: 400ns 4: 500ns 5: 800ns 6: 1.6us 7: 3.2us + 15 + 3 + read-write + + WDT_SYS_RESET_LENGTH + read-write + + NS100 + 100ns + 0 + + + NS200 + 200ns + 1 + + + NS300 + 300ns + 2 + + + NS400 + 400ns + 3 + + + NS500 + 500ns + 4 + + + NS800 + 800ns + 5 + + + NS1600 + 1.6us + 6 + + + NS3200 + 3.2us + 7 + + + + + WDT_CPU_RESET_LENGTH + length of CPU reset selection. 0: 100ns 1: 200ns 2: 300ns 3: 400ns 4: 500ns 5: 800ns 6: 1.6us 7: 3.2us + 18 + 3 + read-write + + WDT_CPU_RESET_LENGTH + read-write + + NS100 + 100ns + 0 + + + NS200 + 200ns + 1 + + + NS300 + 300ns + 2 + + + NS400 + 400ns + 3 + + + NS500 + 500ns + 4 + + + NS800 + 800ns + 5 + + + NS1600 + 1.6us + 6 + + + NS3200 + 3.2us + 7 + + + + + WDT_LEVEL_INT_EN + When set level type interrupt generation is enabled + 21 + 1 + read-write + + + WDT_EDGE_INT_EN + When set edge type interrupt generation is enabled + 22 + 1 + read-write + + + WDT_STG3 + Stage 3 configuration. 0: off 1: interrupt 2: reset CPU 3: reset system + 23 + 2 + read-write + + WDT_STG3 + read-write + + OFF + Off + 0 + + + INTERRUPT + Interrupt + 1 + + + RESET + Reset CPU + 2 + + + RESET_SYS + Reset system + 3 + + + + + WDT_STG2 + Stage 2 configuration. 0: off 1: interrupt 2: reset CPU 3: reset system + 25 + 2 + read-write + + + + WDT_STG1 + Stage 1 configuration. 0: off 1: interrupt 2: reset CPU 3: reset system + 27 + 2 + read-write + + + + WDT_STG0 + Stage 0 configuration. 0: off 1: interrupt 2: reset CPU 3: reset system + 29 + 2 + read-write + + + + WDT_EN + When set SWDT is enabled + 31 + 1 + read-write + + + + + WDTCONFIG1 + 0x4C + 0x20 + 0x00010000 + + + WDT_CLK_PRESCALE + SWDT clock prescale value. Period = 12.5ns * value stored in this register + 16 + 16 + read-write + + + + + WDTCONFIG2 + 0x50 + 0x20 + 0x018CBA80 + + + WDT_STG0_HOLD + Stage 0 timeout value in SWDT clock cycles + 0 + 32 + read-write + + + + + WDTCONFIG3 + 0x54 + 0x20 + 0x07FFFFFF + + + WDT_STG1_HOLD + Stage 1 timeout value in SWDT clock cycles + 0 + 32 + read-write + + + + + WDTCONFIG4 + 0x58 + 0x20 + 0x000FFFFF + + + WDT_STG2_HOLD + Stage 2 timeout value in SWDT clock cycles + 0 + 32 + read-write + + + + + WDTCONFIG5 + 0x5C + 0x20 + 0x000FFFFF + + + WDT_STG3_HOLD + Stage 3 timeout value in SWDT clock cycles + 0 + 32 + read-write + + + + + WDTFEED + 0x60 + 0x20 + + + WDT_FEED + Write any value will feed SWDT + 0 + 32 + write-only + + + + + WDTWPROTECT + 0x64 + 0x20 + 0x50D83AA1 + + + WDT_WKEY + If change its value from default then write protection is on. + 0 + 32 + read-write + + + + + RTCCALICFG + 0x68 + 0x20 + 0x00013000 + + + RTC_CALI_START_CYCLING + 12 + 1 + read-write + + + RTC_CALI_CLK_SEL + 13 + 2 + read-write + + + RTC_CALI_RDY + 15 + 1 + read-only + + + RTC_CALI_MAX + 16 + 15 + read-write + + + RTC_CALI_START + 31 + 1 + read-write + + + + + RTCCALICFG1 + 0x6C + 0x20 + + + RTC_CALI_VALUE + 7 + 25 + read-only + + + + + LACTCONFIG + 0x70 + 0x20 + 0x60002300 + + + LACT_RTC_ONLY + 7 + 1 + read-write + + + LACT_CPST_EN + 8 + 1 + read-write + + + LACT_LAC_EN + 9 + 1 + read-write + + + LACT_ALARM_EN + 10 + 1 + read-write + + + LACT_LEVEL_INT_EN + 11 + 1 + read-write + + + LACT_EDGE_INT_EN + 12 + 1 + read-write + + + LACT_DIVIDER + 13 + 16 + read-write + + + LACT_AUTORELOAD + 29 + 1 + read-write + + + LACT_INCREASE + 30 + 1 + read-write + + + LACT_EN + 31 + 1 + read-write + + + + + LACTRTC + 0x74 + 0x20 + + + LACT_RTC_STEP_LEN + 6 + 26 + read-write + + + + + LACTLO + 0x78 + 0x20 + + + LACT_LO + 0 + 32 + read-only + + + + + LACTHI + 0x7C + 0x20 + + + LACT_HI + 0 + 32 + read-only + + + + + LACTUPDATE + 0x80 + 0x20 + + + LACT_UPDATE + 0 + 32 + write-only + + + + + LACTALARMLO + 0x84 + 0x20 + + + LACT_ALARM_LO + 0 + 32 + read-write + + + + + LACTALARMHI + 0x88 + 0x20 + + + LACT_ALARM_HI + 0 + 32 + read-write + + + + + LACTLOADLO + 0x8C + 0x20 + + + LACT_LOAD_LO + 0 + 32 + read-write + + + + + LACTLOADHI + 0x90 + 0x20 + + + LACT_LOAD_HI + 0 + 32 + read-write + + + + + LACTLOAD + 0x94 + 0x20 + + + LACT_LOAD + 0 + 32 + write-only + + + + + INT_ENA_TIMERS + 0x98 + 0x20 + + + T0_INT_ENA + interrupt when timer0 alarm + 0 + 1 + read-write + + + T1_INT_ENA + interrupt when timer1 alarm + 1 + 1 + read-write + + + WDT_INT_ENA + Interrupt when an interrupt stage timeout + 2 + 1 + read-write + + + LACT_INT_ENA + 3 + 1 + read-write + + + + + INT_RAW_TIMERS + 0x9C + 0x20 + + + T0_INT_RAW + interrupt when timer0 alarm + 0 + 1 + read-only + + + T1_INT_RAW + interrupt when timer1 alarm + 1 + 1 + read-only + + + WDT_INT_RAW + Interrupt when an interrupt stage timeout + 2 + 1 + read-only + + + LACT_INT_RAW + 3 + 1 + read-only + + + + + INT_ST_TIMERS + 0xA0 + 0x20 + + + T0_INT_ST + interrupt when timer0 alarm + 0 + 1 + read-only + + + T1_INT_ST + interrupt when timer1 alarm + 1 + 1 + read-only + + + WDT_INT_ST + Interrupt when an interrupt stage timeout + 2 + 1 + read-only + + + LACT_INT_ST + 3 + 1 + read-only + + + + + INT_CLR_TIMERS + 0xA4 + 0x20 + + + T0_INT_CLR + interrupt when timer0 alarm + 0 + 1 + write-only + + + T1_INT_CLR + interrupt when timer1 alarm + 1 + 1 + write-only + + + WDT_INT_CLR + Interrupt when an interrupt stage timeout + 2 + 1 + write-only + + + LACT_INT_CLR + 3 + 1 + write-only + + + + + NTIMERS_DATE + 0xF8 + 0x20 + 0x01604290 + + + NTIMERS_DATE + Version of this regfile + 0 + 28 + read-write + + + + + TIMGCLK + 0xFC + 0x20 + + + CLK_EN + Force clock enable for this regfile + 31 + 1 + read-write + + + + + + + TIMG1 + Timer Group + 0x3FF60000 + + TG1_T0_LEVEL + 18 + + + TG1_T1_LEVEL + 19 + + + TG1_WDT_LEVEL + 20 + + + TG1_LACT_LEVEL + 21 + + + TG1_T0_EDGE + 62 + + + TG1_T1_EDGE + 63 + + + TG1_WDT_EDGE + 64 + + + TG1_LACT_EDGE + 65 + + + + TWAI + Two-Wire Automotive Interface + TWAI + 0x3FF6B000 + + 0x0 + 0x6C + registers + + + TWAI + 45 + + + + MODE + Mode Register + 0x0 + 0x20 + 0x00000001 + + + RESET_MODE + This bit is used to configure the operating mode of the TWAI Controller. 1: Reset mode; 0: Operating mode. + 0 + 1 + read-write + + + LISTEN_ONLY_MODE + 1: Listen only mode. In this mode the nodes will only receive messages from the bus, without generating the acknowledge signal nor updating the RX error counter. + 1 + 1 + read-write + + + SELF_TEST_MODE + 1: Self test mode. In this mode the TX nodes can perform a successful transmission without receiving the acknowledge signal. This mode is often used to test a single node with the self reception request command. + 2 + 1 + read-write + + + RX_FILTER_MODE + This bit is used to configure the filter mode. 0: Dual filter mode; 1: Single filter mode. + 3 + 1 + read-write + + + + + CMD + Command Register + 0x4 + 0x20 + + + TX_REQ + Set the bit to 1 to allow the driving nodes start transmission. + 0 + 1 + write-only + + + ABORT_TX + Set the bit to 1 to cancel a pending transmission request. + 1 + 1 + write-only + + + RELEASE_BUF + Set the bit to 1 to release the RX buffer. + 2 + 1 + write-only + + + CLR_OVERRUN + Set the bit to 1 to clear the data overrun status bit. + 3 + 1 + write-only + + + SELF_RX_REQ + Self reception request command. Set the bit to 1 to allow a message be transmitted and received simultaneously. + 4 + 1 + write-only + + + + + STATUS + Status register + 0x8 + 0x20 + + + RX_BUF_ST + 1: The data in the RX buffer is not empty, with at least one received data packet. + 0 + 1 + read-only + + + OVERRUN_ST + 1: The RX FIFO is full and data overrun has occurred. + 1 + 1 + read-only + + + TX_BUF_ST + 1: The TX buffer is empty, the CPU may write a message into it. + 2 + 1 + read-only + + + TX_COMPLETE + 1: The TWAI controller has successfully received a packet from the bus. + 3 + 1 + read-only + + + RX_ST + 1: The TWAI Controller is receiving a message from the bus. + 4 + 1 + read-only + + + TX_ST + 1: The TWAI Controller is transmitting a message to the bus. + 5 + 1 + read-only + + + ERR_ST + 1: At least one of the RX/TX error counter has reached or exceeded the value set in register TWAI_ERR_WARNING_LIMIT_REG. + 6 + 1 + read-only + + + BUS_OFF_ST + 1: In bus-off status, the TWAI Controller is no longer involved in bus activities. + 7 + 1 + read-only + + + MISS_ST + This bit reflects whether the data packet in the RX FIFO is complete. 1: The current packet is missing; 0: The current packet is complete + 8 + 1 + read-only + + + + + INT_RAW + Interrupt Register + 0xC + 0x20 + + + RX_INT_ST + Receive interrupt. If this bit is set to 1, it indicates there are messages to be handled in the RX FIFO. + 0 + 1 + read-only + + + TX_INT_ST + Transmit interrupt. If this bit is set to 1, it indicates the message transmitting mis- sion is finished and a new transmission is able to execute. + 1 + 1 + read-only + + + ERR_WARN_INT_ST + Error warning interrupt. If this bit is set to 1, it indicates the error status signal and the bus-off status signal of Status register have changed (e.g., switched from 0 to 1 or from 1 to 0). + 2 + 1 + read-only + + + OVERRUN_INT_ST + Data overrun interrupt. If this bit is set to 1, it indicates a data overrun interrupt is generated in the RX FIFO. + 3 + 1 + read-only + + + ERR_PASSIVE_INT_ST + Error passive interrupt. If this bit is set to 1, it indicates the TWAI Controller is switched between error active status and error passive status due to the change of error counters. + 5 + 1 + read-only + + + ARB_LOST_INT_ST + Arbitration lost interrupt. If this bit is set to 1, it indicates an arbitration lost interrupt is generated. + 6 + 1 + read-only + + + BUS_ERR_INT_ST + Error interrupt. If this bit is set to 1, it indicates an error is detected on the bus. + 7 + 1 + read-only + + + + + INT_ENA + Interrupt Enable Register + 0x10 + 0x20 + + + RX_INT_ENA + Set this bit to 1 to enable receive interrupt. + 0 + 1 + read-write + + + TX_INT_ENA + Set this bit to 1 to enable transmit interrupt. + 1 + 1 + read-write + + + ERR_WARN_INT_ENA + Set this bit to 1 to enable error warning interrupt. + 2 + 1 + read-write + + + OVERRUN_INT_ENA + Set this bit to 1 to enable data overrun interrupt. + 3 + 1 + read-write + + + ERR_PASSIVE_INT_ENA + Set this bit to 1 to enable error passive interrupt. + 5 + 1 + read-write + + + ARB_LOST_INT_ENA + Set this bit to 1 to enable arbitration lost interrupt. + 6 + 1 + read-write + + + BUS_ERR_INT_ENA + Set this bit to 1 to enable error interrupt. + 7 + 1 + read-write + + + + + BUS_TIMING_0 + Bus Timing Register 0 + 0x18 + 0x20 + + + BAUD_PRESC + Baud Rate Prescaler, determines the frequency dividing ratio. + 0 + 14 + + + SYNC_JUMP_WIDTH + Synchronization Jump Width (SJW), 1 \verb+~+ 14 Tq wide. + 14 + 2 + + + + + BUS_TIMING_1 + Bus Timing Register 1 + 0x1C + 0x20 + + + TIME_SEG1 + The width of PBS1. + 0 + 4 + + + TIME_SEG2 + The width of PBS2. + 4 + 3 + + + TIME_SAMP + The number of sample points. 0: the bus is sampled once; 1: the bus is sampled three times + 7 + 1 + + + + + ARB_LOST_CAP + Arbitration Lost Capture Register + 0x2C + 0x20 + + + ARB_LOST_CAP + This register contains information about the bit position of lost arbitration. + 0 + 5 + read-only + + + + + ERR_CODE_CAP + Error Code Capture Register + 0x30 + 0x20 + + + ECC_SEGMENT + This register contains information about the location of errors, see Table 181 for details. + 0 + 5 + read-only + + + ECC_DIRECTION + This register contains information about transmission direction of the node when error occurs. 1: Error occurs when receiving a message; 0: Error occurs when transmitting a message + 5 + 1 + read-only + + + ECC_TYPE + This register contains information about error types: 00: bit error; 01: form error; 10: stuff error; 11: other type of error + 6 + 2 + read-only + + + + + ERR_WARNING_LIMIT + Error Warning Limit Register + 0x34 + 0x20 + 0x00000060 + + + ERR_WARNING_LIMIT + Error warning threshold. In the case when any of a error counter value exceeds the threshold, or all the error counter values are below the threshold, an error warning interrupt will be triggered (given the enable signal is valid). + 0 + 8 + + + + + RX_ERR_CNT + Receive Error Counter Register + 0x38 + 0x20 + + + RX_ERR_CNT + The RX error counter register, reflects value changes under reception status. + 0 + 8 + + + + + TX_ERR_CNT + Transmit Error Counter Register + 0x3C + 0x20 + + + TX_ERR_CNT + The TX error counter register, reflects value changes under transmission status. + 0 + 8 + + + + + DATA_0 + Data register 0 + 0x40 + 0x20 + + + TX_BYTE_0 + In reset mode, it is acceptance code register 0 with R/W Permission. In operation mode, it stores the 0th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_1 + Data register 1 + 0x44 + 0x20 + + + TX_BYTE_1 + In reset mode, it is acceptance code register 1 with R/W Permission. In operation mode, it stores the 1st byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_2 + Data register 2 + 0x48 + 0x20 + + + TX_BYTE_2 + In reset mode, it is acceptance code register 2 with R/W Permission. In operation mode, it stores the 2nd byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_3 + Data register 3 + 0x4C + 0x20 + + + TX_BYTE_3 + In reset mode, it is acceptance code register 3 with R/W Permission. In operation mode, it stores the 3rd byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_4 + Data register 4 + 0x50 + 0x20 + + + TX_BYTE_4 + In reset mode, it is acceptance mask register 0 with R/W Permission. In operation mode, it stores the 4th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_5 + Data register 5 + 0x54 + 0x20 + + + TX_BYTE_5 + In reset mode, it is acceptance mask register 1 with R/W Permission. In operation mode, it stores the 5th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_6 + Data register 6 + 0x58 + 0x20 + + + TX_BYTE_6 + In reset mode, it is acceptance mask register 2 with R/W Permission. In operation mode, it stores the 6th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_7 + Data register 7 + 0x5C + 0x20 + + + TX_BYTE_7 + In reset mode, it is acceptance mask register 3 with R/W Permission. In operation mode, it stores the 7th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_8 + Data register 8 + 0x60 + 0x20 + + + TX_BYTE_8 + Stored the 8th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_9 + Data register 9 + 0x64 + 0x20 + + + TX_BYTE_9 + Stored the 9th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_10 + Data register 10 + 0x68 + 0x20 + + + TX_BYTE_10 + Stored the 10th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_11 + Data register 11 + 0x6C + 0x20 + + + TX_BYTE_11 + Stored the 11th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_12 + Data register 12 + 0x70 + 0x20 + + + TX_BYTE_12 + Stored the 12th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + RX_MESSAGE_CNT + Receive Message Counter Register + 0x74 + 0x20 + + + RX_MESSAGE_COUNTER + This register reflects the number of messages available within the RX FIFO. + 0 + 7 + read-only + + + + + CLOCK_DIVIDER + Clock Divider register + 0x7C + 0x20 + + + CD + These bits are used to configure frequency dividing coefficients of the external CLKOUT pin. + 0 + 8 + read-write + + + CLOCK_OFF + This bit can be configured under reset mode. 1: Disable the external CLKOUT pin; 0: Enable the external CLKOUT pin + 8 + 1 + + + + + + + UART0 + UART (Universal Asynchronous Receiver-Transmitter) Controller + UART + 0x3FF40000 + + 0x0 + 0x7C + registers + + + UART0 + 34 + + + + FIFO + 0x0 + 0x20 + + + RXFIFO_RD_BYTE + This register stores one byte data read by rx fifo. + 0 + 8 + read-write + + + + + INT_RAW + 0x4 + 0x20 + + + RXFIFO_FULL_INT_RAW + This interrupt raw bit turns to high level when receiver receives more data than (rx_flow_thrhd_h3 rx_flow_thrhd). + 0 + 1 + read-only + + + TXFIFO_EMPTY_INT_RAW + This interrupt raw bit turns to high level when the amount of data in transmitter's fifo is less than ((tx_mem_cnttxfifo_cnt) . + 1 + 1 + read-only + + + PARITY_ERR_INT_RAW + This interrupt raw bit turns to high level when receiver detects the parity error of data. + 2 + 1 + read-only + + + FRM_ERR_INT_RAW + This interrupt raw bit turns to high level when receiver detects data's frame error . + 3 + 1 + read-only + + + RXFIFO_OVF_INT_RAW + This interrupt raw bit turns to high level when receiver receives more data than the fifo can store. + 4 + 1 + read-only + + + DSR_CHG_INT_RAW + This interrupt raw bit turns to high level when receiver detects the edge change of dsrn signal. + 5 + 1 + read-only + + + CTS_CHG_INT_RAW + This interrupt raw bit turns to high level when receiver detects the edge change of ctsn signal. + 6 + 1 + read-only + + + BRK_DET_INT_RAW + This interrupt raw bit turns to high level when receiver detects the 0 after the stop bit. + 7 + 1 + read-only + + + RXFIFO_TOUT_INT_RAW + This interrupt raw bit turns to high level when receiver takes more time than rx_tout_thrhd to receive a byte. + 8 + 1 + read-only + + + SW_XON_INT_RAW + This interrupt raw bit turns to high level when receiver receives xoff char with uart_sw_flow_con_en is set to 1. + 9 + 1 + read-only + + + SW_XOFF_INT_RAW + This interrupt raw bit turns to high level when receiver receives xon char with uart_sw_flow_con_en is set to 1. + 10 + 1 + read-only + + + GLITCH_DET_INT_RAW + This interrupt raw bit turns to high level when receiver detects the start bit. + 11 + 1 + read-only + + + TX_BRK_DONE_INT_RAW + This interrupt raw bit turns to high level when transmitter completes sendding 0 after all the datas in transmitter's fifo are send. + 12 + 1 + read-only + + + TX_BRK_IDLE_DONE_INT_RAW + This interrupt raw bit turns to high level when transmitter has kept the shortest duration after the last data has been send. + 13 + 1 + read-only + + + TX_DONE_INT_RAW + This interrupt raw bit turns to high level when transmitter has send all the data in fifo. + 14 + 1 + read-only + + + RS485_PARITY_ERR_INT_RAW + This interrupt raw bit turns to high level when rs485 detects the parity error. + 15 + 1 + read-only + + + RS485_FRM_ERR_INT_RAW + This interrupt raw bit turns to high level when rs485 detects the data frame error. + 16 + 1 + read-only + + + RS485_CLASH_INT_RAW + This interrupt raw bit turns to high level when rs485 detects the clash between transmitter and receiver. + 17 + 1 + read-only + + + AT_CMD_CHAR_DET_INT_RAW + This interrupt raw bit turns to high level when receiver detects the configured at_cmd chars. + 18 + 1 + read-only + + + + + INT_ST + 0x8 + 0x20 + + + RXFIFO_FULL_INT_ST + This is the status bit for rxfifo_full_int_raw when rxfifo_full_int_ena is set to 1. + 0 + 1 + read-only + + + TXFIFO_EMPTY_INT_ST + This is the status bit for txfifo_empty_int_raw when txfifo_empty_int_ena is set to 1. + 1 + 1 + read-only + + + PARITY_ERR_INT_ST + This is the status bit for parity_err_int_raw when parity_err_int_ena is set to 1. + 2 + 1 + read-only + + + FRM_ERR_INT_ST + This is the status bit for frm_err_int_raw when fm_err_int_ena is set to 1. + 3 + 1 + read-only + + + RXFIFO_OVF_INT_ST + This is the status bit for rxfifo_ovf_int_raw when rxfifo_ovf_int_ena is set to 1. + 4 + 1 + read-only + + + DSR_CHG_INT_ST + This is the status bit for dsr_chg_int_raw when dsr_chg_int_ena is set to 1. + 5 + 1 + read-only + + + CTS_CHG_INT_ST + This is the status bit for cts_chg_int_raw when cts_chg_int_ena is set to 1. + 6 + 1 + read-only + + + BRK_DET_INT_ST + This is the status bit for brk_det_int_raw when brk_det_int_ena is set to 1. + 7 + 1 + read-only + + + RXFIFO_TOUT_INT_ST + This is the status bit for rxfifo_tout_int_raw when rxfifo_tout_int_ena is set to 1. + 8 + 1 + read-only + + + SW_XON_INT_ST + This is the status bit for sw_xon_int_raw when sw_xon_int_ena is set to 1. + 9 + 1 + read-only + + + SW_XOFF_INT_ST + This is the status bit for sw_xoff_int_raw when sw_xoff_int_ena is set to 1. + 10 + 1 + read-only + + + GLITCH_DET_INT_ST + This is the status bit for glitch_det_int_raw when glitch_det_int_ena is set to 1. + 11 + 1 + read-only + + + TX_BRK_DONE_INT_ST + This is the status bit for tx_brk_done_int_raw when tx_brk_done_int_ena is set to 1. + 12 + 1 + read-only + + + TX_BRK_IDLE_DONE_INT_ST + This is the stauts bit for tx_brk_idle_done_int_raw when tx_brk_idle_done_int_ena is set to 1. + 13 + 1 + read-only + + + TX_DONE_INT_ST + This is the status bit for tx_done_int_raw when tx_done_int_ena is set to 1. + 14 + 1 + read-only + + + RS485_PARITY_ERR_INT_ST + This is the status bit for rs485_parity_err_int_raw when rs485_parity_int_ena is set to 1. + 15 + 1 + read-only + + + RS485_FRM_ERR_INT_ST + This is the status bit for rs485_fm_err_int_raw when rs485_fm_err_int_ena is set to 1. + 16 + 1 + read-only + + + RS485_CLASH_INT_ST + This is the status bit for rs485_clash_int_raw when rs485_clash_int_ena is set to 1. + 17 + 1 + read-only + + + AT_CMD_CHAR_DET_INT_ST + This is the status bit for at_cmd_det_int_raw when at_cmd_char_det_int_ena is set to 1. + 18 + 1 + read-only + + + + + INT_ENA + 0xC + 0x20 + + + RXFIFO_FULL_INT_ENA + This is the enable bit for rxfifo_full_int_st register. + 0 + 1 + read-write + + + TXFIFO_EMPTY_INT_ENA + This is the enable bit for rxfifo_full_int_st register. + 1 + 1 + read-write + + + PARITY_ERR_INT_ENA + This is the enable bit for parity_err_int_st register. + 2 + 1 + read-write + + + FRM_ERR_INT_ENA + This is the enable bit for frm_err_int_st register. + 3 + 1 + read-write + + + RXFIFO_OVF_INT_ENA + This is the enable bit for rxfifo_ovf_int_st register. + 4 + 1 + read-write + + + DSR_CHG_INT_ENA + This is the enable bit for dsr_chg_int_st register. + 5 + 1 + read-write + + + CTS_CHG_INT_ENA + This is the enable bit for cts_chg_int_st register. + 6 + 1 + read-write + + + BRK_DET_INT_ENA + This is the enable bit for brk_det_int_st register. + 7 + 1 + read-write + + + RXFIFO_TOUT_INT_ENA + This is the enable bit for rxfifo_tout_int_st register. + 8 + 1 + read-write + + + SW_XON_INT_ENA + This is the enable bit for sw_xon_int_st register. + 9 + 1 + read-write + + + SW_XOFF_INT_ENA + This is the enable bit for sw_xoff_int_st register. + 10 + 1 + read-write + + + GLITCH_DET_INT_ENA + This is the enable bit for glitch_det_int_st register. + 11 + 1 + read-write + + + TX_BRK_DONE_INT_ENA + This is the enable bit for tx_brk_done_int_st register. + 12 + 1 + read-write + + + TX_BRK_IDLE_DONE_INT_ENA + This is the enable bit for tx_brk_idle_done_int_st register. + 13 + 1 + read-write + + + TX_DONE_INT_ENA + This is the enable bit for tx_done_int_st register. + 14 + 1 + read-write + + + RS485_PARITY_ERR_INT_ENA + This is the enable bit for rs485_parity_err_int_st register. + 15 + 1 + read-write + + + RS485_FRM_ERR_INT_ENA + This is the enable bit for rs485_parity_err_int_st register. + 16 + 1 + read-write + + + RS485_CLASH_INT_ENA + This is the enable bit for rs485_clash_int_st register. + 17 + 1 + read-write + + + AT_CMD_CHAR_DET_INT_ENA + This is the enable bit for at_cmd_char_det_int_st register. + 18 + 1 + read-write + + + + + INT_CLR + 0x10 + 0x20 + + + RXFIFO_FULL_INT_CLR + Set this bit to clear the rxfifo_full_int_raw interrupt. + 0 + 1 + write-only + + + TXFIFO_EMPTY_INT_CLR + Set this bit to clear txfifo_empty_int_raw interrupt. + 1 + 1 + write-only + + + PARITY_ERR_INT_CLR + Set this bit to clear parity_err_int_raw interrupt. + 2 + 1 + write-only + + + FRM_ERR_INT_CLR + Set this bit to clear frm_err_int_raw interrupt. + 3 + 1 + write-only + + + RXFIFO_OVF_INT_CLR + Set this bit to clear rxfifo_ovf_int_raw interrupt. + 4 + 1 + write-only + + + DSR_CHG_INT_CLR + Set this bit to clear the dsr_chg_int_raw interrupt. + 5 + 1 + write-only + + + CTS_CHG_INT_CLR + Set this bit to clear the cts_chg_int_raw interrupt. + 6 + 1 + write-only + + + BRK_DET_INT_CLR + Set this bit to clear the brk_det_int_raw interrupt. + 7 + 1 + write-only + + + RXFIFO_TOUT_INT_CLR + Set this bit to clear the rxfifo_tout_int_raw interrupt. + 8 + 1 + write-only + + + SW_XON_INT_CLR + Set this bit to clear the sw_xon_int_raw interrupt. + 9 + 1 + write-only + + + SW_XOFF_INT_CLR + Set this bit to clear the sw_xon_int_raw interrupt. + 10 + 1 + write-only + + + GLITCH_DET_INT_CLR + Set this bit to clear the glitch_det_int_raw interrupt. + 11 + 1 + write-only + + + TX_BRK_DONE_INT_CLR + Set this bit to clear the tx_brk_done_int_raw interrupt.. + 12 + 1 + write-only + + + TX_BRK_IDLE_DONE_INT_CLR + Set this bit to clear the tx_brk_idle_done_int_raw interrupt. + 13 + 1 + write-only + + + TX_DONE_INT_CLR + Set this bit to clear the tx_done_int_raw interrupt. + 14 + 1 + write-only + + + RS485_PARITY_ERR_INT_CLR + Set this bit to clear the rs485_parity_err_int_raw interrupt. + 15 + 1 + write-only + + + RS485_FRM_ERR_INT_CLR + Set this bit to clear the rs485_frm_err_int_raw interrupt. + 16 + 1 + write-only + + + RS485_CLASH_INT_CLR + Set this bit to clear the rs485_clash_int_raw interrupt. + 17 + 1 + write-only + + + AT_CMD_CHAR_DET_INT_CLR + Set this bit to clear the at_cmd_char_det_int_raw interrupt. + 18 + 1 + write-only + + + + + CLKDIV + 0x14 + 0x20 + 0x000002B6 + + + CLKDIV + The register value is the integer part of the frequency divider's factor. + 0 + 20 + read-write + + + FRAG + The register value is the decimal part of the frequency divider's factor. + 20 + 4 + read-write + + + + + AUTOBAUD + 0x18 + 0x20 + 0x00001000 + + + EN + This is the enable bit for detecting baudrate. + 0 + 1 + read-write + + + GLITCH_FILT + when input pulse width is lower then this value igore this pulse.this register is used in autobaud detect process. + 8 + 8 + read-write + + + + + STATUS + 0x1C + 0x20 + + + RXFIFO_CNT + (rx_mem_cnt rxfifo_cnt) stores the byte num of valid datas in receiver's fifo. rx_mem_cnt register stores the 3 most significant bits rxfifo_cnt stores the 8 least significant bits. + 0 + 8 + read-only + + + ST_URX_OUT + This register stores the value of receiver's finite state machine. 0:RX_IDLE 1:RX_STRT 2:RX_DAT0 3:RX_DAT1 4:RX_DAT2 5:RX_DAT3 6:RX_DAT4 7:RX_DAT5 8:RX_DAT6 9:RX_DAT7 10:RX_PRTY 11:RX_STP1 12:RX_STP2 13:RX_DL1 + 8 + 4 + read-only + + + DSRN + This register stores the level value of the internal uart dsr signal. + 13 + 1 + read-only + + + CTSN + This register stores the level value of the internal uart cts signal. + 14 + 1 + read-only + + + RXD + This register stores the level value of the internal uart rxd signal. + 15 + 1 + read-only + + + TXFIFO_CNT + (tx_mem_cnt txfifo_cnt) stores the byte num of valid datas in transmitter's fifo.tx_mem_cnt stores the 3 most significant bits txfifo_cnt stores the 8 least significant bits. + 16 + 8 + read-only + + + ST_UTX_OUT + This register stores the value of transmitter's finite state machine. 0:TX_IDLE 1:TX_STRT 2:TX_DAT0 3:TX_DAT1 4:TX_DAT2 5:TX_DAT3 6:TX_DAT4 7:TX_DAT5 8:TX_DAT6 9:TX_DAT7 10:TX_PRTY 11:TX_STP1 12:TX_STP2 13:TX_DL0 14:TX_DL1 + 24 + 4 + read-only + + + DTRN + The register represent the level value of the internal uart dsr signal. + 29 + 1 + read-only + + + RTSN + This register represent the level value of the internal uart cts signal. + 30 + 1 + read-only + + + TXD + This register represent the level value of the internal uart rxd signal. + 31 + 1 + read-only + + + + + CONF0 + 0x20 + 0x20 + 0x0800001C + + + PARITY + This register is used to configure the parity check mode. 0:even 1:odd + 0 + 1 + read-write + + + PARITY_EN + Set this bit to enable uart parity check. + 1 + 1 + read-write + + + BIT_NUM + This registe is used to set the length of data: 0:5bits 1:6bits 2:7bits 3:8bits + 2 + 2 + read-write + + + STOP_BIT_NUM + This register is used to set the length of stop bit. 1:1bit 2:1.5bits 3:2bits + 4 + 2 + read-write + + + SW_RTS + This register is used to configure the software rts signal which is used in software flow control. + 6 + 1 + read-write + + + SW_DTR + This register is used to configure the software dtr signal which is used in software flow control.. + 7 + 1 + read-write + + + TXD_BRK + Set this bit to enbale transmitter to send 0 when the process of sending data is done. + 8 + 1 + read-write + + + IRDA_DPLX + Set this bit to enable irda loopback mode. + 9 + 1 + read-write + + + IRDA_TX_EN + This is the start enable bit for irda transmitter. + 10 + 1 + read-write + + + IRDA_WCTL + 1.the irda transmitter's 11th bit is the same to the 10th bit. 0.set irda transmitter's 11th bit to 0. + 11 + 1 + read-write + + + IRDA_TX_INV + Set this bit to inverse the level value of irda transmitter's level. + 12 + 1 + read-write + + + IRDA_RX_INV + Set this bit to inverse the level value of irda receiver's level. + 13 + 1 + read-write + + + LOOPBACK + Set this bit to enable uart loopback test mode. + 14 + 1 + read-write + + + TX_FLOW_EN + Set this bit to enable transmitter's flow control function. + 15 + 1 + read-write + + + IRDA_EN + Set this bit to enable irda protocol. + 16 + 1 + read-write + + + RXFIFO_RST + Set this bit to reset uart receiver's fifo. + 17 + 1 + read-write + + + TXFIFO_RST + Set this bit to reset uart transmitter's fifo. + 18 + 1 + read-write + + + RXD_INV + Set this bit to inverse the level value of uart rxd signal. + 19 + 1 + read-write + + + CTS_INV + Set this bit to inverse the level value of uart cts signal. + 20 + 1 + read-write + + + DSR_INV + Set this bit to inverse the level value of uart dsr signal. + 21 + 1 + read-write + + + TXD_INV + Set this bit to inverse the level value of uart txd signal. + 22 + 1 + read-write + + + RTS_INV + Set this bit to inverse the level value of uart rts signal. + 23 + 1 + read-write + + + DTR_INV + Set this bit to inverse the level value of uart dtr signal. + 24 + 1 + read-write + + + CLK_EN + 1.force clock on for registers.support clock only when write registers + 25 + 1 + read-write + + + ERR_WR_MASK + 1.receiver stops storing data int fifo when data is wrong. 0.receiver stores the data even if the received data is wrong. + 26 + 1 + read-write + + + TICK_REF_ALWAYS_ON + This register is used to select the clock.1.apb clock 0:ref_tick + 27 + 1 + read-write + + + + + CONF1 + 0x24 + 0x20 + 0x00006060 + + + RXFIFO_FULL_THRHD + When receiver receives more data than its threshold value.receiver will produce rxfifo_full_int_raw interrupt.the threshold value is (rx_flow_thrhd_h3 rxfifo_full_thrhd). + 0 + 7 + read-write + + + TXFIFO_EMPTY_THRHD + when the data amount in transmitter fifo is less than its threshold value. it will produce txfifo_empty_int_raw interrupt. the threshold value is (tx_mem_empty_thrhd txfifo_empty_thrhd) + 8 + 7 + read-write + + + RX_FLOW_THRHD + when receiver receives more data than its threshold value. receiver produce signal to tell the transmitter stop transferring data. the threshold value is (rx_flow_thrhd_h3 rx_flow_thrhd). + 16 + 7 + read-write + + + RX_FLOW_EN + This is the flow enable bit for uart receiver. 1:choose software flow control with configuring sw_rts signal + 23 + 1 + read-write + + + RX_TOUT_THRHD + This register is used to configure the timeout value for uart receiver receiving a byte. + 24 + 7 + read-write + + + RX_TOUT_EN + This is the enble bit for uart receiver's timeout function. + 31 + 1 + read-write + + + + + LOWPULSE + 0x28 + 0x20 + 0x000FFFFF + + + MIN_CNT + This register stores the value of the minimum duration time for the low level pulse. it is used in baudrate-detect process. + 0 + 20 + read-only + + + + + HIGHPULSE + 0x2C + 0x20 + 0x000FFFFF + + + MIN_CNT + This register stores the value of the maxinum duration time for the high level pulse. it is used in baudrate-detect process. + 0 + 20 + read-only + + + + + RXD_CNT + 0x30 + 0x20 + + + RXD_EDGE_CNT + This register stores the count of rxd edge change. it is used in baudrate-detect process. + 0 + 10 + read-only + + + + + FLOW_CONF + 0x34 + 0x20 + + + SW_FLOW_CON_EN + Set this bit to enable software flow control. it is used with register sw_xon or sw_xoff . + 0 + 1 + read-write + + + XONOFF_DEL + Set this bit to remove flow control char from the received data. + 1 + 1 + read-write + + + FORCE_XON + Set this bit to clear ctsn to stop the transmitter from sending data. + 2 + 1 + read-write + + + FORCE_XOFF + Set this bit to set ctsn to enable the transmitter to go on sending data. + 3 + 1 + read-write + + + SEND_XON + Set this bit to send xon char. it is cleared by hardware automatically. + 4 + 1 + read-write + + + SEND_XOFF + Set this bit to send xoff char. it is cleared by hardware automatically. + 5 + 1 + read-write + + + + + SLEEP_CONF + 0x38 + 0x20 + 0x000000F0 + + + ACTIVE_THRESHOLD + When the input rxd edge changes more than this register value. the uart is active from light sleeping mode. + 0 + 10 + read-write + + + + + SWFC_CONF + 0x3C + 0x20 + 0x1311E000 + + + XON_THRESHOLD + when the data amount in receiver's fifo is more than this register value. it will send a xoff char with uart_sw_flow_con_en set to 1. + 0 + 8 + read-write + + + XOFF_THRESHOLD + When the data amount in receiver's fifo is less than this register value. it will send a xon char with uart_sw_flow_con_en set to 1. + 8 + 8 + read-write + + + XON_CHAR + This register stores the xon flow control char. + 16 + 8 + read-write + + + XOFF_CHAR + This register stores the xoff flow control char. + 24 + 8 + read-write + + + + + IDLE_CONF + 0x40 + 0x20 + 0x00A40100 + + + RX_IDLE_THRHD + when receiver takes more time than this register value to receive a byte data. it will produce frame end signal for uhci to stop receiving data. + 0 + 10 + read-write + + + TX_IDLE_NUM + This register is used to configure the duration time between transfers. + 10 + 10 + read-write + + + TX_BRK_NUM + This register is used to configure the num of 0 send after the process of sending data is done. it is active when txd_brk is set to 1. + 20 + 8 + read-write + + + + + RS485_CONF + 0x44 + 0x20 + + + RS485_EN + Set this bit to choose rs485 mode. + 0 + 1 + read-write + + + DL0_EN + Set this bit to delay the stop bit by 1 bit. + 1 + 1 + read-write + + + DL1_EN + Set this bit to delay the stop bit by 1 bit. + 2 + 1 + read-write + + + RS485TX_RX_EN + Set this bit to enable loopback transmitter's output data signal to receiver's input data signal. + 3 + 1 + read-write + + + RS485RXBY_TX_EN + 1: enable rs485's transmitter to send data when rs485's receiver is busy. 0:rs485's transmitter should not send data when its receiver is busy. + 4 + 1 + read-write + + + RS485_RX_DLY_NUM + This register is used to delay the receiver's internal data signal. + 5 + 1 + read-write + + + RS485_TX_DLY_NUM + This register is used to delay the transmitter's internal data signal. + 6 + 4 + read-write + + + + + AT_CMD_PRECNT + 0x48 + 0x20 + 0x00186A00 + + + PRE_IDLE_NUM + This register is used to configure the idle duration time before the first at_cmd is received by receiver. when the the duration is less than this register value it will not take the next data received as at_cmd char. + 0 + 24 + read-write + + + + + AT_CMD_POSTCNT + 0x4C + 0x20 + 0x00186A00 + + + POST_IDLE_NUM + This register is used to configure the duration time between the last at_cmd and the next data. when the duration is less than this register value it will not take the previous data as at_cmd char. + 0 + 24 + read-write + + + + + AT_CMD_GAPTOUT + 0x50 + 0x20 + 0x00001E00 + + + RX_GAP_TOUT + This register is used to configure the duration time between the at_cmd chars. when the duration time is less than this register value it will not take the datas as continous at_cmd chars. + 0 + 24 + read-write + + + + + AT_CMD_CHAR + 0x54 + 0x20 + 0x0000032B + + + AT_CMD_CHAR + This register is used to configure the content of at_cmd char. + 0 + 8 + read-write + + + CHAR_NUM + This register is used to configure the num of continous at_cmd chars received by receiver. + 8 + 8 + read-write + + + + + MEM_CONF + 0x58 + 0x20 + 0x00000088 + + + MEM_PD + Set this bit to power down mem.when reg_mem_pd registers in the 3 uarts are all set to 1 mem will enter low power mode. + 0 + 1 + read-write + + + RX_SIZE + This register is used to configure the amount of mem allocated to receiver's fifo. the default byte num is 128. + 3 + 4 + read-write + + + TX_SIZE + This register is used to configure the amount of mem allocated to transmitter's fifo.the default byte num is 128. + 7 + 4 + read-write + + + RX_FLOW_THRHD_H3 + refer to the rx_flow_thrhd's describtion. + 15 + 3 + read-write + + + RX_TOUT_THRHD_H3 + refer to the rx_tout_thrhd's describtion. + 18 + 3 + read-write + + + XON_THRESHOLD_H2 + refer to the uart_xon_threshold's describtion. + 21 + 2 + read-write + + + XOFF_THRESHOLD_H2 + refer to the uart_xoff_threshold's describtion. + 23 + 2 + read-write + + + RX_MEM_FULL_THRHD + refer to the rxfifo_full_thrhd's describtion. + 25 + 3 + read-write + + + TX_MEM_EMPTY_THRHD + refer to txfifo_empty_thrhd 's describtion. + 28 + 3 + read-write + + + + + MEM_TX_STATUS + 0x5C + 0x20 + + + MEM_TX_STATUS + 0 + 24 + read-only + + + + + MEM_RX_STATUS + 0x60 + 0x20 + + + MEM_RX_STATUS + This register stores the current uart rx mem read address and rx mem write address + 0 + 24 + read-only + + + MEM_RX_RD_ADDR + This register stores the rx mem read address + 2 + 11 + read-only + + + MEM_RX_WR_ADDR + This register stores the rx mem write address + 13 + 11 + read-only + + + + + MEM_CNT_STATUS + 0x64 + 0x20 + + + RX_MEM_CNT + refer to the rxfifo_cnt's describtion. + 0 + 3 + read-only + + + TX_MEM_CNT + refer to the txfifo_cnt's describtion. + 3 + 3 + read-only + + + + + POSPULSE + 0x68 + 0x20 + 0x000FFFFF + + + POSEDGE_MIN_CNT + This register stores the count of rxd posedge edge. it is used in boudrate-detect process. + 0 + 20 + read-only + + + + + NEGPULSE + 0x6C + 0x20 + 0x000FFFFF + + + NEGEDGE_MIN_CNT + This register stores the count of rxd negedge edge. it is used in boudrate-detect process. + 0 + 20 + read-only + + + + + DATE + 0x78 + 0x20 + 0x15122500 + + + DATE + 0 + 32 + read-write + + + + + ID + 0x7C + 0x20 + 0x00000500 + + + ID + 0 + 32 + read-write + + + + + + + UART1 + UART (Universal Asynchronous Receiver-Transmitter) Controller + 0x3FF50000 + + UART1 + 35 + + + + UART2 + UART (Universal Asynchronous Receiver-Transmitter) Controller + 0x3FF6E000 + + UART2 + 36 + + + + UHCI0 + Universal Host Controller Interface + UHCI + 0x3FF54000 + + 0x0 + 0xC8 + registers + + + UHCI0 + 12 + + + + CONF0 + 0x0 + 0x20 + 0x00370100 + + + IN_RST + Set this bit to reset in link operations. + 0 + 1 + read-write + + + OUT_RST + Set this bit to reset out link operations. + 1 + 1 + read-write + + + AHBM_FIFO_RST + Set this bit to reset dma ahb fifo. + 2 + 1 + read-write + + + AHBM_RST + Set this bit to reset dma ahb interface. + 3 + 1 + read-write + + + IN_LOOP_TEST + Set this bit to enable loop test for in links. + 4 + 1 + read-write + + + OUT_LOOP_TEST + Set this bit to enable loop test for out links. + 5 + 1 + read-write + + + OUT_AUTO_WRBACK + when in link's length is 0 go on to use the next in link automatically. + 6 + 1 + read-write + + + OUT_NO_RESTART_CLR + don't use + 7 + 1 + read-write + + + OUT_EOF_MODE + Set this bit to produce eof after DMA pops all data clear this bit to produce eof after DMA pushes all data + 8 + 1 + read-write + + + UART0_CE + Set this bit to use UART to transmit or receive data. + 9 + 1 + read-write + + + UART1_CE + Set this bit to use UART1 to transmit or receive data. + 10 + 1 + read-write + + + UART2_CE + Set this bit to use UART2 to transmit or receive data. + 11 + 1 + read-write + + + OUTDSCR_BURST_EN + Set this bit to enable DMA in links to use burst mode. + 12 + 1 + read-write + + + INDSCR_BURST_EN + Set this bit to enable DMA out links to use burst mode. + 13 + 1 + read-write + + + OUT_DATA_BURST_EN + Set this bit to enable DMA burst MODE + 14 + 1 + read-write + + + MEM_TRANS_EN + 15 + 1 + read-write + + + SEPER_EN + Set this bit to use special char to separate the data frame. + 16 + 1 + read-write + + + HEAD_EN + Set this bit to enable to use head packet before the data frame. + 17 + 1 + read-write + + + CRC_REC_EN + Set this bit to enable receiver''s ability of crc calculation when crc_en bit in head packet is 1 then there will be crc bytes after data_frame + 18 + 1 + read-write + + + UART_IDLE_EOF_EN + Set this bit to enable to use idle time when the idle time after data frame is satisfied this means the end of a data frame. + 19 + 1 + read-write + + + LEN_EOF_EN + Set this bit to enable to use packet_len in packet head when the received data is equal to packet_len this means the end of a data frame. + 20 + 1 + read-write + + + ENCODE_CRC_EN + Set this bit to enable crc calculation for data frame when bit6 in the head packet is 1. + 21 + 1 + read-write + + + CLK_EN + Set this bit to enable clock-gating for read or write registers. + 22 + 1 + read-write + + + UART_RX_BRK_EOF_EN + Set this bit to enable to use brk char as the end of a data frame. + 23 + 1 + read-write + + + + + INT_RAW + 0x4 + 0x20 + + + RX_START_INT_RAW + when a separator char has been send it will produce uhci_rx_start_int interrupt. + 0 + 1 + read-only + + + TX_START_INT_RAW + when DMA detects a separator char it will produce uhci_tx_start_int interrupt. + 1 + 1 + read-only + + + RX_HUNG_INT_RAW + when DMA takes a lot of time to receive a data it will produce uhci_rx_hung_int interrupt. + 2 + 1 + read-only + + + TX_HUNG_INT_RAW + when DMA takes a lot of time to read a data from RAM it will produce uhci_tx_hung_int interrupt. + 3 + 1 + read-only + + + IN_DONE_INT_RAW + when a in link descriptor has been completed it will produce uhci_in_done_int interrupt. + 4 + 1 + read-only + + + IN_SUC_EOF_INT_RAW + when a data packet has been received it will produce uhci_in_suc_eof_int interrupt. + 5 + 1 + read-only + + + IN_ERR_EOF_INT_RAW + when there are some errors about eof in in link descriptor it will produce uhci_in_err_eof_int interrupt. + 6 + 1 + read-only + + + OUT_DONE_INT_RAW + when a out link descriptor is completed it will produce uhci_out_done_int interrupt. + 7 + 1 + read-only + + + OUT_EOF_INT_RAW + when the current descriptor's eof bit is 1 it will produce uhci_out_eof_int interrupt. + 8 + 1 + read-only + + + IN_DSCR_ERR_INT_RAW + when there are some errors about the out link descriptor it will produce uhci_in_dscr_err_int interrupt. + 9 + 1 + read-only + + + OUT_DSCR_ERR_INT_RAW + when there are some errors about the in link descriptor it will produce uhci_out_dscr_err_int interrupt. + 10 + 1 + read-only + + + IN_DSCR_EMPTY_INT_RAW + when there are not enough in links for DMA it will produce uhci_in_dscr_err_int interrupt. + 11 + 1 + read-only + + + OUTLINK_EOF_ERR_INT_RAW + when there are some errors about eof in outlink descriptor it will produce uhci_outlink_eof_err_int interrupt. + 12 + 1 + read-only + + + OUT_TOTAL_EOF_INT_RAW + When all data have been send it will produce uhci_out_total_eof_int interrupt. + 13 + 1 + read-only + + + SEND_S_Q_INT_RAW + When use single send registers to send a short packets it will produce this interrupt when dma has send the short packet. + 14 + 1 + read-only + + + SEND_A_Q_INT_RAW + When use always_send registers to send a series of short packets it will produce this interrupt when dma has send the short packet. + 15 + 1 + read-only + + + DMA_INFIFO_FULL_WM_INT_RAW + 16 + 1 + read-only + + + + + INT_ST + 0x8 + 0x20 + + + RX_START_INT_ST + 0 + 1 + read-only + + + TX_START_INT_ST + 1 + 1 + read-only + + + RX_HUNG_INT_ST + 2 + 1 + read-only + + + TX_HUNG_INT_ST + 3 + 1 + read-only + + + IN_DONE_INT_ST + 4 + 1 + read-only + + + IN_SUC_EOF_INT_ST + 5 + 1 + read-only + + + IN_ERR_EOF_INT_ST + 6 + 1 + read-only + + + OUT_DONE_INT_ST + 7 + 1 + read-only + + + OUT_EOF_INT_ST + 8 + 1 + read-only + + + IN_DSCR_ERR_INT_ST + 9 + 1 + read-only + + + OUT_DSCR_ERR_INT_ST + 10 + 1 + read-only + + + IN_DSCR_EMPTY_INT_ST + 11 + 1 + read-only + + + OUTLINK_EOF_ERR_INT_ST + 12 + 1 + read-only + + + OUT_TOTAL_EOF_INT_ST + 13 + 1 + read-only + + + SEND_S_Q_INT_ST + 14 + 1 + read-only + + + SEND_A_Q_INT_ST + 15 + 1 + read-only + + + DMA_INFIFO_FULL_WM_INT_ST + 16 + 1 + read-only + + + + + INT_ENA + 0xC + 0x20 + + + RX_START_INT_ENA + 0 + 1 + read-write + + + TX_START_INT_ENA + 1 + 1 + read-write + + + RX_HUNG_INT_ENA + 2 + 1 + read-write + + + TX_HUNG_INT_ENA + 3 + 1 + read-write + + + IN_DONE_INT_ENA + 4 + 1 + read-write + + + IN_SUC_EOF_INT_ENA + 5 + 1 + read-write + + + IN_ERR_EOF_INT_ENA + 6 + 1 + read-write + + + OUT_DONE_INT_ENA + 7 + 1 + read-write + + + OUT_EOF_INT_ENA + 8 + 1 + read-write + + + IN_DSCR_ERR_INT_ENA + 9 + 1 + read-write + + + OUT_DSCR_ERR_INT_ENA + 10 + 1 + read-write + + + IN_DSCR_EMPTY_INT_ENA + 11 + 1 + read-write + + + OUTLINK_EOF_ERR_INT_ENA + 12 + 1 + read-write + + + OUT_TOTAL_EOF_INT_ENA + 13 + 1 + read-write + + + SEND_S_Q_INT_ENA + 14 + 1 + read-write + + + SEND_A_Q_INT_ENA + 15 + 1 + read-write + + + DMA_INFIFO_FULL_WM_INT_ENA + 16 + 1 + read-write + + + + + INT_CLR + 0x10 + 0x20 + + + RX_START_INT_CLR + 0 + 1 + write-only + + + TX_START_INT_CLR + 1 + 1 + write-only + + + RX_HUNG_INT_CLR + 2 + 1 + write-only + + + TX_HUNG_INT_CLR + 3 + 1 + write-only + + + IN_DONE_INT_CLR + 4 + 1 + write-only + + + IN_SUC_EOF_INT_CLR + 5 + 1 + write-only + + + IN_ERR_EOF_INT_CLR + 6 + 1 + write-only + + + OUT_DONE_INT_CLR + 7 + 1 + write-only + + + OUT_EOF_INT_CLR + 8 + 1 + write-only + + + IN_DSCR_ERR_INT_CLR + 9 + 1 + write-only + + + OUT_DSCR_ERR_INT_CLR + 10 + 1 + write-only + + + IN_DSCR_EMPTY_INT_CLR + 11 + 1 + write-only + + + OUTLINK_EOF_ERR_INT_CLR + 12 + 1 + write-only + + + OUT_TOTAL_EOF_INT_CLR + 13 + 1 + write-only + + + SEND_S_Q_INT_CLR + 14 + 1 + write-only + + + SEND_A_Q_INT_CLR + 15 + 1 + write-only + + + DMA_INFIFO_FULL_WM_INT_CLR + 16 + 1 + write-only + + + + + DMA_OUT_STATUS + 0x14 + 0x20 + 0x00000002 + + + OUT_FULL + 1:DMA out link descriptor's fifo is full. + 0 + 1 + read-only + + + OUT_EMPTY + 1:DMA in link descriptor's fifo is empty. + 1 + 1 + read-only + + + + + DMA_OUT_PUSH + 0x18 + 0x20 + + + OUTFIFO_WDATA + This is the data need to be pushed into out link descriptor's fifo. + 0 + 9 + read-write + + + OUTFIFO_PUSH + Set this bit to push data in out link descriptor's fifo. + 16 + 1 + read-write + + + + + DMA_IN_STATUS + 0x1C + 0x20 + 0x00000002 + + + IN_FULL + 0 + 1 + read-only + + + IN_EMPTY + 1 + 1 + read-only + + + RX_ERR_CAUSE + This register stores the errors caused in out link descriptor's data packet. + 4 + 3 + read-only + + + + + DMA_IN_POP + 0x20 + 0x20 + + + INFIFO_RDATA + This register stores the data pop from in link descriptor's fifo. + 0 + 12 + read-only + + + INFIFO_POP + Set this bit to pop data in in link descriptor's fifo. + 16 + 1 + read-write + + + + + DMA_OUT_LINK + 0x24 + 0x20 + + + OUTLINK_ADDR + This register stores the least 20 bits of the first out link descriptor's address. + 0 + 20 + read-write + + + OUTLINK_STOP + Set this bit to stop dealing with the out link descriptors. + 28 + 1 + read-write + + + OUTLINK_START + Set this bit to start dealing with the out link descriptors. + 29 + 1 + read-write + + + OUTLINK_RESTART + Set this bit to mount on new out link descriptors + 30 + 1 + read-write + + + OUTLINK_PARK + 1£º the out link descriptor's fsm is in idle state. 0:the out link descriptor's fsm is working. + 31 + 1 + read-only + + + + + DMA_IN_LINK + 0x28 + 0x20 + 0x00100000 + + + INLINK_ADDR + This register stores the least 20 bits of the first in link descriptor's address. + 0 + 20 + read-write + + + INLINK_AUTO_RET + 1:when a packet is wrong in link descriptor returns to the descriptor which is lately used. + 20 + 1 + read-write + + + INLINK_STOP + Set this bit to stop dealing with the in link descriptors. + 28 + 1 + read-write + + + INLINK_START + Set this bit to start dealing with the in link descriptors. + 29 + 1 + read-write + + + INLINK_RESTART + Set this bit to mount on new in link descriptors + 30 + 1 + read-write + + + INLINK_PARK + 1:the in link descriptor's fsm is in idle state. 0:the in link descriptor's fsm is working + 31 + 1 + read-only + + + + + CONF1 + 0x2C + 0x20 + 0x00000033 + + + CHECK_SUM_EN + Set this bit to enable decoder to check check_sum in packet header. + 0 + 1 + read-write + + + CHECK_SEQ_EN + Set this bit to enable decoder to check seq num in packet header. + 1 + 1 + read-write + + + CRC_DISABLE + Set this bit to disable crc calculation. + 2 + 1 + read-write + + + SAVE_HEAD + Set this bit to save packet header . + 3 + 1 + read-write + + + TX_CHECK_SUM_RE + Set this bit to enable hardware replace check_sum in packet header automatically. + 4 + 1 + read-write + + + TX_ACK_NUM_RE + Set this bit to enable hardware replace ack num in packet header automatically. + 5 + 1 + read-write + + + CHECK_OWNER + Set this bit to check the owner bit in link descriptor. + 6 + 1 + read-write + + + WAIT_SW_START + Set this bit to enable software way to add packet header. + 7 + 1 + read-write + + + SW_START + Set this bit to start inserting the packet header. + 8 + 1 + read-write + + + DMA_INFIFO_FULL_THRS + when data amount in link descriptor's fifo is more than this register value it will produce uhci_dma_infifo_full_wm_int interrupt. + 9 + 12 + read-write + + + + + STATE0 + 0x30 + 0x20 + + + STATE0 + 0 + 32 + read-only + + + + + STATE1 + 0x34 + 0x20 + + + STATE1 + 0 + 32 + read-only + + + + + DMA_OUT_EOF_DES_ADDR + 0x38 + 0x20 + + + OUT_EOF_DES_ADDR + This register stores the address of out link descriptoir when eof bit in this descriptor is 1. + 0 + 32 + read-only + + + + + DMA_IN_SUC_EOF_DES_ADDR + 0x3C + 0x20 + + + IN_SUC_EOF_DES_ADDR + This register stores the address of in link descriptor when eof bit in this descriptor is 1. + 0 + 32 + read-only + + + + + DMA_IN_ERR_EOF_DES_ADDR + 0x40 + 0x20 + + + IN_ERR_EOF_DES_ADDR + This register stores the address of in link descriptor when there are some errors in this descriptor. + 0 + 32 + read-only + + + + + DMA_OUT_EOF_BFR_DES_ADDR + 0x44 + 0x20 + + + OUT_EOF_BFR_DES_ADDR + This register stores the address of out link descriptor when there are some errors in this descriptor. + 0 + 32 + read-only + + + + + AHB_TEST + 0x48 + 0x20 + + + AHB_TESTMODE + bit2 is ahb bus test enable ,bit1 is used to choose wrtie(1) or read(0) mode. bit0 is used to choose test only once(1) or continue(0) + 0 + 3 + read-write + + + AHB_TESTADDR + The two bits represent ahb bus address bit[20:19] + 4 + 2 + read-write + + + + + DMA_IN_DSCR + 0x4C + 0x20 + + + INLINK_DSCR + The content of current in link descriptor's third dword + 0 + 32 + read-only + + + + + DMA_IN_DSCR_BF0 + 0x50 + 0x20 + + + INLINK_DSCR_BF0 + The content of current in link descriptor's first dword + 0 + 32 + read-only + + + + + DMA_IN_DSCR_BF1 + 0x54 + 0x20 + + + INLINK_DSCR_BF1 + The content of current in link descriptor's second dword + 0 + 32 + read-only + + + + + DMA_OUT_DSCR + 0x58 + 0x20 + + + OUTLINK_DSCR + The content of current out link descriptor's third dword + 0 + 32 + read-only + + + + + DMA_OUT_DSCR_BF0 + 0x5C + 0x20 + + + OUTLINK_DSCR_BF0 + The content of current out link descriptor's first dword + 0 + 32 + read-only + + + + + DMA_OUT_DSCR_BF1 + 0x60 + 0x20 + + + OUTLINK_DSCR_BF1 + The content of current out link descriptor's second dword + 0 + 32 + read-only + + + + + ESCAPE_CONF + 0x64 + 0x20 + 0x00000033 + + + TX_C0_ESC_EN + Set this bit to enable 0xc0 char decode when DMA receives data. + 0 + 1 + read-write + + + TX_DB_ESC_EN + Set this bit to enable 0xdb char decode when DMA receives data. + 1 + 1 + read-write + + + TX_11_ESC_EN + Set this bit to enable flow control char 0x11 decode when DMA receives data. + 2 + 1 + read-write + + + TX_13_ESC_EN + Set this bit to enable flow control char 0x13 decode when DMA receives data. + 3 + 1 + read-write + + + RX_C0_ESC_EN + Set this bit to enable 0xc0 char replace when DMA sends data. + 4 + 1 + read-write + + + RX_DB_ESC_EN + Set this bit to enable 0xdb char replace when DMA sends data. + 5 + 1 + read-write + + + RX_11_ESC_EN + Set this bit to enable flow control char 0x11 replace when DMA sends data. + 6 + 1 + read-write + + + RX_13_ESC_EN + Set this bit to enable flow control char 0x13 replace when DMA sends data. + 7 + 1 + read-write + + + + + HUNG_CONF + 0x68 + 0x20 + 0x00810810 + + + TXFIFO_TIMEOUT + This register stores the timeout value.when DMA takes more time than this register value to receive a data it will produce uhci_tx_hung_int interrupt. + 0 + 8 + read-write + + + TXFIFO_TIMEOUT_SHIFT + The tick count is cleared when its value >=(17'd8000>>reg_txfifo_timeout_shift) + 8 + 3 + read-write + + + TXFIFO_TIMEOUT_ENA + The enable bit for txfifo receive data timeout + 11 + 1 + read-write + + + RXFIFO_TIMEOUT + This register stores the timeout value.when DMA takes more time than this register value to read a data from RAM it will produce uhci_rx_hung_int interrupt. + 12 + 8 + read-write + + + RXFIFO_TIMEOUT_SHIFT + The tick count is cleared when its value >=(17'd8000>>reg_rxfifo_timeout_shift) + 20 + 3 + read-write + + + RXFIFO_TIMEOUT_ENA + This is the enable bit for DMA send data timeout + 23 + 1 + read-write + + + + + ACK_NUM + 0x6C + 0x20 + + + RX_HEAD + 0x70 + 0x20 + + + RX_HEAD + This register stores the packet header received by DMA + 0 + 32 + read-only + + + + + QUICK_SENT + 0x74 + 0x20 + + + SINGLE_SEND_NUM + The bits are used to choose which short packet + 0 + 3 + read-write + + + SINGLE_SEND_EN + Set this bit to enable send a short packet + 3 + 1 + read-write + + + ALWAYS_SEND_NUM + The bits are used to choose which short packet + 4 + 3 + read-write + + + ALWAYS_SEND_EN + Set this bit to enable continuously send the same short packet + 7 + 1 + read-write + + + + + Q0_WORD0 + 0x78 + 0x20 + + + SEND_Q0_WORD0 + This register stores the content of short packet's first dword + 0 + 32 + read-write + + + + + Q0_WORD1 + 0x7C + 0x20 + + + SEND_Q0_WORD1 + This register stores the content of short packet's second dword + 0 + 32 + read-write + + + + + Q1_WORD0 + 0x80 + 0x20 + + + SEND_Q1_WORD0 + This register stores the content of short packet's first dword + 0 + 32 + read-write + + + + + Q1_WORD1 + 0x84 + 0x20 + + + SEND_Q1_WORD1 + This register stores the content of short packet's second dword + 0 + 32 + read-write + + + + + Q2_WORD0 + 0x88 + 0x20 + + + SEND_Q2_WORD0 + This register stores the content of short packet's first dword + 0 + 32 + read-write + + + + + Q2_WORD1 + 0x8C + 0x20 + + + SEND_Q2_WORD1 + This register stores the content of short packet's second dword + 0 + 32 + read-write + + + + + Q3_WORD0 + 0x90 + 0x20 + + + SEND_Q3_WORD0 + This register stores the content of short packet's first dword + 0 + 32 + read-write + + + + + Q3_WORD1 + 0x94 + 0x20 + + + SEND_Q3_WORD1 + This register stores the content of short packet's second dword + 0 + 32 + read-write + + + + + Q4_WORD0 + 0x98 + 0x20 + + + SEND_Q4_WORD0 + This register stores the content of short packet's first dword + 0 + 32 + read-write + + + + + Q4_WORD1 + 0x9C + 0x20 + + + SEND_Q4_WORD1 + This register stores the content of short packet's second dword + 0 + 32 + read-write + + + + + Q5_WORD0 + 0xA0 + 0x20 + + + SEND_Q5_WORD0 + This register stores the content of short packet's first dword + 0 + 32 + read-write + + + + + Q5_WORD1 + 0xA4 + 0x20 + + + SEND_Q5_WORD1 + This register stores the content of short packet's second dword + 0 + 32 + read-write + + + + + Q6_WORD0 + 0xA8 + 0x20 + + + SEND_Q6_WORD0 + This register stores the content of short packet's first dword + 0 + 32 + read-write + + + + + Q6_WORD1 + 0xAC + 0x20 + + + SEND_Q6_WORD1 + This register stores the content of short packet's second dword + 0 + 32 + read-write + + + + + ESC_CONF0 + 0xB0 + 0x20 + 0x00DCDBC0 + + + SEPER_CHAR + This register stores the seperator char seperator char is used to seperate the data frame. + 0 + 8 + read-write + + + SEPER_ESC_CHAR0 + This register stores thee first char used to replace seperator char in data. + 8 + 8 + read-write + + + SEPER_ESC_CHAR1 + This register stores the second char used to replace seperator char in data . 0xdc 0xdb replace 0xc0 by default. + 16 + 8 + read-write + + + + + ESC_CONF1 + 0xB4 + 0x20 + 0x00DDDBDB + + + ESC_SEQ0 + This register stores the first substitute char used to replace the seperator char. + 0 + 8 + read-write + + + ESC_SEQ0_CHAR0 + This register stores the first char used to replace reg_esc_seq0 in data. + 8 + 8 + read-write + + + ESC_SEQ0_CHAR1 + This register stores the second char used to replace the reg_esc_seq0 in data + 16 + 8 + read-write + + + + + ESC_CONF2 + 0xB8 + 0x20 + 0x00DEDB11 + + + ESC_SEQ1 + This register stores the flow control char to turn on the flow_control + 0 + 8 + read-write + + + ESC_SEQ1_CHAR0 + This register stores the first char used to replace the reg_esc_seq1 in data. + 8 + 8 + read-write + + + ESC_SEQ1_CHAR1 + This register stores the second char used to replace the reg_esc_seq1 in data. + 16 + 8 + read-write + + + + + ESC_CONF3 + 0xBC + 0x20 + 0x00DFDB13 + + + ESC_SEQ2 + This register stores the flow_control char to turn off the flow_control + 0 + 8 + read-write + + + ESC_SEQ2_CHAR0 + This register stores the first char used to replace the reg_esc_seq2 in data. + 8 + 8 + read-write + + + ESC_SEQ2_CHAR1 + This register stores the second char used to replace the reg_esc_seq2 in data. + 16 + 8 + read-write + + + + + PKT_THRES + 0xC0 + 0x20 + 0x00000080 + + + PKT_THRS + when the amount of packet payload is greater than this value the process of receiving data is done. + 0 + 13 + read-write + + + + + DATE + 0xFC + 0x20 + 0x16041001 + + + DATE + version information + 0 + 32 + read-write + + + + + + + UHCI1 + Universal Host Controller Interface + 0x3FF4C000 + + UHCI1 + 13 + + + + \ No newline at end of file diff --git a/ESP32_MasterPx_DesignUhr/ESP32_MasterPx_DesignUhr/index_html.h b/ESP32_MasterPx_DesignUhr/ESP32_MasterPx_DesignUhr/index_html.h new file mode 100644 index 0000000..be7ed5d --- /dev/null +++ b/ESP32_MasterPx_DesignUhr/ESP32_MasterPx_DesignUhr/index_html.h @@ -0,0 +1,560 @@ +const char html_page_index[] PROGMEM = R"rawliteral( + + + N-Tools.de Uhr + + + + + + + +
+
+
+
+
+
+
+
+ +

+
+ + +
+

+
+
+ + +
+
+ + + %
+
+
+ + + + +
+
+
+ + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+ +
+
+
X
+
+

+
+
+
+
+

+
+ +
+
+
+
X
+
+

Optionen

+ % +
+ + + + + + + + +
+ +

+ + + + +
+ + + + +
+ +

+ + + + +
+
+
+
+
+ + + + +)rawliteral"; diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/CMakeLists.txt b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/CMakeLists.txt new file mode 100644 index 0000000..a4e5ac5 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/CMakeLists.txt @@ -0,0 +1,62 @@ +# HUB75 RGB LED matrix library utilizing ESP32 DMA Engine +# https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA +# MIT License + +cmake_minimum_required(VERSION 3.5) +idf_build_get_property(target IDF_TARGET) + +if(ARDUINO_ARCH_ESP32 OR CONFIG_ESP32_HUB75_USE_GFX) + list(APPEND build_dependencies arduino Adafruit-GFX-Library) +else() + list(APPEND build_dependencies esp_lcd driver) +endif() + +if(${target} STREQUAL "esp32s3") + list(APPEND extra_srcs src/platforms/${target}/gdma_lcd_parallel16.cpp) +endif() + +idf_component_register(SRCS "src/platforms/esp32/esp32_i2s_parallel_dma.cpp" "src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp" "src/ESP32-HUB75-MatrixPanel-leddrivers.cpp" ${extra_srcs} + INCLUDE_DIRS "./src" + ) + +# Dependencies cannot be added to the REQUIRES argument of `idf_component_register` because (according to the build process +# listed at https://docs.espressif.com/projects/esp-idf/en/v4.2/esp32/api-guides/build-system.html#build-process) +# `idf_component_register` is processed during the "Enumeration" stage which happens before the sdkconfig file is loaded +# in the "Processing" stage. So if dependencies are going to be loaded based on certain CONFIG_* variables we must +# use `target_link_libraries` instead. This is the method used by Arduino's CMakeLists.txt file. +idf_build_get_property(components BUILD_COMPONENTS) +foreach(component_name IN LISTS build_dependencies) + if (NOT ${component_name} IN_LIST components) + message(FATAL_ERROR "Missing component: ${component_name}") + endif() + idf_component_get_property(lib_name ${component_name} COMPONENT_LIB) + target_link_libraries(${COMPONENT_LIB} PUBLIC ${lib_name}) +endforeach() + +# In case you are running into issues with "missing" header files from 3rd party libraries +# you can add them to the REQUIRES section above. If you use some of the build options below +# you probably want to remove (NO_GFX) or replace Adafruit-GFX-Library (USE_GFX_ROOT) + +# Example to build with USE_GFX_ROOT or NO_GFX / just uncomment the appropriate line +# target_compile_options(${COMPONENT_TARGET} PUBLIC -DUSE_GFX_ROOT) +# target_compile_options(${COMPONENT_TARGET} PUBLIC -DNO_GFX) + +# esp-idf does not have any GFX library support yet, so we need to define NO_GFX +if(ARDUINO_ARCH_ESP32 OR CONFIG_ESP32_HUB75_USE_GFX) +else() + target_compile_options(${COMPONENT_TARGET} PUBLIC -DNO_GFX) + if(${target} STREQUAL "esp32s3") + # Don't enable PSRAM based framebuffer just because it's an S3. + # This is an advanced option and should only be used with an S3 with Octal-SPI RAM. + # target_compile_options(${COMPONENT_TARGET} PUBLIC -DSPIRAM_FRAMEBUFFER) + target_compile_options(${COMPONENT_TARGET} PUBLIC) + endif() +endif() + +# You can also use multiple options like this +# target_compile_options(${COMPONENT_TARGET} PUBLIC -DNO_GFX -DNO_FAST_FUNCTIONS) + +# All options can be found here: +# https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/blob/master/doc/BuildOptions.md + +project(ESP32-HUB75-MatrixPanel-I2S-DMA) diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/Kconfig.projbuild b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/Kconfig.projbuild new file mode 100644 index 0000000..1668a97 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/Kconfig.projbuild @@ -0,0 +1,9 @@ +menu "ESP32 HUB75 Configuration" + + config ESP32_HUB75_USE_GFX + bool "Use Adafruit GFX library." + default y + help + This option enables use of the Adafruit GFX library using the `Adafruit-GFX-Library` component. + +endmenu diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/LICENSE.txt b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/LICENSE.txt new file mode 100644 index 0000000..8cec4d5 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018-2032 Faptastic + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/README.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/README.md new file mode 100644 index 0000000..e20f1dc --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/README.md @@ -0,0 +1,232 @@ +# HUB75 RGB LED matrix panel library utilizing ESP32 DMA + +__[BUILD OPTIONS](/doc/BuildOptions.md) | [EXAMPLES](/examples/README.md)__ | [![PlatformIO CI](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/actions/workflows/pio_arduino_build.yml/badge.svg)](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/actions/workflows/pio_build.yml) + +**Table of Content** + +- [Introduction](#introduction) + * [Features](#features) + * [ESP32 variants supported](#esp32-variants-supported) + * [Required memory](#required-memory) + * [Supported Panels](#supported-panels) + * [Panel driver chips known to be working well](#driver-chips-known-to-be-working-well) + * [Unsupported Panels](#unsupported-panels) +- [Getting Started](#getting-started) + * [1. Library Installation](#1-library-installation) + * [2. Wiring the ESP32 to an LED Matrix Panel](#2-wiring-the-esp32-to-an-led-matrix-panel) + * [3. Run a Test Sketch](#3-run-a-test-sketch) +- [Further Information](#further-information) + * [Can I chain panels?](#can-i-chain-panels) + * [Can I use with a larger panel (i.e. 64x64px square panel)?](#can-i-use-with-a-larger-panel-ie-64x64px-square-panel) + * [Adjusting Panel Brightness](#adjusting-panel-brightness) + * [Build-time options](#build-time-options) + * [Latch blanking](#latch-blanking) + * [Power, Power and Power!](#power-power-and-power) + * [Inspiration](#inspiration) + * [Cool uses of this library](#cool-uses-of-this-library) +- [Thank you!](#thank-you) + +# Introduction +* This is an ESP32 Arduino/IDF library for HUB75 / HUB75E connection based RGB LED panels. +* This library 'out of the box' (mostly) supports HUB75 panels where simple TWO rows/lines are updated in parallel... referred to as 'two scan' panels within this documentation. +* 'Four scan' panels are also supported - but please refer to the Four Scan Panel example sketch. +* The library uses the DMA functionality provided by the ESP32's 'LCD Mode' for fast data output. + +## Features +- **Low CPU overhead** - Pixel data is sent directly with the use of hardware-backed DMA, no CPU involvement +- **Fast** - Updating pixel data involves only bit-wise logic over DMA buffer memory, no pins manipulation or blocking IO +- **Full screen BCM** - Library utilizes [binary-code modulation](http://www.batsocks.co.uk/readme/art_bcm_5.htm) to render pixel color depth / brightness over the entire matrix to give reasonable colour depth +- **Variable color depth** - Up to TrueColor 24 bits output is possible depending on matrix size/refresh rate required +- **CIE 1931** luminance [correction](https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/) (aka natural LED dimming) implemented +- **Adafruit GFX API** - Library can be built with AdafruitGFX, simplified GFX or without a GFX API at all + +## ESP32 variants supported +* Original ESP32 - That being the ESP-WROOM-32 module with ESP32‑D0WDQ6 chip from ~2017. +* ESP32-S2; and +* ESP32-S3 + +RISC-V ESP32's (like the C3) are not supported as they do not have the hardware 'LCD mode' support. + +## Required memory +"*What's the price for those features?*" - It's [memory](/doc/memcalc.md), you pay it all by precious MCU's internal memory (SRAM) for the DMA buffer. + +Please use the ['Memory Calculator'](/doc/memcalc.md) to see what is *typically* achievable with the typical ESP32. This is only a guide. ![Memory Calculator](doc/memcalc.jpg) + +For the ESP32-S3 only, you can use SPIRAM/PSRAM to drive the HUB75 DMA buffer when using an ESP32-S3 with **OCTAL SPI-RAM (PSTRAM)** (i.e. ESP32 S3 N8R8 variant). However, due to bandwidth limitations, the maximum output frequency is limited to approx. 13Mhz, which will limit the real-world number of panels that can be chained without flicker. Please do not use PSRAM as the DMA buffer if using QUAD SPI (Q-SPI), as it's too slow. + +To enable PSRAM support on the ESP32-S3, refer to [the build options](/doc/BuildOptions.md) to enable. + +For all other ESP32 variants (like the most popular ‘original’ ESP32), [only *internal* SRAM can be used](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/55), so you will be limited to the ~200KB or so of 'free' SRAM (because of the memory used for your sketch amongst other things) regardless of how many megabytes of SPIRAM/PSRAM you may have connected. + + +## Supported panel can types +It is impossible to provide a comprehensive list of what panels are supported (or not supported) as new variations of the chips used to 'drive' these panels are created almost weekly (usually from China). You should contact the seller to confirm the chips used in a panel before purchasing to use with this library. + +* 'Two scan' panels where **two** rows/lines are updated in parallel. + * 64x32 (width x height) 'Indoor' panels, which are often referred to as 1/16 'scan panel' as every 16th row is updated in parallel (hence why I refer to it as 'two scan') + * 64x64 pixel 1/32 Scan LED Matrix 'Indoor' Panel + +* 'Four scan' panels where **four** rows/lines are updated in parallel. + * 32x16 pixel 1/4 Scan LED Matrix 'Indoor' Panel using an ingenious workaround as demonstrated in the Four_Scan_Panel example. + * 126x64 [SM5266P](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/164) + +Ones interested in internals of such matrices could find [this article](https://www.sparkfun.com/news/2650) useful. + +![Panel Scan Types](doc/ScanRateGraphic.jpg) + +## Specific chips found to work +* ICND2012 +* [RUC7258](http://www.ruichips.com/en/products.html?cateid=17496) +* FM6126A AKA ICN2038S, [FM6124](https://datasheet4u.com/datasheet-pdf/FINEMADELECTRONICS/FM6124/pdf.php?id=1309677) (Refer to [PatternPlasma](/examples/2_PatternPlasma) example on how to use.) +* SM5266P +* DP3246 with SM5368 row addressing registers + +## Specific chips found NOT TO work +* ANY panel that uses S-PWM or PWM based chips (such as the RUL6024, MBI6024). +* [SM1620B](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/issues/416) +* RUL5358 / SHIFTREG_ABC_BIN_DE based panels are not supported. +* ICN2053 / FM6353 based panels - Refer to [this library](https://github.com/LAutour/ESP32-HUB75-MatrixPanel-DMA-ICN2053), which is a fork of this library ( [discussion link](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/discussions/324)). +* Any other panel not listed above. + +Please use an [alternative library](https://github.com/2dom/PxMatrix) if you bought one of these. + +# Getting Started +## 1. Library Installation + +* Dependency: You will need to install Adafruit_GFX from the "Library > Manage Libraries" menu. +* Install this library from the Arduino Library manager. + +Library also tested to work fine with PlatformIO, install into your PlatformIO projects' lib/ folder as appropriate. Or just add it into [platformio.ini](/doc/BuildOptions.md) [lib_deps](https://docs.platformio.org/en/latest/projectconf/section_env_library.html#lib-deps) section. + +## 2. Wiring the ESP32 to an LED Matrix Panel + +Refer to the '*default-pins.hpp' file within the [applicable platforms folder](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/tree/master/src/platforms). + +``` +If you want to change the GPIO mapping at runtime, simply provide the wanted pin mapping as part of the class initialization structure. For example, in your sketch have something like the following: + +// Change these to whatever suits +#define R1_PIN 25 +#define G1_PIN 26 +#define B1_PIN 27 +#define R2_PIN 14 +#define G2_PIN 12 +#define B2_PIN 13 +#define A_PIN 23 +#define B_PIN 19 +#define C_PIN 5 +#define D_PIN 17 +#define E_PIN -1 // required for 1/32 scan panels, like 64x64px. Any available pin would do, i.e. IO32 +#define LAT_PIN 4 +#define OE_PIN 15 +#define CLK_PIN 16 + +HUB75_I2S_CFG::i2s_pins _pins={R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, LAT_PIN, OE_PIN, CLK_PIN}; +HUB75_I2S_CFG mxconfig( + 64, // Module width + 32, // Module height + 2, // chain length + _pins, // pin mapping +); +dma_display = new MatrixPanel_I2S_DMA(mxconfig); +``` + +Make sure you also connect one of the HUB75 interfaces ground pins to a ground pin of the ESP32, otherwise you may get electrical artefacts on LED Matrix Panel. + +Various people have created PCBs for which one can simply connect an ESP32 to a PCB, and then the PCB to the HUB75 connector, such as: + +* Brian Lough's [ESP32 I2S Matrix Shield](http://blough.ie/i2smat/) +* Charles Hallard's [WeMos Matrix Shield](https://github.com/hallard/WeMos-Matrix-Shield-DMA) +* Bogdan Sass's [Morph Clock Shield](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/discussions/110#discussioncomment-861152) + +Please contact or order these products from the respective authors. + +### Can I use with a larger panel (i.e. 64x64px square panel)? +If you want to use with a 64x64 pixel panel (typically a HUB75*E* panel) you MUST configure a valid *E_PIN* to your ESP32 and connect it to the E pin of the HUB75 panel! Hence the 'E' in 'HUB75E' + + +## 3. Run a Test Sketch +Below is a bare minimum sketch to draw a single white dot in the top left. You must call begin() before you call ANY pixel-drawing (fonts, lines, colours etc.) function of the MatrixPanel_I2S_DMA class. + +Once this is working, refer to the [PIO Test Patterns](/examples/PIO_TestPatterns) example. This sketch draws simple colors/lines/gradients over the entire matrix and it could help to troubleshoot various issues with ghosting, flickering, etc... + +Note: Requires the use of [PlatformIO](https://platformio.org/), which you should probably use if you aren't already. + +# Further information +## Can I chain panels? +Yes! + +[Horizontal](https://user-images.githubusercontent.com/12006953/122657476-cd358d00-d15b-11eb-9c6c-99b61378c56a.mp4) + +For example: If you want to chain two of these horizontally to make a 128x32 panel you can do so by connecting the panels in series using the HUB75 ribbon cable. Than you must provide proper configuration structure to the class constructor letting it know that you use "one long virtual matrix chain". Refer to [Pattern Plasma](/examples/2_PatternPlasma/) example for all the details about configuration setup. + +Finally, if you wanted to chain 4 x (64x32px) panels to make 128x64px display (essentially a 2x2 grid of 64x32 LED Matrix modules), a little more magic will be required. Refer to the [Chained Panels](examples/ChainedPanels/) example. + +Resolutions beyond 128x64 are more likely to result in crashes due to [memory](/doc/i2s_memcalc.md) constraints etc. You are on your own after this point - PLEASE do not raise issues about this, the library can't magically defeat the SRAM memory constraints of the ESP32. + +![ezgif com-video-to-gif](https://user-images.githubusercontent.com/12006953/89837358-b64c0480-db60-11ea-870d-4b6482068a3b.gif) + +## Adjusting Panel Brightness + +By default you should not need to change / set the brightness value (which is 128 or 50%) as it should be sufficient for most purposes. Brightness can be changed by calling `setPanelBrightness(xx)` or `setBrightness8(xx)`. + +The value to pass must be a number between 0 (for a black screen) and 255 (max brightness). + +Example: +``` +void setup() { +Serial.begin(115200); + dma_display->begin(); // setup the LED matrix + dma_display->setBrightness8(192); //0-255 + dma_display->clearScreen(); +} +``` +![Brightness Samples](https://user-images.githubusercontent.com/55933003/211192894-f90311f5-b6fe-4665-bf26-2f363bb36047.png) + +## Build-time options +Although Arduino IDE does not [seem](https://github.com/arduino/Arduino/issues/421) to offer any way of specifying compile-time options for external libs there are other IDE's (like [PlatformIO](https://platformio.org/)/[Eclipse](https://www.eclipse.org/ide/)) that could use that. Check [Build Options](doc/BuildOptions.md) document for reference. + +## Latch blanking +If you are facing issues with image ghosting when pixels has clones with horizontal offset, than you try to change Latch blanking value. Latch blanking controls for how many clock pulses matrix output is disabled via EO signal before/after toggling LAT signal. It hides row bits transitioning and different panels may require longer times for proper operation. Default value is 1 clock before/after LAT row transition. This could be controlled with `MatrixPanel_I2S_DMA::setLatBlanking(uint8_t v)`. v could be between 1 to 4, default is 1, larger values won't give any benefit other than reducing brightness. + +An example: +``` +dma_display->setLatBlanking(2); +``` + +## Power, Power and Power! +Having a good power supply is CRITICAL, and it is highly recommended, for chains of LED Panels to have a 1000-2000uf capacitor soldered to the back of each LED Panel across the [GND and VCC pins](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/39#issuecomment-720780463), otherwise you WILL run into issues with 'flashy' graphics whereby a large amount of LEDs are turned on and off in succession (due to current/power draw peaks and troughs). + + - Refer to this guide written for the [rpi-rgb-led-matrix library](https://github.com/hzeller/rpi-rgb-led-matrix/blob/master/wiring.md#a-word-about-power) for an explanation. +- Refer to this [example](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/39#issuecomment-722691127) issue of what can go wrong with a poor power supply. + + +- Refer to [this comment](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/35#issuecomment-726419862) in regards to certain panels not playing nice with voltages, and a 3.3volt signal that the ESP32 GPIO can only provide. + +## Inspiration +This project was inspired by: +* 'SmartMatrix': https://github.com/pixelmatix/SmartMatrix/tree/teensylc +* Sprite_TM's demo implementation here: https://www.esp32.com/viewtopic.php?f=17&t=3188 + + +## Cool uses of this library +There are a number of great looking LED graphical display projects which leverage this library, these include: +* [128x64 Morph Clock](https://github.com/bogd/esp32-morphing-clock) +* [FFT Audio Visualisation](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/discussions/149) +* [Clock, GIF Animator and Audio Visualiser](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/discussions/153) +* [Aurora Audio Visualiser](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/discussions/188) +* [Big Visualisation](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/discussions/155) +* [Clockwise](https://jnthas.github.io/clockwise/) + +# Thank you! +* [Brian Lough](https://www.tindie.com/stores/brianlough/) ([youtube link](https://www.youtube.com/c/brianlough)) for providing code contributions, hardware and suggestions +* [Vortigont](https://github.com/vortigont) for his game changing code contributions and performance optimisations +* [Galaxy Man](https://github.com/Galaxy-Man) for donation of 1/16 scan panels to support the implemenation of led matrix panel chaining (virtual display) support +* [Pipimaxi](https://github.com/Pipimaxi) for the donation of a ESP32-S2 and [Radu](https://github.com/juniorradu) for the donation of an ESP32-S3 to enable support for ESP32 S2/S3's to be tested and implemented. +* [Mark Donners](https://github.com/donnersm) ('The Electronic Engineer' on [youtube](https://www.youtube.com/watch?v=bQ7c9Vlhyp0&t=118s)) for the donation of a 1/8 scan panel to build and test working support of these led matrix panels! +* [PaintYourDragon](https://github.com/PaintYourDragon) for the DMA logic for the ESP32-S3. +* And lots of others, let me know if I've missed you. + +If you want to donate money to the project, please refer to [this discussion](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/discussions/349) about it. If you want to donate/buy an LED panel for the library author to improve compatibility and/or testing - please feel free to post in the same [discussion](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/discussions/349). + +![It's better in real life](image.jpg) diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/component.mk b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/component.mk new file mode 100644 index 0000000..004b18e --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/component.mk @@ -0,0 +1 @@ +COMPONENT_ADD_INCLUDEDIRS = . diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/BuildOptions.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/BuildOptions.md new file mode 100644 index 0000000..aa31ab7 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/BuildOptions.md @@ -0,0 +1,38 @@ +### Build Options and flags + +This library supports build-time defines to modify its features or enable greater debugging information. Please use the debugging capabilities before raising any issues. + +For example build flags could be set using PlatformIO's .ini file like this + +``` +[env] +framework = arduino +platform = espressif32 +lib_deps = + ESP32 HUB75 LED MATRIX PANEL DMA Display +build_flags = + -DCORE_DEBUG_LEVEL=3 + -DNO_GFX=1 + (etc.....) +``` +Or if using Arduino: 'Tools' menu > 'Core Debug Level' > Select 'Debug' + +... and use the Serial output to see the debug information. + +## Build flags + +| Flag | Description | Note | +| :------------ |---------------|-----| +| **CORE_DEBUG_LEVEL** |Adjust the espressif ESP32 IDF debug level, for which this library leverages to output information on what is going on when allocating memory etc. This will provide detailed information about memory allocations, DMA descriptors setup and color depth [BCM](http://www.batsocks.co.uk/readme/art_bcm_5.htm) |Set value to at least 3 [(Info)](https://iotespresso.com/core-debug-level-in-esp32/) +| **USE_GFX_ROOT** | Use [lightweight](https://github.com/mrfaptastic/Adafruit_GFX_Lite) version of AdafuitGFX, without Adafruit BusIO extensions | You **must** install [Adafruit_GFX_Lite](https://github.com/mrfaptastic/Adafruit_GFX_Lite) library instead of original AdafruitGFX| +| **NO_GFX** | Build without AdafuitGFX API, only native methods supported based on manipulating DMA buffer. I.e. no methods of drawing circles/shapes, typing text or using fonts!!! This might save some resources for applications using it's own internal graphics buffer or working solely with per-pixel manipulation. | Use this if you rely on FastLED, Neomatrix or any other API. For example [Aurora](/examples/AuroraDemo/) effects can work fine w/o AdafruitGFX. | +| **NO_FAST_FUNCTIONS** | Do not build auxiliary speed-optimized functions. Those are used to speed-up operations like drawing straight lines or rectangles. Otherwise lines/shapes are drawn using drawPixel() method. The trade-off for speed is RAM/code-size, take it or leave it ;) | If you are not using AdafruitGFX than you probably do not need this either| +|**NO_CIE1931**|Do not use LED brightness [compensation](https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/) described in [CIE 1931](https://en.wikipedia.org/wiki/CIE_1931_color_space). Normally library would adjust every pixel's RGB888 so that luminance (or brightness control) for the corresponding LED's would appear 'linear' to the human's eye. I.e. a white dot with rgb(128,128,128) would seem to be at 50% brightness between rgb(0,0,0) and rgb(255,255,255). Normally you would like to keep this enabled by default. Not only it makes brightness control "linear", it also makes colours more vivid, otherwise it looks brighter but 'bleached'.|You might want to turn it off in some special cases like:
  • Using some other overlay lib for intermediate calculations that makes it's own compensation, like FastLED's [dimming functions](http://fastled.io/docs/3.1/group___dimming.html).
  • running at low colour depth's - it **might** (or might not) look better in shadows, darker gradients w/o compensation, try it
  • you run for as bright output as possible, no matter what (make sure you have proper powering)
  • you run for speed/save resources at all costs
| +| **FORCE_COLOR_DEPTH** |In some cases the library may reduce colour fidelity to increase the refresh rate (i.e. reduce visible flicker). This is most likely to occur with a large chain of panels. However, if you want to force pure 24bpp colour, at the expense of likely noticeable flicker, then set this defined. |Not required in 99% of cases. +| **SPIRAM_FRAMEBUFFER** |Use SPIRAM/PSRAM for the HUB75 DMA buffer and not internal SRAM. ONLY SUPPORTED ON ESP32-S3 VARIANTS WITH OCTAL (not quad!) SPIRAM/PSRAM, as ony OCTAL PSRAM an provide the required data rate / bandwidth to drive the panels adequately.|ONLY SUPPORTED ON ESP32-S3 VARIANTS WITH OCTAL (not quad) SPIRAM/PSRAM + +## Build-time variables + +| Flag | Description | Note | +| :------------ |---------------|-----| +| **PIXEL_COLOR_DEPTH_BITS=8** | Colour depth per pixel in range 2-8. More bit's - more natural colour. But on the other hand every additional bit:
  • eats ~2.5 bits of DMA memory per pixel
  • reduces matrix refresh rate in power of two due to nature of [BCM](http://www.batsocks.co.uk/readme/art_bcm_5.htm)
| For large chains of panels (i.e. 6 x 64x64 panels) you WILL need to reduce the colour depth, or likely run out of memory. Default is 8 bits per colour per pixel, i.e. True colour 24 bit RGB.

For higher resolutions, from 64x64 and above it is not possible to provide full 24 bits colour without significant flickering OR reducing dynamic range in shadows. In that case using 5-6 bits at high res make very small difference to the human’s eye actually. Refer to the [I2S memcalc](i2s_memcalc.md) for more details. diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/Panel_Chaining_Types.ods b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/Panel_Chaining_Types.ods new file mode 100644 index 0000000..e41e576 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/Panel_Chaining_Types.ods differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/ScanRateGraphic.jpg b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/ScanRateGraphic.jpg new file mode 100644 index 0000000..a875316 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/ScanRateGraphic.jpg differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/ScanRateGraphic.odp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/ScanRateGraphic.odp new file mode 100644 index 0000000..84b98a1 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/ScanRateGraphic.odp differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/VirtualMatrixPanel (old).odp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/VirtualMatrixPanel (old).odp new file mode 100644 index 0000000..4e3a066 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/VirtualMatrixPanel (old).odp differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/VirtualMatrixPanel.odp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/VirtualMatrixPanel.odp new file mode 100644 index 0000000..748a211 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/VirtualMatrixPanel.odp differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/VirtualMatrixPanel.pdf b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/VirtualMatrixPanel.pdf new file mode 100644 index 0000000..f6e7157 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/VirtualMatrixPanel.pdf differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/fillrate.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/fillrate.md new file mode 100644 index 0000000..f667209 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/fillrate.md @@ -0,0 +1,27 @@ +## Estimating fillrate + +Here are some results of simple tests on filling DMA buffer with data. +Filling DMA buffer requires lots of memory operations on a bit level rather than doing simple byte/word wide store and copy. And it looks like it's quite a task both for esp32 core and compiler. +I've done this while optimizing loops and bit logic along with testing compiler results. + +So the testbed is: + - Matrix modules: 4 x FM6126A based 64x64 modules chained in 256x64 + +A testpatterns sketch: + - allocating single DMA buffs for 256x64 + - allocating (NUM_LEDS*3) bytes for CRGB buffer + - measuring microseconds for the following calls: + - clearScreen() - full blanking + - fillScreenRGB888() with monochrome/gray colors + - fill screen using drawPixel() + - filling some gradient into CRGB buff + - painting CRGB buff into DMA buff with looped drawPixelRGB888() + - drawing lines + + +||clearScreen()|drawPixelRGB888(), ticks|fillScreen()|fillScreen with a drawPixel()|fillRect() over Matrix|V-line with drawPixel|fast-V-line|H-line with drawPixel|fast-H-line| +|--|--|--|--|--|--|--|--|--|--| +|v1.2.4|1503113 ticks|9244 non-cached, 675 cached|1719 us, 412272 t|47149 us, 11315418 ticks|-|24505 us, 5880209 ticks|-|24200 us|-| +|FastLines|1503113 ticks|1350 non-cached, 405 cached|1677 us, 401198 t|28511 us, 6841440 ticks|10395 us|14462 us, 3469605 ticks|10391 us, 2492743 ticks|14575 us|5180 us, 1242041 ticks| + +to be continued... \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/memcalc.jpg b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/memcalc.jpg new file mode 100644 index 0000000..16bb077 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/memcalc.jpg differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/memcalc.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/memcalc.md new file mode 100644 index 0000000..2525cf5 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/memcalc.md @@ -0,0 +1,40 @@ +### Memory Calculator + +I've made this [spreadsheet](memcalc.xlsm) to estimate all of the main parameters for ESP32-HUB75-MatrixPanel-DMA lib driving any combination of matrices/chains so that I do not need to reflash it hundreds of times just to check for the debug info about memory. +Be sure to enable embedded macro's to allow refresh rate calculations. + +![](i2scalc.png) +Just fill-in all of the INPUT fields and get the OUTPUTs. + +So there are two main resources used to drive LED matrix + - Memory + - Bus clock speed (resulting in available bandwidth to pump pixel color data) + +And there are lot's of hogs for those: + - matrix resolution (number of pixels) + - number of modules in chain + - pixel color depth + - [BCM](http://www.batsocks.co.uk/readme/art_bcm_5.htm) LSB to MSB transition + - double buffering + +Equalising ones with the others results in **Refresh rate**, + +or (rough approximation) + + +[//]: # (github markdown does not like LaTex formulas) +[//]: # ($$RefreshRate=\frac{resolution \times chain \times (ColorDepth-LSB2MSB)}{ I ^2S _ {clock} }$$) + +So, how to find optimum balance for all of these? Obviously you can't change *resolution* and *chain length*, it is physical characteristics and there is not much you can do about it except cutting off your chain or pushing it to the memory limits. + +There are 3 parameters you can choose from (actually two:) + - **Color Depth** - predefined at [build-time]((/doc/BuildOptions.md)) option + + - I2S clock speed - run-time tunable with a very limited options + +- **LSB-to-MSB** transition - it can't be controlled in any way, library uses it internally trying to balance all of the above + +Using provided table it is possible to estimate all of the parameters before running the library. Besides calculating memory requirements it could help to find **optimum color depth** for your matrix configuration. For higher resolutions default 8 bits could be too much to sustain minimal refresh rate and avoid annoying flickering. So the library would increase MSB transition to keep the balance, thus reducing dynamic range in shadows and dark colors. As a result it is nearly almost the same as just reducing overall color depth. **But** reducing global color depth would also save lot's of precious RAM! +Now it's all up to you to decide :) + +/Vortigont/ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/memcalc.xlsm b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/memcalc.xlsm new file mode 100644 index 0000000..ec8bdb0 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/doc/memcalc.xlsm differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/1_SimpleTestShapes/1_SimpleTestShapes.ino b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/1_SimpleTestShapes/1_SimpleTestShapes.ino new file mode 100644 index 0000000..1d2ca75 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/1_SimpleTestShapes/1_SimpleTestShapes.ino @@ -0,0 +1,166 @@ + +// Example sketch which shows how to display some patterns +// on a 64x32 LED matrix +// + +#include + + +#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module. +#define PANEL_RES_Y 32 // Number of pixels tall of each INDIVIDUAL panel module. +#define PANEL_CHAIN 1 // Total number of panels chained one to another + +//MatrixPanel_I2S_DMA dma_display; +MatrixPanel_I2S_DMA *dma_display = nullptr; + +uint16_t myBLACK = dma_display->color565(0, 0, 0); +uint16_t myWHITE = dma_display->color565(255, 255, 255); +uint16_t myRED = dma_display->color565(255, 0, 0); +uint16_t myGREEN = dma_display->color565(0, 255, 0); +uint16_t myBLUE = dma_display->color565(0, 0, 255); + + + +// Input a value 0 to 255 to get a color value. +// The colours are a transition r - g - b - back to r. +// From: https://gist.github.com/davidegironi/3144efdc6d67e5df55438cc3cba613c8 +uint16_t colorWheel(uint8_t pos) { + if(pos < 85) { + return dma_display->color565(pos * 3, 255 - pos * 3, 0); + } else if(pos < 170) { + pos -= 85; + return dma_display->color565(255 - pos * 3, 0, pos * 3); + } else { + pos -= 170; + return dma_display->color565(0, pos * 3, 255 - pos * 3); + } +} + +void drawText(int colorWheelOffset) +{ + + // draw text with a rotating colour + dma_display->setTextSize(1); // size 1 == 8 pixels high + dma_display->setTextWrap(false); // Don't wrap at end of line - will do ourselves + + dma_display->setCursor(5, 0); // start at top left, with 8 pixel of spacing + uint8_t w = 0; + const char *str = "ESP32 DMA"; + for (w=0; wsetTextColor(colorWheel((w*32)+colorWheelOffset)); + dma_display->print(str[w]); + } + + dma_display->println(); + dma_display->print(" "); + for (w=9; w<18; w++) { + dma_display->setTextColor(colorWheel((w*32)+colorWheelOffset)); + dma_display->print("*"); + } + + dma_display->println(); + + dma_display->setTextColor(dma_display->color444(15,15,15)); + dma_display->println("LED MATRIX!"); + + // print each letter with a fixed rainbow color + dma_display->setTextColor(dma_display->color444(0,8,15)); + dma_display->print('3'); + dma_display->setTextColor(dma_display->color444(15,4,0)); + dma_display->print('2'); + dma_display->setTextColor(dma_display->color444(15,15,0)); + dma_display->print('x'); + dma_display->setTextColor(dma_display->color444(8,15,0)); + dma_display->print('6'); + dma_display->setTextColor(dma_display->color444(8,0,15)); + dma_display->print('4'); + + // Jump a half character + dma_display->setCursor(34, 24); + dma_display->setTextColor(dma_display->color444(0,15,15)); + dma_display->print("*"); + dma_display->setTextColor(dma_display->color444(15,0,0)); + dma_display->print('R'); + dma_display->setTextColor(dma_display->color444(0,15,0)); + dma_display->print('G'); + dma_display->setTextColor(dma_display->color444(0,0,15)); + dma_display->print("B"); + dma_display->setTextColor(dma_display->color444(15,0,8)); + dma_display->println("*"); + +} + + +void setup() { + + // Module configuration + HUB75_I2S_CFG mxconfig( + PANEL_RES_X, // module width + PANEL_RES_Y, // module height + PANEL_CHAIN // Chain length + ); + + //mxconfig.gpio.e = 18; + //mxconfig.clkphase = false; + //mxconfig.driver = HUB75_I2S_CFG::FM6126A; + + // Display Setup + dma_display = new MatrixPanel_I2S_DMA(mxconfig); + dma_display->begin(); + dma_display->setBrightness8(90); //0-255 + dma_display->clearScreen(); + dma_display->fillScreen(myWHITE); + + // fix the screen with green + dma_display->fillRect(0, 0, dma_display->width(), dma_display->height(), dma_display->color444(0, 15, 0)); + delay(500); + + // draw a box in yellow + dma_display->drawRect(0, 0, dma_display->width(), dma_display->height(), dma_display->color444(15, 15, 0)); + delay(500); + + // draw an 'X' in red + dma_display->drawLine(0, 0, dma_display->width()-1, dma_display->height()-1, dma_display->color444(15, 0, 0)); + dma_display->drawLine(dma_display->width()-1, 0, 0, dma_display->height()-1, dma_display->color444(15, 0, 0)); + delay(500); + + // draw a blue circle + dma_display->drawCircle(10, 10, 10, dma_display->color444(0, 0, 15)); + delay(500); + + // fill a violet circle + dma_display->fillCircle(40, 21, 10, dma_display->color444(15, 0, 15)); + delay(500); + + // fill the screen with 'black' + dma_display->fillScreen(dma_display->color444(0, 0, 0)); + + //drawText(0); + +} + +uint8_t wheelval = 0; +void loop() { + + // animate by going through the colour wheel for the first two lines + drawText(wheelval); + wheelval +=1; + + delay(20); +/* + drawText(0); + delay(2000); + dma_display->clearScreen(); + dma_display->fillScreen(myBLACK); + delay(2000); + dma_display->fillScreen(myBLUE); + delay(2000); + dma_display->fillScreen(myRED); + delay(2000); + dma_display->fillScreen(myGREEN); + delay(2000); + dma_display->fillScreen(myWHITE); + dma_display->clearScreen(); + */ + +} diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/2_PatternPlasma/2_PatternPlasma.ino b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/2_PatternPlasma/2_PatternPlasma.ino new file mode 100644 index 0000000..65f85b9 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/2_PatternPlasma/2_PatternPlasma.ino @@ -0,0 +1,207 @@ +/* + * Portions of this code are adapted from Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from LedEffects Plasma by Robert Atkins: https://bitbucket.org/ratkins/ledeffects/src/26ed3c51912af6fac5f1304629c7b4ab7ac8ca4b/Plasma.cpp?at=default + * Copyright (c) 2013 Robert Atkins + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +// HUB75E pinout +// R1 | G1 +// B1 | GND +// R2 | G2 +// B2 | E +// A | B +// C | D +// CLK| LAT +// OE | GND + +/* Default library pin configuration for the reference + you can redefine only ones you need later on object creation + +#define R1 25 +#define G1 26 +#define BL1 27 +#define R2 14 +#define G2 12 +#define BL2 13 +#define CH_A 23 +#define CH_B 19 +#define CH_C 5 +#define CH_D 17 +#define CH_E -1 // assign to any available pin if using two panels or 64x64 panels with 1/32 scan +#define CLK 16 +#define LAT 4 +#define OE 15 + +*/ + + +#include +#include + +// Configure for your panel(s) as appropriate! +#define PANEL_WIDTH 64 +#define PANEL_HEIGHT 64 // Panel height of 64 will required PIN_E to be defined. +#define PANELS_NUMBER 2 // Number of chained panels, if just a single panel, obviously set to 1 +#define PIN_E 32 + +#define PANE_WIDTH PANEL_WIDTH * PANELS_NUMBER +#define PANE_HEIGHT PANEL_HEIGHT + + +// placeholder for the matrix object +MatrixPanel_I2S_DMA *dma_display = nullptr; + + +uint16_t time_counter = 0, cycles = 0, fps = 0; +unsigned long fps_timer; + +CRGB currentColor; +CRGBPalette16 palettes[] = {HeatColors_p, LavaColors_p, RainbowColors_p, RainbowStripeColors_p, CloudColors_p}; +CRGBPalette16 currentPalette = palettes[0]; + + +CRGB ColorFromCurrentPalette(uint8_t index = 0, uint8_t brightness = 255, TBlendType blendType = LINEARBLEND) { + return ColorFromPalette(currentPalette, index, brightness, blendType); +} + +void setup() { + + Serial.begin(115200); + + Serial.println(F("*****************************************************")); + Serial.println(F("* ESP32-HUB75-MatrixPanel-I2S-DMA DEMO *")); + Serial.println(F("*****************************************************")); + + /* + The configuration for MatrixPanel_I2S_DMA object is held in HUB75_I2S_CFG structure, + pls refer to the lib header file for full details. + All options has it's predefined default values. So we can create a new structure and redefine only the options we need + + // those are the defaults + mxconfig.mx_width = 64; // physical width of a single matrix panel module (in pixels, usually it is always 64 ;) ) + mxconfig.mx_height = 32; // physical height of a single matrix panel module (in pixels, usually almost always it is either 32 or 64) + mxconfig.chain_length = 1; // number of chained panels regardless of the topology, default 1 - a single matrix module + mxconfig.gpio.r1 = R1; // pin mappings + mxconfig.gpio.g1 = G1; + mxconfig.gpio.b1 = B1; // etc + mxconfig.driver = HUB75_I2S_CFG::SHIFT; // shift reg driver, default is plain shift register + mxconfig.double_buff = false; // use double buffer (twice amount of RAM required) + mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_10M;// I2S clock speed, better leave as-is unless you want to experiment + */ + + /* + For example we have two 64x64 panels chained, so we need to customize our setup like this + + */ + HUB75_I2S_CFG mxconfig; + mxconfig.mx_height = PANEL_HEIGHT; // we have 64 pix heigh panels + mxconfig.chain_length = PANELS_NUMBER; // we have 2 panels chained + mxconfig.gpio.e = PIN_E; // we MUST assign pin e to some free pin on a board to drive 64 pix height panels with 1/32 scan + //mxconfig.driver = HUB75_I2S_CFG::FM6126A; // in case that we use panels based on FM6126A chip, we can change that + + /* + //Another way of creating config structure + //Custom pin mapping for all pins + HUB75_I2S_CFG::i2s_pins _pins={R1, G1, BL1, R2, G2, BL2, CH_A, CH_B, CH_C, CH_D, CH_E, LAT, OE, CLK}; + HUB75_I2S_CFG mxconfig( + 64, // width + 64, // height + 4, // chain length + _pins, // pin mapping + HUB75_I2S_CFG::FM6126A // driver chip + ); + + */ + + + // OK, now we can create our matrix object + dma_display = new MatrixPanel_I2S_DMA(mxconfig); + + // let's adjust default brightness to about 75% + dma_display->setBrightness8(192); // range is 0-255, 0 - 0%, 255 - 100% + + // Allocate memory and start DMA display + if( not dma_display->begin() ) + Serial.println("****** !KABOOM! I2S memory allocation failed ***********"); + + // well, hope we are OK, let's draw some colors first :) + Serial.println("Fill screen: RED"); + dma_display->fillScreenRGB888(255, 0, 0); + delay(1000); + + Serial.println("Fill screen: GREEN"); + dma_display->fillScreenRGB888(0, 255, 0); + delay(1000); + + Serial.println("Fill screen: BLUE"); + dma_display->fillScreenRGB888(0, 0, 255); + delay(1000); + + Serial.println("Fill screen: Neutral White"); + dma_display->fillScreenRGB888(64, 64, 64); + delay(1000); + + Serial.println("Fill screen: black"); + dma_display->fillScreenRGB888(0, 0, 0); + delay(1000); + + + // Set current FastLED palette + currentPalette = RainbowColors_p; + Serial.println("Starting plasma effect..."); + fps_timer = millis(); +} + +void loop() { + + for (int x = 0; x < PANE_WIDTH; x++) { + for (int y = 0; y < PANE_HEIGHT; y++) { + int16_t v = 0; + uint8_t wibble = sin8(time_counter); + v += sin16(x * wibble * 3 + time_counter); + v += cos16(y * (128 - wibble) + time_counter); + v += sin16(y * x * cos8(-time_counter) / 8); + + currentColor = ColorFromPalette(currentPalette, (v >> 8) + 127); //, brightness, currentBlendType); + dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.g, currentColor.b); + } + } + + ++time_counter; + ++cycles; + ++fps; + + if (cycles >= 1024) { + time_counter = 0; + cycles = 0; + currentPalette = palettes[random(0,sizeof(palettes)/sizeof(palettes[0]))]; + } + + // print FPS rate every 5 seconds + // Note: this is NOT a matrix refresh rate, it's the number of data frames being drawn to the DMA buffer per second + if (fps_timer + 5000 < millis()){ + Serial.printf_P(PSTR("Effect fps: %d\n"), fps/5); + fps_timer = millis(); + fps = 0; + } +} // end loop \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/2_PatternPlasma/PatternWave.jpg b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/2_PatternPlasma/PatternWave.jpg new file mode 100644 index 0000000..e6ce3c3 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/2_PatternPlasma/PatternWave.jpg differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/2_PatternPlasma/README.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/2_PatternPlasma/README.md new file mode 100644 index 0000000..172a99f --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/2_PatternPlasma/README.md @@ -0,0 +1,5 @@ +# Wave Pattern + +Demo of the colours, and the little flicker. + +![It's better in real life](PatternWave.jpg) diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/3_DoubleBuffer/3_DoubleBuffer.ino b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/3_DoubleBuffer/3_DoubleBuffer.ino new file mode 100644 index 0000000..5a41d67 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/3_DoubleBuffer/3_DoubleBuffer.ino @@ -0,0 +1,90 @@ +// Example uses the following configuration: mxconfig.double_buff = true; +// to enable double buffering, which means display->flipDMABuffer(); is required. + +// Bounce squares around the screen, doing the re-drawing in the background back-buffer. +// Double buffering is not always required in reality. + +#include + +MatrixPanel_I2S_DMA *display = nullptr; + +uint16_t myDARK = display->color565(64, 64, 64); +uint16_t myWHITE = display->color565(192, 192, 192); +uint16_t myRED = display->color565(255, 0, 0); +uint16_t myGREEN = display->color565(0, 255, 0); +uint16_t myBLUE = display->color565(0, 0, 255); + +uint16_t colours[5] = { myDARK, myWHITE, myRED, myGREEN, myBLUE }; + +struct Square +{ + float xpos, ypos; + float velocityx; + float velocityy; + boolean xdir, ydir; + uint16_t square_size; + uint16_t colour; +}; + +const int numSquares = 25; +Square Squares[numSquares]; + +void setup() +{ + // put your setup code here, to run once: + delay(1000); + Serial.begin(115200); + delay(200); + + Serial.println("...Starting Display"); + HUB75_I2S_CFG mxconfig; + mxconfig.double_buff = true; // <------------- Turn on double buffer + //mxconfig.clkphase = false; + + // OK, now we can create our matrix object + display = new MatrixPanel_I2S_DMA(mxconfig); + display->begin(); // setup display with pins as pre-defined in the library + + // Create some random squares + for (int i = 0; i < numSquares; i++) + { + Squares[i].square_size = random(2,10); + Squares[i].xpos = random(0, display->width() - Squares[i].square_size); + Squares[i].ypos = random(0, display->height() - Squares[i].square_size); + Squares[i].velocityx = static_cast (rand()) / static_cast (RAND_MAX); + Squares[i].velocityy = static_cast (rand()) / static_cast (RAND_MAX); + + int random_num = random(6); + Squares[i].colour = colours[random_num]; + } +} + +void loop() +{ + + display->flipDMABuffer(); // Show the back buffer, set currently output buffer to the back (i.e. no longer being sent to LED panels) + display->clearScreen(); // Now clear the back-buffer + + delay(16); // <----------- Shouldn't see this clearscreen occur as it happens on the back buffer when double buffering is enabled. + + for (int i = 0; i < numSquares; i++) + { + // Draw rect and then calculate + display->fillRect(Squares[i].xpos, Squares[i].ypos, Squares[i].square_size, Squares[i].square_size, Squares[i].colour); + + if (Squares[i].square_size + Squares[i].xpos >= display->width()) { + Squares[i].velocityx *= -1; + } else if (Squares[i].xpos <= 0) { + Squares[i].velocityx = abs (Squares[i].velocityx); + } + + if (Squares[i].square_size + Squares[i].ypos >= display->height()) { + Squares[i].velocityy *= -1; + } else if (Squares[i].ypos <= 0) { + Squares[i].velocityy = abs (Squares[i].velocityy); + } + + Squares[i].xpos += Squares[i].velocityx; + Squares[i].ypos += Squares[i].velocityy; + } +} diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/4_OtherShiftDriverPanel/4_OtherShiftDriverPanel.ino b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/4_OtherShiftDriverPanel/4_OtherShiftDriverPanel.ino new file mode 100644 index 0000000..e62cecc --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/4_OtherShiftDriverPanel/4_OtherShiftDriverPanel.ino @@ -0,0 +1,114 @@ +/********************************************************************** + * The library by default supports simple 'shift register' based panels + * with A,B,C,D,E lines to select a specific row, but there are plenty + * of examples of new chips coming on the market that work different. + * + * Please search through the project's issues. For some of these chips + * (you will need to look at the back of your panel to identify), this + * library has workarounds. This can be configured through using one of: + + // mxconfig.driver = HUB75_I2S_CFG::FM6126A; + //mxconfig.driver = HUB75_I2S_CFG::ICN2038S; + //mxconfig.driver = HUB75_I2S_CFG::FM6124; + //mxconfig.driver = HUB75_I2S_CFG::MBI5124; + */ + + +#include +#include +#include + +//////////////////////////////////////////////////////////////////// + +// Output resolution and panel chain length configuration +#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module. +#define PANEL_RES_Y 32 // Number of pixels tall of each INDIVIDUAL panel module. +#define PANEL_CHAIN 1 // Total number of panels chained one to another + +// placeholder for the matrix object +MatrixPanel_I2S_DMA *dma_display = nullptr; + +/////////////////////////////////////////////////////////////// + +// FastLED variables for pattern output +uint16_t time_counter = 0, cycles = 0, fps = 0; +unsigned long fps_timer; + +CRGB currentColor; +CRGBPalette16 palettes[] = {HeatColors_p, LavaColors_p, RainbowColors_p, RainbowStripeColors_p, CloudColors_p}; +CRGBPalette16 currentPalette = palettes[0]; + + +CRGB ColorFromCurrentPalette(uint8_t index = 0, uint8_t brightness = 255, TBlendType blendType = LINEARBLEND) { + return ColorFromPalette(currentPalette, index, brightness, blendType); +} + +void setup(){ + + HUB75_I2S_CFG mxconfig( + PANEL_RES_X, // module width + PANEL_RES_Y, // module height + PANEL_CHAIN // Chain length + ); + + // in case that we use panels based on FM6126A chip, we can set it here before creating MatrixPanel_I2S_DMA object + mxconfig.driver = HUB75_I2S_CFG::FM6126A; + //mxconfig.driver = HUB75_I2S_CFG::ICN2038S; + //mxconfig.driver = HUB75_I2S_CFG::FM6124; + //mxconfig.driver = HUB75_I2S_CFG::MBI5124; + + + // OK, now we can create our matrix object + dma_display = new MatrixPanel_I2S_DMA(mxconfig); + + // If you experience ghosting, you will need to reduce the brightness level, not all RGB Matrix + // Panels are the same - some seem to display ghosting artefacts at lower brightness levels. + // In the setup() function do something like: + + // let's adjust default brightness to about 75% + dma_display->setBrightness8(192); // range is 0-255, 0 - 0%, 255 - 100% + + // Allocate memory and start DMA display + if( not dma_display->begin() ) + Serial.println("****** !KABOOM! Insufficient memory - allocation failed ***********"); + + fps_timer = millis(); + +} + +void loop(){ + for (int x = 0; x < dma_display->width(); x++) { + for (int y = 0; y < dma_display->height(); y++) { + int16_t v = 0; + uint8_t wibble = sin8(time_counter); + v += sin16(x * wibble * 3 + time_counter); + v += cos16(y * (128 - wibble) + time_counter); + v += sin16(y * x * cos8(-time_counter) / 8); + + currentColor = ColorFromPalette(currentPalette, (v >> 8) + 127); //, brightness, currentBlendType); + dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.g, currentColor.b); + } + } + + ++time_counter; + ++cycles; + ++fps; + + if (cycles >= 1024) { + time_counter = 0; + cycles = 0; + currentPalette = palettes[random(0,sizeof(palettes)/sizeof(palettes[0]))]; + } + + // print FPS rate every 5 seconds + // Note: this is NOT a matrix refresh rate, it's the number of data frames being drawn to the DMA buffer per second + if (fps_timer + 5000 < millis()){ + Serial.printf_P(PSTR("Effect fps: %d\n"), fps/5); + fps_timer = millis(); + fps = 0; + } +} + + +// FM6126 panel , thanks goes to: +// https://github.com/hzeller/rpi-rgb-led-matrix/issues/746 diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/4_OtherShiftDriverPanel/FM6126A.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/4_OtherShiftDriverPanel/FM6126A.md new file mode 100644 index 0000000..1641c16 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/4_OtherShiftDriverPanel/FM6126A.md @@ -0,0 +1,51 @@ +## The mystery of control registers for FM6126A chips + + +The only available Datasheet for this chips is in Chinese and does not shed a light on what those two control regs are. + +An excellent insight could be found here https://github.com/hzeller/rpi-rgb-led-matrix/issues/746#issuecomment-453860510 + + + +So there are two regs in this chip - **REG1** and **REG2**, +one could be written with 12 clock pulses (and usually called reg12, dunno why :)) +the other one could be written with 13 clock pulses (and usually called reg13, dunno why :)) + + +I've done some measurements on power consumption while toggling bits of **REG1** and it looks that it could provide a fine grained brightness control over the entire matrix with no need for bitbanging over RGB or EO pins. +There are 6 bits (6 to 11) giving an increased brightness (compared to all-zeroes) and 4 bits (2-5) giving decreased brightness!!! +Still unclear if FM6112A brightness control is internally PWMed or current limited, might require some poking with oscilloscope. + +So it seems that the most bright (and hungry for power) value is bool REG1[16] = {0,0,0,0,0, 1,1,1,1,1,1, 0,0,0,0,0}; and not {0,1,1,1,1, 1,1,1,1,1,1, 1,1,1,1,1} as it is usually used. +I'm not sure about bit 1 - it is either not used or I was unable to measure it's influence to brightness/power. + +Giving at least 10 bits of hardware brightness control opens pretty nice options for offloading and simplifying matrix output. Should dig into this more deeper. + +Here are some of the measurements I've took for 2 64x64 panels filled with white color - reg value and corresponding current drain in amps. + + +|REG1 |bit value|Current, amps | +|--|--|--| +|REG1| 0111111 00000| >5 amps| +|REG1| 0100010 00000| 3.890 amp| +|REG1| 0100000 00000| 3.885 amp| +|REG1| 0011110 00000| 3.640 amp| +|REG1| 0011100 00000| 3.620 amp| +|REG1| 0011000 00000| 3.240 amp| +|REG1| 0010010 00000| 2.520 amp| +|REG1| 0010001 00000| 2.518 amp| +|REG1| 0010001 10000| 2.493 amp| +|REG1| 0010000 00000| 2.490 amp| +|REG1| 0010000 11110| 2.214 amp| +|REG1| 0001100 00000| 2.120 amp| +|REG1| 0001000 00000| 1.750 amp| +|REG1| 0000100 00000| 1.375 amp| +|REG1| 0000010 00000| 1.000 amp| +|REG1| **0000000 00000**| 0.995 amp| +|REG1| 0000001 11111| 0.700 amp| +|REG1| 0000000 01111| 0.690 amp| +|REG1| 0000000 10000| 0.690 amp| +|REG1| 0000000 11110| 0.686 amp| + + +/Vortigont/ \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/4_OtherShiftDriverPanel/README.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/4_OtherShiftDriverPanel/README.md new file mode 100644 index 0000000..40289cc --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/4_OtherShiftDriverPanel/README.md @@ -0,0 +1,13 @@ +## Ohter driver based LED Matrix Panels ## + +Limited support for other panels exists, but requires this to be passed as a configuration option when using the library. + +These panels require a special reset sequence before they can be used, check your panel chipset if you have issues. Refer to the example. + + +``` + mxconfig.driver = HUB75_I2S_CFG::FM6126A; + mxconfig.driver = HUB75_I2S_CFG::ICN2038S; + mxconfig.driver = HUB75_I2S_CFG::FM6124; + mxconfig.driver = HUB75_I2S_CFG::MBI5124; +``` diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/AnimatedGIFPanel_SD.ino b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/AnimatedGIFPanel_SD.ino new file mode 100644 index 0000000..9612244 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/AnimatedGIFPanel_SD.ino @@ -0,0 +1,268 @@ +/********************************************************************* + * AnimatedGif LED Matrix Panel example where the GIFs are + * stored on a SD card connected to the ESP32 using the + * standard GPIO pins used for SD card acces via. SPI. + * + * Put the gifs into a directory called 'gifs' (case sensitive) on + * a FAT32 formatted SDcard. + ********************************************************************/ +#include "FS.h" +#include "SD.h" +#include "SPI.h" +#include +#include + +/******************************************************************** + * Pin mapping below is for LOLIN D32 (ESP 32) + * + * Default pin mapping used by this library is NOT compatable with the use of the + * ESP32-Arduino 'SD' card library (there is overlap). As such, some of the pins + * used for the HUB75 panel need to be shifted. + * + * 'SD' card library requires GPIO 23, 18 and 19 + * https://github.com/espressif/arduino-esp32/tree/master/libraries/SD + * + */ + +/* + * Connect the SD card to the following pins: + * + * SD Card | ESP32 + * D2 - + * D3 SS + * CMD MOSI + * VSS GND + * VDD 3.3V + * CLK SCK + * VSS GND + * D0 MISO + * D1 - + */ + +/**** SD Card GPIO mappings ****/ +#define SS_PIN 5 +//#define MOSI_PIN 23 +//#define MISO_PIN 19 +//#define CLK_PIN 18 + + +/**** HUB75 GPIO mapping ****/ +// GPIO 34+ are on the ESP32 are input only!! +// https://randomnerdtutorials.com/esp32-pinout-reference-gpios/ + +#define A_PIN 33 // remap esp32 library default from 23 to 33 +#define B_PIN 32 // remap esp32 library default from 19 to 32 +#define C_PIN 22 // remap esp32 library defaultfrom 5 to 22 + +//#define R1_PIN 25 // library default for the esp32, unchanged +//#define G1_PIN 26 // library default for the esp32, unchanged +//#define B1_PIN 27 // library default for the esp32, unchanged +//#define R2_PIN 14 // library default for the esp32, unchanged +//#define G2_PIN 12 // library default for the esp32, unchanged +//#define B2_PIN 13 // library default for the esp32, unchanged +//#define D_PIN 17 // library default for the esp32, unchanged +//#define E_PIN -1 // IMPORTANT: Change to a valid pin if using a 64x64px panel. + +//#define LAT_PIN 4 // library default for the esp32, unchanged +//#define OE_PIN 15 // library default for the esp32, unchanged +//#define CLK_PIN 16 // library default for the esp32, unchanged + +/*************************************************************** + * HUB 75 LED DMA Matrix Panel Configuration + **************************************************************/ +#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module. +#define PANEL_RES_Y 32 // Number of pixels tall of each INDIVIDUAL panel module. +#define PANEL_CHAIN 1 // Total number of panels chained one to another + +/**************************************************************/ + +AnimatedGIF gif; +MatrixPanel_I2S_DMA *dma_display = nullptr; + +static int totalFiles = 0; // GIF files count + +static File FSGifFile; // temp gif file holder +static File GifRootFolder; // directory listing + +std::vector GifFiles; // GIF files path + +const int maxGifDuration = 30000; // ms, max GIF duration + +#include "gif_functions.hpp" +#include "sdcard_functions.hpp" + + +/**************************************************************/ +void draw_test_patterns(); +int gifPlay( const char* gifPath ) +{ // 0=infinite + + if( ! gif.open( gifPath, GIFOpenFile, GIFCloseFile, GIFReadFile, GIFSeekFile, GIFDraw ) ) { + log_n("Could not open gif %s", gifPath ); + } + + Serial.print("Playing: "); Serial.println(gifPath); + + int frameDelay = 0; // store delay for the last frame + int then = 0; // store overall delay + + while (gif.playFrame(true, &frameDelay)) { + + then += frameDelay; + if( then > maxGifDuration ) { // avoid being trapped in infinite GIF's + //log_w("Broke the GIF loop, max duration exceeded"); + break; + } + } + + gif.close(); + + return then; +} + + +void setup() +{ + Serial.begin(115200); + + // **************************** Setup SD Card access via SPI **************************** + if(!SD.begin(SS_PIN)){ + // bool begin(uint8_t ssPin=SS, SPIClass &spi=SPI, uint32_t frequency=4000000, const char * mountpoint="/sd", uint8_t max_files=5, bool format_if_empty=false); + Serial.println("Card Mount Failed"); + return; + } + uint8_t cardType = SD.cardType(); + + if(cardType == CARD_NONE){ + Serial.println("No SD card attached"); + return; + } + + Serial.print("SD Card Type: "); + if(cardType == CARD_MMC){ + Serial.println("MMC"); + } else if(cardType == CARD_SD){ + Serial.println("SDSC"); + } else if(cardType == CARD_SDHC){ + Serial.println("SDHC"); + } else { + Serial.println("UNKNOWN"); + } + + uint64_t cardSize = SD.cardSize() / (1024 * 1024); + Serial.printf("SD Card Size: %lluMB\n", cardSize); + + //listDir(SD, "/", 1, false); + + Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024)); + Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024)); + + + + // **************************** Setup DMA Matrix **************************** + HUB75_I2S_CFG mxconfig( + PANEL_RES_X, // module width + PANEL_RES_Y, // module height + PANEL_CHAIN // Chain length + ); + + // Need to remap these HUB75 DMA pins because the SPI SDCard is using them. + // Otherwise the SD Card will not work. + mxconfig.gpio.a = A_PIN; + mxconfig.gpio.b = B_PIN; + mxconfig.gpio.c = C_PIN; + // mxconfig.gpio.d = D_PIN; + + //mxconfig.clkphase = false; + //mxconfig.driver = HUB75_I2S_CFG::FM6126A; + + // Display Setup + dma_display = new MatrixPanel_I2S_DMA(mxconfig); + + // Allocate memory and start DMA display + if( not dma_display->begin() ) + Serial.println("****** !KABOOM! HUB75 memory allocation failed ***********"); + + dma_display->setBrightness8(128); //0-255 + dma_display->clearScreen(); + + + // **************************** Setup Sketch **************************** + Serial.println("Starting AnimatedGIFs Sketch"); + + // SD CARD STOPS WORKING WITH DMA DISPLAY ENABLED>... + + File root = SD.open("/gifs"); + if(!root){ + Serial.println("Failed to open directory"); + return; + } + + File file = root.openNextFile(); + while(file){ + if(!file.isDirectory()) + { + Serial.print(" FILE: "); + Serial.print(file.name()); + Serial.print(" SIZE: "); + Serial.println(file.size()); + + std::string filename = "/gifs/" + std::string(file.name()); + Serial.println(filename.c_str()); + + GifFiles.push_back( filename ); + // Serial.println("Adding to gif list:" + String(filename)); + totalFiles++; + + } + file = root.openNextFile(); + } + + file.close(); + Serial.printf("Found %d GIFs to play.", totalFiles); + //totalFiles = getGifInventory("/gifs"); + + + + // This is important - Set the right endianness. + gif.begin(LITTLE_ENDIAN_PIXELS); + +} + +void loop(){ + + // Iterate over a vector using range based for loop + for(auto & elem : GifFiles) + { + gifPlay( elem.c_str() ); + gif.reset(); + delay(500); + } + +} + +void draw_test_patterns() +{ + // fix the screen with green + dma_display->fillRect(0, 0, dma_display->width(), dma_display->height(), dma_display->color444(0, 15, 0)); + delay(500); + + // draw a box in yellow + dma_display->drawRect(0, 0, dma_display->width(), dma_display->height(), dma_display->color444(15, 15, 0)); + delay(500); + + // draw an 'X' in red + dma_display->drawLine(0, 0, dma_display->width()-1, dma_display->height()-1, dma_display->color444(15, 0, 0)); + dma_display->drawLine(dma_display->width()-1, 0, 0, dma_display->height()-1, dma_display->color444(15, 0, 0)); + delay(500); + + // draw a blue circle + dma_display->drawCircle(10, 10, 10, dma_display->color444(0, 0, 15)); + delay(500); + + // fill a violet circle + dma_display->fillCircle(40, 21, 10, dma_display->color444(15, 0, 15)); + delay(500); + delay(1000); + +} diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/Readme.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/Readme.md new file mode 100644 index 0000000..6f9f06a --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/Readme.md @@ -0,0 +1,15 @@ +# ESP32-HUB75-MatrixPanel-DMA SDCard example + +A very basic example using the 'Animated GIF' library by Larry Bank + the SD / File system library provided for Arduino by Espressif. + +Some default HUB75 pins need to be remapped to accomodate for the SD Card. + +![image](esp32_sdcard.jpg) + +## How to use it? + +1. Format a SD Card with FAT32 file system (default setting) +2. Create a directory called 'gifs' +3. Drop your gifs in there. The resolution of the GIFS must match that of the display. + + diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/esp32_sdcard.jpg b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/esp32_sdcard.jpg new file mode 100644 index 0000000..4a4441d Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/esp32_sdcard.jpg differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gif_functions.hpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gif_functions.hpp new file mode 100644 index 0000000..7a16a63 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gif_functions.hpp @@ -0,0 +1,132 @@ + +// Code copied from AnimatedGIF examples + +#ifndef M5STACK_SD + // for custom ESP32 builds + #define M5STACK_SD SD +#endif + + +static void * GIFOpenFile(const char *fname, int32_t *pSize) +{ + //log_d("GIFOpenFile( %s )\n", fname ); + FSGifFile = M5STACK_SD.open(fname); + if (FSGifFile) { + *pSize = FSGifFile.size(); + return (void *)&FSGifFile; + } + return NULL; +} + + +static void GIFCloseFile(void *pHandle) +{ + File *f = static_cast(pHandle); + if (f != NULL) + f->close(); +} + + +static int32_t GIFReadFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen) +{ + int32_t iBytesRead; + iBytesRead = iLen; + File *f = static_cast(pFile->fHandle); + // Note: If you read a file all the way to the last byte, seek() stops working + if ((pFile->iSize - pFile->iPos) < iLen) + iBytesRead = pFile->iSize - pFile->iPos - 1; // <-- ugly work-around + if (iBytesRead <= 0) + return 0; + iBytesRead = (int32_t)f->read(pBuf, iBytesRead); + pFile->iPos = f->position(); + return iBytesRead; +} + + +static int32_t GIFSeekFile(GIFFILE *pFile, int32_t iPosition) +{ + int i = micros(); + File *f = static_cast(pFile->fHandle); + f->seek(iPosition); + pFile->iPos = (int32_t)f->position(); + i = micros() - i; + //log_d("Seek time = %d us\n", i); + return pFile->iPos; +} + + +// Draw a line of image directly on the LCD +void GIFDraw(GIFDRAW *pDraw) +{ + uint8_t *s; + uint16_t *d, *usPalette, usTemp[320]; + int x, y, iWidth; + + iWidth = pDraw->iWidth; + if (iWidth > PANEL_RES_X) + iWidth = PANEL_RES_X; + usPalette = pDraw->pPalette; + y = pDraw->iY + pDraw->y; // current line + + s = pDraw->pPixels; + if (pDraw->ucDisposalMethod == 2) {// restore to background color + for (x=0; xucTransparent) + s[x] = pDraw->ucBackground; + } + pDraw->ucHasTransparency = 0; + } + // Apply the new pixels to the main image + if (pDraw->ucHasTransparency) { // if transparency used + uint8_t *pEnd, c, ucTransparent = pDraw->ucTransparent; + int x, iCount; + pEnd = s + iWidth; + x = 0; + iCount = 0; // count non-transparent pixels + while(x < iWidth) { + c = ucTransparent-1; + d = usTemp; + while (c != ucTransparent && s < pEnd) { + c = *s++; + if (c == ucTransparent) { // done, stop + s--; // back up to treat it like transparent + } else { // opaque + *d++ = usPalette[c]; + iCount++; + } + } // while looking for opaque pixels + if (iCount) { // any opaque pixels? + for(int xOffset = 0; xOffset < iCount; xOffset++ ){ + dma_display->drawPixel(x + xOffset, y, usTemp[xOffset]); // 565 Color Format + } + x += iCount; + iCount = 0; + } + // no, look for a run of transparent pixels + c = ucTransparent; + while (c == ucTransparent && s < pEnd) { + c = *s++; + if (c == ucTransparent) + iCount++; + else + s--; + } + if (iCount) { + x += iCount; // skip these + iCount = 0; + } + } + } else { + s = pDraw->pPixels; + // Translate the 8-bit pixels through the RGB565 palette (already byte reversed) + for (x=0; xdrawPixel(x, y, usPalette[*s++]); // color 565 + /* + usTemp[x] = usPalette[*s++]; + + for (x=0; xiWidth; x++) { + dma_display->drawPixel(x, y, usTemp[*s++]); // color 565 + } */ + + } +} /* GIFDraw() */ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/cartoon.gif b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/cartoon.gif new file mode 100644 index 0000000..32a0e25 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/cartoon.gif differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/ezgif.com-pacmn.gif b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/ezgif.com-pacmn.gif new file mode 100644 index 0000000..0a219a4 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/ezgif.com-pacmn.gif differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/loading.io-64x32px.gif b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/loading.io-64x32px.gif new file mode 100644 index 0000000..342f8ae Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/loading.io-64x32px.gif differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/matrix-spin.gif b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/matrix-spin.gif new file mode 100644 index 0000000..7925d68 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/matrix-spin.gif differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/parasite1.gif b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/parasite1.gif new file mode 100644 index 0000000..8b8b67a Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/parasite1.gif differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/parasite2.gif b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/parasite2.gif new file mode 100644 index 0000000..60d03c7 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/parasite2.gif differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/shock-gs.gif b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/shock-gs.gif new file mode 100644 index 0000000..1d023d9 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/gifs/shock-gs.gif differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/sdcard_functions.hpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/sdcard_functions.hpp new file mode 100644 index 0000000..51ff5b1 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SD/sdcard_functions.hpp @@ -0,0 +1,102 @@ +/************************ SD Card Code ************************/ +// As per: https://github.com/espressif/arduino-esp32/tree/master/libraries/SD/examples/SD_Test + + + +void listDir(fs::FS &fs, const char * dirname, uint8_t levels, bool add_to_gif_list = false){ + Serial.printf("Listing directory: %s\n", dirname); + + File root = fs.open(dirname); + if(!root){ + Serial.println("Failed to open directory"); + return; + } + if(!root.isDirectory()){ + Serial.println("Not a directory"); + return; + } + + File file = root.openNextFile(); + while(file){ + if(file.isDirectory()){ + Serial.print(" DIR : "); + Serial.println(file.name()); + if(levels){ + listDir(fs, file.path(), levels -1, false); + } + } else { + Serial.print(" FILE: "); + Serial.print(file.name()); + Serial.print(" SIZE: "); + Serial.println(file.size()); + + if (add_to_gif_list && levels == 0) + { + GifFiles.push_back( std::string(dirname) + file.name() ); + Serial.println("Adding to gif list:" + String(dirname) +"/" + file.name()); + totalFiles++; + } + } + file = root.openNextFile(); + } + + file.close(); +} + +void readFile(fs::FS &fs, const char * path){ + Serial.printf("Reading file: %s\n", path); + + File file = fs.open(path); + if(!file){ + Serial.println("Failed to open file for reading"); + return; + } + + Serial.print("Read from file: "); + while(file.available()){ + Serial.write(file.read()); + } + file.close(); +} + +void testFileIO(fs::FS &fs, const char * path){ + File file = fs.open(path); + static uint8_t buf[512]; + size_t len = 0; + uint32_t start = millis(); + uint32_t end = start; + if(file){ + len = file.size(); + size_t flen = len; + start = millis(); + while(len){ + size_t toRead = len; + if(toRead > 512){ + toRead = 512; + } + file.read(buf, toRead); + len -= toRead; + } + end = millis() - start; + Serial.printf("%u bytes read for %u ms\n", flen, end); + file.close(); + } else { + Serial.println("Failed to open file for reading"); + } + + + file = fs.open(path, FILE_WRITE); + if(!file){ + Serial.println("Failed to open file for writing"); + return; + } + + size_t i; + start = millis(); + for(i=0; i<2048; i++){ + file.write(buf, 512); + } + end = millis() - start; + Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end); + file.close(); +} \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/AnimatedGIFPanel_SPIFFS.ino b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/AnimatedGIFPanel_SPIFFS.ino new file mode 100644 index 0000000..9d6d182 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/AnimatedGIFPanel_SPIFFS.ino @@ -0,0 +1,290 @@ +// Example sketch which shows how to display a 64x32 animated GIF image stored in FLASH memory +// on a 64x32 LED matrix +// +// Credits: https://github.com/bitbank2/AnimatedGIF/tree/master/examples/ESP32_LEDMatrix_I2S +// + +/* INSTRUCTIONS + * + * 1. First Run the 'ESP32 Sketch Data Upload Tool' in Arduino from the 'Tools' Menu. + * - If you don't know what this is or see it as an option, then read this: + * https://github.com/me-no-dev/arduino-esp32fs-plugin + * - This tool will upload the contents of the data/ directory in the sketch folder onto + * the ESP32 itself. + * + * 2. You can drop any animated GIF you want in there, but keep it to the resolution of the + * MATRIX you're displaying to. To resize a gif, use this online website: https://ezgif.com/ + * + * 3. Have fun. + */ + +#define FILESYSTEM SPIFFS +#include +#include +#include + +// ---------------------------- + +/* + * Below is an is the 'legacy' way of initialising the MatrixPanel_I2S_DMA class. + * i.e. MATRIX_WIDTH and MATRIX_HEIGHT are modified by compile-time directives. + * By default the library assumes a single 64x32 pixel panel is connected. + * + * Refer to the example '2_PatternPlasma' on the new / correct way to setup this library + * for different resolutions / panel chain lengths within the sketch 'setup()'. + * + */ + +#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module. +#define PANEL_RES_Y 32 // Number of pixels tall of each INDIVIDUAL panel module. +#define PANEL_CHAIN 1 // Total number of panels chained one to another + +//MatrixPanel_I2S_DMA dma_display; +MatrixPanel_I2S_DMA *dma_display = nullptr; + +uint16_t myBLACK = dma_display->color565(0, 0, 0); +uint16_t myWHITE = dma_display->color565(255, 255, 255); +uint16_t myRED = dma_display->color565(255, 0, 0); +uint16_t myGREEN = dma_display->color565(0, 255, 0); +uint16_t myBLUE = dma_display->color565(0, 0, 255); + + +AnimatedGIF gif; +File f; +int x_offset, y_offset; + + + +// Draw a line of image directly on the LED Matrix +void GIFDraw(GIFDRAW *pDraw) +{ + uint8_t *s; + uint16_t *d, *usPalette, usTemp[320]; + int x, y, iWidth; + + iWidth = pDraw->iWidth; + if (iWidth > MATRIX_WIDTH) + iWidth = MATRIX_WIDTH; + + usPalette = pDraw->pPalette; + y = pDraw->iY + pDraw->y; // current line + + s = pDraw->pPixels; + if (pDraw->ucDisposalMethod == 2) // restore to background color + { + for (x=0; xucTransparent) + s[x] = pDraw->ucBackground; + } + pDraw->ucHasTransparency = 0; + } + // Apply the new pixels to the main image + if (pDraw->ucHasTransparency) // if transparency used + { + uint8_t *pEnd, c, ucTransparent = pDraw->ucTransparent; + int x, iCount; + pEnd = s + pDraw->iWidth; + x = 0; + iCount = 0; // count non-transparent pixels + while(x < pDraw->iWidth) + { + c = ucTransparent-1; + d = usTemp; + while (c != ucTransparent && s < pEnd) + { + c = *s++; + if (c == ucTransparent) // done, stop + { + s--; // back up to treat it like transparent + } + else // opaque + { + *d++ = usPalette[c]; + iCount++; + } + } // while looking for opaque pixels + if (iCount) // any opaque pixels? + { + for(int xOffset = 0; xOffset < iCount; xOffset++ ){ + dma_display->drawPixel(x + xOffset, y, usTemp[xOffset]); // 565 Color Format + } + x += iCount; + iCount = 0; + } + // no, look for a run of transparent pixels + c = ucTransparent; + while (c == ucTransparent && s < pEnd) + { + c = *s++; + if (c == ucTransparent) + iCount++; + else + s--; + } + if (iCount) + { + x += iCount; // skip these + iCount = 0; + } + } + } + else // does not have transparency + { + s = pDraw->pPixels; + // Translate the 8-bit pixels through the RGB565 palette (already byte reversed) + for (x=0; xiWidth; x++) + { + dma_display->drawPixel(x, y, usPalette[*s++]); // color 565 + } + } +} /* GIFDraw() */ + + +void * GIFOpenFile(const char *fname, int32_t *pSize) +{ + Serial.print("Playing gif: "); + Serial.println(fname); + f = FILESYSTEM.open(fname); + if (f) + { + *pSize = f.size(); + return (void *)&f; + } + return NULL; +} /* GIFOpenFile() */ + +void GIFCloseFile(void *pHandle) +{ + File *f = static_cast(pHandle); + if (f != NULL) + f->close(); +} /* GIFCloseFile() */ + +int32_t GIFReadFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen) +{ + int32_t iBytesRead; + iBytesRead = iLen; + File *f = static_cast(pFile->fHandle); + // Note: If you read a file all the way to the last byte, seek() stops working + if ((pFile->iSize - pFile->iPos) < iLen) + iBytesRead = pFile->iSize - pFile->iPos - 1; // <-- ugly work-around + if (iBytesRead <= 0) + return 0; + iBytesRead = (int32_t)f->read(pBuf, iBytesRead); + pFile->iPos = f->position(); + return iBytesRead; +} /* GIFReadFile() */ + +int32_t GIFSeekFile(GIFFILE *pFile, int32_t iPosition) +{ + int i = micros(); + File *f = static_cast(pFile->fHandle); + f->seek(iPosition); + pFile->iPos = (int32_t)f->position(); + i = micros() - i; +// Serial.printf("Seek time = %d us\n", i); + return pFile->iPos; +} /* GIFSeekFile() */ + +unsigned long start_tick = 0; + +void ShowGIF(char *name) +{ + start_tick = millis(); + + if (gif.open(name, GIFOpenFile, GIFCloseFile, GIFReadFile, GIFSeekFile, GIFDraw)) + { + x_offset = (MATRIX_WIDTH - gif.getCanvasWidth())/2; + if (x_offset < 0) x_offset = 0; + y_offset = (MATRIX_HEIGHT - gif.getCanvasHeight())/2; + if (y_offset < 0) y_offset = 0; + Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n", gif.getCanvasWidth(), gif.getCanvasHeight()); + Serial.flush(); + while (gif.playFrame(true, NULL)) + { + if ( (millis() - start_tick) > 8000) { // we'll get bored after about 8 seconds of the same looping gif + break; + } + } + gif.close(); + } + +} /* ShowGIF() */ + + + +/************************* Arduino Sketch Setup and Loop() *******************************/ +void setup() { + Serial.begin(115200); + delay(1000); + + HUB75_I2S_CFG mxconfig( + PANEL_RES_X, // module width + PANEL_RES_Y, // module height + PANEL_CHAIN // Chain length + ); + + // mxconfig.gpio.e = 18; + // mxconfig.clkphase = false; + //mxconfig.driver = HUB75_I2S_CFG::FM6126A; + + // Display Setup + dma_display = new MatrixPanel_I2S_DMA(mxconfig); + dma_display->begin(); + dma_display->setBrightness8(128); //0-255 + dma_display->clearScreen(); + dma_display->fillScreen(myWHITE); + + Serial.println("Starting AnimatedGIFs Sketch"); + + // Start filesystem + Serial.println(" * Loading SPIFFS"); + if(!SPIFFS.begin()){ + Serial.println("SPIFFS Mount Failed"); + } + + dma_display->begin(); + + /* all other pixel drawing functions can only be called after .begin() */ + dma_display->fillScreen(dma_display->color565(0, 0, 0)); + gif.begin(LITTLE_ENDIAN_PIXELS); + +} + +String gifDir = "/gifs"; // play all GIFs in this directory on the SD card +char filePath[256] = { 0 }; +File root, gifFile; + +void loop() +{ + while (1) // run forever + { + + root = FILESYSTEM.open(gifDir); + if (root) + { + gifFile = root.openNextFile(); + while (gifFile) + { + if (!gifFile.isDirectory()) // play it + { + + // C-strings... urghh... + memset(filePath, 0x0, sizeof(filePath)); + strcpy(filePath, gifFile.path()); + + // Show it. + ShowGIF(filePath); + + } + gifFile.close(); + gifFile = root.openNextFile(); + } + root.close(); + } // root + + delay(1000); // pause before restarting + + } // while +} \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/README.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/README.md new file mode 100644 index 0000000..63ff899 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/README.md @@ -0,0 +1,13 @@ +## Animated GIF Decoding Example + +### Prerequisites +1. The excellent 'AnimatedGIF' library by Larry Bank needs to be installed: https://github.com/bitbank2/AnimatedGIF + +This is available via the Arduino Library manager, or can be placed in the 'libs' directory with PlatformIO. + +2. The files in the 'data' folder are written to the ESP32's SPIFFS file system. + + +## Credits + +https://github.com/bitbank2/AnimatedGIF diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/cartoon.gif b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/cartoon.gif new file mode 100644 index 0000000..32a0e25 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/cartoon.gif differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/ezgif.com-pacmn.gif b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/ezgif.com-pacmn.gif new file mode 100644 index 0000000..0a219a4 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/ezgif.com-pacmn.gif differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/loading.io-64x32px.gif b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/loading.io-64x32px.gif new file mode 100644 index 0000000..342f8ae Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/loading.io-64x32px.gif differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/matrix-spin.gif b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/matrix-spin.gif new file mode 100644 index 0000000..7925d68 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/matrix-spin.gif differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/parasite1.gif b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/parasite1.gif new file mode 100644 index 0000000..8b8b67a Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/parasite1.gif differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/parasite2.gif b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/parasite2.gif new file mode 100644 index 0000000..60d03c7 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/parasite2.gif differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/shock-gs.gif b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/shock-gs.gif new file mode 100644 index 0000000..1d023d9 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AnimatedGIFPanel_SPIFFS/data/gifs/shock-gs.gif differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Attractor.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Attractor.h new file mode 100644 index 0000000..668ba53 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Attractor.h @@ -0,0 +1,50 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from "Attractor" in "The Nature of Code" by Daniel Shiffman: http://natureofcode.com/ + * Copyright (c) 2014 Daniel Shiffman + * http://www.shiffman.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "Vector.h" + +class Attractor { +public: + float mass; // Mass, tied to size + float G; // Gravitational Constant + PVector location; // Location + + Attractor() { + location = PVector(MATRIX_CENTRE_X, MATRIX_CENTRE_Y); + mass = 10; + G = .5; + } + + PVector attract(Boid m) { + PVector force = location - m.location; // Calculate direction of force + float d = force.mag(); // Distance between objects + d = constrain(d, 5.0, 32.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects + force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction) + float strength = (G * mass * m.mass) / (d * d); // Calculate gravitational force magnitude + force *= strength; // Get force vector --> magnitude * direction + return force; + } +}; diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/AuroraDemo.ino b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/AuroraDemo.ino new file mode 100644 index 0000000..14b61be --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/AuroraDemo.ino @@ -0,0 +1,150 @@ +#include + +/*--------------------- MATRIX GPIO CONFIG -------------------------*/ +#define R1_PIN 25 +#define G1_PIN 26 +#define B1_PIN 27 +#define R2_PIN 14 +#define G2_PIN 12 +#define B2_PIN 13 +#define A_PIN 23 +#define B_PIN 19 // Changed from library default +#define C_PIN 5 +#define D_PIN 17 +#define E_PIN -1 +#define LAT_PIN 4 +#define OE_PIN 15 +#define CLK_PIN 16 + + +/*--------------------- MATRIX PANEL CONFIG -------------------------*/ +#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module. +#define PANEL_RES_Y 32 // Number of pixels tall of each INDIVIDUAL panel module. +#define PANEL_CHAIN 1 // Total number of panels chained one to another + +/* +//Another way of creating config structure +//Custom pin mapping for all pins +HUB75_I2S_CFG::i2s_pins _pins={R1, G1, BL1, R2, G2, BL2, CH_A, CH_B, CH_C, CH_D, CH_E, LAT, OE, CLK}; +HUB75_I2S_CFG mxconfig( + 64, // width + 64, // height + 4, // chain length + _pins, // pin mapping + HUB75_I2S_CFG::FM6126A // driver chip +); + +*/ +MatrixPanel_I2S_DMA *dma_display = nullptr; + +// Module configuration +HUB75_I2S_CFG mxconfig( + PANEL_RES_X, // module width + PANEL_RES_Y, // module height + PANEL_CHAIN // Chain length +); + + +//mxconfig.gpio.e = -1; // Assign a pin if you have a 64x64 panel +//mxconfig.clkphase = false; // Change this if you have issues with ghosting. +//mxconfig.driver = HUB75_I2S_CFG::FM6126A; // Change this according to your pane. + + + +#include + +#include "Effects.h" +Effects effects; + +#include "Drawable.h" +#include "Playlist.h" +//#include "Geometry.h" + +#include "Patterns.h" +Patterns patterns; + +/* -------------------------- Some variables -------------------------- */ +unsigned long fps = 0, fps_timer; // fps (this is NOT a matrix refresh rate!) +unsigned int default_fps = 30, pattern_fps = 30; // default fps limit (this is not a matrix refresh counter!) +unsigned long ms_animation_max_duration = 20000; // 20 seconds +unsigned long last_frame=0, ms_previous=0; + +void setup() +{ + /************** SERIAL **************/ + Serial.begin(115200); + delay(250); + + /************** DISPLAY **************/ + Serial.println("...Starting Display"); + dma_display = new MatrixPanel_I2S_DMA(mxconfig); + dma_display->begin(); + dma_display->setBrightness8(90); //0-255 + + dma_display->fillScreenRGB888(128,0,0); + delay(1000); + dma_display->fillScreenRGB888(0,0,128); + delay(1000); + dma_display->clearScreen(); + delay(1000); + Serial.println("**************** Starting Aurora Effects Demo ****************"); + + + // setup the effects generator + effects.Setup(); + + delay(500); + Serial.println("Effects being loaded: "); + listPatterns(); + + + patterns.moveRandom(1); // start from a random pattern + + Serial.print("Starting with pattern: "); + Serial.println(patterns.getCurrentPatternName()); + patterns.start(); + ms_previous = millis(); + fps_timer = millis(); +} + +void loop() +{ + // menu.run(mainMenuItems, mainMenuItemCount); + + if ( (millis() - ms_previous) > ms_animation_max_duration ) + { + patterns.stop(); + patterns.moveRandom(1); + //patterns.move(1); + patterns.start(); + + Serial.print("Changing pattern to: "); + Serial.println(patterns.getCurrentPatternName()); + + ms_previous = millis(); + + // Select a random palette as well + //effects.RandomPalette(); + } + + if ( 1000 / pattern_fps + last_frame < millis()){ + last_frame = millis(); + pattern_fps = patterns.drawFrame(); + if (!pattern_fps) + pattern_fps = default_fps; + + ++fps; + } + + if (fps_timer + 1000 < millis()){ + Serial.printf_P(PSTR("Effect fps: %ld\n"), fps); + fps_timer = millis(); + fps = 0; + } + +} + + +void listPatterns() { + patterns.listPatterns(); +} \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Boid.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Boid.h new file mode 100644 index 0000000..61a1758 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Boid.h @@ -0,0 +1,326 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from "Flocking" in "The Nature of Code" by Daniel Shiffman: http://natureofcode.com/ + * Copyright (c) 2014 Daniel Shiffman + * http://www.shiffman.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +// Flocking +// Daniel Shiffman +// The Nature of Code, Spring 2009 + +// Boid class +// Methods for Separation, Cohesion, Alignment added + +class Boid { + public: + + PVector location; + PVector velocity; + PVector acceleration; + float maxforce; // Maximum steering force + float maxspeed; // Maximum speed + + float desiredseparation = 4; + float neighbordist = 8; + byte colorIndex = 0; + float mass; + + boolean enabled = true; + + Boid() {} + + Boid(float x, float y) { + acceleration = PVector(0, 0); + velocity = PVector(randomf(), randomf()); + location = PVector(x, y); + maxspeed = 1.5; + maxforce = 0.05; + } + + static float randomf() { + return mapfloat(random(0, 255), 0, 255, -.5, .5); + } + + static float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } + + void run(Boid boids [], uint8_t boidCount) { + flock(boids, boidCount); + update(); + // wrapAroundBorders(); + // render(); + } + + // Method to update location + void update() { + // Update velocity + velocity += acceleration; + // Limit speed + velocity.limit(maxspeed); + location += velocity; + // Reset acceleration to 0 each cycle + acceleration *= 0; + } + + void applyForce(PVector force) { + // We could add mass here if we want A = F / M + acceleration += force; + } + + void repelForce(PVector obstacle, float radius) { + //Force that drives boid away from obstacle. + + PVector futPos = location + velocity; //Calculate future position for more effective behavior. + PVector dist = obstacle - futPos; + float d = dist.mag(); + + if (d <= radius) { + PVector repelVec = location - obstacle; + repelVec.normalize(); + if (d != 0) { //Don't divide by zero. + // float scale = 1.0 / d; //The closer to the obstacle, the stronger the force. + repelVec.normalize(); + repelVec *= (maxforce * 7); + if (repelVec.mag() < 0) { //Don't let the boids turn around to avoid the obstacle. + repelVec.y = 0; + } + } + applyForce(repelVec); + } + } + + // We accumulate a new acceleration each time based on three rules + void flock(Boid boids [], uint8_t boidCount) { + PVector sep = separate(boids, boidCount); // Separation + PVector ali = align(boids, boidCount); // Alignment + PVector coh = cohesion(boids, boidCount); // Cohesion + // Arbitrarily weight these forces + sep *= 1.5; + ali *= 1.0; + coh *= 1.0; + // Add the force vectors to acceleration + applyForce(sep); + applyForce(ali); + applyForce(coh); + } + + // Separation + // Method checks for nearby boids and steers away + PVector separate(Boid boids [], uint8_t boidCount) { + PVector steer = PVector(0, 0); + int count = 0; + // For every boid in the system, check if it's too close + for (int i = 0; i < boidCount; i++) { + Boid other = boids[i]; + if (!other.enabled) + continue; + float d = location.dist(other.location); + // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) + if ((d > 0) && (d < desiredseparation)) { + // Calculate vector pointing away from neighbor + PVector diff = location - other.location; + diff.normalize(); + diff /= d; // Weight by distance + steer += diff; + count++; // Keep track of how many + } + } + // Average -- divide by how many + if (count > 0) { + steer /= (float) count; + } + + // As long as the vector is greater than 0 + if (steer.mag() > 0) { + // Implement Reynolds: Steering = Desired - Velocity + steer.normalize(); + steer *= maxspeed; + steer -= velocity; + steer.limit(maxforce); + } + return steer; + } + + // Alignment + // For every nearby boid in the system, calculate the average velocity + PVector align(Boid boids [], uint8_t boidCount) { + PVector sum = PVector(0, 0); + int count = 0; + for (int i = 0; i < boidCount; i++) { + Boid other = boids[i]; + if (!other.enabled) + continue; + float d = location.dist(other.location); + if ((d > 0) && (d < neighbordist)) { + sum += other.velocity; + count++; + } + } + if (count > 0) { + sum /= (float) count; + sum.normalize(); + sum *= maxspeed; + PVector steer = sum - velocity; + steer.limit(maxforce); + return steer; + } + else { + return PVector(0, 0); + } + } + + // Cohesion + // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location + PVector cohesion(Boid boids [], uint8_t boidCount) { + PVector sum = PVector(0, 0); // Start with empty vector to accumulate all locations + int count = 0; + for (int i = 0; i < boidCount; i++) { + Boid other = boids[i]; + if (!other.enabled) + continue; + float d = location.dist(other.location); + if ((d > 0) && (d < neighbordist)) { + sum += other.location; // Add location + count++; + } + } + if (count > 0) { + sum /= count; + return seek(sum); // Steer towards the location + } + else { + return PVector(0, 0); + } + } + + // A method that calculates and applies a steering force towards a target + // STEER = DESIRED MINUS VELOCITY + PVector seek(PVector target) { + PVector desired = target - location; // A vector pointing from the location to the target + // Normalize desired and scale to maximum speed + desired.normalize(); + desired *= maxspeed; + // Steering = Desired minus Velocity + PVector steer = desired - velocity; + steer.limit(maxforce); // Limit to maximum steering force + return steer; + } + + // A method that calculates a steering force towards a target + // STEER = DESIRED MINUS VELOCITY + void arrive(PVector target) { + PVector desired = target - location; // A vector pointing from the location to the target + float d = desired.mag(); + // Normalize desired and scale with arbitrary damping within 100 pixels + desired.normalize(); + if (d < 4) { + float m = map(d, 0, 100, 0, maxspeed); + desired *= m; + } + else { + desired *= maxspeed; + } + + // Steering = Desired minus Velocity + PVector steer = desired - velocity; + steer.limit(maxforce); // Limit to maximum steering force + applyForce(steer); + //Serial.println(d); + } + + void wrapAroundBorders() { + if (location.x < 0) location.x = MATRIX_WIDTH - 1; + if (location.y < 0) location.y = MATRIX_HEIGHT - 1; + if (location.x >= MATRIX_WIDTH) location.x = 0; + if (location.y >= MATRIX_HEIGHT) location.y = 0; + } + + void avoidBorders() { + PVector desired = velocity; + + if (location.x < 8) desired = PVector(maxspeed, velocity.y); + if (location.x >= MATRIX_WIDTH - 8) desired = PVector(-maxspeed, velocity.y); + if (location.y < 8) desired = PVector(velocity.x, maxspeed); + if (location.y >= MATRIX_HEIGHT - 8) desired = PVector(velocity.x, -maxspeed); + + if (desired != velocity) { + PVector steer = desired - velocity; + steer.limit(maxforce); + applyForce(steer); + } + + if (location.x < 0) location.x = 0; + if (location.y < 0) location.y = 0; + if (location.x >= MATRIX_WIDTH) location.x = MATRIX_WIDTH - 1; + if (location.y >= MATRIX_HEIGHT) location.y = MATRIX_HEIGHT - 1; + } + + bool bounceOffBorders(float bounce) { + bool bounced = false; + + if (location.x >= MATRIX_WIDTH) { + location.x = MATRIX_WIDTH - 1; + velocity.x *= -bounce; + bounced = true; + } + else if (location.x < 0) { + location.x = 0; + velocity.x *= -bounce; + bounced = true; + } + + if (location.y >= MATRIX_HEIGHT) { + location.y = MATRIX_HEIGHT - 1; + velocity.y *= -bounce; + bounced = true; + } + else if (location.y < 0) { + location.y = 0; + velocity.y *= -bounce; + bounced = true; + } + + return bounced; + } + + void render() { + //// Draw a triangle rotated in the direction of velocity + //float theta = velocity.heading2D() + radians(90); + //fill(175); + //stroke(0); + //pushMatrix(); + //translate(location.x,location.y); + //rotate(theta); + //beginShape(TRIANGLES); + //vertex(0, -r*2); + //vertex(-r, r*2); + //vertex(r, r*2); + //endShape(); + //popMatrix(); + //dma_display->drawBackgroundPixelRGB888(location.x, location.y, CRGB::Blue); + } +}; + +static const uint8_t AVAILABLE_BOID_COUNT = 40; +Boid boids[AVAILABLE_BOID_COUNT]; diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Drawable.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Drawable.h new file mode 100644 index 0000000..56b3eb2 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Drawable.h @@ -0,0 +1,55 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Drawable_H +#define Drawable_H + +class Drawable{ +public: + char* name; + + virtual bool isRunnable() { + return false; + } + + virtual bool isPlaylist() { + return false; + } + + // a single frame should be drawn as fast as possible, without any delay or blocking + // return how many millisecond delay is requested before the next call to drawFrame() + virtual unsigned int drawFrame() { + dma_display->fillScreen(0); + //backgroundLayer.fillScreen({ 0, 0, 0 }); + return 0; + }; + + virtual void printTesting() + { + Serial.println("Testing..."); + } + + virtual void start() {}; + virtual void stop() {}; +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Effects.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Effects.h new file mode 100644 index 0000000..1b50329 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Effects.h @@ -0,0 +1,848 @@ + +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from "Funky Clouds" by Stefan Petrick: https://gist.github.com/anonymous/876f908333cd95315c35 + * Portions of this code are adapted from "NoiseSmearing" by Stefan Petrick: https://gist.github.com/StefanPetrick/9ee2f677dbff64e3ba7a + * Copyright (c) 2014 Stefan Petrick + * http://www.stefan-petrick.de/wordpress_beta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Effects_H +#define Effects_H + +/* ---------------------------- GLOBAL CONSTANTS ----------------------------- */ + +const int MATRIX_CENTER_X = MATRIX_WIDTH / 2; +const int MATRIX_CENTER_Y = MATRIX_HEIGHT / 2; +// US vs GB, huh? :) +//const byte MATRIX_CENTRE_X = MATRIX_CENTER_X - 1; +//const byte MATRIX_CENTRE_Y = MATRIX_CENTER_Y - 1; +#define MATRIX_CENTRE_X MATRIX_CENTER_X +#define MATRIX_CENTRE_Y MATRIX_CENTER_Y + + +const uint16_t NUM_LEDS = (MATRIX_WIDTH * MATRIX_HEIGHT) + 1; // one led spare to capture out of bounds + +// forward declaration +uint16_t XY16( uint16_t x, uint16_t y); + +/* Convert x,y co-ordinate to flat array index. + * x and y positions start from 0, so must not be >= 'real' panel width or height + * (i.e. 64 pixels or 32 pixels.). Max value: MATRIX_WIDTH-1 etc. + * Ugh... uint8_t - really??? this weak method can't cope with 256+ pixel matrices :( + */ +uint16_t XY( uint8_t x, uint8_t y) +{ + return XY16(x, y); +} + +/** + * The one for 256+ matrices + * otherwise this: + * for (uint8_t i = 0; i < MATRIX_WIDTH; i++) {} + * turns into an infinite loop + */ +uint16_t XY16( uint16_t x, uint16_t y) +{ + if( x >= MATRIX_WIDTH) return 0; + if( y >= MATRIX_HEIGHT) return 0; + + return (y * MATRIX_WIDTH) + x + 1; // everything offset by one to compute out of bounds stuff - never displayed by ShowFrame() +} + + +uint8_t beatcos8(accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255, uint32_t timebase = 0, uint8_t phase_offset = 0) +{ + uint8_t beat = beat8(beats_per_minute, timebase); + uint8_t beatcos = cos8(beat + phase_offset); + uint8_t rangewidth = highest - lowest; + uint8_t scaledbeat = scale8(beatcos, rangewidth); + uint8_t result = lowest + scaledbeat; + return result; +} + +uint8_t mapsin8(uint8_t theta, uint8_t lowest = 0, uint8_t highest = 255) { + uint8_t beatsin = sin8(theta); + uint8_t rangewidth = highest - lowest; + uint8_t scaledbeat = scale8(beatsin, rangewidth); + uint8_t result = lowest + scaledbeat; + return result; +} + +uint8_t mapcos8(uint8_t theta, uint8_t lowest = 0, uint8_t highest = 255) { + uint8_t beatcos = cos8(theta); + uint8_t rangewidth = highest - lowest; + uint8_t scaledbeat = scale8(beatcos, rangewidth); + uint8_t result = lowest + scaledbeat; + return result; +} + +// Array of temperature readings at each simulation cell +//byte heat[NUM_LEDS]; // none of the currently enabled effects uses this + +uint32_t noise_x; +uint32_t noise_y; +uint32_t noise_z; +uint32_t noise_scale_x; +uint32_t noise_scale_y; + +//uint8_t noise[MATRIX_WIDTH][MATRIX_HEIGHT]; +uint8_t **noise = nullptr; // we will allocate mem later +uint8_t noisesmoothing; + +class Effects { +public: + CRGB *leds; + //CRGB leds[NUM_LEDS]; + //CRGB leds2[NUM_LEDS]; // Faptastic: getting rid of this and any dependant effects or algos. to save memory 24*64*32 bytes of ram (50k). + + Effects(){ + // we do dynamic allocation for leds buffer, otherwise esp32 toolchain can't link static arrays of such a big size for 256+ matrices + leds = (CRGB *)malloc(NUM_LEDS * sizeof(CRGB)); + + // allocate mem for noise effect + // (there should be some guards for malloc errors eventually) + noise = (uint8_t **)malloc(MATRIX_WIDTH * sizeof(uint8_t *)); + for (int i = 0; i < MATRIX_WIDTH; ++i) { + noise[i] = (uint8_t *)malloc(MATRIX_HEIGHT * sizeof(uint8_t)); + } + + ClearFrame(); + //dma_display->clearScreen(); + } + ~Effects(){ + free(leds); + for (int i = 0; i < MATRIX_WIDTH; ++i) { + free(noise[i]); + } + free(noise); + } + + /* The only 'framebuffer' we have is what is contained in the leds and leds2 variables. + * We don't store what the color a particular pixel might be, other than when it's turned + * into raw electrical signal output gobbly-gook (i.e. the DMA matrix buffer), but this * is not reversible. + * + * As such, any time these effects want to write a pixel color, we first have to update + * the leds or leds2 array, and THEN write it to the RGB panel. This enables us to 'look up' the array to see what a pixel color was previously, each drawFrame(). + */ + void drawBackgroundFastLEDPixelCRGB(int16_t x, int16_t y, CRGB color) + { + leds[XY(x, y)] = color; + //dma_display->drawPixelRGB888(x, y, color.r, color.g, color.b); + } + + // write one pixel with the specified color from the current palette to coordinates + void Pixel(int x, int y, uint8_t colorIndex) { + leds[XY(x, y)] = ColorFromCurrentPalette(colorIndex); + //dma_display->drawPixelRGB888(x, y, temp.r, temp.g, temp.b); // now draw it? + } + + void PrepareFrame() { + // leds = (CRGB*) backgroundLayer.backBuffer(); + } + + void ShowFrame() { + //#if (FASTLED_VERSION >= 3001000) + // nblendPaletteTowardPalette(currentPalette, targetPalette, 24); + //#else + currentPalette = targetPalette; + //#endif + + // backgroundLayer.swapBuffers(); + // leds = (CRGB*) backgroundLayer.backBuffer(); + // LEDS.countFPS(); + + for (int y=0; ydrawPixelRGB888( x, y, leds[_pixel].r, leds[_pixel].g, leds[_pixel].b); + } // end loop to copy fast led to the dma matrix + } + } + + // scale the brightness of the screenbuffer down + void DimAll(byte value) + { + for (int i = 0; i < NUM_LEDS; i++) + { + leds[i].nscale8(value); + } + } + + void ClearFrame() + { + memset(leds, 0x00, NUM_LEDS * sizeof(CRGB)); // flush + } + + + +/* + void CircleStream(uint8_t value) { + DimAll(value); ShowFrame(); + + for (uint8_t offset = 0; offset < MATRIX_CENTER_X; offset++) { + boolean hasprev = false; + uint16_t prevxy = 0; + + for (uint8_t theta = 0; theta < 255; theta++) { + uint8_t x = mapcos8(theta, offset, (MATRIX_WIDTH - 1) - offset); + uint8_t y = mapsin8(theta, offset, (MATRIX_HEIGHT - 1) - offset); + + uint16_t xy = XY(x, y); + + if (hasprev) { + leds[prevxy] += leds[xy]; + } + + prevxy = xy; + hasprev = true; + } + } + + for (uint8_t x = 0; x < MATRIX_WIDTH; x++) { + for (uint8_t y = 0; y < MATRIX_HEIGHT; y++) { + uint16_t xy = XY(x, y); + leds[xy] = leds2[xy]; + leds[xy].nscale8(value); + leds2[xy].nscale8(value); + } + } + } +*/ + + // palettes + static const int paletteCount = 10; + int paletteIndex = -1; + TBlendType currentBlendType = LINEARBLEND; + CRGBPalette16 currentPalette; + CRGBPalette16 targetPalette; + char* currentPaletteName; + + static const int HeatColorsPaletteIndex = 6; + static const int RandomPaletteIndex = 9; + + void Setup() { + currentPalette = RainbowColors_p; + loadPalette(0); + NoiseVariablesSetup(); + } + + void CyclePalette(int offset = 1) { + loadPalette(paletteIndex + offset); + } + + void RandomPalette() { + loadPalette(RandomPaletteIndex); + } + + void loadPalette(int index) { + paletteIndex = index; + + if (paletteIndex >= paletteCount) + paletteIndex = 0; + else if (paletteIndex < 0) + paletteIndex = paletteCount - 1; + + switch (paletteIndex) { + case 0: + targetPalette = RainbowColors_p; + currentPaletteName = (char *)"Rainbow"; + break; + //case 1: + // targetPalette = RainbowStripeColors_p; + // currentPaletteName = (char *)"RainbowStripe"; + // break; + case 1: + targetPalette = OceanColors_p; + currentPaletteName = (char *)"Ocean"; + break; + case 2: + targetPalette = CloudColors_p; + currentPaletteName = (char *)"Cloud"; + break; + case 3: + targetPalette = ForestColors_p; + currentPaletteName = (char *)"Forest"; + break; + case 4: + targetPalette = PartyColors_p; + currentPaletteName = (char *)"Party"; + break; + case 5: + setupGrayscalePalette(); + currentPaletteName = (char *)"Grey"; + break; + case HeatColorsPaletteIndex: + targetPalette = HeatColors_p; + currentPaletteName = (char *)"Heat"; + break; + case 7: + targetPalette = LavaColors_p; + currentPaletteName = (char *)"Lava"; + break; + case 8: + setupIcePalette(); + currentPaletteName = (char *)"Ice"; + break; + case RandomPaletteIndex: + loadPalette(random(0, paletteCount - 1)); + paletteIndex = RandomPaletteIndex; + currentPaletteName = (char *)"Random"; + break; + } + } + + void setPalette(String paletteName) { + if (paletteName == "Rainbow") + loadPalette(0); + //else if (paletteName == "RainbowStripe") + // loadPalette(1); + else if (paletteName == "Ocean") + loadPalette(1); + else if (paletteName == "Cloud") + loadPalette(2); + else if (paletteName == "Forest") + loadPalette(3); + else if (paletteName == "Party") + loadPalette(4); + else if (paletteName == "Grayscale") + loadPalette(5); + else if (paletteName == "Heat") + loadPalette(6); + else if (paletteName == "Lava") + loadPalette(7); + else if (paletteName == "Ice") + loadPalette(8); + else if (paletteName == "Random") + RandomPalette(); + } + + void listPalettes() { + Serial.println(F("{")); + Serial.print(F(" \"count\": ")); + Serial.print(paletteCount); + Serial.println(","); + Serial.println(F(" \"results\": [")); + + String paletteNames [] = { + "Rainbow", + // "RainbowStripe", + "Ocean", + "Cloud", + "Forest", + "Party", + "Grayscale", + "Heat", + "Lava", + "Ice", + "Random" + }; + + for (int i = 0; i < paletteCount; i++) { + Serial.print(F(" \"")); + Serial.print(paletteNames[i]); + if (i == paletteCount - 1) + Serial.println(F("\"")); + else + Serial.println(F("\",")); + } + + Serial.println(" ]"); + Serial.println("}"); + } + + void setupGrayscalePalette() { + targetPalette = CRGBPalette16(CRGB::Black, CRGB::White); + } + + void setupIcePalette() { + targetPalette = CRGBPalette16(CRGB::Black, CRGB::Blue, CRGB::Aqua, CRGB::White); + } + + // Oscillators and Emitters + + // the oscillators: linear ramps 0-255 + byte osci[6]; + + // sin8(osci) swinging between 0 to MATRIX_WIDTH - 1 + byte p[6]; + + // set the speeds (and by that ratios) of the oscillators here + void MoveOscillators() { + osci[0] = osci[0] + 5; + osci[1] = osci[1] + 2; + osci[2] = osci[2] + 3; + osci[3] = osci[3] + 4; + osci[4] = osci[4] + 1; + if (osci[4] % 2 == 0) + osci[5] = osci[5] + 1; // .5 + for (int i = 0; i < 4; i++) { + p[i] = map8(sin8(osci[i]), 0, MATRIX_WIDTH - 1); //why? to keep the result in the range of 0-MATRIX_WIDTH (matrix size) + } + } + + + // All the caleidoscope functions work directly within the screenbuffer (leds array). + // Draw whatever you like in the area x(0-15) and y (0-15) and then copy it arround. + + // rotates the first 16x16 quadrant 3 times onto a 32x32 (+90 degrees rotation for each one) + void Caleidoscope1() { + for (int x = 0; x < MATRIX_CENTER_X; x++) { + for (int y = 0; y < MATRIX_CENTER_Y; y++) { + leds[XY16(MATRIX_WIDTH - 1 - x, y)] = leds[XY16(x, y)]; + leds[XY16(MATRIX_WIDTH - 1 - x, MATRIX_HEIGHT - 1 - y)] = leds[XY16(x, y)]; + leds[XY16(x, MATRIX_HEIGHT - 1 - y)] = leds[XY16(x, y)]; + } + } + } + + + // mirror the first 16x16 quadrant 3 times onto a 32x32 + void Caleidoscope2() { + for (int x = 0; x < MATRIX_CENTER_X; x++) { + for (int y = 0; y < MATRIX_CENTER_Y; y++) { + leds[XY16(MATRIX_WIDTH - 1 - x, y)] = leds[XY16(y, x)]; + leds[XY16(x, MATRIX_HEIGHT - 1 - y)] = leds[XY16(y, x)]; + leds[XY16(MATRIX_WIDTH - 1 - x, MATRIX_HEIGHT - 1 - y)] = leds[XY16(x, y)]; + } + } + } + + // copy one diagonal triangle into the other one within a 16x16 + void Caleidoscope3() { + for (int x = 0; x <= MATRIX_CENTRE_X && x < MATRIX_HEIGHT; x++) { + for (int y = 0; y <= x && y= 0; y--) { + leds[XY16(x, y)] = leds[XY16(y, x)]; + } + } + } + + void Caleidoscope6() { + for (int x = 1; x < MATRIX_CENTER_X; x++) { + leds[XY16(7 - x, 7)] = leds[XY16(x, 0)]; + } //a + for (int x = 2; x < MATRIX_CENTER_X; x++) { + leds[XY16(7 - x, 6)] = leds[XY16(x, 1)]; + } //b + for (int x = 3; x < MATRIX_CENTER_X; x++) { + leds[XY16(7 - x, 5)] = leds[XY16(x, 2)]; + } //c + for (int x = 4; x < MATRIX_CENTER_X; x++) { + leds[XY16(7 - x, 4)] = leds[XY16(x, 3)]; + } //d + for (int x = 5; x < MATRIX_CENTER_X; x++) { + leds[XY16(7 - x, 3)] = leds[XY16(x, 4)]; + } //e + for (int x = 6; x < MATRIX_CENTER_X; x++) { + leds[XY16(7 - x, 2)] = leds[XY16(x, 5)]; + } //f + for (int x = 7; x < MATRIX_CENTER_X; x++) { + leds[XY16(7 - x, 1)] = leds[XY16(x, 6)]; + } //g + } + + // create a square twister to the left or counter-clockwise + // x and y for center, r for radius + void SpiralStream(int x, int y, int r, byte dimm) { + for (int d = r; d >= 0; d--) { // from the outside to the inside + for (int i = x - d; i <= x + d; i++) { + leds[XY16(i, y - d)] += leds[XY16(i + 1, y - d)]; // lowest row to the right + leds[XY16(i, y - d)].nscale8(dimm); + } + for (int i = y - d; i <= y + d; i++) { + leds[XY16(x + d, i)] += leds[XY16(x + d, i + 1)]; // right column up + leds[XY16(x + d, i)].nscale8(dimm); + } + for (int i = x + d; i >= x - d; i--) { + leds[XY16(i, y + d)] += leds[XY16(i - 1, y + d)]; // upper row to the left + leds[XY16(i, y + d)].nscale8(dimm); + } + for (int i = y + d; i >= y - d; i--) { + leds[XY16(x - d, i)] += leds[XY16(x - d, i - 1)]; // left column down + leds[XY16(x - d, i)].nscale8(dimm); + } + } + } + + // expand everything within a circle + void Expand(int centerX, int centerY, int radius, byte dimm) { + if (radius == 0) + return; + + int currentRadius = radius; + + while (currentRadius > 0) { + int a = radius, b = 0; + int radiusError = 1 - a; + + int nextRadius = currentRadius - 1; + int nextA = nextRadius - 1, nextB = 0; + int nextRadiusError = 1 - nextA; + + while (a >= b) + { + // move them out one pixel on the radius + leds[XY16(a + centerX, b + centerY)] = leds[XY16(nextA + centerX, nextB + centerY)]; + leds[XY16(b + centerX, a + centerY)] = leds[XY16(nextB + centerX, nextA + centerY)]; + leds[XY16(-a + centerX, b + centerY)] = leds[XY16(-nextA + centerX, nextB + centerY)]; + leds[XY16(-b + centerX, a + centerY)] = leds[XY16(-nextB + centerX, nextA + centerY)]; + leds[XY16(-a + centerX, -b + centerY)] = leds[XY16(-nextA + centerX, -nextB + centerY)]; + leds[XY16(-b + centerX, -a + centerY)] = leds[XY16(-nextB + centerX, -nextA + centerY)]; + leds[XY16(a + centerX, -b + centerY)] = leds[XY16(nextA + centerX, -nextB + centerY)]; + leds[XY16(b + centerX, -a + centerY)] = leds[XY16(nextB + centerX, -nextA + centerY)]; + + // dim them + leds[XY16(a + centerX, b + centerY)].nscale8(dimm); + leds[XY16(b + centerX, a + centerY)].nscale8(dimm); + leds[XY16(-a + centerX, b + centerY)].nscale8(dimm); + leds[XY16(-b + centerX, a + centerY)].nscale8(dimm); + leds[XY16(-a + centerX, -b + centerY)].nscale8(dimm); + leds[XY16(-b + centerX, -a + centerY)].nscale8(dimm); + leds[XY16(a + centerX, -b + centerY)].nscale8(dimm); + leds[XY16(b + centerX, -a + centerY)].nscale8(dimm); + + b++; + if (radiusError < 0) + radiusError += 2 * b + 1; + else + { + a--; + radiusError += 2 * (b - a + 1); + } + + nextB++; + if (nextRadiusError < 0) + nextRadiusError += 2 * nextB + 1; + else + { + nextA--; + nextRadiusError += 2 * (nextB - nextA + 1); + } + } + + currentRadius--; + } + } + + // give it a linear tail to the right + void StreamRight(byte scale, int fromX = 0, int toX = MATRIX_WIDTH, int fromY = 0, int toY = MATRIX_HEIGHT) + { + for (int x = fromX + 1; x < toX; x++) { + for (int y = fromY; y < toY; y++) { + leds[XY16(x, y)] += leds[XY16(x - 1, y)]; + leds[XY16(x, y)].nscale8(scale); + } + } + for (int y = fromY; y < toY; y++) + leds[XY16(0, y)].nscale8(scale); + } + + // give it a linear tail to the left + void StreamLeft(byte scale, int fromX = MATRIX_WIDTH, int toX = 0, int fromY = 0, int toY = MATRIX_HEIGHT) + { + for (int x = toX; x < fromX; x++) { + for (int y = fromY; y < toY; y++) { + leds[XY16(x, y)] += leds[XY16(x + 1, y)]; + leds[XY16(x, y)].nscale8(scale); + } + } + for (int y = fromY; y < toY; y++) + leds[XY16(0, y)].nscale8(scale); + } + + // give it a linear tail downwards + void StreamDown(byte scale) + { + for (int x = 0; x < MATRIX_WIDTH; x++) { + for (int y = 1; y < MATRIX_HEIGHT; y++) { + leds[XY16(x, y)] += leds[XY16(x, y - 1)]; + leds[XY16(x, y)].nscale8(scale); + } + } + for (int x = 0; x < MATRIX_WIDTH; x++) + leds[XY16(x, 0)].nscale8(scale); + } + + // give it a linear tail upwards + void StreamUp(byte scale) + { + for (int x = 0; x < MATRIX_WIDTH; x++) { + for (int y = MATRIX_HEIGHT - 2; y >= 0; y--) { + leds[XY16(x, y)] += leds[XY16(x, y + 1)]; + leds[XY16(x, y)].nscale8(scale); + } + } + for (int x = 0; x < MATRIX_WIDTH; x++) + leds[XY16(x, MATRIX_HEIGHT - 1)].nscale8(scale); + } + + // give it a linear tail up and to the left + void StreamUpAndLeft(byte scale) + { + for (int x = 0; x < MATRIX_WIDTH - 1; x++) { + for (int y = MATRIX_HEIGHT - 2; y >= 0; y--) { + leds[XY16(x, y)] += leds[XY16(x + 1, y + 1)]; + leds[XY16(x, y)].nscale8(scale); + } + } + for (int x = 0; x < MATRIX_WIDTH; x++) + leds[XY16(x, MATRIX_HEIGHT - 1)].nscale8(scale); + for (int y = 0; y < MATRIX_HEIGHT; y++) + leds[XY16(MATRIX_WIDTH - 1, y)].nscale8(scale); + } + + // give it a linear tail up and to the right + void StreamUpAndRight(byte scale) + { + for (int x = 0; x < MATRIX_WIDTH - 1; x++) { + for (int y = MATRIX_HEIGHT - 2; y >= 0; y--) { + leds[XY16(x + 1, y)] += leds[XY16(x, y + 1)]; + leds[XY16(x, y)].nscale8(scale); + } + } + // fade the bottom row + for (int x = 0; x < MATRIX_WIDTH; x++) + leds[XY16(x, MATRIX_HEIGHT - 1)].nscale8(scale); + + // fade the right column + for (int y = 0; y < MATRIX_HEIGHT; y++) + leds[XY16(MATRIX_WIDTH - 1, y)].nscale8(scale); + } + + // just move everything one line down + void MoveDown() { + for (int y = MATRIX_HEIGHT - 1; y > 0; y--) { + for (int x = 0; x < MATRIX_WIDTH; x++) { + leds[XY16(x, y)] = leds[XY16(x, y - 1)]; + } + } + } + + // just move everything one line down + void VerticalMoveFrom(int start, int end) { + for (int y = end; y > start; y--) { + for (int x = 0; x < MATRIX_WIDTH; x++) { + leds[XY16(x, y)] = leds[XY16(x, y - 1)]; + } + } + } + + // copy the rectangle defined with 2 points x0, y0, x1, y1 + // to the rectangle beginning at x2, x3 + void Copy(byte x0, byte y0, byte x1, byte y1, byte x2, byte y2) { + for (int y = y0; y < y1 + 1; y++) { + for (int x = x0; x < x1 + 1; x++) { + leds[XY16(x + x2 - x0, y + y2 - y0)] = leds[XY16(x, y)]; + } + } + } + + // rotate + copy triangle (MATRIX_CENTER_X*MATRIX_CENTER_X) + void RotateTriangle() { + for (int x = 1; x < MATRIX_CENTER_X; x++) { + for (int y = 0; y < x; y++) { + leds[XY16(x, 7 - y)] = leds[XY16(7 - x, y)]; + } + } + } + + // mirror + copy triangle (MATRIX_CENTER_X*MATRIX_CENTER_X) + void MirrorTriangle() { + for (int x = 1; x < MATRIX_CENTER_X; x++) { + for (int y = 0; y < x; y++) { + leds[XY16(7 - y, x)] = leds[XY16(7 - x, y)]; + } + } + } + + // draw static rainbow triangle pattern (MATRIX_CENTER_XxWIDTH / 2) + // (just for debugging) + void RainbowTriangle() { + for (int i = 0; i < MATRIX_CENTER_X; i++) { + for (int j = 0; j <= i; j++) { + Pixel(7 - i, j, i * j * 4); + } + } + } + + void BresenhamLine(int x0, int y0, int x1, int y1, byte colorIndex) + { + BresenhamLine(x0, y0, x1, y1, ColorFromCurrentPalette(colorIndex)); + } + + void BresenhamLine(int x0, int y0, int x1, int y1, CRGB color) + { + int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; + int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1; + int err = dx + dy, e2; + for (;;) { + leds[XY16(x0, y0)] += color; + if (x0 == x1 && y0 == y1) break; + e2 = 2 * err; + if (e2 > dy) { + err += dy; + x0 += sx; + } + if (e2 < dx) { + err += dx; + y0 += sy; + } + } + } + + + CRGB ColorFromCurrentPalette(uint8_t index = 0, uint8_t brightness = 255, TBlendType blendType = LINEARBLEND) { + return ColorFromPalette(currentPalette, index, brightness, currentBlendType); + } + + CRGB HsvToRgb(uint8_t h, uint8_t s, uint8_t v) { + CHSV hsv = CHSV(h, s, v); + CRGB rgb; + hsv2rgb_spectrum(hsv, rgb); + return rgb; + } + + void NoiseVariablesSetup() { + noisesmoothing = 200; + + noise_x = random16(); + noise_y = random16(); + noise_z = random16(); + noise_scale_x = 6000; + noise_scale_y = 6000; + } + + void FillNoise() { + for (uint16_t i = 0; i < MATRIX_WIDTH; i++) { + uint32_t ioffset = noise_scale_x * (i - MATRIX_CENTRE_Y); + + for (uint16_t j = 0; j < MATRIX_HEIGHT; j++) { + uint32_t joffset = noise_scale_y * (j - MATRIX_CENTRE_Y); + + byte data = inoise16(noise_x + ioffset, noise_y + joffset, noise_z) >> 8; + + uint8_t olddata = noise[i][j]; + uint8_t newdata = scale8(olddata, noisesmoothing) + scale8(data, 256 - noisesmoothing); + data = newdata; + + noise[i][j] = data; + } + } + } + + // non leds2 memory version. + void MoveX(byte delta) + { + + CRGB tmp = 0; + + for (int y = 0; y < MATRIX_HEIGHT; y++) + { + + // Shift Left: https://codedost.com/c/arraypointers-in-c/c-program-shift-elements-array-left-direction/ + // Computationally heavier but doesn't need an entire leds2 array + + tmp = leds[XY16(0, y)]; + for (int m = 0; m < delta; m++) + { + // Do this delta time for each row... computationally expensive potentially. + for(int x = 0; x < MATRIX_WIDTH; x++) + { + leds[XY16(x, y)] = leds [XY16(x+1, y)]; + } + + leds[XY16(MATRIX_WIDTH-1, y)] = tmp; + } + + + /* + // Shift + for (int x = 0; x < MATRIX_WIDTH - delta; x++) { + leds2[XY(x, y)] = leds[XY(x + delta, y)]; + } + + // Wrap around + for (int x = MATRIX_WIDTH - delta; x < MATRIX_WIDTH; x++) { + leds2[XY(x, y)] = leds[XY(x + delta - MATRIX_WIDTH, y)]; + } + */ + } // end row loop + + /* + // write back to leds + for (uint8_t y = 0; y < MATRIX_HEIGHT; y++) { + for (uint8_t x = 0; x < MATRIX_WIDTH; x++) { + leds[XY(x, y)] = leds2[XY(x, y)]; + } + } + */ + } + + void MoveY(byte delta) + { + + CRGB tmp = 0; + for (int x = 0; x < MATRIX_WIDTH; x++) + { + tmp = leds[XY16(x, 0)]; + for (int m = 0; m < delta; m++) // moves + { + // Do this delta time for each row... computationally expensive potentially. + for(int y = 0; y < MATRIX_HEIGHT; y++) + { + leds[XY16(x, y)] = leds [XY16(x, y+1)]; + } + + leds[XY16(x, MATRIX_HEIGHT-1)] = tmp; + } + } // end column loop + } /// MoveY + + +}; + +#endif \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Geometry.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Geometry.h new file mode 100644 index 0000000..4e47557 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Geometry.h @@ -0,0 +1,150 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from Noel Bundy's work: https://github.com/TwystNeko/Object3d + * Copyright (c) 2014 Noel Bundy + * + * Portions of this code are adapted from the Petty library: https://code.google.com/p/peggy/ + * Copyright (c) 2008 Windell H Oskay. All right reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Geometry_H +#define Geometry_H + +struct Vertex +{ + float x, y, z; + Vertex() + { + this->set(0, 0, 0); + } + + Vertex(float x, float y, float z) + { + this->set(x, y, z); + } + + void set(float x, float y, float z) + { + this->x = x; + this->y = y; + this->z = z; + } +}; + +struct EdgePoint +{ + int x, y; + boolean visible; + + EdgePoint() + { + this->set(0, 0); + this->visible = false; + } + + void set(int a, int b) + { + this->x = a; + this->y = b; + } +}; + +struct Point +{ + float x, y; + + Point() + { + set(0, 0); + } + + Point(float x, float y) + { + set(x, y); + } + + void set(float x, float y) + { + this->x = x; + this->y = y; + } + +}; + +struct squareFace +{ + int length; + int sommets[4]; + int ed[4]; + + squareFace() + { + set(-1, -1, -1, -1); + } + + squareFace(int a, int b, int c, int d) + { + this->length = 4; + this->sommets[0] = a; + this->sommets[1] = b; + this->sommets[2] = c; + this->sommets[3] = d; + } + + void set(int a, int b, int c, int d) + { + this->length = 4; + this->sommets[0] = a; + this->sommets[1] = b; + this->sommets[2] = c; + this->sommets[3] = d; + } + +}; + +struct triFace +{ + int length; + int sommets[3]; + int ed[3]; + + triFace() + { + set(-1,-1,-1); + } + triFace(int a, int b, int c) + { + this->length =3; + this->sommets[0]=a; + this->sommets[1]=b; + this->sommets[2]=c; + } + void set(int a, int b, int c) + { + this->length =3; + this->sommets[0]=a; + this->sommets[1]=b; + this->sommets[2]=c; + } +}; + +#endif \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternAttract.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternAttract.h new file mode 100644 index 0000000..dcb6491 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternAttract.h @@ -0,0 +1,74 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternAttract_H + +class PatternAttract : public Drawable { +private: + const int count = 8; + Attractor attractor; + +public: + PatternAttract() { + name = (char *)"Attract"; + } + + void start() { + int direction = random(0, 2); + if (direction == 0) + direction = -1; + + for (int i = 0; i < count; i++) { + Boid boid = Boid(15, 31 - i); + boid.mass = 1; // random(0.1, 2); + boid.velocity.x = ((float) random(40, 50)) / 100.0; + boid.velocity.x *= direction; + boid.velocity.y = 0; + boid.colorIndex = i * 32; + boids[i] = boid; + //dim = random(170, 250); + } + } + + unsigned int drawFrame() { + // dim all pixels on the display + uint8_t dim = beatsin8(2, 170, 250); + effects.DimAll(dim); + + for (int i = 0; i < count; i++) { + Boid boid = boids[i]; + + PVector force = attractor.attract(boid); + boid.applyForce(force); + + boid.update(); + effects.drawBackgroundFastLEDPixelCRGB(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex)); + + boids[i] = boid; + } + + effects.ShowFrame(); + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternBounce.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternBounce.h new file mode 100644 index 0000000..7340514 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternBounce.h @@ -0,0 +1,73 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternBounce_H + +class PatternBounce : public Drawable { +private: + static const int count = 32; + PVector gravity = PVector(0, 0.0125); + +public: + PatternBounce() { + name = (char *)"Bounce"; + } + + void start() { + unsigned int colorWidth = 256 / count; + for (int i = 0; i < count; i++) { + Boid boid = Boid(i, 0); + boid.velocity.x = 0; + boid.velocity.y = i * -0.01; + boid.colorIndex = colorWidth * i; + boid.maxforce = 10; + boid.maxspeed = 10; + boids[i] = boid; + } + } + + unsigned int drawFrame() { + // dim all pixels on the display + effects.DimAll(170); effects.ShowFrame(); + + for (int i = 0; i < count; i++) { + Boid boid = boids[i]; + + boid.applyForce(gravity); + + boid.update(); + + effects.drawBackgroundFastLEDPixelCRGB(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex)); + + if (boid.location.y >= MATRIX_HEIGHT - 1) { + boid.location.y = MATRIX_HEIGHT - 1; + boid.velocity.y *= -1.0; + } + + boids[i] = boid; + } + + return 15; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternCube.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternCube.h new file mode 100644 index 0000000..f2c60bc --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternCube.h @@ -0,0 +1,219 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from Noel Bundy's work: https://github.com/TwystNeko/Object3d + * Copyright (c) 2014 Noel Bundy + * + * Portions of this code are adapted from the Petty library: https://code.google.com/p/peggy/ + * Copyright (c) 2008 Windell H Oskay. All right reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternCube_H +#define PatternCube_H + +class PatternCube : public Drawable { + private: + float focal = 30; // Focal of the camera + int cubeWidth = 28; // Cube size + float Angx = 20.0, AngxSpeed = 0.05; // rotation (angle+speed) around X-axis + float Angy = 10.0, AngySpeed = 0.05; // rotation (angle+speed) around Y-axis + float Ox = 15.5, Oy = 15.5; // position (x,y) of the frame center + int zCamera = 110; // distance from cube to the eye of the camera + + // Local vertices + Vertex local[8]; + // Camera aligned vertices + Vertex aligned[8]; + // On-screen projected vertices + Point screen[8]; + // Faces + squareFace face[6]; + // Edges + EdgePoint edge[12]; + int nbEdges; + // ModelView matrix + float m00, m01, m02, m10, m11, m12, m20, m21, m22; + + // constructs the cube + void make(int w) + { + nbEdges = 0; + + local[0].set(-w, w, w); + local[1].set(w, w, w); + local[2].set(w, -w, w); + local[3].set(-w, -w, w); + local[4].set(-w, w, -w); + local[5].set(w, w, -w); + local[6].set(w, -w, -w); + local[7].set(-w, -w, -w); + + face[0].set(1, 0, 3, 2); + face[1].set(0, 4, 7, 3); + face[2].set(4, 0, 1, 5); + face[3].set(4, 5, 6, 7); + face[4].set(1, 2, 6, 5); + face[5].set(2, 3, 7, 6); + + int f, i; + for (f = 0; f < 6; f++) + { + for (i = 0; i < face[f].length; i++) + { + face[f].ed[i] = this->findEdge(face[f].sommets[i], face[f].sommets[i ? i - 1 : face[f].length - 1]); + } + } + } + + // finds edges from faces + int findEdge(int a, int b) + { + int i; + for (i = 0; i < nbEdges; i++) + if ((edge[i].x == a && edge[i].y == b) || (edge[i].x == b && edge[i].y == a)) + return i; + edge[nbEdges++].set(a, b); + return i; + } + + // rotates according to angle x&y + void rotate(float angx, float angy) + { + int i; + float cx = cos(angx); + float sx = sin(angx); + float cy = cos(angy); + float sy = sin(angy); + + m00 = cy; + m01 = 0; + m02 = -sy; + m10 = sx * sy; + m11 = cx; + m12 = sx * cy; + m20 = cx * sy; + m21 = -sx; + m22 = cx * cy; + + for (i = 0; i < 8; i++) + { + aligned[i].x = m00 * local[i].x + m01 * local[i].y + m02 * local[i].z; + aligned[i].y = m10 * local[i].x + m11 * local[i].y + m12 * local[i].z; + aligned[i].z = m20 * local[i].x + m21 * local[i].y + m22 * local[i].z + zCamera; + + screen[i].x = floor((Ox + focal * aligned[i].x / aligned[i].z)); + screen[i].y = floor((Oy - focal * aligned[i].y / aligned[i].z)); + } + + for (i = 0; i < 12; i++) + edge[i].visible = false; + + Point *pa, *pb, *pc; + for (i = 0; i < 6; i++) + { + pa = screen + face[i].sommets[0]; + pb = screen + face[i].sommets[1]; + pc = screen + face[i].sommets[2]; + + boolean back = ((pb->x - pa->x) * (pc->y - pa->y) - (pb->y - pa->y) * (pc->x - pa->x)) < 0; + if (!back) + { + int j; + for (j = 0; j < 4; j++) + { + edge[face[i].ed[j]].visible = true; + } + } + } + } + + byte hue = 0; + int step = 0; + + public: + PatternCube() { + name = (char *)"Cube"; + make(cubeWidth); + } + + unsigned int drawFrame() { + uint8_t blurAmount = beatsin8(2, 10, 255); + +#if FASTLED_VERSION >= 3001000 + blur2d(effects.leds, MATRIX_WIDTH, MATRIX_HEIGHT, blurAmount); +#else + effects.DimAll(blurAmount); effects.ShowFrame(); +#endif + + zCamera = beatsin8(2, 100, 140); + AngxSpeed = beatsin8(3, 1, 10) / 100.0f; + AngySpeed = beatcos8(5, 1, 10) / 100.0f; + + // Update values + Angx += AngxSpeed; + Angy += AngySpeed; + if (Angx >= TWO_PI) + Angx -= TWO_PI; + if (Angy >= TWO_PI) + Angy -= TWO_PI; + + rotate(Angx, Angy); + + // Draw cube + int i; + + CRGB color = effects.ColorFromCurrentPalette(hue, 128); + + // Backface + EdgePoint *e; + for (i = 0; i < 12; i++) + { + e = edge + i; + if (!e->visible) { + dma_display->drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color); + } + } + + color = effects.ColorFromCurrentPalette(hue, 255); + + // Frontface + for (i = 0; i < 12; i++) + { + e = edge + i; + if (e->visible) + { + dma_display->drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color); + } + } + + step++; + if (step == 8) { + step = 0; + hue++; + } + + effects.ShowFrame(); + + return 20; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternElectricMandala.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternElectricMandala.h new file mode 100644 index 0000000..880de25 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternElectricMandala.h @@ -0,0 +1,116 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from "Funky Noise" by Stefan Petrick: https://github.com/StefanPetrick/FunkyNoise + * Copyright (c) 2014 Stefan Petrick + * http://www.stefan-petrick.de/wordpress_beta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternElectricMandala_H + +class PatternElectricMandala : public Drawable { + private: + + // The coordinates for 16-bit noise spaces. +#define NUM_LAYERS 1 + + // used for the random based animations + int16_t dx; + int16_t dy; + int16_t dz; + int16_t dsx; + int16_t dsy; + + public: + PatternElectricMandala() { + name = (char *)"ElectricMandala"; + } + + void start() { + // set to reasonable values to avoid a black out + noisesmoothing = 200; + + // just any free input pin + //random16_add_entropy(analogRead(18)); + + // fill coordinates with random values + // set zoom levels + noise_x = random16(); + noise_y = random16(); + noise_z = random16(); + noise_scale_x = 6000; + noise_scale_y = 6000; + + // for the random movement + dx = random8(); + dy = random8(); + dz = random8(); + dsx = random8(); + dsy = random8(); + } + + unsigned int drawFrame() { +#if FASTLED_VERSION >= 3001000 + // a new parameter set every 15 seconds + EVERY_N_SECONDS(15) { + //SetupRandomPalette3(); + dy = random16(500) - 250; // random16(2000) - 1000 is pretty fast but works fine, too + dx = random16(500) - 250; + dz = random16(500) - 250; + noise_scale_x = random16(10000) + 2000; + noise_scale_y = random16(10000) + 2000; + } +#endif + + noise_y += dy; + noise_x += dx; + noise_z += dz; + + effects.FillNoise(); + ShowNoiseLayer(0, 1, 0); + + effects.Caleidoscope3(); + effects.Caleidoscope1(); + + effects.ShowFrame(); + + return 30; + } + + // show just one layer + void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) { + for (uint16_t i = 0; i < MATRIX_WIDTH; i++) { + for (uint16_t j = 0; j < MATRIX_HEIGHT; j++) { + + uint8_t color = noise[i][j]; + + uint8_t bri = color; + + // assign a color depending on the actual palette + CRGB pixel = ColorFromPalette(effects.currentPalette, colorrepeat * (color + colorshift), bri); + + effects.leds[XY16(i, j)] = pixel; + } + } + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternFire.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternFire.h new file mode 100644 index 0000000..83aa67c --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternFire.h @@ -0,0 +1,118 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/tree/master/examples/Fire2012WithPalette + * Copyright (c) 2013 FastLED + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternFire_H +#define PatternFire_H + +#ifndef Effects_H +#include "Effects.h" +#endif + +class PatternFire : public Drawable { + private: + + public: + PatternFire() { + name = (char *)"Fire"; + } + + // There are two main parameters you can play with to control the look and + // feel of your fire: COOLING (used in step 1 above), and SPARKING (used + // in step 3 above). + // + // cooling: How much does the air cool as it rises? + // Less cooling = taller flames. More cooling = shorter flames. + // Default 55, suggested range 20-100 + int cooling = 100; + + // sparking: What chance (out of 255) is there that a new spark will be lit? + // Higher chance = more roaring fire. Lower chance = more flickery fire. + // Default 120, suggested range 50-200. + unsigned int sparking = 100; + + unsigned int drawFrame() { + // Add entropy to random number generator; we use a lot of it. + random16_add_entropy( random16()); + + effects.DimAll(235); + + for (int x = 0; x < MATRIX_WIDTH; x++) { + // Step 1. Cool down every cell a little + for (int y = 0; y < MATRIX_HEIGHT; y++) { + int xy = XY(x, y); + heat[xy] = qsub8(heat[xy], random8(0, ((cooling * 10) / MATRIX_HEIGHT) + 2)); + } + + // Step 2. Heat from each cell drifts 'up' and diffuses a little + for (int y = 0; y < MATRIX_HEIGHT; y++) { + heat[XY(x, y)] = (heat[XY(x, y + 1)] + heat[XY(x, y + 2)] + heat[XY(x, y + 2)]) / 3; + } + + // Step 2. Randomly ignite new 'sparks' of heat + if (random8() < sparking) { + // int x = (p[0] + p[1] + p[2]) / 3; + + int xy = XY(x, MATRIX_HEIGHT - 1); + heat[xy] = qadd8(heat[xy], random8(160, 255)); + } + + // Step 4. Map from heat cells to LED colors + for (int y = 0; y < MATRIX_HEIGHT; y++) { + int xy = XY(x, y); + byte colorIndex = heat[xy]; + + // Recommend that you use values 0-240 rather than + // the usual 0-255, as the last 15 colors will be + // 'wrapping around' from the hot end to the cold end, + // which looks wrong. + colorIndex = scale8(colorIndex, 200); + + // override color 0 to ensure a black background? + if (colorIndex != 0) + // effects.leds[xy] = CRGB::Black; + // else + effects.leds[xy] = effects.ColorFromCurrentPalette(colorIndex); + } + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(2); + effects.MoveFractionalNoiseX(2); + + + effects.ShowFrame(); + + return 15; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternFlock.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternFlock.h new file mode 100644 index 0000000..3ae31b1 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternFlock.h @@ -0,0 +1,125 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from "Flocking" in "The Nature of Code" by Daniel Shiffman: http://natureofcode.com/ + * Copyright (c) 2014 Daniel Shiffman + * http://www.shiffman.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +// Flocking +// Daniel Shiffman +// The Nature of Code, Spring 2009 + +// Demonstration of Craig Reynolds' "Flocking" behavior +// See: http://www.red3d.com/cwr/ +// Rules: Cohesion, Separation, Alignment + +#ifndef PatternFlock_H +#define PatternFlock_H + +class PatternFlock : public Drawable { + public: + PatternFlock() { + name = (char *)"Flock"; + } + + static const int boidCount = 10; + Boid predator; + + PVector wind; + byte hue = 0; + bool predatorPresent = true; + + void start() { + for (int i = 0; i < boidCount; i++) { + boids[i] = Boid(15, 15); + boids[i].maxspeed = 0.380; + boids[i].maxforce = 0.015; + } + + predatorPresent = random(0, 2) >= 1; + if (predatorPresent) { + predator = Boid(31, 31); + predatorPresent = true; + predator.maxspeed = 0.385; + predator.maxforce = 0.020; + predator.neighbordist = 16.0; + predator.desiredseparation = 0.0; + } + } + + unsigned int drawFrame() { + effects.DimAll(230); effects.ShowFrame(); + + bool applyWind = random(0, 255) > 250; + if (applyWind) { + wind.x = Boid::randomf() * .015; + wind.y = Boid::randomf() * .015; + } + + CRGB color = effects.ColorFromCurrentPalette(hue); + + for (int i = 0; i < boidCount; i++) { + Boid * boid = &boids[i]; + + if (predatorPresent) { + // flee from predator + boid->repelForce(predator.location, 10); + } + + boid->run(boids, boidCount); + boid->wrapAroundBorders(); + PVector location = boid->location; + // PVector velocity = boid->velocity; + // backgroundLayer.drawLine(location.x, location.y, location.x - velocity.x, location.y - velocity.y, color); + // effects.leds[XY(location.x, location.y)] += color; + effects.drawBackgroundFastLEDPixelCRGB(location.x, location.y, color); + + if (applyWind) { + boid->applyForce(wind); + applyWind = false; + } + } + + if (predatorPresent) { + predator.run(boids, boidCount); + predator.wrapAroundBorders(); + color = effects.ColorFromCurrentPalette(hue + 128); + PVector location = predator.location; + // PVector velocity = predator.velocity; + // backgroundLayer.drawLine(location.x, location.y, location.x - velocity.x, location.y - velocity.y, color); + // effects.leds[XY(location.x, location.y)] += color; + effects.drawBackgroundFastLEDPixelCRGB(location.x, location.y, color); + } + + EVERY_N_MILLIS(200) { + hue++; + } + + EVERY_N_SECONDS(30) { + predatorPresent = !predatorPresent; + } + + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternFlowField.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternFlowField.h new file mode 100644 index 0000000..38f1083 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternFlowField.h @@ -0,0 +1,92 @@ +/* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternFlowField_H + +class PatternFlowField : public Drawable { + public: + PatternFlowField() { + name = (char *)"FlowField"; + } + + uint16_t x; + uint16_t y; + uint16_t z; + + uint16_t speed = 1; + uint16_t scale = 26; + + static const int count = 40; + + byte hue = 0; + + void start() { + x = random16(); + y = random16(); + z = random16(); + + for (int i = 0; i < count; i++) { + boids[i] = Boid(random(MATRIX_WIDTH), 0); + } + } + + unsigned int drawFrame() { + effects.DimAll(240); + + // CRGB color = effects.ColorFromCurrentPalette(hue); + + for (int i = 0; i < count; i++) { + Boid * boid = &boids[i]; + + int ioffset = scale * boid->location.x; + int joffset = scale * boid->location.y; + + byte angle = inoise8(x + ioffset, y + joffset, z); + + boid->velocity.x = (float) sin8(angle) * 0.0078125 - 1.0; + boid->velocity.y = -((float)cos8(angle) * 0.0078125 - 1.0); + boid->update(); + + effects.drawBackgroundFastLEDPixelCRGB(boid->location.x, boid->location.y, effects.ColorFromCurrentPalette(angle + hue)); // color + + if (boid->location.x < 0 || boid->location.x >= MATRIX_WIDTH || + boid->location.y < 0 || boid->location.y >= MATRIX_HEIGHT) { + boid->location.x = random(MATRIX_WIDTH); + boid->location.y = 0; + } + } + + EVERY_N_MILLIS(200) { + hue++; + } + + x += speed; + y += speed; + z += speed; + + effects.ShowFrame(); + + return 50; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternIncrementalDrift.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternIncrementalDrift.h new file mode 100644 index 0000000..f68c04f --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternIncrementalDrift.h @@ -0,0 +1,51 @@ +/* +* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternIncrementalDrift_H +#define PatternIncrementalDrift_H + +class PatternIncrementalDrift : public Drawable { + public: + PatternIncrementalDrift() { + name = (char *)"Incremental Drift"; + } + + unsigned int drawFrame() { + uint8_t dim = beatsin8(2, 230, 250); + effects.DimAll(dim); effects.ShowFrame(); + + for (int i = 2; i <= MATRIX_WIDTH / 2; i++) + { + CRGB color = effects.ColorFromCurrentPalette((i - 2) * (240 / (MATRIX_WIDTH / 2))); + + uint8_t x = beatcos8((17 - i) * 2, MATRIX_CENTER_X - i, MATRIX_CENTER_X + i); + uint8_t y = beatsin8((17 - i) * 2, MATRIX_CENTER_Y - i, MATRIX_CENTER_Y + i); + + effects.drawBackgroundFastLEDPixelCRGB(x, y, color); + } + + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternIncrementalDrift2.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternIncrementalDrift2.h new file mode 100644 index 0000000..0ce06c2 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternIncrementalDrift2.h @@ -0,0 +1,63 @@ +/* +* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternIncrementalDrift2_H +#define PatternIncrementalDrift2_H + +class PatternIncrementalDrift2 : public Drawable { + public: + PatternIncrementalDrift2() { + name = (char *)"Incremental Drift Rose"; + } + + unsigned int drawFrame() { + uint8_t dim = beatsin8(2, 170, 250); + effects.DimAll(dim); effects.ShowFrame(); + + for (uint8_t i = 0; i < 32; i++) + { + CRGB color; + + uint8_t x = 0; + uint8_t y = 0; + + if (i < 16) { + x = beatcos8((i + 1) * 2, i, MATRIX_WIDTH - i); + y = beatsin8((i + 1) * 2, i, MATRIX_HEIGHT - i); + color = effects.ColorFromCurrentPalette(i * 14); + } + else + { + x = beatsin8((32 - i) * 2, MATRIX_WIDTH - i, i + 1); + y = beatcos8((32 - i) * 2, MATRIX_HEIGHT - i, i + 1); + color = effects.ColorFromCurrentPalette((31 - i) * 14); + } + + effects.drawBackgroundFastLEDPixelCRGB(x, y, color); + } + + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternInfinity.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternInfinity.h new file mode 100644 index 0000000..0c068ad --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternInfinity.h @@ -0,0 +1,61 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternInfinity_H + +class PatternInfinity : public Drawable { +public: + PatternInfinity() { + name = (char *)"Infinity"; + } + + unsigned int drawFrame() { + // dim all pixels on the display slightly + // to 250/255 (98%) of their current brightness + blur2d(effects.leds, MATRIX_WIDTH > 255 ? 255 : MATRIX_WIDTH, MATRIX_HEIGHT > 255 ? 255 : MATRIX_HEIGHT, 250); + // effects.DimAll(250); effects.ShowFrame(); + + + // the Effects class has some sample oscillators + // that move from 0 to 255 at different speeds + effects.MoveOscillators(); + + // the horizontal position of the head of the infinity sign + // oscillates from 0 to the maximum horizontal and back + int x = (MATRIX_WIDTH - 1) - effects.p[1]; + + // the vertical position of the head oscillates + // from 8 to 23 and back (hard-coded for a 32x32 matrix) + int y = map8(sin8(effects.osci[3]), 8, 23); + + // the hue oscillates from 0 to 255, overflowing back to 0 + byte hue = sin8(effects.osci[5]); + + // draw a pixel at x,y using a color from the current palette + effects.Pixel(x, y, hue); + + effects.ShowFrame(); + return 30; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternInvaders.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternInvaders.h new file mode 100644 index 0000000..e2df82e --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternInvaders.h @@ -0,0 +1,154 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Inspired by 'Space Invader Generator': https://the8bitpimp.wordpress.com/2013/05/07/space-invader-generator + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternInvaders_H +#define PatternInvaders_H + +class PatternInvadersSmall : public Drawable { + private: + uint8_t x = 1; + uint8_t y = 1; + + public: + PatternInvadersSmall() { + name = (char *)"Invaders Small"; + } + + void start() { + dma_display->fillScreen(0); + } + + unsigned int drawFrame() { + CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255)); + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 5; j++) { + CRGB color = CRGB::Black; + + if (random(0, 2) == 1) color = color1; + + effects.drawBackgroundFastLEDPixelCRGB(x + i, y + j, color); + + if (i < 2) + effects.drawBackgroundFastLEDPixelCRGB(x + (4 - i), y + j, color); + } + } + + x += 6; + if (x > 25) { + x = 1; + y += 6; + } + + if (y > 25) y = x = 1; + + effects.ShowFrame(); + + return 125; + } +}; + +class PatternInvadersMedium : public Drawable { + private: + uint8_t x = 0; + uint8_t y = 0; + + public: + PatternInvadersMedium() { + name = (char *)"Invaders Medium"; + } + + void start() { + dma_display->fillScreen(0); + } + + unsigned int drawFrame() { + CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255)); + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 5; j++) { + CRGB color = CRGB::Black; + + if (random(0, 2) == 1) color = color1; + + dma_display->fillRect(x + (i * 2), y + (j * 2), x + (i * 2 + 1), y + (j * 2 + 1), color); + + if (i < 2) + dma_display->fillRect(x + (8 - i * 2), y + (j * 2), x + (9 - i * 2), y + (j * 2 + 1), color); + } + } + + x += 11; + if (x > 22) { + x = 0; + y += 11; + } + + if (y > 22) y = x = 0; + + effects.ShowFrame(); + + return 500; + } +}; + +class PatternInvadersLarge : public Drawable { + private: + + public: + PatternInvadersLarge() { + name = (char *)"Invaders Large"; + } + + void start() { + dma_display->fillScreen(0); + } + + unsigned int drawFrame() { + dma_display->fillScreen(0); + + CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255)); + + for (int x = 0; x < 3; x++) { + for (int y = 0; y < 5; y++) { + CRGB color = CRGB::Black; + + if (random(0, 2) == 1) { + color = color1; + } + + dma_display->fillRect(1 + x * 6, 1 + y * 6, 5 + x * 6, 5 + y * 6, color); + + if (x < 2) + dma_display->fillRect(1 + (4 - x) * 6, 1 + y * 6, 5 + (4 - x) * 6, 5 + y * 6, color); + } + } + + effects.ShowFrame(); + + return 2000; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternLife.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternLife.h new file mode 100644 index 0000000..7c9ef30 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternLife.h @@ -0,0 +1,129 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from Andrew: http://pastebin.com/f22bfe94d + * which, in turn, was "Adapted from the Life example on the Processing.org site" + * + * Made much more colorful by J.B. Langston: https://github.com/jblang/aurora/commit/6db5a884e3df5d686445c4f6b669f1668841929b + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternLife_H +#define PatternLife_H + +class Cell { +public: + byte alive : 1; + byte prev : 1; + byte hue: 6; + byte brightness; +}; + +class PatternLife : public Drawable { +private: + Cell world[MATRIX_WIDTH][MATRIX_HEIGHT]; + unsigned int density = 50; + int generation = 0; + + void randomFillWorld() { + for (int i = 0; i < MATRIX_WIDTH; i++) { + for (int j = 0; j < MATRIX_HEIGHT; j++) { + if (random(100) < density) { + world[i][j].alive = 1; + world[i][j].brightness = 255; + } + else { + world[i][j].alive = 0; + world[i][j].brightness = 0; + } + world[i][j].prev = world[i][j].alive; + world[i][j].hue = 0; + } + } + } + + int neighbours(int x, int y) { + return (world[(x + 1) % MATRIX_WIDTH][y].prev) + + (world[x][(y + 1) % MATRIX_HEIGHT].prev) + + (world[(x + MATRIX_WIDTH - 1) % MATRIX_WIDTH][y].prev) + + (world[x][(y + MATRIX_HEIGHT - 1) % MATRIX_HEIGHT].prev) + + (world[(x + 1) % MATRIX_WIDTH][(y + 1) % MATRIX_HEIGHT].prev) + + (world[(x + MATRIX_WIDTH - 1) % MATRIX_WIDTH][(y + 1) % MATRIX_HEIGHT].prev) + + (world[(x + MATRIX_WIDTH - 1) % MATRIX_WIDTH][(y + MATRIX_HEIGHT - 1) % MATRIX_HEIGHT].prev) + + (world[(x + 1) % MATRIX_WIDTH][(y + MATRIX_HEIGHT - 1) % MATRIX_HEIGHT].prev); + } + +public: + PatternLife() { + name = (char *)"Life"; + } + + unsigned int drawFrame() { + if (generation == 0) { + effects.ClearFrame(); + + randomFillWorld(); + } + + // Display current generation + for (int i = 0; i < MATRIX_WIDTH; i++) { + for (int j = 0; j < MATRIX_HEIGHT; j++) { + effects.leds[XY(i, j)] = effects.ColorFromCurrentPalette(world[i][j].hue * 4, world[i][j].brightness); + } + } + + // Birth and death cycle + for (int x = 0; x < MATRIX_WIDTH; x++) { + for (int y = 0; y < MATRIX_HEIGHT; y++) { + // Default is for cell to stay the same + if (world[x][y].brightness > 0 && world[x][y].prev == 0) + world[x][y].brightness *= 0.9; + int count = neighbours(x, y); + if (count == 3 && world[x][y].prev == 0) { + // A new cell is born + world[x][y].alive = 1; + world[x][y].hue += 2; + world[x][y].brightness = 255; + } else if ((count < 2 || count > 3) && world[x][y].prev == 1) { + // Cell dies + world[x][y].alive = 0; + } + } + } + + // Copy next generation into place + for (int x = 0; x < MATRIX_WIDTH; x++) { + for (int y = 0; y < MATRIX_HEIGHT; y++) { + world[x][y].prev = world[x][y].alive; + } + } + + + generation++; + if (generation >= 256) + generation = 0; + + effects.ShowFrame(); + + return 60; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternMaze.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternMaze.h new file mode 100644 index 0000000..c469922 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternMaze.h @@ -0,0 +1,264 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Many thanks to Jamis Buck for the documentation of the Growing Tree maze generation algorithm: http://weblog.jamisbuck.org/2011/1/27/maze-generation-growing-tree-algorithm + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternMaze_H +#define PatternMaze_H + +class PatternMaze : public Drawable { +private: + enum Directions { + None = 0, + Up = 1, + Down = 2, + Left = 4, + Right = 8, + }; + + struct Point{ + int x; + int y; + + static Point New(int x, int y) { + Point point; + point.x = x; + point.y = y; + return point; + } + + Point Move(Directions direction) { + switch (direction) + { + case Up: + return New(x, y - 1); + + case Down: + return New(x, y + 1); + + case Left: + return New(x - 1, y); + + case Right: + default: + return New(x + 1, y); + } + } + + static Directions Opposite(Directions direction) { + switch (direction) { + case Up: + return Down; + + case Down: + return Up; + + case Left: + return Right; + + case Right: + default: + return Left; + } + } + }; + +// int width = 16; +// int height = 16; + + static const int width = MATRIX_WIDTH / 2; + static const int height = MATRIX_HEIGHT / 2; + + + Directions grid[width][height]; + + Point point; + + Point cells[256]; + int cellCount = 0; + + int algorithm = 0; + int algorithmCount = 1; + + byte hue = 0; + byte hueOffset = 0; + + Directions directions[4] = { Up, Down, Left, Right }; + + void removeCell(int index) {// shift cells after index down one + for (int i = index; i < cellCount - 1; i++) { + cells[i] = cells[i + 1]; + } + + cellCount--; + } + + void shuffleDirections() { + for (int a = 0; a < 4; a++) + { + int r = random(a, 4); + Directions temp = directions[a]; + directions[a] = directions[r]; + directions[r] = temp; + } + } + + Point createPoint(int x, int y) { + Point point; + point.x = x; + point.y = y; + return point; + } + + CRGB chooseColor(int index) { + byte h = index + hueOffset; + + switch (algorithm) { + case 0: + default: + return effects.ColorFromCurrentPalette(h); + + case 1: + return effects.ColorFromCurrentPalette(hue++); + } + } + + int chooseIndex(int max) { + switch (algorithm) { + case 0: + default: + // choose newest (recursive backtracker) + return max - 1; + + case 1: + // choose random(Prim's) + return random(max); + + // case 2: + // // choose oldest (not good, so disabling) + // return 0; + } + } + + void generateMaze() { + while (cellCount > 1) { + drawNextCell(); + } + } + + void drawNextCell() { + int index = chooseIndex(cellCount); + + if (index < 0) + return; + + point = cells[index]; + + Point imagePoint = createPoint(point.x * 2, point.y * 2); + + //effects.drawBackgroundFastLEDPixelCRGB(imagePoint.x, imagePoint.y, CRGB(CRGB::Gray)); + + shuffleDirections(); + + CRGB color = chooseColor(index); + + for (int i = 0; i < 4; i++) { + Directions direction = directions[i]; + + Point newPoint = point.Move(direction); + if (newPoint.x >= 0 && newPoint.y >= 0 && newPoint.x < width && newPoint.y < height && grid[newPoint.y][newPoint.x] == None) { + grid[point.y][point.x] = (Directions) ((int) grid[point.y][point.x] | (int) direction); + grid[newPoint.y][newPoint.x] = (Directions) ((int) grid[newPoint.y][newPoint.x] | (int) point.Opposite(direction)); + + Point newImagePoint = imagePoint.Move(direction); + + effects.drawBackgroundFastLEDPixelCRGB(newImagePoint.x, newImagePoint.y, color); + + cellCount++; + cells[cellCount - 1] = newPoint; + + index = -1; + break; + } + } + + if (index > -1) { + Point finishedPoint = cells[index]; + imagePoint = createPoint(finishedPoint.x * 2, finishedPoint.y * 2); + effects.drawBackgroundFastLEDPixelCRGB(imagePoint.x, imagePoint.y, color); + + removeCell(index); + } + } + +public: + PatternMaze() { + name = (char *)"Maze"; + } + + unsigned int drawFrame() { + if (cellCount < 1) { + + effects.ClearFrame(); + + // reset the maze grid + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + grid[y][x] = None; + } + } + + int x = random(width); + int y = random(height); + + cells[0] = createPoint(x, y); + + cellCount = 1; + + hue = 0; + hueOffset = random(0, 256); + + } + + drawNextCell(); + + if (cellCount < 1) { + algorithm++; + if (algorithm >= algorithmCount) + algorithm = 0; + + return 0; + } + + effects.ShowFrame(); + + return 0; + } + + void start() { + effects.ClearFrame(); + cellCount = 0; + hue = 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternMunch.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternMunch.h new file mode 100644 index 0000000..f580828 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternMunch.h @@ -0,0 +1,73 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Munch pattern created by J.B. Langston: https://github.com/jblang/aurora/blob/master/PatternMunch.h + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternMunch_H +#define PatternMunch_H + + +class PatternMunch : public Drawable { +private: + byte count = 0; + byte dir = 1; + byte flip = 0; + byte generation = 0; + +public: + PatternMunch() { + name = (char *)"Munch"; + } + + unsigned int drawFrame() { + + for (uint16_t x = 0; x < MATRIX_WIDTH; x++) { + for (uint16_t y = 0; y < MATRIX_HEIGHT; y++) { + effects.leds[XY16(x, y)] = (x ^ y ^ flip) < count ? effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) : CRGB::Black; + + // The below is more pleasant + // effects.leds[XY(x, y)] = effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) ; + } + } + + count += dir; + + if (count <= 0 || count >= MATRIX_WIDTH) { + dir = -dir; + } + + if (count <= 0) { + if (flip == 0) + flip = MATRIX_WIDTH-1; + else + flip = 0; + } + + generation++; + + // show it ffs! + effects.ShowFrame(); + return 60; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternNoiseSmearing.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternNoiseSmearing.h new file mode 100644 index 0000000..ab7ed7b --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternNoiseSmearing.h @@ -0,0 +1,338 @@ +/* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Portions of this code are adapted from "Noise Smearing" by Stefan Petrick: https://gist.githubusercontent.com/embedded-creations/5cd47d83cb0e04f4574d/raw/ebf6a82b4755d55cfba3bf6598f7b19047f89daf/NoiseSmearing.ino +* Copyright (c) 2014 Stefan Petrick +* http://www.stefan-petrick.de/wordpress_beta +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternNoiseSmearing_H +#define PatternNoiseSmearing_H + +byte patternNoiseSmearingHue = 0; + +class PatternMultipleStream : public Drawable { +public: + PatternMultipleStream() { + name = (char *)"MultipleStream"; + } + + // this pattern draws two points to the screen based on sin/cos if a counter + // (comment out NoiseSmearWithRadius to see pattern of pixels) + // these pixels are smeared by a large radius, giving a lot of movement + // the image is dimmed before each drawing to not saturate the screen with color + // the smear has an offset so the pixels usually have a trail leading toward the upper left + unsigned int drawFrame() { + static unsigned long counter = 0; +#if 0 + // this counter lets put delays between each frame and still get the same animation + counter++; +#else + // this counter updates in real time and can't be slowed down for debugging + counter = millis() / 10; +#endif + + byte x1 = 4 + sin8(counter * 2) / 10; + byte x2 = 8 + sin8(counter * 2) / 16; + byte y2 = 8 + cos8((counter * 2) / 3) / 16; + + effects.leds[XY(x1, x2)] = effects.ColorFromCurrentPalette(patternNoiseSmearingHue); + effects.leds[XY(x2, y2)] = effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 128); + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(8); + effects.MoveFractionalNoiseX(); + + effects.MoveY(8); + effects.MoveFractionalNoiseY(); + + patternNoiseSmearingHue++; + + return 0; + } +}; + +class PatternMultipleStream2 : public Drawable { +public: + PatternMultipleStream2() { + name = (char *)"MultipleStream2"; + } + + unsigned int drawFrame() { + effects.DimAll(230); effects.ShowFrame(); + + byte xx = 4 + sin8(millis() / 9) / 10; + byte yy = 4 + cos8(millis() / 10) / 10; + effects.leds[XY(xx, yy)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue); + + xx = 8 + sin8(millis() / 10) / 16; + yy = 8 + cos8(millis() / 7) / 16; + effects.leds[XY(xx, yy)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 80); + + effects.leds[XY(15, 15)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 160); + + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + effects.MoveFractionalNoiseY(4); + + effects.MoveY(3); + effects.MoveFractionalNoiseX(4); + + patternNoiseSmearingHue++; + + return 0; + } +}; + +class PatternMultipleStream3 : public Drawable { +public: + PatternMultipleStream3() { + name = (char *)"MultipleStream3"; + } + + unsigned int drawFrame() { + //CLS(); + effects.DimAll(235); effects.ShowFrame(); + + for (uint8_t i = 3; i < 32; i = i + 4) { + effects.leds[XY(i, 15)] += effects.ColorFromCurrentPalette(i * 8); + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + effects.MoveFractionalNoiseY(4); + + effects.MoveY(3); + effects.MoveFractionalNoiseX(4); + + effects.ShowFrame(); + + return 1; + } +}; + +class PatternMultipleStream4 : public Drawable { +public: + PatternMultipleStream4() { + name = (char *)"MultipleStream4"; + } + + unsigned int drawFrame() { + + //CLS(); + effects.DimAll(235); effects.ShowFrame(); + + effects.leds[XY(15, 15)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue); + + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(8); + effects.MoveFractionalNoiseX(); + + effects.MoveY(8); + effects.MoveFractionalNoiseY(); + + patternNoiseSmearingHue++; + + return 0; + } +}; + +class PatternMultipleStream5 : public Drawable { +public: + PatternMultipleStream5() { + name = (char *)"MultipleStream5"; + } + + unsigned int drawFrame() { + + //CLS(); + effects.DimAll(235); effects.ShowFrame(); + + + for (uint8_t i = 3; i < 32; i = i + 4) { + effects.leds[XY(i, 31)] += effects.ColorFromCurrentPalette(i * 8); + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + effects.MoveFractionalNoiseY(4); + + effects.MoveY(4); + effects.MoveFractionalNoiseX(4); + + return 0; + } +}; + +class PatternMultipleStream8 : public Drawable { +public: + PatternMultipleStream8() { + name = (char *)"MultipleStream8"; + } + + unsigned int drawFrame() { + effects.DimAll(230); effects.ShowFrame(); + + // draw grid of rainbow dots on top of the dimmed image + for (uint8_t y = 1; y < 32; y = y + 6) { + for (uint8_t x = 1; x < 32; x = x + 6) { + + effects.leds[XY(x, y)] += effects.ColorFromCurrentPalette((x * y) / 4); + } + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + effects.MoveFractionalNoiseX(4); + + effects.MoveY(3); + effects.MoveFractionalNoiseY(4); + + return 0; + } +}; + +class PatternPaletteSmear : public Drawable { +public: + PatternPaletteSmear() { + name = (char *)"PaletteSmear"; + } + + unsigned int drawFrame() { + + effects.DimAll(170); effects.ShowFrame(); + + // draw a rainbow color palette + for (uint8_t y = 0; y < MATRIX_HEIGHT; y++) { + for (uint8_t x = 0; x < MATRIX_WIDTH; x++) { + effects.leds[XY(x, y)] += effects.ColorFromCurrentPalette(x * 8, y * 8 + 7); + } + } + + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + + effects.FillNoise(); + + effects.MoveX(3); + //effects.MoveFractionalNoiseY(4); + + effects.MoveY(3); + effects.MoveFractionalNoiseX(4); + effects.ShowFrame(); + + return 0; + } +}; + +class PatternRainbowFlag : public Drawable { +public: + PatternRainbowFlag() { + name = (char *)"RainbowFlag"; + } + + unsigned int drawFrame() { + effects.DimAll(10); effects.ShowFrame(); + + CRGB rainbow[7] = { + CRGB::Red, + CRGB::Orange, + CRGB::Yellow, + CRGB::Green, + CRGB::Blue, + CRGB::Violet + }; + + uint8_t y = 2; + + for (uint8_t c = 0; c < 6; c++) { + for (uint8_t j = 0; j < 5; j++) { + for (uint8_t x = 0; x < MATRIX_WIDTH; x++) { + effects.leds[XY(x, y)] += rainbow[c]; + } + + y++; + if (y >= MATRIX_HEIGHT) + break; + } + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + effects.MoveFractionalNoiseY(4); + + effects.MoveY(3); + effects.MoveFractionalNoiseX(4); + + return 0; + } +}; +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternPendulumWave.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternPendulumWave.h new file mode 100644 index 0000000..08fd5b7 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternPendulumWave.h @@ -0,0 +1,66 @@ +/* +* +* Inspired by and based on a loading animation for Prismata by Lunarch Studios: +* http://www.reddit.com/r/gifs/comments/2on8si/connecting_to_server_so_mesmerizing/cmow0sz +* +* Lunarch Studios Inc. hereby publishes the Actionscript 3 source code pasted in this +* comment under the Creative Commons CC0 1.0 Universal Public Domain Dedication. +* Lunarch Studios Inc. waives all rights to the work worldwide under copyright law, +* including all related and neighboring rights, to the extent allowed by law. +* You can copy, modify, distribute and perform the work, even for commercial purposes, +* all without asking permission. +* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternPendulumWave_H +#define PatternPendulumWave_H + +#define WAVE_BPM 25 +#define AMP_BPM 2 +#define SKEW_BPM 4 +#define WAVE_TIMEMINSKEW MATRIX_WIDTH/8 +#define WAVE_TIMEMAXSKEW MATRIX_WIDTH/2 + +class PatternPendulumWave : public Drawable { + public: + PatternPendulumWave() { + name = (char *)"Pendulum Wave"; + } + + unsigned int drawFrame() { + effects.ClearFrame(); + + for (int x = 0; x < MATRIX_WIDTH; ++x) + { + uint16_t amp = beatsin16(AMP_BPM, MATRIX_HEIGHT/8, MATRIX_HEIGHT-1); + uint16_t offset = (MATRIX_HEIGHT - beatsin16(AMP_BPM, 0, MATRIX_HEIGHT))/2; + + uint8_t y = beatsin16(WAVE_BPM, 0, amp, x*beatsin16(SKEW_BPM, WAVE_TIMEMINSKEW, WAVE_TIMEMAXSKEW)) + offset; + + effects.drawBackgroundFastLEDPixelCRGB(x, y, effects.ColorFromCurrentPalette(x * 7)); + } + effects.ShowFrame(); + return 20; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternPlasma.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternPlasma.h new file mode 100644 index 0000000..99500b1 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternPlasma.h @@ -0,0 +1,66 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from LedEffects Plasma by Robert Atkins: https://bitbucket.org/ratkins/ledeffects/src/26ed3c51912af6fac5f1304629c7b4ab7ac8ca4b/Plasma.cpp?at=default + * Copyright (c) 2013 Robert Atkins + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternPlasma_H +#define PatternPlasma_H + +class PatternPlasma : public Drawable { +private: + int time = 0; + int cycles = 0; + +public: + PatternPlasma() { + name = (char *)"Plasma"; + } + + unsigned int drawFrame() { + for (int x = 0; x < MATRIX_WIDTH; x++) { + for (int y = 0; y < MATRIX_HEIGHT; y++) { + int16_t v = 0; + uint8_t wibble = sin8(time); + v += sin16(x * wibble * 2 + time); + v += cos16(y * (128 - wibble) * 2 + time); + v += sin16(y * x * cos8(-time) / 2); + + effects.Pixel(x, y, (v >> 8) + 127); + } + } + + time += 1; + cycles++; + + if (cycles >= 2048) { + time = 0; + cycles = 0; + } + + effects.ShowFrame(); + + return 30; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternPulse.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternPulse.h new file mode 100644 index 0000000..4d4ba69 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternPulse.h @@ -0,0 +1,82 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Based at least in part on someone else's work that I can no longer find. + * Please let me know if you recognize any of this code! + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternPulse_H +#define PatternPulse_H + +class PatternPulse : public Drawable { + private: + int hue; + int centerX = 0; + int centerY = 0; + int step = -1; + int maxSteps = 16; + float fadeRate = 0.8; + int diff; + + public: + PatternPulse() { + name = (char *)"Pulse"; + } + + unsigned int drawFrame() { + effects.DimAll(235); + + if (step == -1) { + centerX = random(32); + centerY = random(32); + hue = random(256); // 170; + step = 0; + } + + if (step == 0) { + dma_display->drawCircle(centerX, centerY, step, effects.ColorFromCurrentPalette(hue)); + step++; + } + else { + if (step < maxSteps) { + // initial pulse + dma_display->drawCircle(centerX, centerY, step, effects.ColorFromCurrentPalette(hue, pow(fadeRate, step - 2) * 255)); + + // secondary pulse + if (step > 3) { + dma_display->drawCircle(centerX, centerY, step - 3, effects.ColorFromCurrentPalette(hue, pow(fadeRate, step - 2) * 255)); + } + step++; + } + else { + step = -1; + } + } + + effects.standardNoiseSmearing(); + + effects.ShowFrame(); + + return 30; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternRadar.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternRadar.h new file mode 100644 index 0000000..1dc4484 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternRadar.h @@ -0,0 +1,56 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternRadar_H + +class PatternRadar : public Drawable { + private: + byte theta = 0; + byte hueoffset = 0; + + public: + PatternRadar() { + name = (char *)"Radar"; + } + + unsigned int drawFrame() { + effects.DimAll(254); effects.ShowFrame(); + + for (int offset = 0; offset < MATRIX_CENTER_X; offset++) { + byte hue = 255 - (offset * 16 + hueoffset); + CRGB color = effects.ColorFromCurrentPalette(hue); + uint8_t x = mapcos8(theta, offset, (MATRIX_WIDTH - 1) - offset); + uint8_t y = mapsin8(theta, offset, (MATRIX_HEIGHT - 1) - offset); + uint16_t xy = XY(x, y); + effects.leds[xy] = color; + + EVERY_N_MILLIS(25) { + theta += 2; + hueoffset += 1; + } + } + + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSimplexNoise.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSimplexNoise.h new file mode 100644 index 0000000..0c47bff --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSimplexNoise.h @@ -0,0 +1,79 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/blob/master/examples/Noise/Noise.ino + * Copyright (c) 2013 FastLED + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternSimplexNoise_H +#define PatternSimplexNoise_H + +class PatternSimplexNoise : public Drawable { + public: + PatternSimplexNoise() { + name = (char *)"Noise"; + } + + void start() { + // Initialize our coordinates to some random values + noise_x = random16(); + noise_y = random16(); + noise_z = random16(); + } + + unsigned int drawFrame() { +#if FASTLED_VERSION >= 3001000 + // a new parameter set every 15 seconds + EVERY_N_SECONDS(15) { + noise_x = random16(); + noise_y = random16(); + noise_z = random16(); + } +#endif + + uint32_t speed = 100; + + effects.FillNoise(); + ShowNoiseLayer(0, 1, 0); + + // noise_x += speed; + noise_y += speed; + noise_z += speed; + + effects.ShowFrame(); + + return 30; + } + + // show just one layer + void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) { + for (uint16_t i = 0; i < MATRIX_WIDTH; i++) { + for (uint16_t j = 0; j < MATRIX_HEIGHT; j++) { + uint8_t pixel = noise[i][j]; + + // assign a color depending on the actual palette + effects.leds[XY16(i, j)] = effects.ColorFromCurrentPalette(colorrepeat * (pixel + colorshift), pixel); + } + } + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSnake.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSnake.h new file mode 100644 index 0000000..e25756f --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSnake.h @@ -0,0 +1,145 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from LedEffects Snake by Robert Atkins: https://bitbucket.org/ratkins/ledeffects/src/26ed3c51912af6fac5f1304629c7b4ab7ac8ca4b/Snake.cpp?at=default + * Copyright (c) 2013 Robert Atkins + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternSnake_H +#define PatternSnake_H + +class PatternSnake : public Drawable { +private: + static const byte SNAKE_LENGTH = 16; + + CRGB colors[SNAKE_LENGTH]; + uint8_t initialHue; + + enum Direction { + UP, DOWN, LEFT, RIGHT + }; + + struct Pixel { + uint8_t x; + uint8_t y; + }; + + struct Snake { + Pixel pixels[SNAKE_LENGTH]; + + Direction direction; + + void newDirection() { + switch (direction) { + case UP: + case DOWN: + direction = random(0, 2) == 1 ? RIGHT : LEFT; + break; + + case LEFT: + case RIGHT: + direction = random(0, 2) == 1 ? DOWN : UP; + + default: + break; + } + } + + void shuffleDown() { + for (byte i = SNAKE_LENGTH - 1; i > 0; i--) { + pixels[i] = pixels[i - 1]; + } + } + + void reset() { + direction = UP; + for (int i = 0; i < SNAKE_LENGTH; i++) { + pixels[i].x = 0; + pixels[i].y = 0; + } + } + + void move() { + switch (direction) { + case UP: + pixels[0].y = (pixels[0].y + 1) % MATRIX_HEIGHT; + break; + case LEFT: + pixels[0].x = (pixels[0].x + 1) % MATRIX_WIDTH; + break; + case DOWN: + pixels[0].y = pixels[0].y == 0 ? MATRIX_HEIGHT - 1 : pixels[0].y - 1; + break; + case RIGHT: + pixels[0].x = pixels[0].x == 0 ? MATRIX_WIDTH - 1 : pixels[0].x - 1; + break; + } + } + + void draw(CRGB colors[SNAKE_LENGTH]) { + for (byte i = 0; i < SNAKE_LENGTH; i++) { + effects.leds[XY(pixels[i].x, pixels[i].y)] = colors[i] %= (255 - i * (255 / SNAKE_LENGTH)); + } + } + }; + + static const int snakeCount = 6; + Snake snakes[snakeCount]; + +public: + PatternSnake() { + name = (char *)"Snake"; + for (int i = 0; i < snakeCount; i++) { + Snake* snake = &snakes[i]; + snake->reset(); + } + } + + void start() + { + effects.ClearFrame(); + } + + unsigned int drawFrame() { + + + fill_palette(colors, SNAKE_LENGTH, initialHue++, 5, effects.currentPalette, 255, LINEARBLEND); + + for (int i = 0; i < snakeCount; i++) { + Snake* snake = &snakes[i]; + + snake->shuffleDown(); + + if (random(10) > 7) { + snake->newDirection(); + } + + snake->move(); + snake->draw(colors); + } + + effects.ShowFrame(); + + return 30; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSpark.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSpark.h new file mode 100644 index 0000000..74f3b16 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSpark.h @@ -0,0 +1,113 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/tree/master/examples/Fire2012WithPalette + * Copyright (c) 2013 FastLED + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternSpark_H +#define PatternSpark_H + +class PatternSpark : public Drawable { + private: + + public: + PatternSpark() { + name = (char *)"Spark"; + } + + // There are two main parameters you can play with to control the look and + // feel of your fire: COOLING (used in step 1 above), and SPARKING (used + // in step 3 above). + // + // COOLING: How much does the air cool as it rises? + // Less cooling = taller flames. More cooling = shorter flames. + // Default 55, suggested range 20-100 + uint8_t cooling = 100; + + // SPARKING: What chance (out of 255) is there that a new spark will be lit? + // Higher chance = more roaring fire. Lower chance = more flickery fire. + // Default 120, suggested range 50-200. + uint8_t sparking = 50; + + unsigned int drawFrame() { + // Add entropy to random number generator; we use a lot of it. + random16_add_entropy( random16()); + + effects.DimAll(235); effects.ShowFrame(); + + for (uint8_t x = 0; x < MATRIX_WIDTH; x++) { + // Step 1. Cool down every cell a little + for (int y = 0; y < MATRIX_HEIGHT; y++) { + int xy = XY(x, y); + heat[xy] = qsub8(heat[xy], random8(0, ((cooling * 10) / MATRIX_HEIGHT) + 2)); + } + + // Step 2. Heat from each cell drifts 'up' and diffuses a little + for (int y = 0; y < MATRIX_HEIGHT; y++) { + heat[XY(x, y)] = (heat[XY(x, y + 1)] + heat[XY(x, y + 2)] + heat[XY(x, y + 2)]) / 3; + } + + // Step 2. Randomly ignite new 'sparks' of heat + if (random8() < sparking) { + uint8_t xt = random8(MATRIX_CENTRE_X - 2, MATRIX_CENTER_X + 3); + + int xy = XY(xt, MATRIX_HEIGHT - 1); + heat[xy] = qadd8(heat[xy], random8(160, 255)); + } + + // Step 4. Map from heat cells to LED colors + for (int y = 0; y < MATRIX_HEIGHT; y++) { + int xy = XY(x, y); + byte colorIndex = heat[xy]; + + // Recommend that you use values 0-240 rather than + // the usual 0-255, as the last 15 colors will be + // 'wrapping around' from the hot end to the cold end, + // which looks wrong. + colorIndex = scale8(colorIndex, 240); + + // override color 0 to ensure a black background? + if (colorIndex != 0) + // effects.leds[xy] = CRGB::Black; + // else + effects.leds[xy] = effects.ColorFromCurrentPalette(colorIndex); + } + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + effects.MoveFractionalNoiseX(4); + + effects.ShowFrame(); + + return 15; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSpin.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSpin.h new file mode 100644 index 0000000..c3497e7 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSpin.h @@ -0,0 +1,100 @@ +/* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternSpin_H + + + +class PatternSpin : public Drawable { +public: + PatternSpin() { + name = (char *)"Spin"; + } + + float degrees = 0; + float radius = 16; + + float speedStart = 1; + float velocityStart = 0.6; + + float maxSpeed = 30; + + float speed = speedStart; + float velocity = velocityStart; + + void start() { + speed = speedStart; + velocity = velocityStart; + degrees = 0; + } + + unsigned int drawFrame() { + effects.DimAll(190); effects.ShowFrame(); + + CRGB color = effects.ColorFromCurrentPalette(speed * 8); + + // start position + int x; + int y; + + // target position + float targetDegrees = degrees + speed; + float targetRadians = radians(targetDegrees); + int targetX = (int) (MATRIX_CENTER_X + radius * cos(targetRadians)); + int targetY = (int) (MATRIX_CENTER_Y - radius * sin(targetRadians)); + + float tempDegrees = degrees; + + do{ + float radians = radians(tempDegrees); + x = (int) (MATRIX_CENTER_X + radius * cos(radians)); + y = (int) (MATRIX_CENTER_Y - radius * sin(radians)); + + effects.drawBackgroundFastLEDPixelCRGB(x, y, color); + effects.drawBackgroundFastLEDPixelCRGB(y, x, color); + + tempDegrees += 1; + if (tempDegrees >= 360) + tempDegrees = 0; + } while (x != targetX || y != targetY); + + degrees += speed; + + // add velocity to the particle each pass around the accelerator + if (degrees >= 360) { + degrees = 0; + speed += velocity; + if (speed <= speedStart) { + speed = speedStart; + velocity *= -1; + } + else if (speed > maxSpeed){ + speed = maxSpeed - velocity; + velocity *= -1; + } + } + + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSpiral.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSpiral.h new file mode 100644 index 0000000..b8e6f07 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSpiral.h @@ -0,0 +1,138 @@ +/* + * Portions of this code are adapted from "Funky Clouds" by Stefan Petrick: + * https://gist.github.com/anonymous/876f908333cd95315c35 + * + * Copyright (c) 2014 Stefan Petrick + * http://www.stefan-petrick.de/wordpress_beta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternSpiral_H +#define PatternSpiral_H + +class PatternSpiral : public Drawable { +private: + // Timer stuff (Oscillators) + struct timer { + unsigned long takt; + unsigned long lastMillis; + unsigned long count; + int delta; + byte up; + byte down; + }; + timer multiTimer[5]; + + int timers = sizeof(multiTimer) / sizeof(multiTimer[0]); + + // counts all variables with different speeds linear up and down + void UpdateTimers() + { + unsigned long now = millis(); + for (int i = 0; i < timers; i++) + { + while (now - multiTimer[i].lastMillis >= multiTimer[i].takt) + { + multiTimer[i].lastMillis += multiTimer[i].takt; + multiTimer[i].count = multiTimer[i].count + multiTimer[i].delta; + if ((multiTimer[i].count == multiTimer[i].up) || (multiTimer[i].count == multiTimer[i].down)) + { + multiTimer[i].delta = -multiTimer[i].delta; + } + } + } + } + +public: + PatternSpiral() { + name = (char *)"Spiral"; + } + + void start() { + // set all counting directions positive for the beginning + for (int i = 0; i < timers; i++) multiTimer[i].delta = 1; + + // set range (up/down), speed (takt=ms between steps) and starting point of all oscillators + + unsigned long now = millis(); + + multiTimer[0].lastMillis = now; + multiTimer[0].takt = 42; //x1 + multiTimer[0].up = MATRIX_WIDTH - 1; + multiTimer[0].down = 0; + multiTimer[0].count = 0; + + multiTimer[1].lastMillis = now; + multiTimer[1].takt = 55; //y1 + multiTimer[1].up = MATRIX_HEIGHT - 1; + multiTimer[1].down = 0; + multiTimer[1].count = 0; + + multiTimer[2].lastMillis = now; + multiTimer[2].takt = 3; //color + multiTimer[2].up = 255; + multiTimer[2].down = 0; + multiTimer[2].count = 0; + + multiTimer[3].lastMillis = now; + multiTimer[3].takt = 71; //x2 + multiTimer[3].up = MATRIX_WIDTH - 1; + multiTimer[3].down = 0; + multiTimer[3].count = 0; + + multiTimer[4].lastMillis = now; + multiTimer[4].takt = 89; //y2 + multiTimer[4].up = MATRIX_HEIGHT - 1; + multiTimer[4].down = 0; + multiTimer[4].count = 0; + } + + unsigned int drawFrame() { + // manage the Oscillators + UpdateTimers(); + + // draw just a line defined by 5 oscillators + effects.BresenhamLine( + multiTimer[3].count, // x1 + multiTimer[4].count, // y1 + multiTimer[0].count, // x2 + multiTimer[1].count, // y2 + multiTimer[2].count); // color + + // manipulate the screen buffer + // with fixed parameters (could be oscillators too) + // Params: center x, y, radius, scale color down + // --> NOTE: Affects always a SQUARE with an odd length + // effects.SpiralStream(15, 15, 10, 128); + + effects.SpiralStream(31, 15, 64, 128); // for 64 pixel wide matrix! + // effects.SpiralStream(47, 15, 10, 128); // for 64 pixel wide matrix! + + // why not several times?! + // effects.SpiralStream(16, 6, 6, 128); + // effects.SpiralStream(10, 24, 10, 128); + + // increase the contrast + effects.DimAll(250); effects.ShowFrame(); + + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSpiro.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSpiro.h new file mode 100644 index 0000000..c41a3c6 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSpiro.h @@ -0,0 +1,112 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternSpiro_H + +class PatternSpiro : public Drawable { + private: + byte theta1 = 0; + byte theta2 = 0; + byte hueoffset = 0; + + uint8_t radiusx = MATRIX_WIDTH / 4; + uint8_t radiusy = MATRIX_HEIGHT / 4; + uint8_t minx = MATRIX_CENTER_X - radiusx; + uint8_t maxx = MATRIX_CENTER_X + radiusx + 1; + uint8_t miny = MATRIX_CENTER_Y - radiusy; + uint8_t maxy = MATRIX_CENTER_Y + radiusy + 1; + + uint8_t spirocount = 1; + uint8_t spirooffset = 256 / spirocount; + boolean spiroincrement = true; + + boolean handledChange = false; + + public: + PatternSpiro() { + name = (char *)"Spiro"; + } + + void start(){ + effects.ClearFrame(); + }; + + unsigned int drawFrame() { + blur2d(effects.leds, MATRIX_WIDTH > 255 ? 255 : MATRIX_WIDTH, MATRIX_HEIGHT > 255 ? 255 : MATRIX_HEIGHT, 192); + + boolean change = false; + + for (int i = 0; i < spirocount; i++) { + uint8_t x = mapsin8(theta1 + i * spirooffset, minx, maxx); + uint8_t y = mapcos8(theta1 + i * spirooffset, miny, maxy); + + uint8_t x2 = mapsin8(theta2 + i * spirooffset, x - radiusx, x + radiusx); + uint8_t y2 = mapcos8(theta2 + i * spirooffset, y - radiusy, y + radiusy); + + CRGB color = effects.ColorFromCurrentPalette(hueoffset + i * spirooffset, 128); + effects.leds[XY(x2, y2)] += color; + + if((x2 == MATRIX_CENTER_X && y2 == MATRIX_CENTER_Y) || + (x2 == MATRIX_CENTRE_X && y2 == MATRIX_CENTRE_Y)) change = true; + } + + theta2 += 1; + + EVERY_N_MILLIS(25) { + theta1 += 1; + } + + EVERY_N_MILLIS(100) { + if (change && !handledChange) { + handledChange = true; + + if (spirocount >= MATRIX_WIDTH || spirocount == 1) spiroincrement = !spiroincrement; + + if (spiroincrement) { + if(spirocount >= 4) + spirocount *= 2; + else + spirocount += 1; + } + else { + if(spirocount > 4) + spirocount /= 2; + else + spirocount -= 1; + } + + spirooffset = 256 / spirocount; + } + + if(!change) handledChange = false; + } + + EVERY_N_MILLIS(33) { + hueoffset += 1; + } + + effects.ShowFrame(); + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSwirl.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSwirl.h new file mode 100644 index 0000000..a81ed61 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternSwirl.h @@ -0,0 +1,79 @@ +/* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Portions of this code are adapted from SmartMatrixSwirl by Mark Kriegsman: https://gist.github.com/kriegsman/5adca44e14ad025e6d3b +* https://www.youtube.com/watch?v=bsGBT-50cts +* Copyright (c) 2014 Mark Kriegsman +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternSwirl_H + +class PatternSwirl : public Drawable { + private: + const uint8_t borderWidth = 2; + + public: + PatternSwirl() { + name = (char *)"Swirl"; + } + + void start() { + effects.ClearFrame(); + } + + unsigned int drawFrame() { + // Apply some blurring to whatever's already on the matrix + // Note that we never actually clear the matrix, we just constantly + // blur it repeatedly. Since the blurring is 'lossy', there's + // an automatic trend toward black -- by design. + uint8_t blurAmount = beatsin8(2, 10, 255); + +#if FASTLED_VERSION >= 3001000 + blur2d(effects.leds, MATRIX_WIDTH > 255 ? 255 : MATRIX_WIDTH, MATRIX_HEIGHT > 255 ? 255 : MATRIX_HEIGHT, blurAmount); +#else + effects.DimAll(blurAmount); +#endif + + // Use two out-of-sync sine waves + uint8_t i = beatsin8(256/MATRIX_HEIGHT, borderWidth, MATRIX_WIDTH - borderWidth); + uint8_t j = beatsin8(2048/MATRIX_WIDTH, borderWidth, MATRIX_HEIGHT - borderWidth); + + // Also calculate some reflections + uint8_t ni = (MATRIX_WIDTH - 1) - i; + uint8_t nj = (MATRIX_HEIGHT - 1) - j; + + // The color of each point shifts over time, each at a different speed. + uint16_t ms = millis(); + effects.leds[XY(i, j)] += effects.ColorFromCurrentPalette(ms / 11); + //effects.leds[XY(j, i)] += effects.ColorFromCurrentPalette(ms / 13); // this doesn't work for non-square matrices + effects.leds[XY(ni, nj)] += effects.ColorFromCurrentPalette(ms / 17); + //effects.leds[XY(nj, ni)] += effects.ColorFromCurrentPalette(ms / 29); // this doesn't work for non-square matrices + effects.leds[XY(i, nj)] += effects.ColorFromCurrentPalette(ms / 37); + effects.leds[XY(ni, j)] += effects.ColorFromCurrentPalette(ms / 41); + + + effects.ShowFrame(); + return 0; + + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternTest.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternTest.h new file mode 100644 index 0000000..61e870a --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternTest.h @@ -0,0 +1,20 @@ + +#ifndef PatternTest_H +#define PatternTest_H + +class PatternTest : public Drawable { + private: + + public: + PatternTest() { + name = (char *)"Test Pattern"; + } + + unsigned int drawFrame() { + + dma_display->fillScreen(dma_display->color565(128, 0, 0)); + return 1000; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternWave.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternWave.h new file mode 100644 index 0000000..8246a5f --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/PatternWave.h @@ -0,0 +1,120 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternWave_H +#define PatternWave_H + +class PatternWave : public Drawable { +private: + byte thetaUpdate = 0; + byte thetaUpdateFrequency = 0; + byte theta = 0; + + byte hueUpdate = 0; + byte hueUpdateFrequency = 0; + byte hue = 0; + + byte rotation = 0; + + uint8_t scale = 256 / MATRIX_WIDTH; + + uint8_t maxX = MATRIX_WIDTH - 1; + uint8_t maxY = MATRIX_HEIGHT - 1; + + uint8_t waveCount = 1; + +public: + PatternWave() { + name = (char *)"Wave"; + } + + void start() { + rotation = random(0, 4); + waveCount = random(1, 3); + + } + + unsigned int drawFrame() { + int n = 0; + + switch (rotation) { + case 0: + for (int x = 0; x < MATRIX_WIDTH; x++) { + n = quadwave8(x * 2 + theta) / scale; + effects.drawBackgroundFastLEDPixelCRGB(x, n, effects.ColorFromCurrentPalette(x + hue)); + if (waveCount == 2) + effects.drawBackgroundFastLEDPixelCRGB(x, maxY - n, effects.ColorFromCurrentPalette(x + hue)); + } + break; + + case 1: + for (int y = 0; y < MATRIX_HEIGHT; y++) { + n = quadwave8(y * 2 + theta) / scale; + effects.drawBackgroundFastLEDPixelCRGB(n, y, effects.ColorFromCurrentPalette(y + hue)); + if (waveCount == 2) + effects.drawBackgroundFastLEDPixelCRGB(maxX - n, y, effects.ColorFromCurrentPalette(y + hue)); + } + break; + + case 2: + for (int x = 0; x < MATRIX_WIDTH; x++) { + n = quadwave8(x * 2 - theta) / scale; + effects.drawBackgroundFastLEDPixelCRGB(x, n, effects.ColorFromCurrentPalette(x + hue)); + if (waveCount == 2) + effects.drawBackgroundFastLEDPixelCRGB(x, maxY - n, effects.ColorFromCurrentPalette(x + hue)); + } + break; + + case 3: + for (int y = 0; y < MATRIX_HEIGHT; y++) { + n = quadwave8(y * 2 - theta) / scale; + effects.drawBackgroundFastLEDPixelCRGB(n, y, effects.ColorFromCurrentPalette(y + hue)); + if (waveCount == 2) + effects.drawBackgroundFastLEDPixelCRGB(maxX - n, y, effects.ColorFromCurrentPalette(y + hue)); + } + break; + } + + effects.DimAll(254); + effects.ShowFrame(); + + if (thetaUpdate >= thetaUpdateFrequency) { + thetaUpdate = 0; + theta++; + } + else { + thetaUpdate++; + } + + if (hueUpdate >= hueUpdateFrequency) { + hueUpdate = 0; + hue++; + } + else { + hueUpdate++; + } + + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Patterns.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Patterns.h new file mode 100644 index 0000000..100a545 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Patterns.h @@ -0,0 +1,299 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Patterns_H +#define Patterns_H + +#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) + +#include "Vector.h" +#include "Boid.h" +#include "Attractor.h" + +/* + * Note from mrfaptastic: + * + * Commented out patterns are due to the fact they either didn't work properly with a non-square display, + * or from my personal opinion, are crap. + */ + +#include "PatternTest.h" +//#include "PatternNoiseSmearing.h" // Doesn't seem to work, omitting. +#include "PatternSpiro.h" +#include "PatternRadar.h" +#include "PatternSwirl.h" +#include "PatternPendulumWave.h" +#include "PatternFlowField.h" +#include "PatternIncrementalDrift.h" +//#include "PatternIncrementalDrift2.h" // Doesn't seem to work, omitting. +#include "PatternMunch.h" +#include "PatternElectricMandala.h" +//#include "PatternSpin.h" // Doesn't seem to work, omitting. +#include "PatternSimplexNoise.h" +#include "PatternWave.h" +#include "PatternAttract.h" +//#include "PatternBounce.h" // Doesn't seem to work, omitting. +#include "PatternFlock.h" +#include "PatternInfinity.h" +#include "PatternPlasma.h" +#include "PatternSnake.h" +#include "PatternInvaders.h" +//#include "PatternCube.h" // Doesn't seem to work, omitting. +//#include "PatternFire.h" // Doesn't seem to work, omitting. +#include "PatternLife.h" +#include "PatternMaze.h" +//#include "PatternPulse.h" // Doesn't seem to work, omitting. +//#include "PatternSpark.h" // Doesn't seem to work, omitting. +#include "PatternSpiral.h" + +class Patterns : public Playlist { + private: + PatternTest patternTest; + // PatternRainbowFlag rainbowFlag; // doesn't work + // PatternPaletteSmear paletteSmear; + // PatternMultipleStream multipleStream; // doesn't work + // PatternMultipleStream2 multipleStream2; // doesn't work + // PatternMultipleStream3 multipleStream3; // doesn't work + // PatternMultipleStream4 multipleStream4; // doesn't work + // PatternMultipleStream5 multipleStream5; // doesn't work + // PatternMultipleStream8 multipleStream8; // doesn't work + PatternSpiro spiro; + // PatternRadar radar; + PatternSwirl swirl; + PatternPendulumWave pendulumWave; + PatternFlowField flowField; + PatternIncrementalDrift incrementalDrift; + // PatternIncrementalDrift2 incrementalDrift2; + PatternMunch munch; + PatternElectricMandala electricMandala; + // PatternSpin spin; + PatternSimplexNoise simplexNoise; + PatternWave wave; + PatternAttract attract; + // PatternBounce bounce; + PatternFlock flock; + PatternInfinity infinity; + PatternPlasma plasma; + PatternInvadersSmall invadersSmall; + // PatternInvadersMedium invadersMedium; + // PatternInvadersLarge invadersLarge; + PatternSnake snake; + // PatternCube cube; + // PatternFire fire; + PatternLife life; + PatternMaze maze; + // PatternPulse pulse; + // PatternSpark spark; + PatternSpiral spiral; + + int currentIndex = 0; + Drawable* currentItem; + + int getCurrentIndex() { + return currentIndex; + } + + //const static int PATTERN_COUNT = 37; + + const static int PATTERN_COUNT = 17; + + Drawable* shuffledItems[PATTERN_COUNT]; + + Drawable* items[PATTERN_COUNT] = { + // &patternTest, // ok + &spiro, // cool + // &paletteSmear, // fail + // &multipleStream, // fail + // &multipleStream8,// fail + // &multipleStream5,// fail + // &multipleStream3,// fail + // &radar, // fail + // &multipleStream4, // fail + // &multipleStream2, // fail + &life, // ok + &flowField, + &pendulumWave, //11 ok + + &incrementalDrift, //12 ok + // &incrementalDrift2, // 13 fail + &munch, // 14 ok + &electricMandala, // 15 ok + // &spin, // 16 ok but repetitive + &simplexNoise, // 17 - cool! + // &wave, // 18 ok (can't work with 256+ matrix due to uint8_t vars) + // &rainbowFlag, //20 // fail + &attract, // 21 ok + &swirl, // 22 + // &bounce, // bouncing line crap + &flock, // works + &infinity, // works + &plasma, // works + &invadersSmall, // works ish + // &invadersMedium, // fail + // &invadersLarge, // fail + &snake, // ok + // &cube, // works ish + // &fire, // ok ish + &maze, // ok + // &pulse,// fail + // &spark, // same as fire + &spiral, // ok + }; + + public: + Patterns() { + // add the items to the shuffledItems array + for (int a = 0; a < PATTERN_COUNT; a++) { + shuffledItems[a] = items[a]; + } + + shuffleItems(); + + this->currentItem = items[0]; + this->currentItem->start(); + } + + char* Drawable::name = (char *)"Patterns"; + + void stop() { + if (currentItem) + currentItem->stop(); + } + + void start() { + if (currentItem) + currentItem->start(); + } + + void move(int step) { + currentIndex += step; + + if (currentIndex >= PATTERN_COUNT) currentIndex = 0; + else if (currentIndex < 0) currentIndex = PATTERN_COUNT - 1; + + if (effects.paletteIndex == effects.RandomPaletteIndex) + effects.RandomPalette(); + + moveTo(currentIndex); + + //if (!isTimeAvailable && currentItem == &analogClock) + // move(step); + } + + void moveRandom(int step) { + currentIndex += step; + + if (currentIndex >= PATTERN_COUNT) currentIndex = 0; + else if (currentIndex < 0) currentIndex = PATTERN_COUNT - 1; + + if (effects.paletteIndex == effects.RandomPaletteIndex) + effects.RandomPalette(); + + if (currentItem) + currentItem->stop(); + + currentItem = shuffledItems[currentIndex]; + + if (currentItem) + currentItem->start(); + + // if (!isTimeAvailable && currentItem == &analogClock) + // moveRandom(step); + } + + void shuffleItems() { + for (int a = 0; a < PATTERN_COUNT; a++) + { + int r = random(a, PATTERN_COUNT); + Drawable* temp = shuffledItems[a]; + shuffledItems[a] = shuffledItems[r]; + shuffledItems[r] = temp; + } + } + + + unsigned int drawFrame() { + return currentItem->drawFrame(); + } + + void listPatterns() { + Serial.println(F("{")); + Serial.print(F(" \"count\": ")); + Serial.print(PATTERN_COUNT); + Serial.println(","); + Serial.println(F(" \"results\": [")); + + for (int i = 0; i < PATTERN_COUNT; i++) { + Serial.print(F(" \"")); + Serial.print(i, DEC); + Serial.print(F(": ")); + Serial.print(items[i]->name); + if (i == PATTERN_COUNT - 1) + Serial.println(F("\"")); + else + Serial.println(F("\",")); + } + + Serial.println(" ]"); + Serial.println("}"); + } + + char * getCurrentPatternName() + { + return currentItem->name; + } + + void moveTo(int index) { + if (currentItem) + currentItem->stop(); + + currentIndex = index; + + currentItem = items[currentIndex]; + + if (currentItem) + currentItem->start(); + } + + bool setPattern(String name) { + for (int i = 0; i < PATTERN_COUNT; i++) { + if (name.compareTo(items[i]->name) == 0) { + moveTo(i); + return true; + } + } + + return false; + } + + + bool setPattern(int index) { + if (index >= PATTERN_COUNT || index < 0) + return false; + + moveTo(index); + + return true; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Playlist.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Playlist.h new file mode 100644 index 0000000..29c0c87 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Playlist.h @@ -0,0 +1,39 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Playlist_H +#define Playlist_H + +class Playlist : public Drawable { +public: + virtual bool isPlaylist() { + return true; + } + + boolean isCurrentItemFinished = true; + + virtual void move(int step) = 0; + virtual void moveRandom(int step) = 0; + virtual int getCurrentIndex(); +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/README.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/README.md new file mode 100644 index 0000000..2344367 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/README.md @@ -0,0 +1,6 @@ +A port of Aurora visualisations +====== + +Not all of the visualisations have been ported. About 17 of 37 work, or have been included as I think they look best. + +Original source: https://github.com/pixelmatix/aurora \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Vector.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Vector.h new file mode 100644 index 0000000..8acbadc --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/AuroraDemo/Vector.h @@ -0,0 +1,169 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Vector_H +#define Vector_H + +template +class Vector2 { +public: + T x, y; + + Vector2() :x(0), y(0) {} + Vector2(T x, T y) : x(x), y(y) {} + Vector2(const Vector2& v) : x(v.x), y(v.y) {} + + Vector2& operator=(const Vector2& v) { + x = v.x; + y = v.y; + return *this; + } + + bool isEmpty() { + return x == 0 && y == 0; + } + + bool operator==(Vector2& v) { + return x == v.x && y == v.y; + } + + bool operator!=(Vector2& v) { + return !(x == y); + } + + Vector2 operator+(Vector2& v) { + return Vector2(x + v.x, y + v.y); + } + Vector2 operator-(Vector2& v) { + return Vector2(x - v.x, y - v.y); + } + + Vector2& operator+=(Vector2& v) { + x += v.x; + y += v.y; + return *this; + } + Vector2& operator-=(Vector2& v) { + x -= v.x; + y -= v.y; + return *this; + } + + Vector2 operator+(double s) { + return Vector2(x + s, y + s); + } + Vector2 operator-(double s) { + return Vector2(x - s, y - s); + } + Vector2 operator*(double s) { + return Vector2(x * s, y * s); + } + Vector2 operator/(double s) { + return Vector2(x / s, y / s); + } + + Vector2& operator+=(double s) { + x += s; + y += s; + return *this; + } + Vector2& operator-=(double s) { + x -= s; + y -= s; + return *this; + } + Vector2& operator*=(double s) { + x *= s; + y *= s; + return *this; + } + Vector2& operator/=(double s) { + x /= s; + y /= s; + return *this; + } + + void set(T x, T y) { + this->x = x; + this->y = y; + } + + void rotate(double deg) { + double theta = deg / 180.0 * M_PI; + double c = cos(theta); + double s = sin(theta); + double tx = x * c - y * s; + double ty = x * s + y * c; + x = tx; + y = ty; + } + + Vector2& normalize() { + if (length() == 0) return *this; + *this *= (1.0 / length()); + return *this; + } + + float dist(Vector2 v) const { + Vector2 d(v.x - x, v.y - y); + return d.length(); + } + float length() const { + return sqrt(x * x + y * y); + } + + float mag() const { + return length(); + } + + float magSq() { + return (x * x + y * y); + } + + void truncate(double length) { + double angle = atan2f(y, x); + x = length * cos(angle); + y = length * sin(angle); + } + + Vector2 ortho() const { + return Vector2(y, -x); + } + + static float dot(Vector2 v1, Vector2 v2) { + return v1.x * v2.x + v1.y * v2.y; + } + static float cross(Vector2 v1, Vector2 v2) { + return (v1.x * v2.y) - (v1.y * v2.x); + } + + void limit(float max) { + if (magSq() > max*max) { + normalize(); + *this *= max; + } + } +}; + +typedef Vector2 PVector; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/BitmapIcons.ino b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/BitmapIcons.ino new file mode 100644 index 0000000..ab1b6e4 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/BitmapIcons.ino @@ -0,0 +1,204 @@ +#include +#include +#include "Dhole_weather_icons32px.h" + +/*--------------------- DEBUG -------------------------*/ +#define Sprintln(a) (Serial.println(a)) +#define SprintlnDEC(a, x) (Serial.println(a, x)) + +#define Sprint(a) (Serial.print(a)) +#define SprintDEC(a, x) (Serial.print(a, x)) + + +/*--------------------- RGB DISPLAY PINS -------------------------*/ +#define R1_PIN 25 +#define G1_PIN 26 +#define B1_PIN 27 +#define R2_PIN 14 +#define G2_PIN 12 +#define B2_PIN 13 +#define A_PIN 23 +#define B_PIN 19 // Changed from library default +#define C_PIN 5 +#define D_PIN 17 +#define E_PIN -1 +#define LAT_PIN 4 +#define OE_PIN 15 +#define CLK_PIN 16 + + +/*--------------------- MATRIX LILBRARY CONFIG -------------------------*/ +#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module. +#define PANEL_RES_Y 32 // Number of pixels tall of each INDIVIDUAL panel module. +#define PANEL_CHAIN 1 // Total number of panels chained one to another + +MatrixPanel_I2S_DMA *dma_display = nullptr; + +// Module configuration +HUB75_I2S_CFG mxconfig( + PANEL_RES_X, // module width + PANEL_RES_Y, // module height + PANEL_CHAIN // Chain length +); + +/* +//Another way of creating config structure +//Custom pin mapping for all pins +HUB75_I2S_CFG::i2s_pins _pins={R1, G1, BL1, R2, G2, BL2, CH_A, CH_B, CH_C, CH_D, CH_E, LAT, OE, CLK}; +HUB75_I2S_CFG mxconfig( + 64, // width + 64, // height + 4, // chain length + _pins, // pin mapping + HUB75_I2S_CFG::FM6126A // driver chip +); + +*/ + + +//mxconfig.gpio.e = -1; // Assign a pin if you have a 64x64 panel +//mxconfig.clkphase = false; // Change this if you have issues with ghosting. +//mxconfig.driver = HUB75_I2S_CFG::FM6126A; // Change this according to your pane. + + +/* + * Wifi Logo, generated with the following steps: + * + * Python and Paint.Net needs to be installed. + * + * 1. SAVE BITMAP AS 1BIT COLOUR in paint.net + * 2. Run: bmp2hex.py -i -x + * 3. Copy paste output into sketch. + * + */ + +const char wifi_image1bit[] PROGMEM = { + 0x00,0x00,0x00,0xf8,0x1f,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0x01,0x00, + 0x00,0x00,0x00,0xf0,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0x1f, + 0x00,0x00,0x00,0x00,0xfe,0x07,0xe0,0x7f,0x00,0x00,0x00,0x80,0xff,0x00,0x00, + 0xff,0x01,0x00,0x00,0xc0,0x1f,0x00,0x00,0xf8,0x03,0x00,0x00,0xe0,0x0f,0x00, + 0x00,0xf0,0x07,0x00,0x00,0xf0,0x03,0xf0,0x0f,0xc0,0x0f,0x00,0x00,0xe0,0x01, + 0xff,0xff,0x80,0x07,0x00,0x00,0xc0,0xc0,0xff,0xff,0x03,0x03,0x00,0x00,0x00, + 0xe0,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0xf8,0x0f,0xf0,0x1f,0x00,0x00,0x00, + 0x00,0xfc,0x01,0x80,0x3f,0x00,0x00,0x00,0x00,0x7c,0x00,0x00,0x3e,0x00,0x00, + 0x00,0x00,0x38,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x10,0xe0,0x07,0x08,0x00, + 0x00,0x00,0x00,0x00,0xfc,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x7f,0x00, + 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xf8, + 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0xc0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x03,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00 }; + + +void drawXbm565(int x, int y, int width, int height, const char *xbm, uint16_t color = 0xffff) +{ + if (width % 8 != 0) { + width = ((width / 8) + 1) * 8; + } + for (int i = 0; i < width * height / 8; i++ ) { + unsigned char charColumn = pgm_read_byte(xbm + i); + for (int j = 0; j < 8; j++) { + int targetX = (i * 8 + j) % width + x; + int targetY = (8 * i / (width)) + y; + if (bitRead(charColumn, j)) { + dma_display->drawPixel(targetX, targetY, color); + } + } + } +} + +/* Bitmaps */ +int current_icon = 0; +static int num_icons = 22; + +static char icon_name[22][30] = { +"cloud_moon_bits", +"cloud_sun_bits", +"clouds_bits", +"cloud_wind_moon_bits", +"cloud_wind_sun_bits", +"cloud_wind_bits", +"cloud_bits", +"lightning_bits", +"moon_bits", +"rain0_sun_bits", +"rain0_bits", +"rain1_moon_bits", +"rain1_sun_bits", +"rain1_bits", +"rain2_bits", +"rain_lightning_bits", +"rain_snow_bits", +"snow_moon_bits", +"snow_sun_bits", +"snow_bits", +"sun_bits", +"wind_bits" }; + +static char *icon_bits[22] = { cloud_moon_bits, +cloud_sun_bits, +clouds_bits, +cloud_wind_moon_bits, +cloud_wind_sun_bits, +cloud_wind_bits, +cloud_bits, +lightning_bits, +moon_bits, +rain0_sun_bits, +rain0_bits, +rain1_moon_bits, +rain1_sun_bits, +rain1_bits, +rain2_bits, +rain_lightning_bits, +rain_snow_bits, +snow_moon_bits, +snow_sun_bits, +snow_bits, +sun_bits, +wind_bits}; + + + +void setup() { + + // put your setup code here, to run once: + delay(1000); Serial.begin(115200); delay(200); + + + /************** DISPLAY **************/ + Sprintln("...Starting Display"); + dma_display = new MatrixPanel_I2S_DMA(mxconfig); + dma_display->begin(); + dma_display->setBrightness8(90); //0-255 + dma_display->clearScreen(); + + dma_display->fillScreen(dma_display->color444(0, 1, 0)); + + // Fade a Red Wifi Logo In + for (int r=0; r < 255; r++ ) + { + drawXbm565(0,0,64,32, wifi_image1bit, dma_display->color565(r,0,0)); + delay(10); + } + + delay(2000); + dma_display->clearScreen(); +} + + +void loop() { + + // Loop through Weather Icons + Serial.print("Showing icon "); + Serial.println(icon_name[current_icon]); + drawXbm565(0,0, 32, 32, icon_bits[current_icon]); + + current_icon = (current_icon +1 ) % num_icons; + delay(2000); + dma_display->clearScreen(); + +} \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/Dhole_weather_icons32px.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/Dhole_weather_icons32px.h new file mode 100644 index 0000000..5fb8b3b --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/Dhole_weather_icons32px.h @@ -0,0 +1,308 @@ +#define cloud_moon_width 32 +#define cloud_moon_height 32 +static char cloud_moon_bits[] = { + 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x7C, 0x00, + 0x00, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x67, 0x00, + 0x00, 0x00, 0xE3, 0x00, 0x00, 0x00, 0xC3, 0x01, 0x00, 0xF0, 0x87, 0xC3, + 0x00, 0xFC, 0x1F, 0xFF, 0x00, 0x1E, 0x3C, 0xFE, 0x00, 0x06, 0x30, 0x60, + 0x00, 0x07, 0xF0, 0x79, 0x00, 0x03, 0xE0, 0x3F, 0xE0, 0x03, 0x00, 0x0F, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0E, 0x1C, 0x00, 0x00, 0x07, 0x38, 0x00, 0x80, 0x03, + 0xF0, 0xFF, 0xFF, 0x01, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define cloud_sun_width 32 +#define cloud_sun_height 32 +static char cloud_sun_bits[] = { + 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x80, 0xC1, 0x60, + 0x00, 0x80, 0x03, 0x70, 0x00, 0x00, 0xF3, 0x33, 0x00, 0x00, 0xF8, 0x07, + 0x00, 0x00, 0x1C, 0x0E, 0x00, 0x00, 0x0E, 0x1C, 0x00, 0xF0, 0x07, 0x18, + 0x00, 0xFC, 0x1F, 0xD8, 0x00, 0x1E, 0x3C, 0xD8, 0x00, 0x06, 0x30, 0x18, + 0x00, 0x07, 0xF0, 0x1D, 0x00, 0x03, 0xE0, 0x0F, 0xE0, 0x03, 0x00, 0x07, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0E, 0x1C, 0x00, 0x00, 0x07, 0x38, 0x00, 0x80, 0x03, + 0xF0, 0xFF, 0xFF, 0x01, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define clouds_width 32 +#define clouds_height 32 +static char clouds_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0xC0, 0xFF, 0x01, + 0x00, 0xE0, 0xC1, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0xF0, 0x07, 0x1F, + 0x00, 0xFC, 0x1F, 0x3E, 0x00, 0x1E, 0x3C, 0x70, 0x00, 0x06, 0x30, 0xE0, + 0x00, 0x07, 0xF0, 0xC1, 0x00, 0x03, 0xE0, 0xC3, 0xE0, 0x03, 0x00, 0xC7, + 0xF0, 0x01, 0x00, 0xCE, 0x38, 0x00, 0x00, 0xCC, 0x1C, 0x00, 0x00, 0xEC, + 0x0C, 0x00, 0x00, 0x6C, 0x0C, 0x00, 0x00, 0x2C, 0x0C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0E, 0x1C, 0x00, 0x00, 0x07, 0x38, 0x00, 0x80, 0x03, + 0xF0, 0xFF, 0xFF, 0x01, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define cloud_wind_moon_width 32 +#define cloud_wind_moon_height 32 +static char cloud_wind_moon_bits[] = { + 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x7C, 0x00, + 0x00, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x67, 0x00, + 0x00, 0x00, 0xE3, 0x00, 0x00, 0x00, 0xC3, 0x01, 0x00, 0xF0, 0x87, 0xC3, + 0x00, 0xFC, 0x1F, 0xFF, 0x00, 0x1E, 0x3C, 0xFE, 0x00, 0x06, 0x30, 0x60, + 0x00, 0x07, 0xF0, 0x79, 0x00, 0x03, 0xE0, 0x3F, 0xE0, 0x03, 0x00, 0x0F, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, + 0xFC, 0xFF, 0x3F, 0x0E, 0xFC, 0xFF, 0x3F, 0x07, 0x00, 0x00, 0x80, 0x03, + 0xFF, 0xFF, 0xEF, 0x01, 0xFF, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFC, 0xFF, 0x3F, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define cloud_wind_sun_width 32 +#define cloud_wind_sun_height 32 +static char cloud_wind_sun_bits[] = { + 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x80, 0xC1, 0x60, + 0x00, 0x80, 0x03, 0x70, 0x00, 0x00, 0xF3, 0x33, 0x00, 0x00, 0xF8, 0x07, + 0x00, 0x00, 0x1C, 0x0E, 0x00, 0x00, 0x0E, 0x1C, 0x00, 0xF0, 0x07, 0x18, + 0x00, 0xFC, 0x1F, 0xD8, 0x00, 0x1E, 0x3C, 0xD8, 0x00, 0x06, 0x30, 0x18, + 0x00, 0x07, 0xF0, 0x1D, 0x00, 0x03, 0xE0, 0x0F, 0xE0, 0x03, 0x00, 0x07, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, + 0xFC, 0xFF, 0x3F, 0x0E, 0xFC, 0xFF, 0x3F, 0x07, 0x00, 0x00, 0x80, 0x03, + 0xFF, 0xFF, 0xEF, 0x01, 0xFF, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFC, 0xFF, 0x3F, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define cloud_wind_width 32 +#define cloud_wind_height 32 +static char cloud_wind_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, + 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x06, 0x30, 0x00, + 0x00, 0x07, 0xF0, 0x01, 0x00, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0x00, 0x07, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, + 0xFC, 0xFF, 0x3F, 0x0E, 0xFC, 0xFF, 0x3F, 0x07, 0x00, 0x00, 0x80, 0x03, + 0xFF, 0xFF, 0xEF, 0x01, 0xFF, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFC, 0xFF, 0x3F, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define cloud_width 32 +#define cloud_height 32 +static char cloud_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, + 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x06, 0x30, 0x00, + 0x00, 0x07, 0xF0, 0x01, 0x00, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0x00, 0x07, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0E, 0x1C, 0x00, 0x00, 0x07, 0x38, 0x00, 0x80, 0x03, + 0xF0, 0xFF, 0xFF, 0x01, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define lightning_width 32 +#define lightning_height 32 +static char lightning_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, + 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x06, 0x30, 0x00, + 0x00, 0x07, 0xF0, 0x01, 0x00, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0x00, 0x07, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0xC0, 0x01, 0x0C, + 0x0C, 0xC0, 0x01, 0x0E, 0x1C, 0xC0, 0x00, 0x07, 0x38, 0xE0, 0x80, 0x03, + 0xF0, 0x6F, 0xFC, 0x01, 0xE0, 0xEF, 0xFD, 0x00, 0x00, 0x80, 0x01, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define moon_width 32 +#define moon_height 32 +static char moon_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x78, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, + 0x80, 0x1B, 0x00, 0x00, 0xC0, 0x19, 0x00, 0x00, 0xE0, 0x1C, 0x00, 0x00, + 0x60, 0x0C, 0x00, 0x00, 0x70, 0x0C, 0x00, 0x00, 0x30, 0x0C, 0x00, 0x00, + 0x30, 0x0C, 0x00, 0x00, 0x38, 0x1C, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x18, 0x38, 0x00, 0x00, 0x18, 0x30, 0x00, 0x00, 0x18, 0x70, 0x00, 0x00, + 0x38, 0xE0, 0x01, 0x18, 0x30, 0xC0, 0x87, 0x1F, 0x70, 0x00, 0xFF, 0x1F, + 0x60, 0x00, 0xFC, 0x0C, 0xE0, 0x00, 0x00, 0x0E, 0xC0, 0x01, 0x00, 0x07, + 0x80, 0x03, 0x80, 0x03, 0x00, 0x0F, 0xE0, 0x01, 0x00, 0x3E, 0xFC, 0x00, + 0x00, 0xF8, 0x3F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define rain0_sun_width 32 +#define rain0_sun_height 32 +static char rain0_sun_bits[] = { + 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x80, 0xC1, 0x60, + 0x00, 0x80, 0x03, 0x70, 0x00, 0x00, 0xF3, 0x33, 0x00, 0x00, 0xF8, 0x07, + 0x00, 0x00, 0x1C, 0x0E, 0x00, 0x00, 0x0E, 0x1C, 0x00, 0xF0, 0x07, 0x18, + 0x00, 0xFC, 0x1F, 0xD8, 0x00, 0x1E, 0x3C, 0xD8, 0x00, 0x06, 0x30, 0x18, + 0x00, 0x07, 0xF0, 0x1D, 0x00, 0x03, 0xE0, 0x0F, 0xE0, 0x03, 0x00, 0x07, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x60, 0x06, 0x0C, + 0x0C, 0x60, 0x06, 0x0E, 0x1C, 0x70, 0x07, 0x07, 0x38, 0x30, 0x83, 0x03, + 0xF0, 0x33, 0xFB, 0x01, 0xE0, 0x01, 0xF8, 0x00, 0x00, 0xCC, 0x00, 0x00, + 0x00, 0xCC, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define rain0_width 32 +#define rain0_height 32 +static char rain0_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, + 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x06, 0x30, 0x00, + 0x00, 0x07, 0xF0, 0x01, 0x00, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0x00, 0x07, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x60, 0x06, 0x0C, + 0x0C, 0x60, 0x06, 0x0E, 0x1C, 0x70, 0x07, 0x07, 0x38, 0x30, 0x83, 0x03, + 0xF0, 0x33, 0xFB, 0x01, 0xE0, 0x01, 0xF8, 0x00, 0x00, 0xCC, 0x00, 0x00, + 0x00, 0xCC, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define rain1_moon_width 32 +#define rain1_moon_height 32 +static char rain1_moon_bits[] = { + 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x7C, 0x00, + 0x00, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x67, 0x00, + 0x00, 0x00, 0xE3, 0x00, 0x00, 0x00, 0xC3, 0x01, 0x00, 0xF0, 0x87, 0xC3, + 0x00, 0xFC, 0x1F, 0xFF, 0x00, 0x1E, 0x3C, 0xFE, 0x00, 0x06, 0x30, 0x60, + 0x00, 0x07, 0xF0, 0x79, 0x00, 0x03, 0xE0, 0x3F, 0xE0, 0x03, 0x00, 0x0F, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x60, 0x06, 0x0C, + 0x0C, 0x60, 0x06, 0x0E, 0x1C, 0x70, 0x07, 0x07, 0x38, 0x30, 0x83, 0x03, + 0xF0, 0xBB, 0xFB, 0x01, 0xE0, 0x99, 0xF9, 0x00, 0x00, 0xDC, 0x01, 0x00, + 0x00, 0xCC, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define rain1_sun_width 32 +#define rain1_sun_height 32 +static char rain1_sun_bits[] = { + 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x80, 0xC1, 0x60, + 0x00, 0x80, 0x03, 0x70, 0x00, 0x00, 0xF3, 0x33, 0x00, 0x00, 0xF8, 0x07, + 0x00, 0x00, 0x1C, 0x0E, 0x00, 0x00, 0x0E, 0x1C, 0x00, 0xF0, 0x07, 0x18, + 0x00, 0xFC, 0x1F, 0xD8, 0x00, 0x1E, 0x3C, 0xD8, 0x00, 0x06, 0x30, 0x18, + 0x00, 0x07, 0xF0, 0x1D, 0x00, 0x03, 0xE0, 0x0F, 0xE0, 0x03, 0x00, 0x07, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x60, 0x06, 0x0C, + 0x0C, 0x60, 0x06, 0x0E, 0x1C, 0x70, 0x07, 0x07, 0x38, 0x30, 0x83, 0x03, + 0xF0, 0xBB, 0xFB, 0x01, 0xE0, 0x99, 0xF9, 0x00, 0x00, 0xDC, 0x01, 0x00, + 0x00, 0xCC, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define rain1_width 32 +#define rain1_height 32 +static char rain1_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, + 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x06, 0x30, 0x00, + 0x00, 0x07, 0xF0, 0x01, 0x00, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0x00, 0x07, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x60, 0x06, 0x0C, + 0x0C, 0x60, 0x06, 0x0E, 0x1C, 0x70, 0x07, 0x07, 0x38, 0x30, 0x83, 0x03, + 0xF0, 0xBB, 0xFB, 0x01, 0xE0, 0x99, 0xF9, 0x00, 0x00, 0xDC, 0x01, 0x00, + 0x00, 0xCC, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define rain2_width 32 +#define rain2_height 32 +static char rain2_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, + 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x06, 0x30, 0x00, + 0x00, 0x07, 0xF0, 0x01, 0x00, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0x00, 0x07, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x66, 0x66, 0x0C, + 0x0C, 0x66, 0x66, 0x0E, 0x1C, 0x77, 0x77, 0x07, 0x38, 0x33, 0x33, 0x03, + 0xB0, 0xBB, 0xBB, 0x01, 0x80, 0x99, 0x99, 0x00, 0xC0, 0xDD, 0x1D, 0x00, + 0xC0, 0xCC, 0x0C, 0x00, 0xC0, 0xEE, 0x0C, 0x00, 0x00, 0x66, 0x00, 0x00, + 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define rain_lightning_width 32 +#define rain_lightning_height 32 +static char rain_lightning_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, + 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x06, 0x30, 0x00, + 0x00, 0x07, 0xF0, 0x01, 0x00, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0x00, 0x07, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0xCC, 0x1C, 0x0C, + 0x0C, 0xCC, 0x1C, 0x0E, 0x1C, 0xEE, 0x0C, 0x07, 0x38, 0x66, 0x8E, 0x03, + 0x70, 0x77, 0xC6, 0x01, 0x20, 0x33, 0xDE, 0x00, 0x80, 0x3B, 0x18, 0x00, + 0x80, 0x19, 0x0C, 0x00, 0x80, 0x1D, 0x0C, 0x00, 0x00, 0x0C, 0x04, 0x00, + 0x00, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define rain_snow_width 32 +#define rain_snow_height 32 +static char rain_snow_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, + 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x06, 0x30, 0x00, + 0x00, 0x07, 0xF0, 0x01, 0x00, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0x00, 0x07, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0xCC, 0x08, 0x0C, + 0x0C, 0xCC, 0x1C, 0x0E, 0x1C, 0xEE, 0x36, 0x07, 0x38, 0x66, 0x9C, 0x03, + 0x70, 0x77, 0xC8, 0x01, 0x20, 0x33, 0xE2, 0x00, 0x80, 0x3B, 0x07, 0x00, + 0x80, 0x99, 0x0D, 0x00, 0x80, 0x1D, 0x07, 0x00, 0x00, 0x0C, 0x02, 0x00, + 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define snow_moon_width 32 +#define snow_moon_height 32 +static char snow_moon_bits[] = { + 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x7C, 0x00, + 0x00, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x67, 0x00, + 0x00, 0x00, 0xE3, 0x00, 0x00, 0x00, 0xC3, 0x01, 0x00, 0xF0, 0x87, 0xC3, + 0x00, 0xFC, 0x1F, 0xFF, 0x00, 0x1E, 0x3C, 0xFE, 0x00, 0x06, 0x30, 0x60, + 0x00, 0x07, 0xF0, 0x79, 0x00, 0x03, 0xE0, 0x3F, 0xE0, 0x03, 0x00, 0x0F, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0E, 0x1C, 0x40, 0x00, 0x07, 0x38, 0xE0, 0x80, 0x03, + 0xF0, 0xB1, 0xF1, 0x01, 0xE0, 0xE0, 0xE0, 0x00, 0x00, 0x44, 0x04, 0x00, + 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00, 0x0E, 0x0E, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define snow_sun_width 32 +#define snow_sun_height 32 +static char snow_sun_bits[] = { + 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x80, 0xC1, 0x60, + 0x00, 0x80, 0x03, 0x70, 0x00, 0x00, 0xF3, 0x33, 0x00, 0x00, 0xF8, 0x07, + 0x00, 0x00, 0x1C, 0x0E, 0x00, 0x00, 0x0E, 0x1C, 0x00, 0xF0, 0x07, 0x18, + 0x00, 0xFC, 0x1F, 0xD8, 0x00, 0x1E, 0x3C, 0xD8, 0x00, 0x06, 0x30, 0x18, + 0x00, 0x07, 0xF0, 0x1D, 0x00, 0x03, 0xE0, 0x0F, 0xE0, 0x03, 0x00, 0x07, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0E, 0x1C, 0x40, 0x00, 0x07, 0x38, 0xE0, 0x80, 0x03, + 0xF0, 0xB1, 0xF1, 0x01, 0xE0, 0xE0, 0xE0, 0x00, 0x00, 0x44, 0x04, 0x00, + 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00, 0x0E, 0x0E, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define snow_width 32 +#define snow_height 32 +static char snow_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, + 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x06, 0x30, 0x00, + 0x00, 0x07, 0xF0, 0x01, 0x00, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0x00, 0x07, + 0xF0, 0x01, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, + 0x0C, 0x00, 0x00, 0x0E, 0x1C, 0x40, 0x00, 0x07, 0x38, 0xE0, 0x80, 0x03, + 0xF0, 0xB1, 0xF1, 0x01, 0xE0, 0xE0, 0xE0, 0x00, 0x00, 0x44, 0x04, 0x00, + 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00, 0x0E, 0x0E, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define sun_width 32 +#define sun_height 32 +static char sun_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, + 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x83, 0xC1, 0x00, + 0x00, 0x07, 0xE0, 0x00, 0x00, 0xE6, 0x67, 0x00, 0x00, 0xF0, 0x0F, 0x00, + 0x00, 0x38, 0x1C, 0x00, 0x00, 0x1C, 0x38, 0x00, 0x00, 0x0C, 0x30, 0x00, + 0xF0, 0x0D, 0xB0, 0x0F, 0xF0, 0x0D, 0xB0, 0x0F, 0x00, 0x0C, 0x30, 0x00, + 0x00, 0x1C, 0x38, 0x00, 0x00, 0x38, 0x1C, 0x00, 0x00, 0xF0, 0x0F, 0x00, + 0x00, 0xE6, 0x67, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x83, 0xC1, 0x00, + 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, + 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +#define wind_width 32 +#define wind_height 32 +static char wind_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x80, 0x01, + 0xF0, 0xFF, 0xFF, 0x19, 0xF0, 0xFF, 0xFF, 0x3C, 0x00, 0x00, 0x00, 0x30, + 0xFC, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, + 0xF0, 0xFF, 0xFF, 0x01, 0xF0, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/README.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/README.md new file mode 100644 index 0000000..155365e --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/README.md @@ -0,0 +1,13 @@ +# Xbm Bitmap example +## Requirements +* To generate the required Xbm data to be copied into the Sketch. Have python and [paint.net](https://www.getpaint.net/) installed. +* Bitmap should match the resolution of your display configuration. + +## Instructions + 1. SAVE BITMAP AS 1BIT COLOUR in paint.net + 1. Run: bmp2hex.py -i -x (e.g. "bmp2hex.py -i -x WiFi1bit.bmp") + 1. Copy paste output into sketch. + + ![bmp2hex usage screenshot](screenshot.jpg) + + diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/WiFi1bit.bmp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/WiFi1bit.bmp new file mode 100644 index 0000000..2bace87 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/WiFi1bit.bmp differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/bmp2hex.py b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/bmp2hex.py new file mode 100644 index 0000000..49e1c65 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/bmp2hex.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python + +##@file bmp2hex.py +# @ingroup util +# A script for converting a 1-bit bitmap to HEX for use in an Arduino sketch. +# +# The BMP format is well publicized. The byte order of the actual bitmap is a +# little unusual. The image is stored bottom to top, left to right. In addition, +# The pixel rows are rounded to DWORDS which are 4 bytes long. SO, to convert this +# to left to right, top to bottom, no byte padding. We have to do some calculations +# as we loop through the rows and bytes of the image. See below for more +# +# Usage: +# >>>bmp2hex.py [-i] [-r] [-n] [-d] [-x] [-w ] [-b ] +# +# @param infile The file to convert. +# @param tablename The name of the table to create +# @param raw "-r", bitmap written as raw table [optional] +# @param invert "-i", to invert image pixel colors [optional] +# @param tablewidth "-w , The number of characters for each row of the output table [optional] +# @param sizebytes "-b , Bytes = 0, 1, or 2. 0 = auto. 1 = 1-byte for sizes. 2 = 2-byte sizes (big endian) [optional] +# @param named "-n", use a names structure [optional] +## @param double "-d", use double bytes rather than single ones [optional] +# @param xbm "-x", use XBM format (bits reversed in byte) [optional] +# @param version "-v", returns version number +# +# @author Robert Gallup 2016-02 +# +# Author: Robert Gallup (bg@robertgallup.com) +# License: MIT Opensource License +# +# Copyright 2016-2018 Robert Gallup +# + +import sys, array, os, textwrap, math, random, argparse + +class DEFAULTS(object): + STRUCTURE_NAME = 'GFXMeta' + VERSION = '2.3.4' + +def main (): + + # Default parameters + infile = "" + tablename = "" + tablewidth = 16 + sizebytes = 0 + invert = False + raw = False + named = False + double = False + xbm = False + version = False + + # Set up parser and handle arguments + parser = argparse.ArgumentParser() + # parser.add_argument ("infile", help="The BMP file(s) to convert", type=argparse.FileType('r'), nargs='+', default=['-']) + parser.add_argument ("infile", help="The BMP file(s) to convert", type=argparse.FileType('r'), nargs='*', default=['-']) + parser.add_argument ("-r", "--raw", help="Outputs all data in raw table format", action="store_true") + parser.add_argument ("-i", "--invert", help="Inverts bitmap pixels", action="store_true") + parser.add_argument ("-w", "--width", help="Output table width in hex bytes [default: 16]", type=int) + parser.add_argument ("-b", "--bytes", help="Byte width of BMP sizes: 0=auto, 1, or 2 (big endian) [default: 0]", type=int) + parser.add_argument ("-n", "--named", help="Uses named structure (" + DEFAULTS.STRUCTURE_NAME + ") for data", action="store_true") +# parser.add_argument ("-d", "--double", help="Defines data in 'words' rather than bytes", action="store_true") + parser.add_argument ("-x", "--xbm", help="Uses XBM bit order (low order bit is first pixel of byte)", action="store_true") + parser.add_argument ("-v", "--version", help="Returns the current bmp2hex version", action="store_true") + args = parser.parse_args() + + # Required arguments + infile = args.infile + + # Options + if args.raw: + raw = args.raw + if args.invert: + invert = args.invert + if args.width: + tablewidth = args.width + if args.bytes: + sizebytes = args.bytes % 3 + if args.named: + named = args.named + # if args.double: + # double = args.double + double = False + if args.xbm: + xbm = args.xbm + if args.version: + print ('// bmp2hex version ' + DEFAULTS.VERSION) + + # Output named structure, if requested + if (named): + print ('struct ' + DEFAULTS.STRUCTURE_NAME + ' {') + print (' unsigned int width;') + print (' unsigned int height;') + print (' unsigned int bitDepth;') + print (' int baseline;') + print (' ' + getDoubleType(double)[0] + 'pixel_data;') + print ('};') + print ('') + + # Do the work + for f in args.infile: + if f == '-': + sys.exit() + bmp2hex(f.name, tablewidth, sizebytes, invert, raw, named, double, xbm) + +# Utility function. Return a long int from array (little endian) +def getLONG(a, n): + return (a[n+3] * (2**24)) + (a[n+2] * (2**16)) + (a[n+1] * (2**8)) + (a[n]) + +# Utility function. Return an int from array (little endian) +def getINT(a, n): + return ((a[n+1] * (2**8)) + (a[n])) + +# Reverses pixels in byte +def reflect(a): + r = 0 + for i in range(8): + r <<= 1 + r |= (a & 0x01) + a >>= 1 + return (r) + +# Returns as a tuple, the data type and length for double versus short data types +def getDoubleType (d): + if d: + dType = 'uint16_t' + ' *' + dLen = 2 + else: + dType = 'uint8_t' + ' *' + dLen = 1 + + return (dType, dLen) + + +# Main conversion function +def bmp2hex(infile, tablewidth, sizebytes, invert, raw, named, double, xbm): + + # Set up some variables to handle the "-d" option + (pixelDataType, dataByteLength) = getDoubleType(double) + + # Set the table name to the uppercase root of the file name + tablename = os.path.splitext(infile)[0].upper() + + # Convert tablewidth to characters from hex bytes + tablewidth = int(tablewidth) * 6 + + # Initialize output buffer + outstring = '' + + # Open File + fin = open(os.path.expanduser(infile), "rb") + uint8_tstoread = os.path.getsize(os.path.expanduser(infile)) + valuesfromfile = array.array('B') + try: + valuesfromfile.fromfile(fin, uint8_tstoread) + finally: + fin.close() + + # Get bytes from file + values=valuesfromfile.tolist() + + # Exit if it's not a Windows BMP + if ((values[0] != 0x42) or (values[1] != 0x4D)): + sys.exit ("Error: Unsupported BMP format. Make sure your file is a Windows BMP.") + + # Calculate width, height + dataOffset = getLONG(values, 10) # Offset to image data + pixelWidth = getLONG(values, 18) # Width of image + pixelHeight = getLONG(values, 22) # Height of image + bitDepth = getINT (values, 28) # Bits per pixel + dataSize = getLONG(values, 34) # Size of raw data + + # Calculate line width in bytes and padded byte width (each row is padded to 4-byte multiples) + byteWidth = int(math.ceil(float(pixelWidth * bitDepth)/8.0)) + paddedWidth = int(math.ceil(float(byteWidth)/4.0)*4.0) + + # For auto (sizebytes = 0), set sizebytes to 1 or 2, depending on size of the bitmap + if (sizebytes==0): + if (pixelWidth>255) or (pixelHeight>255): + sizebytes = 2 + else: + sizebytes = 1 + + # The invert byte is set based on the invert command line flag (but, the logic is reversed for 1-bit files) + invertbyte = 0xFF if invert else 0x00 + if (bitDepth == 1): + invertbyte = invertbyte ^ 0xFF + + # Output the hex table declaration + # With "raw" output, output just an array of chars + if (raw): + # Output the data declaration + print ('PROGMEM unsigned char const ' + tablename + ' [] = {') + + # Output the size of the BMP + if (not (sizebytes%2)): + print ("{0:#04X}".format((pixelWidth>>8) & 0xFF) + ", " + "{0:#04X}".format(pixelWidth & 0xFF) + ", " + \ + "{0:#04X}".format((pixelHeight>>8) & 0xFF) + ", " + "{0:#04X}".format(pixelHeight & 0xFF) + ",") + else: + print ("{0:#04X}".format(pixelWidth & 0xFF) + ", " + "{0:#04X}".format(pixelHeight & 0xFF) + ",") + + elif (named): + print ('PROGMEM ' + getDoubleType(double)[0] + ' const ' + tablename + '_PIXELS[] = {') + + elif (xbm): + print ('#define ' + tablename + '_width ' + str(pixelWidth)) + print ('#define ' + tablename + '_height ' + str(pixelHeight)) + print ('PROGMEM ' + getDoubleType(double)[0] + ' const ' + tablename + '_bits[] = {') + + else: + print ('PROGMEM const struct {') + print (' unsigned int width;') + print (' unsigned int height;') + print (' unsigned int bitDepth;') + print (' ' + pixelDataType + 'pixel_data[{0}];'.format(byteWidth * pixelHeight / dataByteLength)) + print ('} ' + tablename + ' = {') + print ('{0}, {1}, {2}, {{'.format(pixelWidth, pixelHeight, bitDepth)) + + # Generate HEX bytes for pixel data in output buffer + try: + for i in range(pixelHeight): + for j in range (byteWidth): + ndx = dataOffset + ((pixelHeight-1-i) * paddedWidth) + j + v = values[ndx] ^ invertbyte + if (xbm): + v = reflect(v) + # print ("{0:#04x}".format(v)) + outstring += "{0:#04x}".format(v) + ", " + + # Wrap the output buffer. Print. Then, finish. + finally: + outstring = textwrap.fill(outstring[:-2], tablewidth) + print (outstring) + + if (named): + print ('};') + print (DEFAULTS.STRUCTURE_NAME + ' const ' + tablename + ' = {{{0}, {1}, {2}, 0, '.format(pixelWidth, pixelHeight, bitDepth) + \ + pixelDataType + tablename + "_PIXELS};\n\n") + else: + if (not (raw or xbm)): + print ("}") + print ("};") + + +# Only run if launched from commandline +if __name__ == '__main__': main() \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/screenshot.jpg b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/screenshot.jpg new file mode 100644 index 0000000..1148260 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/BitmapIcons/screenshot.jpg differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanels/ChainedPanels.ino b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanels/ChainedPanels.ino new file mode 100644 index 0000000..1343d9b --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanels/ChainedPanels.ino @@ -0,0 +1,169 @@ +/****************************************************************************** + ------------------------------------------------------------------------- + Steps to create a virtual display made up of a chain of panels in a grid + ------------------------------------------------------------------------- + + Read the documentation! + https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/tree/master/examples/ChainedPanels + + tl/dr: + + - Set values for NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, PANEL_CHAIN_TYPE. + + - Other than where the matrix is defined and matrix.begin in the setup, you + should now be using the virtual display for everything (drawing pixels, writing text etc). + You can do a find and replace of all calls if it's an existing sketch + (just make sure you don't replace the definition and the matrix.begin) + + - If the sketch makes use of MATRIX_HEIGHT or MATRIX_WIDTH, these will need to be + replaced with the width and height of your virtual screen. + Either make new defines and use that, or you can use virtualDisp.width() or .height() + +*****************************************************************************/ +// 1) Include key virtual display library + #include + +// 2) Set configuration + #define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module. + #define PANEL_RES_Y 32 // Number of pixels tall of each INDIVIDUAL panel module. + + #define NUM_ROWS 2 // Number of rows of chained INDIVIDUAL PANELS + #define NUM_COLS 2 // Number of INDIVIDUAL PANELS per ROW + #define PANEL_CHAIN NUM_ROWS*NUM_COLS // total number of panels chained one to another + + /* Configure the serpetine chaining approach. Options are: + CHAIN_TOP_LEFT_DOWN + CHAIN_TOP_RIGHT_DOWN + CHAIN_BOTTOM_LEFT_UP + CHAIN_BOTTOM_RIGHT_UP + + The location (i.e. 'TOP_LEFT', 'BOTTOM_RIGHT') etc. refers to the starting point where + the ESP32 is located, and how the chain of panels will 'roll out' from there. + + In this example we're using 'CHAIN_BOTTOM_LEFT_UP' which would look like this in the real world: + + Chain of 4 x 64x32 panels with the ESP at the BOTTOM_LEFT: + + +---------+---------+ + | 4 | 3 | + | | | + +---------+---------+ + | 1 | 2 | + | (ESP) | | + +---------+---------+ + + */ + #define VIRTUAL_MATRIX_CHAIN_TYPE CHAIN_BOTTOM_LEFT_UP + +// 3) Create the runtime objects to use + + // placeholder for the matrix object + MatrixPanel_I2S_DMA *dma_display = nullptr; + + // placeholder for the virtual display object + VirtualMatrixPanel *virtualDisp = nullptr; + + +/****************************************************************************** + * Setup! + ******************************************************************************/ +void setup() { + + delay(2000); + Serial.begin(115200); + Serial.println(""); Serial.println(""); Serial.println(""); + Serial.println("*****************************************************"); + Serial.println(" HELLO !"); + Serial.println("*****************************************************"); + + + /****************************************************************************** + * Create physical DMA panel class AND virtual (chained) display class. + ******************************************************************************/ + + /* + The configuration for MatrixPanel_I2S_DMA object is held in HUB75_I2S_CFG structure, + All options has it's predefined default values. So we can create a new structure and redefine only the options we need + + Please refer to the '2_PatternPlasma.ino' example for detailed example of how to use the MatrixPanel_I2S_DMA configuration + */ + + HUB75_I2S_CFG mxconfig( + PANEL_RES_X, // module width + PANEL_RES_Y, // module height + PANEL_CHAIN // chain length + ); + + //mxconfig.driver = HUB75_I2S_CFG::FM6126A; // in case that we use panels based on FM6126A chip, we can set it here before creating MatrixPanel_I2S_DMA object + + // Sanity checks + if (NUM_ROWS <= 1) { + Serial.println(F("There is no reason to use the VirtualDisplay class for a single horizontal chain and row!")); + } + + // OK, now we can create our matrix object + dma_display = new MatrixPanel_I2S_DMA(mxconfig); + + // let's adjust default brightness to about 75% + dma_display->setBrightness8(192); // range is 0-255, 0 - 0%, 255 - 100% + + // Allocate memory and start DMA display + if( not dma_display->begin() ) + Serial.println("****** !KABOOM! I2S memory allocation failed ***********"); + + // create VirtualDisplay object based on our newly created dma_display object + virtualDisp = new VirtualMatrixPanel((*dma_display), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, VIRTUAL_MATRIX_CHAIN_TYPE); + + // So far so good, so continue + virtualDisp->fillScreen(virtualDisp->color444(0, 0, 0)); + virtualDisp->drawDisplayTest(); // draw text numbering on each screen to check connectivity + + // delay(1000); + + Serial.println("Chain of 4x 64x32 panels for this example:"); + Serial.println("+---------+---------+"); + Serial.println("| 4 | 3 |"); + Serial.println("| | |"); + Serial.println("+---------+---------+"); + Serial.println("| 1 | 2 |"); + Serial.println("| (ESP32) | |"); + Serial.println("+---------+---------+"); + + // draw blue text + virtualDisp->setFont(&FreeSansBold12pt7b); + virtualDisp->setTextColor(virtualDisp->color565(0, 0, 255)); + virtualDisp->setTextSize(3); + virtualDisp->setCursor(0, virtualDisp->height()- ((virtualDisp->height()-45)/2)); + virtualDisp->print("ABCD"); + + // Red text inside red rect (2 pix in from edge) + virtualDisp->drawRect(1,1, virtualDisp->width()-2, virtualDisp->height()-2, virtualDisp->color565(255,0,0)); + + // White line from top left to bottom right + virtualDisp->drawLine(0,0, virtualDisp->width()-1, virtualDisp->height()-1, virtualDisp->color565(255,255,255)); + + virtualDisp->drawDisplayTest(); // re draw text numbering on each screen to check connectivity + +} + +void loop() { + + +} // end loop + + +/***************************************************************************** + + Thanks to: + + * Brian Lough for the original example as raised in this issue: + https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/26 + + YouTube: https://www.youtube.com/brianlough + Tindie: https://www.tindie.com/stores/brianlough/ + Twitter: https://twitter.com/witnessmenow + + * Galaxy-Man for the kind donation of panels make/test that this is possible: + https://github.com/Galaxy-Man + +*****************************************************************************/ \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanels/README.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanels/README.md new file mode 100644 index 0000000..c5aca88 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanels/README.md @@ -0,0 +1,51 @@ +## Chained Panels example - Chaining individual LED matrix panels to make a larger panel ## + +This is the PatternPlasma Demo adopted for use with multiple LED Matrix Panel displays arranged in a non standard order (i.e. a grid) to make a bigger display. + +![334894846_975082690567510_1362796919784291270_n](https://user-images.githubusercontent.com/89576620/224304944-94fe3483-d3cc-4aba-be0a-40b33ff901dc.jpg) + +### What do we mean by 'non standard order'? ### + +When you link / chain multiple panels together, the ESP32-HUB75-MatrixPanel-I2S-DMA library treats as one wide horizontal panel. This would be a 'standard' (default) order. + +Non-standard order is essentially the creation of a non-horizontal-only display that you can draw to in the same way you would any other display, with VirtualDisplay library looking after the pixel mapping to the physical chained panels. + +For example: You bought four (4) 64x32px panels, and wanted to use them to create a 128x64pixel display. You would use the VirtualMatrixPanel class. + +[Refer to this document](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/blob/master/doc/VirtualMatrixPanel.pdf) for an explanation and refer to this example on how to use. + + +### Steps to Use ### + +1. [Refer to this document](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/blob/master/doc/VirtualMatrixPanel.pdf) for an explanation and refer to this example on how to use. + +2. In your Arduino sketch, configure these defines accordingly: +``` +#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module. +#define PANEL_RES_Y 32 // Number of pixels tall of each INDIVIDUAL panel module. + +#define NUM_ROWS 2 // Number of rows of chained INDIVIDUAL PANELS +#define NUM_COLS 2 // Number of INDIVIDUAL PANELS per ROW + +#define PANEL_CHAIN NUM_ROWS*NUM_COLS // total number of panels chained one to another + +#define VIRTUAL_MATRIX_CHAIN_TYPE + +``` +VIRTUAL_MATRIX_CHAIN_TYPE's: +![image](https://user-images.githubusercontent.com/12006953/224537356-e3c8e87b-0bc0-4185-8f5d-d2d3b328d176.png) + + +3. In your Arduino sketch, use the 'VirtualMatrixPanel' class instance (virtualDisp) to draw to the display (i.e. drawPixel), instead of the underling MatrixPanel_I2S_DMA class instance (dma_display). + + +#### Thanks to #### +* Brian Lough for the Virtual to Real pixel co-ordinate code. + +YouTube: https://www.youtube.com/brianlough + +Tindie: https://www.tindie.com/stores/brianlough/ + +Twitter: https://twitter.com/witnessmenow + +* Galaxy-Man for the donation of hardware for testing. diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Attractor.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Attractor.h new file mode 100644 index 0000000..668ba53 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Attractor.h @@ -0,0 +1,50 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from "Attractor" in "The Nature of Code" by Daniel Shiffman: http://natureofcode.com/ + * Copyright (c) 2014 Daniel Shiffman + * http://www.shiffman.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "Vector.h" + +class Attractor { +public: + float mass; // Mass, tied to size + float G; // Gravitational Constant + PVector location; // Location + + Attractor() { + location = PVector(MATRIX_CENTRE_X, MATRIX_CENTRE_Y); + mass = 10; + G = .5; + } + + PVector attract(Boid m) { + PVector force = location - m.location; // Calculate direction of force + float d = force.mag(); // Distance between objects + d = constrain(d, 5.0, 32.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects + force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction) + float strength = (G * mass * m.mass) / (d * d); // Calculate gravitational force magnitude + force *= strength; // Get force vector --> magnitude * direction + return force; + } +}; diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Boid.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Boid.h new file mode 100644 index 0000000..fa5a9e6 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Boid.h @@ -0,0 +1,326 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from "Flocking" in "The Nature of Code" by Daniel Shiffman: http://natureofcode.com/ + * Copyright (c) 2014 Daniel Shiffman + * http://www.shiffman.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +// Flocking +// Daniel Shiffman +// The Nature of Code, Spring 2009 + +// Boid class +// Methods for Separation, Cohesion, Alignment added + +class Boid { + public: + + PVector location; + PVector velocity; + PVector acceleration; + float maxforce; // Maximum steering force + float maxspeed; // Maximum speed + + float desiredseparation = 4; + float neighbordist = 8; + byte colorIndex = 0; + float mass; + + boolean enabled = true; + + Boid() {} + + Boid(float x, float y) { + acceleration = PVector(0, 0); + velocity = PVector(randomf(), randomf()); + location = PVector(x, y); + maxspeed = 1.5; + maxforce = 0.05; + } + + static float randomf() { + return mapfloat(random(0, 255), 0, 255, -.5, .5); + } + + static float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } + + void run(Boid boids [], uint8_t boidCount) { + flock(boids, boidCount); + update(); + // wrapAroundBorders(); + // render(); + } + + // Method to update location + void update() { + // Update velocity + velocity += acceleration; + // Limit speed + velocity.limit(maxspeed); + location += velocity; + // Reset acceleration to 0 each cycle + acceleration *= 0; + } + + void applyForce(PVector force) { + // We could add mass here if we want A = F / M + acceleration += force; + } + + void repelForce(PVector obstacle, float radius) { + //Force that drives boid away from obstacle. + + PVector futPos = location + velocity; //Calculate future position for more effective behavior. + PVector dist = obstacle - futPos; + float d = dist.mag(); + + if (d <= radius) { + PVector repelVec = location - obstacle; + repelVec.normalize(); + if (d != 0) { //Don't divide by zero. + // float scale = 1.0 / d; //The closer to the obstacle, the stronger the force. + repelVec.normalize(); + repelVec *= (maxforce * 7); + if (repelVec.mag() < 0) { //Don't let the boids turn around to avoid the obstacle. + repelVec.y = 0; + } + } + applyForce(repelVec); + } + } + + // We accumulate a new acceleration each time based on three rules + void flock(Boid boids [], uint8_t boidCount) { + PVector sep = separate(boids, boidCount); // Separation + PVector ali = align(boids, boidCount); // Alignment + PVector coh = cohesion(boids, boidCount); // Cohesion + // Arbitrarily weight these forces + sep *= 1.5; + ali *= 1.0; + coh *= 1.0; + // Add the force vectors to acceleration + applyForce(sep); + applyForce(ali); + applyForce(coh); + } + + // Separation + // Method checks for nearby boids and steers away + PVector separate(Boid boids [], uint8_t boidCount) { + PVector steer = PVector(0, 0); + int count = 0; + // For every boid in the system, check if it's too close + for (int i = 0; i < boidCount; i++) { + Boid other = boids[i]; + if (!other.enabled) + continue; + float d = location.dist(other.location); + // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) + if ((d > 0) && (d < desiredseparation)) { + // Calculate vector pointing away from neighbor + PVector diff = location - other.location; + diff.normalize(); + diff /= d; // Weight by distance + steer += diff; + count++; // Keep track of how many + } + } + // Average -- divide by how many + if (count > 0) { + steer /= (float) count; + } + + // As long as the vector is greater than 0 + if (steer.mag() > 0) { + // Implement Reynolds: Steering = Desired - Velocity + steer.normalize(); + steer *= maxspeed; + steer -= velocity; + steer.limit(maxforce); + } + return steer; + } + + // Alignment + // For every nearby boid in the system, calculate the average velocity + PVector align(Boid boids [], uint8_t boidCount) { + PVector sum = PVector(0, 0); + int count = 0; + for (int i = 0; i < boidCount; i++) { + Boid other = boids[i]; + if (!other.enabled) + continue; + float d = location.dist(other.location); + if ((d > 0) && (d < neighbordist)) { + sum += other.velocity; + count++; + } + } + if (count > 0) { + sum /= (float) count; + sum.normalize(); + sum *= maxspeed; + PVector steer = sum - velocity; + steer.limit(maxforce); + return steer; + } + else { + return PVector(0, 0); + } + } + + // Cohesion + // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location + PVector cohesion(Boid boids [], uint8_t boidCount) { + PVector sum = PVector(0, 0); // Start with empty vector to accumulate all locations + int count = 0; + for (int i = 0; i < boidCount; i++) { + Boid other = boids[i]; + if (!other.enabled) + continue; + float d = location.dist(other.location); + if ((d > 0) && (d < neighbordist)) { + sum += other.location; // Add location + count++; + } + } + if (count > 0) { + sum /= count; + return seek(sum); // Steer towards the location + } + else { + return PVector(0, 0); + } + } + + // A method that calculates and applies a steering force towards a target + // STEER = DESIRED MINUS VELOCITY + PVector seek(PVector target) { + PVector desired = target - location; // A vector pointing from the location to the target + // Normalize desired and scale to maximum speed + desired.normalize(); + desired *= maxspeed; + // Steering = Desired minus Velocity + PVector steer = desired - velocity; + steer.limit(maxforce); // Limit to maximum steering force + return steer; + } + + // A method that calculates a steering force towards a target + // STEER = DESIRED MINUS VELOCITY + void arrive(PVector target) { + PVector desired = target - location; // A vector pointing from the location to the target + float d = desired.mag(); + // Normalize desired and scale with arbitrary damping within 100 pixels + desired.normalize(); + if (d < 4) { + float m = map(d, 0, 100, 0, maxspeed); + desired *= m; + } + else { + desired *= maxspeed; + } + + // Steering = Desired minus Velocity + PVector steer = desired - velocity; + steer.limit(maxforce); // Limit to maximum steering force + applyForce(steer); + //Serial.println(d); + } + + void wrapAroundBorders() { + if (location.x < 0) location.x = VPANEL_W - 1; + if (location.y < 0) location.y = VPANEL_H - 1; + if (location.x >= VPANEL_W) location.x = 0; + if (location.y >= VPANEL_H) location.y = 0; + } + + void avoidBorders() { + PVector desired = velocity; + + if (location.x < 8) desired = PVector(maxspeed, velocity.y); + if (location.x >= VPANEL_W - 8) desired = PVector(-maxspeed, velocity.y); + if (location.y < 8) desired = PVector(velocity.x, maxspeed); + if (location.y >= VPANEL_H - 8) desired = PVector(velocity.x, -maxspeed); + + if (desired != velocity) { + PVector steer = desired - velocity; + steer.limit(maxforce); + applyForce(steer); + } + + if (location.x < 0) location.x = 0; + if (location.y < 0) location.y = 0; + if (location.x >= VPANEL_W) location.x = VPANEL_W - 1; + if (location.y >= VPANEL_H) location.y = VPANEL_H - 1; + } + + bool bounceOffBorders(float bounce) { + bool bounced = false; + + if (location.x >= VPANEL_W) { + location.x = VPANEL_W - 1; + velocity.x *= -bounce; + bounced = true; + } + else if (location.x < 0) { + location.x = 0; + velocity.x *= -bounce; + bounced = true; + } + + if (location.y >= VPANEL_H) { + location.y = VPANEL_H - 1; + velocity.y *= -bounce; + bounced = true; + } + else if (location.y < 0) { + location.y = 0; + velocity.y *= -bounce; + bounced = true; + } + + return bounced; + } + + void render() { + //// Draw a triangle rotated in the direction of velocity + //float theta = velocity.heading2D() + radians(90); + //fill(175); + //stroke(0); + //pushMatrix(); + //translate(location.x,location.y); + //rotate(theta); + //beginShape(TRIANGLES); + //vertex(0, -r*2); + //vertex(-r, r*2); + //vertex(r, r*2); + //endShape(); + //popMatrix(); + //matrix.drawBackgroundPixelRGB888(location.x, location.y, CRGB::Blue); + } +}; + +static const uint8_t AVAILABLE_BOID_COUNT = 40; +Boid boids[AVAILABLE_BOID_COUNT]; diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/ChainedPanelsAuroraDemo.ino b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/ChainedPanelsAuroraDemo.ino new file mode 100644 index 0000000..f1cd7de --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/ChainedPanelsAuroraDemo.ino @@ -0,0 +1,209 @@ +#include + +/* Default library pin configuration for the reference + you can redefine only ones you need later on object creation + +#define R1 25 +#define G1 26 +#define BL1 27 +#define R2 14 +#define G2 12 +#define BL2 13 +#define CH_A 23 +#define CH_B 19 +#define CH_C 5 +#define CH_D 17 +#define CH_E -1 // assign to any available pin if using two panels or 64x64 panels with 1/32 scan +#define CLK 16 +#define LAT 4 +#define OE 15 + +*/ + + +/* -------------------------- Display Config Initialisation -------------------- */ +// Assume we have four 64x32 panels daisy-chained and ESP32 attached to the bottom right corner +#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module. +#define PANEL_RES_Y 32 // Number of pixels tall of each INDIVIDUAL panel module. + +#define NUM_ROWS 2 // Number of rows of chained INDIVIDUAL PANELS +#define NUM_COLS 2 // Number of INDIVIDUAL PANELS per ROW +#define PANEL_CHAIN NUM_ROWS*NUM_COLS // total number of panels chained one to another + +// Change this to your needs, for details on VirtualPanel pls see ChainedPanels example +#define SERPENT false +#define TOPDOWN false + +// Virtual Panel dimensions - our combined panel would be a square 4x4 modules with a combined resolution of 128x128 pixels +#define VPANEL_W PANEL_RES_X*NUM_COLS // Kosso: All Pattern files have had the MATRIX_WIDTH and MATRIX_HEIGHT replaced by these. +#define VPANEL_H PANEL_RES_Y*NUM_ROWS // + +// Kosso added: Button with debounce +#define BTN_PIN 0 // Pattern advance. Using EPS32 Boot button. +int buttonState; // the current reading from the input pin +int lastButtonState = LOW; // the previous reading from the input pin +unsigned long lastDebounceTime = 0; // the last time the output pin was toggled +unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers + +// The palettes are set to change every 60 seconds. + +// Kosso added: Non-volatile memory to save last pattern index. +#include +Preferences preferences; +int lastPattern = 0; + + +/* -------------------------- Class Initialisation -------------------------- */ +#include +#include // Used for some mathematics calculations and effects. + +// placeholder for the matrix object +MatrixPanel_I2S_DMA *matrix = nullptr; + +// placeholder for the virtual display object +VirtualMatrixPanel *virtualDisp = nullptr; + +// Aurora related +#include "Effects.h" +Effects effects; + +#include "Drawable.h" +#include "Playlist.h" +//#include "Geometry.h" +#include "Patterns.h" +Patterns patterns; + +/* -------------------------- Some variables -------------------------- */ +unsigned long ms_current = 0; +unsigned long ms_previous = 0; +unsigned long ms_animation_max_duration = 20000; // 10 seconds +unsigned long next_frame = 0; + +void listPatterns(); + +void setup() +{ + // Setup serial interface + Serial.begin(115200); + delay(250); + + // Added a button to manually advance the pattern index. + pinMode(BTN_PIN, INPUT); + // For saving last pattern index. TO reboot with same. + preferences.begin("RGBMATRIX", false); + lastPattern = preferences.getInt("lastPattern", 0); + + // Configure your matrix setup here + HUB75_I2S_CFG mxconfig(PANEL_RES_X, PANEL_RES_Y, PANEL_CHAIN); + + // custom pin mapping (if required) + //HUB75_I2S_CFG::i2s_pins _pins={R1, G1, BL1, R2, G2, BL2, CH_A, CH_B, CH_C, CH_D, CH_E, LAT, OE, CLK}; + //mxconfig.gpio = _pins; + + // in case that we use panels based on FM6126A chip, we can change that + //mxconfig.driver = HUB75_I2S_CFG::FM6126A; + + // FM6126A panels could be cloked at 20MHz with no visual artefacts + // mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M; + + // OK, now we can create our matrix object + matrix = new MatrixPanel_I2S_DMA(mxconfig); + + // Allocate memory and start DMA display + if( not matrix->begin() ) + Serial.println("****** !KABOOM! I2S memory allocation failed ***********"); + + // let's adjust default brightness to about 75% + matrix->setBrightness8(96); // range is 0-255, 0 - 0%, 255 - 100% + + // create VirtualDisplay object based on our newly created dma_display object + virtualDisp = new VirtualMatrixPanel((*matrix), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, CHAIN_TOP_LEFT_DOWN); + + Serial.println("**************** Starting Aurora Effects Demo ****************"); + + Serial.print("MATRIX_WIDTH: "); Serial.println(PANEL_RES_X*PANEL_CHAIN); + Serial.print("MATRIX_HEIGHT: "); Serial.println(PANEL_RES_Y); + +#ifdef VPANEL_W + Serial.println("VIRTUAL PANEL WIDTH " + String(VPANEL_W)); + Serial.println("VIRTUAL PANEL HEIGHT " + String(VPANEL_H)); +#endif + + // setup the effects generator + effects.Setup(); + + delay(500); + Serial.println("Effects being loaded: "); + listPatterns(); + + Serial.println("LastPattern index: " + String(lastPattern)); + + patterns.setPattern(lastPattern); // // simple noise + patterns.start(); + + Serial.print("Starting with pattern: "); + Serial.println(patterns.getCurrentPatternName()); + + preferences.end(); + +} + + +void patternAdvance(){ + // Go to next pattern in the list (se Patterns.h) + patterns.stop(); + patterns.moveRandom(1); + //patterns.move(1); + patterns.start(); + // Select a random palette as well + effects.RandomPalette(); + Serial.print("Changing pattern to: "); + Serial.println(patterns.getCurrentPatternName()); + //Serial.println(patterns.getPatternIndex()); + //lastPattern = patterns.getPatternIndex(); + // Save last index. + preferences.begin("RGBMATRIX", false); + preferences.putInt("lastPattern", lastPattern); + preferences.end(); + +} + +void loop() +{ + // Boot button Pattern advance with debounce + int reading = digitalRead(BTN_PIN); + if (reading != lastButtonState) { + lastDebounceTime = millis(); + } + + if ((millis() - lastDebounceTime) > debounceDelay) { + if (reading != buttonState) { + buttonState = reading; + if (buttonState == LOW) { + Serial.println("NEXT PATTERN ..."); + patternAdvance(); + } + } + } + lastButtonState = reading; + // end button debounce + + ms_current = millis(); + + if ( (ms_current - ms_previous) > ms_animation_max_duration ) + { + patternAdvance(); + // just auto-change the palette + effects.RandomPalette(); + ms_previous = ms_current; + } + + if ( next_frame < ms_current) + next_frame = patterns.drawFrame() + ms_current; + +} + + +void listPatterns() { + patterns.listPatterns(); +} diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Drawable.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Drawable.h new file mode 100644 index 0000000..b2169fe --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Drawable.h @@ -0,0 +1,55 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Drawable_H +#define Drawable_H + +class Drawable{ +public: + char* name; + + virtual bool isRunnable() { + return false; + } + + virtual bool isPlaylist() { + return false; + } + + // a single frame should be drawn as fast as possible, without any delay or blocking + // return how many millisecond delay is requested before the next call to drawFrame() + virtual unsigned int drawFrame() { + matrix->fillScreen(0); + //backgroundLayer.fillScreen({ 0, 0, 0 }); + return 0; + }; + + virtual void printTesting() + { + Serial.println("Testing..."); + } + + virtual void start() {}; + virtual void stop() {}; +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Effects.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Effects.h new file mode 100644 index 0000000..3d4affb --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Effects.h @@ -0,0 +1,852 @@ + +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from "Funky Clouds" by Stefan Petrick: https://gist.github.com/anonymous/876f908333cd95315c35 + * Portions of this code are adapted from "NoiseSmearing" by Stefan Petrick: https://gist.github.com/StefanPetrick/9ee2f677dbff64e3ba7a + * Copyright (c) 2014 Stefan Petrick + * http://www.stefan-petrick.de/wordpress_beta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Effects_H +#define Effects_H + +/* ---------------------------- GLOBAL CONSTANTS ----------------------------- */ + +const int MATRIX_CENTER_X = VPANEL_W / 2; +const int MATRIX_CENTER_Y = VPANEL_H / 2; +// US vs GB, huh? :) +//const byte MATRIX_CENTRE_X = MATRIX_CENTER_X - 1; +//const byte MATRIX_CENTRE_Y = MATRIX_CENTER_Y - 1; +#define MATRIX_CENTRE_X MATRIX_CENTER_X +#define MATRIX_CENTRE_Y MATRIX_CENTER_Y + + +const uint16_t NUM_LEDS = (VPANEL_W * VPANEL_H) + 1; // one led spare to capture out of bounds + +// forward declaration +uint16_t XY16( uint16_t x, uint16_t y); + +/* Convert x,y co-ordinate to flat array index. + * x and y positions start from 0, so must not be >= 'real' panel width or height + * (i.e. 64 pixels or 32 pixels.). Max value: VPANEL_W-1 etc. + * Ugh... uint8_t - really??? this weak method can't cope with 256+ pixel matrices :( + */ +uint16_t XY( uint8_t x, uint8_t y) +{ + return XY16(x, y); +} + +/** + * The one for 256+ matrices + * otherwise this: + * for (uint8_t i = 0; i < VPANEL_W; i++) {} + * turns into an infinite loop + */ +uint16_t XY16( uint16_t x, uint16_t y) +{ + if( x >= VPANEL_W) return 0; + if( y >= VPANEL_H) return 0; + + return (y * VPANEL_W) + x + 1; // everything offset by one to compute out of bounds stuff - never displayed by ShowFrame() +} + + +uint8_t beatcos8(accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255, uint32_t timebase = 0, uint8_t phase_offset = 0) +{ + uint8_t beat = beat8(beats_per_minute, timebase); + uint8_t beatcos = cos8(beat + phase_offset); + uint8_t rangewidth = highest - lowest; + uint8_t scaledbeat = scale8(beatcos, rangewidth); + uint8_t result = lowest + scaledbeat; + return result; +} + +uint8_t mapsin8(uint8_t theta, uint8_t lowest = 0, uint8_t highest = 255) { + uint8_t beatsin = sin8(theta); + uint8_t rangewidth = highest - lowest; + uint8_t scaledbeat = scale8(beatsin, rangewidth); + uint8_t result = lowest + scaledbeat; + return result; +} + +uint8_t mapcos8(uint8_t theta, uint8_t lowest = 0, uint8_t highest = 255) { + uint8_t beatcos = cos8(theta); + uint8_t rangewidth = highest - lowest; + uint8_t scaledbeat = scale8(beatcos, rangewidth); + uint8_t result = lowest + scaledbeat; + return result; +} + +// Array of temperature readings at each simulation cell +//byte heat[NUM_LEDS]; // none of the currently enabled effects uses this + +uint32_t noise_x; +uint32_t noise_y; +uint32_t noise_z; +uint32_t noise_scale_x; +uint32_t noise_scale_y; + +//uint8_t noise[VPANEL_W][VPANEL_H]; +uint8_t **noise = nullptr; // we will allocate mem later +uint8_t noisesmoothing; + +class Effects { +public: + CRGB *leds; + + Effects(){ + // we do dynamic allocation for leds buffer, otherwise esp32 toolchain can't link static arrays of such a big size for 256+ matrices + leds = (CRGB *)malloc(NUM_LEDS * sizeof(CRGB)); + + // allocate mem for noise effect + // (there should be some guards for malloc errors eventually) + noise = (uint8_t **)malloc(VPANEL_W * sizeof(uint8_t *)); + for (int i = 0; i < VPANEL_W; ++i) { + noise[i] = (uint8_t *)malloc(VPANEL_H * sizeof(uint8_t)); + } + + ClearFrame(); + } + ~Effects(){ + free(leds); + for (int i = 0; i < VPANEL_W; ++i) { + free(noise[i]); + } + free(noise); + } + + /* The only 'framebuffer' we have is what is contained in the leds and leds2 variables. + * We don't store what the color a particular pixel might be, other than when it's turned + * into raw electrical signal output gobbly-gook (i.e. the DMA matrix buffer), but this * is not reversible. + * + * As such, any time these effects want to write a pixel color, we first have to update + * the leds or leds2 array, and THEN write it to the RGB panel. This enables us to 'look up' the array to see what a pixel color was previously, each drawFrame(). + */ + void drawBackgroundFastLEDPixelCRGB(int16_t x, int16_t y, CRGB color) + { + leds[XY(x, y)] = color; + //matrix.drawPixelRGB888(x, y, color.r, color.g, color.b); + } + + // write one pixel with the specified color from the current palette to coordinates + void Pixel(int x, int y, uint8_t colorIndex) { + leds[XY(x, y)] = ColorFromCurrentPalette(colorIndex); + //matrix.drawPixelRGB888(x, y, temp.r, temp.g, temp.b); // now draw it? + } + + void PrepareFrame() { + // leds = (CRGB*) backgroundLayer.backBuffer(); + } + + void ShowFrame() { + //#if (FASTLED_VERSION >= 3001000) + // nblendPaletteTowardPalette(currentPalette, targetPalette, 24); + //#else + currentPalette = targetPalette; + //#endif + + // backgroundLayer.swapBuffers(); + // leds = (CRGB*) backgroundLayer.backBuffer(); + // LEDS.countFPS(); + + for (int y=0; ydrawPixelRGB888( x, y, leds[_pixel].r, leds[_pixel].g, leds[_pixel].b); + } // end loop to copy fast led to the dma matrix + } + } + + // scale the brightness of the screenbuffer down + void DimAll(byte value) + { + for (int i = 0; i < NUM_LEDS; i++) + { + leds[i].nscale8(value); + } + } + + void ClearFrame() + { + memset(leds, 0x00, NUM_LEDS * sizeof(CRGB)); // flush + } + + + +/* + void CircleStream(uint8_t value) { + DimAll(value); ShowFrame(); + + for (uint8_t offset = 0; offset < MATRIX_CENTER_X; offset++) { + boolean hasprev = false; + uint16_t prevxy = 0; + + for (uint8_t theta = 0; theta < 255; theta++) { + uint8_t x = mapcos8(theta, offset, (VPANEL_W - 1) - offset); + uint8_t y = mapsin8(theta, offset, (VPANEL_H - 1) - offset); + + uint16_t xy = XY(x, y); + + if (hasprev) { + leds[prevxy] += leds[xy]; + } + + prevxy = xy; + hasprev = true; + } + } + + for (uint8_t x = 0; x < VPANEL_W; x++) { + for (uint8_t y = 0; y < VPANEL_H; y++) { + uint16_t xy = XY(x, y); + leds[xy] = leds2[xy]; + leds[xy].nscale8(value); + leds2[xy].nscale8(value); + } + } + } +*/ + + // palettes + static const int paletteCount = 10; + int paletteIndex = -1; + TBlendType currentBlendType = LINEARBLEND; + CRGBPalette16 currentPalette; + CRGBPalette16 targetPalette; + char* currentPaletteName; + + static const int HeatColorsPaletteIndex = 6; + static const int RandomPaletteIndex = 9; + + void Setup() { + currentPalette = RainbowColors_p; + loadPalette(0); + NoiseVariablesSetup(); + } + + void CyclePalette(int offset = 1) { + loadPalette(paletteIndex + offset); + } + + void RandomPalette() { + loadPalette(RandomPaletteIndex); + } + + void loadPalette(int index) { + paletteIndex = index; + + if (paletteIndex >= paletteCount) + paletteIndex = 0; + else if (paletteIndex < 0) + paletteIndex = paletteCount - 1; + + switch (paletteIndex) { + case 0: + targetPalette = RainbowColors_p; + currentPaletteName = (char *)"Rainbow"; + break; + //case 1: + // targetPalette = RainbowStripeColors_p; + // currentPaletteName = (char *)"RainbowStripe"; + // break; + case 1: + targetPalette = OceanColors_p; + currentPaletteName = (char *)"Ocean"; + break; + case 2: + targetPalette = CloudColors_p; + currentPaletteName = (char *)"Cloud"; + break; + case 3: + targetPalette = ForestColors_p; + currentPaletteName = (char *)"Forest"; + break; + case 4: + targetPalette = PartyColors_p; + currentPaletteName = (char *)"Party"; + break; + case 5: + setupGrayscalePalette(); + currentPaletteName = (char *)"Grey"; + break; + case HeatColorsPaletteIndex: + targetPalette = HeatColors_p; + currentPaletteName = (char *)"Heat"; + break; + case 7: + targetPalette = LavaColors_p; + currentPaletteName = (char *)"Lava"; + break; + case 8: + setupIcePalette(); + currentPaletteName = (char *)"Ice"; + break; + case RandomPaletteIndex: + loadPalette(random(0, paletteCount - 1)); + paletteIndex = RandomPaletteIndex; + currentPaletteName = (char *)"Random"; + break; + } + } + + void setPalette(String paletteName) { + if (paletteName == "Rainbow") + loadPalette(0); + //else if (paletteName == "RainbowStripe") + // loadPalette(1); + else if (paletteName == "Ocean") + loadPalette(1); + else if (paletteName == "Cloud") + loadPalette(2); + else if (paletteName == "Forest") + loadPalette(3); + else if (paletteName == "Party") + loadPalette(4); + else if (paletteName == "Grayscale") + loadPalette(5); + else if (paletteName == "Heat") + loadPalette(6); + else if (paletteName == "Lava") + loadPalette(7); + else if (paletteName == "Ice") + loadPalette(8); + else if (paletteName == "Random") + RandomPalette(); + } + + void listPalettes() { + Serial.println(F("{")); + Serial.print(F(" \"count\": ")); + Serial.print(paletteCount); + Serial.println(","); + Serial.println(F(" \"results\": [")); + + String paletteNames [] = { + "Rainbow", + // "RainbowStripe", + "Ocean", + "Cloud", + "Forest", + "Party", + "Grayscale", + "Heat", + "Lava", + "Ice", + "Random" + }; + + for (int i = 0; i < paletteCount; i++) { + Serial.print(F(" \"")); + Serial.print(paletteNames[i]); + if (i == paletteCount - 1) + Serial.println(F("\"")); + else + Serial.println(F("\",")); + } + + Serial.println(" ]"); + Serial.println("}"); + } + + void setupGrayscalePalette() { + targetPalette = CRGBPalette16(CRGB::Black, CRGB::White); + } + + void setupIcePalette() { + targetPalette = CRGBPalette16(CRGB::Black, CRGB::Blue, CRGB::Aqua, CRGB::White); + } + + // Oscillators and Emitters + + // the oscillators: linear ramps 0-255 + byte osci[6]; + + // sin8(osci) swinging between 0 to VPANEL_W - 1 + byte p[6]; + + // set the speeds (and by that ratios) of the oscillators here + void MoveOscillators() { + osci[0] = osci[0] + 5; + osci[1] = osci[1] + 2; + osci[2] = osci[2] + 3; + osci[3] = osci[3] + 4; + osci[4] = osci[4] + 1; + if (osci[4] % 2 == 0) + osci[5] = osci[5] + 1; // .5 + for (int i = 0; i < 4; i++) { + p[i] = map8(sin8(osci[i]), 0, VPANEL_W - 1); //why? to keep the result in the range of 0-VPANEL_W (matrix size) + } + } + + + // All the caleidoscope functions work directly within the screenbuffer (leds array). + // Draw whatever you like in the area x(0-15) and y (0-15) and then copy it arround. + + // rotates the first 16x16 quadrant 3 times onto a 32x32 (+90 degrees rotation for each one) + void Caleidoscope1() { + for (int x = 0; x < MATRIX_CENTER_X; x++) { + for (int y = 0; y < MATRIX_CENTER_Y; y++) { + leds[XY16(VPANEL_W - 1 - x, y)] = leds[XY16(x, y)]; + leds[XY16(VPANEL_W - 1 - x, VPANEL_H - 1 - y)] = leds[XY16(x, y)]; + leds[XY16(x, VPANEL_H - 1 - y)] = leds[XY16(x, y)]; + } + } + } + + + // mirror the first 16x16 quadrant 3 times onto a 32x32 + void Caleidoscope2() { + for (int x = 0; x < MATRIX_CENTER_X; x++) { + for (int y = 0; y < MATRIX_CENTER_Y; y++) { + leds[XY16(VPANEL_W - 1 - x, y)] = leds[XY16(y, x)]; + leds[XY16(x, VPANEL_H - 1 - y)] = leds[XY16(y, x)]; + leds[XY16(VPANEL_W - 1 - x, VPANEL_H - 1 - y)] = leds[XY16(x, y)]; + } + } + } + + // copy one diagonal triangle into the other one within a 16x16 + void Caleidoscope3() { + for (int x = 0; x <= MATRIX_CENTRE_X && x < VPANEL_H; x++) { + for (int y = 0; y <= x && y= 0; y--) { + leds[XY16(x, y)] = leds[XY16(y, x)]; + } + } + } + + void Caleidoscope6() { + for (int x = 1; x < MATRIX_CENTER_X; x++) { + leds[XY16(7 - x, 7)] = leds[XY16(x, 0)]; + } //a + for (int x = 2; x < MATRIX_CENTER_X; x++) { + leds[XY16(7 - x, 6)] = leds[XY16(x, 1)]; + } //b + for (int x = 3; x < MATRIX_CENTER_X; x++) { + leds[XY16(7 - x, 5)] = leds[XY16(x, 2)]; + } //c + for (int x = 4; x < MATRIX_CENTER_X; x++) { + leds[XY16(7 - x, 4)] = leds[XY16(x, 3)]; + } //d + for (int x = 5; x < MATRIX_CENTER_X; x++) { + leds[XY16(7 - x, 3)] = leds[XY16(x, 4)]; + } //e + for (int x = 6; x < MATRIX_CENTER_X; x++) { + leds[XY16(7 - x, 2)] = leds[XY16(x, 5)]; + } //f + for (int x = 7; x < MATRIX_CENTER_X; x++) { + leds[XY16(7 - x, 1)] = leds[XY16(x, 6)]; + } //g + } + + // create a square twister to the left or counter-clockwise + // x and y for center, r for radius + void SpiralStream(int x, int y, int r, byte dimm) { + for (int d = r; d >= 0; d--) { // from the outside to the inside + for (int i = x - d; i <= x + d; i++) { + leds[XY16(i, y - d)] += leds[XY16(i + 1, y - d)]; // lowest row to the right + leds[XY16(i, y - d)].nscale8(dimm); + } + for (int i = y - d; i <= y + d; i++) { + leds[XY16(x + d, i)] += leds[XY16(x + d, i + 1)]; // right column up + leds[XY16(x + d, i)].nscale8(dimm); + } + for (int i = x + d; i >= x - d; i--) { + leds[XY16(i, y + d)] += leds[XY16(i - 1, y + d)]; // upper row to the left + leds[XY16(i, y + d)].nscale8(dimm); + } + for (int i = y + d; i >= y - d; i--) { + leds[XY16(x - d, i)] += leds[XY16(x - d, i - 1)]; // left column down + leds[XY16(x - d, i)].nscale8(dimm); + } + } + } + + // expand everything within a circle + void Expand(int centerX, int centerY, int radius, byte dimm) { + if (radius == 0) + return; + + int currentRadius = radius; + + while (currentRadius > 0) { + int a = radius, b = 0; + int radiusError = 1 - a; + + int nextRadius = currentRadius - 1; + int nextA = nextRadius - 1, nextB = 0; + int nextRadiusError = 1 - nextA; + + while (a >= b) + { + // move them out one pixel on the radius + leds[XY16(a + centerX, b + centerY)] = leds[XY16(nextA + centerX, nextB + centerY)]; + leds[XY16(b + centerX, a + centerY)] = leds[XY16(nextB + centerX, nextA + centerY)]; + leds[XY16(-a + centerX, b + centerY)] = leds[XY16(-nextA + centerX, nextB + centerY)]; + leds[XY16(-b + centerX, a + centerY)] = leds[XY16(-nextB + centerX, nextA + centerY)]; + leds[XY16(-a + centerX, -b + centerY)] = leds[XY16(-nextA + centerX, -nextB + centerY)]; + leds[XY16(-b + centerX, -a + centerY)] = leds[XY16(-nextB + centerX, -nextA + centerY)]; + leds[XY16(a + centerX, -b + centerY)] = leds[XY16(nextA + centerX, -nextB + centerY)]; + leds[XY16(b + centerX, -a + centerY)] = leds[XY16(nextB + centerX, -nextA + centerY)]; + + // dim them + leds[XY16(a + centerX, b + centerY)].nscale8(dimm); + leds[XY16(b + centerX, a + centerY)].nscale8(dimm); + leds[XY16(-a + centerX, b + centerY)].nscale8(dimm); + leds[XY16(-b + centerX, a + centerY)].nscale8(dimm); + leds[XY16(-a + centerX, -b + centerY)].nscale8(dimm); + leds[XY16(-b + centerX, -a + centerY)].nscale8(dimm); + leds[XY16(a + centerX, -b + centerY)].nscale8(dimm); + leds[XY16(b + centerX, -a + centerY)].nscale8(dimm); + + b++; + if (radiusError < 0) + radiusError += 2 * b + 1; + else + { + a--; + radiusError += 2 * (b - a + 1); + } + + nextB++; + if (nextRadiusError < 0) + nextRadiusError += 2 * nextB + 1; + else + { + nextA--; + nextRadiusError += 2 * (nextB - nextA + 1); + } + } + + currentRadius--; + } + } + + // give it a linear tail to the right + void StreamRight(byte scale, int fromX = 0, int toX = VPANEL_W, int fromY = 0, int toY = VPANEL_H) + { + for (int x = fromX + 1; x < toX; x++) { + for (int y = fromY; y < toY; y++) { + leds[XY16(x, y)] += leds[XY16(x - 1, y)]; + leds[XY16(x, y)].nscale8(scale); + } + } + for (int y = fromY; y < toY; y++) + leds[XY16(0, y)].nscale8(scale); + } + + // give it a linear tail to the left + void StreamLeft(byte scale, int fromX = VPANEL_W, int toX = 0, int fromY = 0, int toY = VPANEL_H) + { + for (int x = toX; x < fromX; x++) { + for (int y = fromY; y < toY; y++) { + leds[XY16(x, y)] += leds[XY16(x + 1, y)]; + leds[XY16(x, y)].nscale8(scale); + } + } + for (int y = fromY; y < toY; y++) + leds[XY16(0, y)].nscale8(scale); + } + + // give it a linear tail downwards + void StreamDown(byte scale) + { + for (int x = 0; x < VPANEL_W; x++) { + for (int y = 1; y < VPANEL_H; y++) { + leds[XY16(x, y)] += leds[XY16(x, y - 1)]; + leds[XY16(x, y)].nscale8(scale); + } + } + for (int x = 0; x < VPANEL_W; x++) + leds[XY16(x, 0)].nscale8(scale); + } + + // give it a linear tail upwards + void StreamUp(byte scale) + { + for (int x = 0; x < VPANEL_W; x++) { + for (int y = VPANEL_H - 2; y >= 0; y--) { + leds[XY16(x, y)] += leds[XY16(x, y + 1)]; + leds[XY16(x, y)].nscale8(scale); + } + } + for (int x = 0; x < VPANEL_W; x++) + leds[XY16(x, VPANEL_H - 1)].nscale8(scale); + } + + // give it a linear tail up and to the left + void StreamUpAndLeft(byte scale) + { + for (int x = 0; x < VPANEL_W - 1; x++) { + for (int y = VPANEL_H - 2; y >= 0; y--) { + leds[XY16(x, y)] += leds[XY16(x + 1, y + 1)]; + leds[XY16(x, y)].nscale8(scale); + } + } + for (int x = 0; x < VPANEL_W; x++) + leds[XY16(x, VPANEL_H - 1)].nscale8(scale); + for (int y = 0; y < VPANEL_H; y++) + leds[XY16(VPANEL_W - 1, y)].nscale8(scale); + } + + // give it a linear tail up and to the right + void StreamUpAndRight(byte scale) + { + for (int x = 0; x < VPANEL_W - 1; x++) { + for (int y = VPANEL_H - 2; y >= 0; y--) { + leds[XY16(x + 1, y)] += leds[XY16(x, y + 1)]; + leds[XY16(x, y)].nscale8(scale); + } + } + // fade the bottom row + for (int x = 0; x < VPANEL_W; x++) + leds[XY16(x, VPANEL_H - 1)].nscale8(scale); + + // fade the right column + for (int y = 0; y < VPANEL_H; y++) + leds[XY16(VPANEL_W - 1, y)].nscale8(scale); + } + + // just move everything one line down + void MoveDown() { + for (int y = VPANEL_H - 1; y > 0; y--) { + for (int x = 0; x < VPANEL_W; x++) { + leds[XY16(x, y)] = leds[XY16(x, y - 1)]; + } + } + } + + // just move everything one line down + void VerticalMoveFrom(int start, int end) { + for (int y = end; y > start; y--) { + for (int x = 0; x < VPANEL_W; x++) { + leds[XY16(x, y)] = leds[XY16(x, y - 1)]; + } + } + } + + // copy the rectangle defined with 2 points x0, y0, x1, y1 + // to the rectangle beginning at x2, x3 + void Copy(byte x0, byte y0, byte x1, byte y1, byte x2, byte y2) { + for (int y = y0; y < y1 + 1; y++) { + for (int x = x0; x < x1 + 1; x++) { + leds[XY16(x + x2 - x0, y + y2 - y0)] = leds[XY16(x, y)]; + } + } + } + + // rotate + copy triangle (MATRIX_CENTER_X*MATRIX_CENTER_X) + void RotateTriangle() { + for (int x = 1; x < MATRIX_CENTER_X; x++) { + for (int y = 0; y < x; y++) { + leds[XY16(x, 7 - y)] = leds[XY16(7 - x, y)]; + } + } + } + + // mirror + copy triangle (MATRIX_CENTER_X*MATRIX_CENTER_X) + void MirrorTriangle() { + for (int x = 1; x < MATRIX_CENTER_X; x++) { + for (int y = 0; y < x; y++) { + leds[XY16(7 - y, x)] = leds[XY16(7 - x, y)]; + } + } + } + + // draw static rainbow triangle pattern (MATRIX_CENTER_XxWIDTH / 2) + // (just for debugging) + void RainbowTriangle() { + for (int i = 0; i < MATRIX_CENTER_X; i++) { + for (int j = 0; j <= i; j++) { + Pixel(7 - i, j, i * j * 4); + } + } + } + + void BresenhamLine(int x0, int y0, int x1, int y1, byte colorIndex) + { + BresenhamLine(x0, y0, x1, y1, ColorFromCurrentPalette(colorIndex)); + } + + void BresenhamLine(int x0, int y0, int x1, int y1, CRGB color) + { + int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; + int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1; + int err = dx + dy, e2; + for (;;) { + leds[XY16(x0, y0)] += color; + if (x0 == x1 && y0 == y1) break; + e2 = 2 * err; + if (e2 > dy) { + err += dy; + x0 += sx; + } + if (e2 < dx) { + err += dx; + y0 += sy; + } + } + } + + // write one pixel with the specified color from the current palette to coordinates + /* + void Pixel(int x, int y, uint8_t colorIndex) { + leds[XY(x, y)] = ColorFromCurrentPalette(colorIndex); + matrix.drawBackgroundPixelRGB888(x,y, leds[XY(x, y)]); // now draw it? + } + */ + + CRGB ColorFromCurrentPalette(uint8_t index = 0, uint8_t brightness = 255, TBlendType blendType = LINEARBLEND) { + return ColorFromPalette(currentPalette, index, brightness, currentBlendType); + } + + CRGB HsvToRgb(uint8_t h, uint8_t s, uint8_t v) { + CHSV hsv = CHSV(h, s, v); + CRGB rgb; + hsv2rgb_spectrum(hsv, rgb); + return rgb; + } + + void NoiseVariablesSetup() { + noisesmoothing = 200; + + noise_x = random16(); + noise_y = random16(); + noise_z = random16(); + noise_scale_x = 6000; + noise_scale_y = 6000; + } + + void FillNoise() { + for (uint16_t i = 0; i < VPANEL_W; i++) { + uint32_t ioffset = noise_scale_x * (i - MATRIX_CENTRE_Y); + + for (uint16_t j = 0; j < VPANEL_H; j++) { + uint32_t joffset = noise_scale_y * (j - MATRIX_CENTRE_Y); + + byte data = inoise16(noise_x + ioffset, noise_y + joffset, noise_z) >> 8; + + uint8_t olddata = noise[i][j]; + uint8_t newdata = scale8(olddata, noisesmoothing) + scale8(data, 256 - noisesmoothing); + data = newdata; + + noise[i][j] = data; + } + } + } + + // non leds2 memory version. + void MoveX(byte delta) + { + + CRGB tmp = 0; + + for (int y = 0; y < VPANEL_H; y++) + { + + // Shift Left: https://codedost.com/c/arraypointers-in-c/c-program-shift-elements-array-left-direction/ + // Computationally heavier but doesn't need an entire leds2 array + + tmp = leds[XY16(0, y)]; + for (int m = 0; m < delta; m++) + { + // Do this delta time for each row... computationally expensive potentially. + for(int x = 0; x < VPANEL_W; x++) + { + leds[XY16(x, y)] = leds [XY16(x+1, y)]; + } + + leds[XY16(VPANEL_W-1, y)] = tmp; + } + + + /* + // Shift + for (int x = 0; x < VPANEL_W - delta; x++) { + leds2[XY(x, y)] = leds[XY(x + delta, y)]; + } + + // Wrap around + for (int x = VPANEL_W - delta; x < VPANEL_W; x++) { + leds2[XY(x, y)] = leds[XY(x + delta - VPANEL_W, y)]; + } + */ + } // end row loop + + /* + // write back to leds + for (uint8_t y = 0; y < VPANEL_H; y++) { + for (uint8_t x = 0; x < VPANEL_W; x++) { + leds[XY(x, y)] = leds2[XY(x, y)]; + } + } + */ + } + + void MoveY(byte delta) + { + + CRGB tmp = 0; + for (int x = 0; x < VPANEL_W; x++) + { + tmp = leds[XY16(x, 0)]; + for (int m = 0; m < delta; m++) // moves + { + // Do this delta time for each row... computationally expensive potentially. + for(int y = 0; y < VPANEL_H; y++) + { + leds[XY16(x, y)] = leds [XY16(x, y+1)]; + } + + leds[XY16(x, VPANEL_H-1)] = tmp; + } + } // end column loop + } /// MoveY + + +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Geometry.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Geometry.h new file mode 100644 index 0000000..4e47557 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Geometry.h @@ -0,0 +1,150 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from Noel Bundy's work: https://github.com/TwystNeko/Object3d + * Copyright (c) 2014 Noel Bundy + * + * Portions of this code are adapted from the Petty library: https://code.google.com/p/peggy/ + * Copyright (c) 2008 Windell H Oskay. All right reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Geometry_H +#define Geometry_H + +struct Vertex +{ + float x, y, z; + Vertex() + { + this->set(0, 0, 0); + } + + Vertex(float x, float y, float z) + { + this->set(x, y, z); + } + + void set(float x, float y, float z) + { + this->x = x; + this->y = y; + this->z = z; + } +}; + +struct EdgePoint +{ + int x, y; + boolean visible; + + EdgePoint() + { + this->set(0, 0); + this->visible = false; + } + + void set(int a, int b) + { + this->x = a; + this->y = b; + } +}; + +struct Point +{ + float x, y; + + Point() + { + set(0, 0); + } + + Point(float x, float y) + { + set(x, y); + } + + void set(float x, float y) + { + this->x = x; + this->y = y; + } + +}; + +struct squareFace +{ + int length; + int sommets[4]; + int ed[4]; + + squareFace() + { + set(-1, -1, -1, -1); + } + + squareFace(int a, int b, int c, int d) + { + this->length = 4; + this->sommets[0] = a; + this->sommets[1] = b; + this->sommets[2] = c; + this->sommets[3] = d; + } + + void set(int a, int b, int c, int d) + { + this->length = 4; + this->sommets[0] = a; + this->sommets[1] = b; + this->sommets[2] = c; + this->sommets[3] = d; + } + +}; + +struct triFace +{ + int length; + int sommets[3]; + int ed[3]; + + triFace() + { + set(-1,-1,-1); + } + triFace(int a, int b, int c) + { + this->length =3; + this->sommets[0]=a; + this->sommets[1]=b; + this->sommets[2]=c; + } + void set(int a, int b, int c) + { + this->length =3; + this->sommets[0]=a; + this->sommets[1]=b; + this->sommets[2]=c; + } +}; + +#endif \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PaletteFireKoz.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PaletteFireKoz.h new file mode 100644 index 0000000..86799ee --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PaletteFireKoz.h @@ -0,0 +1,3 @@ +const uint8_t PROGMEM palette_fire[] = {/* RGB888 R,G,B,R,G,B,R,G,B,... */ +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x05,0x00,0x00,0x0a,0x00,0x00,0x10,0x00,0x00,0x15,0x00,0x00,0x1b,0x00,0x00,0x20,0x00,0x00,0x25,0x00,0x00,0x2b,0x00,0x00,0x31,0x00,0x00,0x36,0x00,0x00,0x3c,0x00,0x00,0x41,0x00,0x00,0x46,0x00,0x00,0x4c,0x00,0x00,0x52,0x00,0x00,0x57,0x00,0x00,0x5d,0x00,0x00,0x62,0x00,0x00,0x68,0x00,0x00,0x6d,0x00,0x00,0x73,0x00,0x00,0x79,0x00,0x00,0x7e,0x00,0x00,0x83,0x00,0x00,0x89,0x00,0x00,0x8e,0x00,0x00,0x94,0x00,0x00,0x9a,0x00,0x00,0x9f,0x00,0x00,0xa5,0x00,0x00,0xaa,0x00,0x00,0xb0,0x00,0x00,0xb5,0x00,0x00,0xbb,0x00,0x00,0xc0,0x00,0x00,0xc6,0x00,0x00,0xcb,0x00,0x00,0xd1,0x00,0x00,0xd7,0x00,0x00,0xdc,0x00,0x00,0xe1,0x00,0x00,0xe6,0x00,0x00,0xe8,0x02,0x00,0xe9,0x08,0x00,0xe9,0x0f,0x00,0xe9,0x13,0x00,0xe9,0x16,0x00,0xe9,0x1b,0x00,0xe9,0x21,0x00,0xe9,0x26,0x00,0xe9,0x2a,0x00,0xe9,0x2e,0x00,0xe9,0x32,0x00,0xe9,0x37,0x00,0xe9,0x3b,0x00,0xe9,0x3f,0x00,0xe9,0x44,0x00,0xe9,0x4a,0x00,0xe9,0x4e,0x00,0xe9,0x52,0x00,0xe9,0x56,0x00,0xe9,0x5a,0x00,0xe9,0x5d,0x00,0xe9,0x63,0x00,0xe9,0x67,0x00,0xe9,0x6b,0x00,0xe9,0x71,0x00,0xe9,0x77,0x00,0xe9,0x78,0x00,0xe9,0x7c,0x00,0xe9,0x81,0x00,0xe9,0x86,0x00,0xe9,0x8b,0x00,0xe9,0x8f,0x00,0xe9,0x93,0x00,0xe9,0x99,0x00,0xe9,0x9d,0x00,0xe9,0xa0,0x00,0xe9,0xa4,0x00,0xe9,0xaa,0x00,0xe9,0xb0,0x00,0xe9,0xb4,0x00,0xe9,0xb5,0x00,0xe9,0xb9,0x00,0xe9,0xbe,0x00,0xe9,0xc3,0x00,0xe9,0xc9,0x00,0xe9,0xce,0x00,0xe9,0xd2,0x00,0xe9,0xd6,0x00,0xe9,0xd9,0x00,0xe9,0xdd,0x00,0xe9,0xe2,0x00,0xe9,0xe7,0x02,0xe9,0xe9,0x0e,0xe9,0xe9,0x1c,0xe9,0xe9,0x28,0xe9,0xe9,0x38,0xe9,0xe9,0x48,0xe9,0xe9,0x57,0xe9,0xe9,0x67,0xe9,0xe9,0x73,0xe9,0xe9,0x81,0xe9,0xe9,0x90,0xe9,0xe9,0xa1,0xe9,0xe9,0xb1,0xe9,0xe9,0xbf,0xe9,0xe9,0xcb,0xe9,0xe9,0xcb,0xe9,0xe9,0xcd,0xe9,0xe9,0xd9,0xe9,0xe9,0xe5,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe7,0xe7,0xe7,0xe7,0xe7,0xe7,0xe6,0xe6,0xe6,0xe4,0xe4,0xe4,0xe3,0xe3,0xe3,0xe0,0xe0,0xe0,0xdc,0xdc,0xdc,0xd8,0xd8,0xd8,0xd2,0xd2,0xd2,0xca,0xca,0xca,0xc1,0xc1,0xc1,0xb7,0xb7,0xb7,0xab,0xab,0xab,0x9d,0x9d,0x9d,0x8f,0x8f,0x8f,0x81,0x81,0x81,0x72,0x72,0x72,0x64,0x64,0x64,0x56,0x56,0x56,0x4a,0x4a,0x4a,0x3e,0x3e,0x3e,0x33,0x33,0x33,0x2a,0x2a,0x2a,0x22,0x22,0x22,0x1b,0x1b,0x1b,0x16,0x16,0x16,0x11,0x11,0x11,0x0d,0x0d,0x0d,0x0b,0x0b,0x0b,0x08,0x08,0x08,0x07,0x07,0x07,0x06,0x06,0x06,0x05,0x05,0x05,0x04,0x04,0x04,0x03,0x03,0x03,0x03,0x03,0x03,0x02,0x02,0x02,0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternAttract.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternAttract.h new file mode 100644 index 0000000..dcb6491 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternAttract.h @@ -0,0 +1,74 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternAttract_H + +class PatternAttract : public Drawable { +private: + const int count = 8; + Attractor attractor; + +public: + PatternAttract() { + name = (char *)"Attract"; + } + + void start() { + int direction = random(0, 2); + if (direction == 0) + direction = -1; + + for (int i = 0; i < count; i++) { + Boid boid = Boid(15, 31 - i); + boid.mass = 1; // random(0.1, 2); + boid.velocity.x = ((float) random(40, 50)) / 100.0; + boid.velocity.x *= direction; + boid.velocity.y = 0; + boid.colorIndex = i * 32; + boids[i] = boid; + //dim = random(170, 250); + } + } + + unsigned int drawFrame() { + // dim all pixels on the display + uint8_t dim = beatsin8(2, 170, 250); + effects.DimAll(dim); + + for (int i = 0; i < count; i++) { + Boid boid = boids[i]; + + PVector force = attractor.attract(boid); + boid.applyForce(force); + + boid.update(); + effects.drawBackgroundFastLEDPixelCRGB(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex)); + + boids[i] = boid; + } + + effects.ShowFrame(); + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternBounce.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternBounce.h new file mode 100644 index 0000000..c0d595a --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternBounce.h @@ -0,0 +1,73 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternBounce_H + +class PatternBounce : public Drawable { +private: + static const int count = 32; + PVector gravity = PVector(0, 0.0125); + +public: + PatternBounce() { + name = (char *)"Bounce"; + } + + void start() { + unsigned int colorWidth = 256 / count; + for (int i = 0; i < count; i++) { + Boid boid = Boid(i, 0); + boid.velocity.x = 0; + boid.velocity.y = i * -0.01; + boid.colorIndex = colorWidth * i; + boid.maxforce = 10; + boid.maxspeed = 10; + boids[i] = boid; + } + } + + unsigned int drawFrame() { + // dim all pixels on the display + effects.DimAll(170); effects.ShowFrame(); + + for (int i = 0; i < count; i++) { + Boid boid = boids[i]; + + boid.applyForce(gravity); + + boid.update(); + + effects.drawBackgroundFastLEDPixelCRGB(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex)); + + if (boid.location.y >= VPANEL_H - 1) { + boid.location.y = VPANEL_H - 1; + boid.velocity.y *= -1.0; + } + + boids[i] = boid; + } + + return 15; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternCube.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternCube.h new file mode 100644 index 0000000..bebf5c8 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternCube.h @@ -0,0 +1,219 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from Noel Bundy's work: https://github.com/TwystNeko/Object3d + * Copyright (c) 2014 Noel Bundy + * + * Portions of this code are adapted from the Petty library: https://code.google.com/p/peggy/ + * Copyright (c) 2008 Windell H Oskay. All right reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternCube_H +#define PatternCube_H + +class PatternCube : public Drawable { + private: + float focal = 30; // Focal of the camera + int cubeWidth = 28; // Cube size + float Angx = 20.0, AngxSpeed = 0.05; // rotation (angle+speed) around X-axis + float Angy = 10.0, AngySpeed = 0.05; // rotation (angle+speed) around Y-axis + float Ox = 15.5, Oy = 15.5; // position (x,y) of the frame center + int zCamera = 110; // distance from cube to the eye of the camera + + // Local vertices + Vertex local[8]; + // Camera aligned vertices + Vertex aligned[8]; + // On-screen projected vertices + Point screen[8]; + // Faces + squareFace face[6]; + // Edges + EdgePoint edge[12]; + int nbEdges; + // ModelView matrix + float m00, m01, m02, m10, m11, m12, m20, m21, m22; + + // constructs the cube + void make(int w) + { + nbEdges = 0; + + local[0].set(-w, w, w); + local[1].set(w, w, w); + local[2].set(w, -w, w); + local[3].set(-w, -w, w); + local[4].set(-w, w, -w); + local[5].set(w, w, -w); + local[6].set(w, -w, -w); + local[7].set(-w, -w, -w); + + face[0].set(1, 0, 3, 2); + face[1].set(0, 4, 7, 3); + face[2].set(4, 0, 1, 5); + face[3].set(4, 5, 6, 7); + face[4].set(1, 2, 6, 5); + face[5].set(2, 3, 7, 6); + + int f, i; + for (f = 0; f < 6; f++) + { + for (i = 0; i < face[f].length; i++) + { + face[f].ed[i] = this->findEdge(face[f].sommets[i], face[f].sommets[i ? i - 1 : face[f].length - 1]); + } + } + } + + // finds edges from faces + int findEdge(int a, int b) + { + int i; + for (i = 0; i < nbEdges; i++) + if ((edge[i].x == a && edge[i].y == b) || (edge[i].x == b && edge[i].y == a)) + return i; + edge[nbEdges++].set(a, b); + return i; + } + + // rotates according to angle x&y + void rotate(float angx, float angy) + { + int i; + float cx = cos(angx); + float sx = sin(angx); + float cy = cos(angy); + float sy = sin(angy); + + m00 = cy; + m01 = 0; + m02 = -sy; + m10 = sx * sy; + m11 = cx; + m12 = sx * cy; + m20 = cx * sy; + m21 = -sx; + m22 = cx * cy; + + for (i = 0; i < 8; i++) + { + aligned[i].x = m00 * local[i].x + m01 * local[i].y + m02 * local[i].z; + aligned[i].y = m10 * local[i].x + m11 * local[i].y + m12 * local[i].z; + aligned[i].z = m20 * local[i].x + m21 * local[i].y + m22 * local[i].z + zCamera; + + screen[i].x = floor((Ox + focal * aligned[i].x / aligned[i].z)); + screen[i].y = floor((Oy - focal * aligned[i].y / aligned[i].z)); + } + + for (i = 0; i < 12; i++) + edge[i].visible = false; + + Point *pa, *pb, *pc; + for (i = 0; i < 6; i++) + { + pa = screen + face[i].sommets[0]; + pb = screen + face[i].sommets[1]; + pc = screen + face[i].sommets[2]; + + boolean back = ((pb->x - pa->x) * (pc->y - pa->y) - (pb->y - pa->y) * (pc->x - pa->x)) < 0; + if (!back) + { + int j; + for (j = 0; j < 4; j++) + { + edge[face[i].ed[j]].visible = true; + } + } + } + } + + byte hue = 0; + int step = 0; + + public: + PatternCube() { + name = (char *)"Cube"; + make(cubeWidth); + } + + unsigned int drawFrame() { + uint8_t blurAmount = beatsin8(2, 10, 255); + +#if FASTLED_VERSION >= 3001000 + blur2d(effects.leds, VPANEL_W, VPANEL_H, blurAmount); +#else + effects.DimAll(blurAmount); effects.ShowFrame(); +#endif + + zCamera = beatsin8(2, 100, 140); + AngxSpeed = beatsin8(3, 1, 10) / 100.0f; + AngySpeed = beatcos8(5, 1, 10) / 100.0f; + + // Update values + Angx += AngxSpeed; + Angy += AngySpeed; + if (Angx >= TWO_PI) + Angx -= TWO_PI; + if (Angy >= TWO_PI) + Angy -= TWO_PI; + + rotate(Angx, Angy); + + // Draw cube + int i; + + CRGB color = effects.ColorFromCurrentPalette(hue, 128); + + // Backface + EdgePoint *e; + for (i = 0; i < 12; i++) + { + e = edge + i; + if (!e->visible) { + matrix.drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color); + } + } + + color = effects.ColorFromCurrentPalette(hue, 255); + + // Frontface + for (i = 0; i < 12; i++) + { + e = edge + i; + if (e->visible) + { + matrix.drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color); + } + } + + step++; + if (step == 8) { + step = 0; + hue++; + } + + effects.ShowFrame(); + + return 20; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternElectricMandala.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternElectricMandala.h new file mode 100644 index 0000000..1977a83 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternElectricMandala.h @@ -0,0 +1,116 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from "Funky Noise" by Stefan Petrick: https://github.com/StefanPetrick/FunkyNoise + * Copyright (c) 2014 Stefan Petrick + * http://www.stefan-petrick.de/wordpress_beta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternElectricMandala_H + +class PatternElectricMandala : public Drawable { + private: + + // The coordinates for 16-bit noise spaces. +#define NUM_LAYERS 1 + + // used for the random based animations + int16_t dx; + int16_t dy; + int16_t dz; + int16_t dsx; + int16_t dsy; + + public: + PatternElectricMandala() { + name = (char *)"ElectricMandala"; + } + + void start() { + // set to reasonable values to avoid a black out + noisesmoothing = 200; + + // just any free input pin + //random16_add_entropy(analogRead(18)); + + // fill coordinates with random values + // set zoom levels + noise_x = random16(); + noise_y = random16(); + noise_z = random16(); + noise_scale_x = 6000; + noise_scale_y = 6000; + + // for the random movement + dx = random8(); + dy = random8(); + dz = random8(); + dsx = random8(); + dsy = random8(); + } + + unsigned int drawFrame() { +#if FASTLED_VERSION >= 3001000 + // a new parameter set every 15 seconds + EVERY_N_SECONDS(15) { + //SetupRandomPalette3(); + dy = random16(500) - 250; // random16(2000) - 1000 is pretty fast but works fine, too + dx = random16(500) - 250; + dz = random16(500) - 250; + noise_scale_x = random16(10000) + 2000; + noise_scale_y = random16(10000) + 2000; + } +#endif + + noise_y += dy; + noise_x += dx; + noise_z += dz; + + effects.FillNoise(); + ShowNoiseLayer(0, 1, 0); + + effects.Caleidoscope3(); + effects.Caleidoscope1(); + + effects.ShowFrame(); + + return 30; + } + + // show just one layer + void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) { + for (uint16_t i = 0; i < VPANEL_W; i++) { + for (uint16_t j = 0; j < VPANEL_H; j++) { + + uint8_t color = noise[i][j]; + + uint8_t bri = color; + + // assign a color depending on the actual palette + CRGB pixel = ColorFromPalette(effects.currentPalette, colorrepeat * (color + colorshift), bri); + + effects.leds[XY16(i, j)] = pixel; + } + } + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternFire.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternFire.h new file mode 100644 index 0000000..731aff9 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternFire.h @@ -0,0 +1,118 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/tree/master/examples/Fire2012WithPalette + * Copyright (c) 2013 FastLED + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternFire_H +#define PatternFire_H + +#ifndef Effects_H +#include "Effects.h" +#endif + +class PatternFire : public Drawable { + private: + + public: + PatternFire() { + name = (char *)"Fire"; + } + + // There are two main parameters you can play with to control the look and + // feel of your fire: COOLING (used in step 1 above), and SPARKING (used + // in step 3 above). + // + // cooling: How much does the air cool as it rises? + // Less cooling = taller flames. More cooling = shorter flames. + // Default 55, suggested range 20-100 + int cooling = 100; + + // sparking: What chance (out of 255) is there that a new spark will be lit? + // Higher chance = more roaring fire. Lower chance = more flickery fire. + // Default 120, suggested range 50-200. + unsigned int sparking = 100; + + unsigned int drawFrame() { + // Add entropy to random number generator; we use a lot of it. + random16_add_entropy( random16()); + + effects.DimAll(235); + + for (int x = 0; x < VPANEL_W; x++) { + // Step 1. Cool down every cell a little + for (int y = 0; y < VPANEL_H; y++) { + int xy = XY(x, y); + heat[xy] = qsub8(heat[xy], random8(0, ((cooling * 10) / VPANEL_H) + 2)); + } + + // Step 2. Heat from each cell drifts 'up' and diffuses a little + for (int y = 0; y < VPANEL_H; y++) { + heat[XY(x, y)] = (heat[XY(x, y + 1)] + heat[XY(x, y + 2)] + heat[XY(x, y + 2)]) / 3; + } + + // Step 2. Randomly ignite new 'sparks' of heat + if (random8() < sparking) { + // int x = (p[0] + p[1] + p[2]) / 3; + + int xy = XY(x, VPANEL_H - 1); + heat[xy] = qadd8(heat[xy], random8(160, 255)); + } + + // Step 4. Map from heat cells to LED colors + for (int y = 0; y < VPANEL_H; y++) { + int xy = XY(x, y); + byte colorIndex = heat[xy]; + + // Recommend that you use values 0-240 rather than + // the usual 0-255, as the last 15 colors will be + // 'wrapping around' from the hot end to the cold end, + // which looks wrong. + colorIndex = scale8(colorIndex, 200); + + // override color 0 to ensure a black background? + if (colorIndex != 0) + // effects.leds[xy] = CRGB::Black; + // else + effects.leds[xy] = effects.ColorFromCurrentPalette(colorIndex); + } + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(2); + effects.MoveFractionalNoiseX(2); + + + effects.ShowFrame(); + + return 15; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternFireKoz.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternFireKoz.h new file mode 100644 index 0000000..c553d6b --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternFireKoz.h @@ -0,0 +1,109 @@ +/* + Aurora: https://github.com/pixelmatix/aurora + Copyright (c) 2014 Jason Coon + + Added by @Kosso. Cobbled together from various places which I can't remember. I'll update this when I track it down. + Requires PaletteFireKoz.h + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternFireKoz_H +#define PatternFireKoz_H + +class PatternFireKoz : public Drawable { + private: + + const int FIRE_HEIGHT = 800; + + int Bit = 0, NBit = 1; + float fire_c; + // might not need this buffer here... there some led buffers set up in Effects.h + uint8_t fireBuffer[VPANEL_W][VPANEL_H][2]; + + public: + PatternFireKoz() { + name = (char *)"FireKoz"; + } + + unsigned int drawFrame() { + + for (int x = 1; x < VPANEL_W - 1; x++) + { + fireBuffer[x][VPANEL_H - 2][Bit] = random(0, FIRE_HEIGHT); + if (random(0, 100) > 80) + { + fireBuffer[x][VPANEL_H - 2][Bit] = 0; + fireBuffer[x][VPANEL_H - 3][Bit] = 0; + } + } + for (int y = 1; y < VPANEL_H - 1; y++) + { + for (int x = 1; x < VPANEL_W - 1; x++) + { + fire_c = (fireBuffer[x - 1][y][Bit] + + fireBuffer[x + 1][y][Bit] + + fireBuffer[x][y - 1][Bit] + + fireBuffer[x][y + 1][Bit] + + fireBuffer[x][y][Bit]) / + 5.0; + + fire_c = (fireBuffer[x - 1][y][Bit] + + fireBuffer[x + 1][y][Bit] + + fireBuffer[x][y - 1][Bit] + + fireBuffer[x][y + 1][Bit] + + fireBuffer[x][y][Bit]) / + 5.0; + + if (fire_c > (FIRE_HEIGHT / 2) && fire_c < FIRE_HEIGHT) { + fire_c -= 0.2; + } else if (fire_c > (FIRE_HEIGHT / 4) && fire_c < (FIRE_HEIGHT / 2)) { + fire_c -= 0.4; + } else if (fire_c <= (FIRE_HEIGHT / 8)) { + fire_c -= 0.7; + } else { + fire_c -= 1; + } + if (fire_c < 0) + fire_c = 0; + if (fire_c >= FIRE_HEIGHT + 1) + fire_c = FIRE_HEIGHT - 1; + fireBuffer[x][y - 1][NBit] = fire_c; + int index = (int)fire_c * 3; + if (fire_c == 0) + { + effects.drawBackgroundFastLEDPixelCRGB(x, y, CRGB(0, 0, 0)); + } + else + { + effects.drawBackgroundFastLEDPixelCRGB(x, y, CRGB(palette_fire[index], palette_fire[index + 1], palette_fire[index + 2])); + } + } + } + //display.drawRect(0, 0, VPANEL_W, VPANEL_H, display.color565(25, 25, 25)); + + NBit = Bit; + Bit = 1 - Bit; + + effects.ShowFrame(); + + return 30; // no idea what this is for... + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternFlock.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternFlock.h new file mode 100644 index 0000000..3ae31b1 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternFlock.h @@ -0,0 +1,125 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from "Flocking" in "The Nature of Code" by Daniel Shiffman: http://natureofcode.com/ + * Copyright (c) 2014 Daniel Shiffman + * http://www.shiffman.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +// Flocking +// Daniel Shiffman +// The Nature of Code, Spring 2009 + +// Demonstration of Craig Reynolds' "Flocking" behavior +// See: http://www.red3d.com/cwr/ +// Rules: Cohesion, Separation, Alignment + +#ifndef PatternFlock_H +#define PatternFlock_H + +class PatternFlock : public Drawable { + public: + PatternFlock() { + name = (char *)"Flock"; + } + + static const int boidCount = 10; + Boid predator; + + PVector wind; + byte hue = 0; + bool predatorPresent = true; + + void start() { + for (int i = 0; i < boidCount; i++) { + boids[i] = Boid(15, 15); + boids[i].maxspeed = 0.380; + boids[i].maxforce = 0.015; + } + + predatorPresent = random(0, 2) >= 1; + if (predatorPresent) { + predator = Boid(31, 31); + predatorPresent = true; + predator.maxspeed = 0.385; + predator.maxforce = 0.020; + predator.neighbordist = 16.0; + predator.desiredseparation = 0.0; + } + } + + unsigned int drawFrame() { + effects.DimAll(230); effects.ShowFrame(); + + bool applyWind = random(0, 255) > 250; + if (applyWind) { + wind.x = Boid::randomf() * .015; + wind.y = Boid::randomf() * .015; + } + + CRGB color = effects.ColorFromCurrentPalette(hue); + + for (int i = 0; i < boidCount; i++) { + Boid * boid = &boids[i]; + + if (predatorPresent) { + // flee from predator + boid->repelForce(predator.location, 10); + } + + boid->run(boids, boidCount); + boid->wrapAroundBorders(); + PVector location = boid->location; + // PVector velocity = boid->velocity; + // backgroundLayer.drawLine(location.x, location.y, location.x - velocity.x, location.y - velocity.y, color); + // effects.leds[XY(location.x, location.y)] += color; + effects.drawBackgroundFastLEDPixelCRGB(location.x, location.y, color); + + if (applyWind) { + boid->applyForce(wind); + applyWind = false; + } + } + + if (predatorPresent) { + predator.run(boids, boidCount); + predator.wrapAroundBorders(); + color = effects.ColorFromCurrentPalette(hue + 128); + PVector location = predator.location; + // PVector velocity = predator.velocity; + // backgroundLayer.drawLine(location.x, location.y, location.x - velocity.x, location.y - velocity.y, color); + // effects.leds[XY(location.x, location.y)] += color; + effects.drawBackgroundFastLEDPixelCRGB(location.x, location.y, color); + } + + EVERY_N_MILLIS(200) { + hue++; + } + + EVERY_N_SECONDS(30) { + predatorPresent = !predatorPresent; + } + + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternFlowField.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternFlowField.h new file mode 100644 index 0000000..be91ff2 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternFlowField.h @@ -0,0 +1,92 @@ +/* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternFlowField_H + +class PatternFlowField : public Drawable { + public: + PatternFlowField() { + name = (char *)"FlowField"; + } + + uint16_t x; + uint16_t y; + uint16_t z; + + uint16_t speed = 1; + uint16_t scale = 26; + + static const int count = 40; + + byte hue = 0; + + void start() { + x = random16(); + y = random16(); + z = random16(); + + for (int i = 0; i < count; i++) { + boids[i] = Boid(random(VPANEL_W), 0); + } + } + + unsigned int drawFrame() { + effects.DimAll(240); + + // CRGB color = effects.ColorFromCurrentPalette(hue); + + for (int i = 0; i < count; i++) { + Boid * boid = &boids[i]; + + int ioffset = scale * boid->location.x; + int joffset = scale * boid->location.y; + + byte angle = inoise8(x + ioffset, y + joffset, z); + + boid->velocity.x = (float) sin8(angle) * 0.0078125 - 1.0; + boid->velocity.y = -((float)cos8(angle) * 0.0078125 - 1.0); + boid->update(); + + effects.drawBackgroundFastLEDPixelCRGB(boid->location.x, boid->location.y, effects.ColorFromCurrentPalette(angle + hue)); // color + + if (boid->location.x < 0 || boid->location.x >= VPANEL_W || + boid->location.y < 0 || boid->location.y >= VPANEL_H) { + boid->location.x = random(VPANEL_W); + boid->location.y = 0; + } + } + + EVERY_N_MILLIS(200) { + hue++; + } + + x += speed; + y += speed; + z += speed; + + effects.ShowFrame(); + + return 50; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternIncrementalDrift.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternIncrementalDrift.h new file mode 100644 index 0000000..573c765 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternIncrementalDrift.h @@ -0,0 +1,51 @@ +/* +* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternIncrementalDrift_H +#define PatternIncrementalDrift_H + +class PatternIncrementalDrift : public Drawable { + public: + PatternIncrementalDrift() { + name = (char *)"Incremental Drift"; + } + + unsigned int drawFrame() { + uint8_t dim = beatsin8(2, 230, 250); + effects.DimAll(dim); effects.ShowFrame(); + + for (int i = 2; i <= VPANEL_W / 2; i++) + { + CRGB color = effects.ColorFromCurrentPalette((i - 2) * (240 / (VPANEL_W / 2))); + + uint8_t x = beatcos8((17 - i) * 2, MATRIX_CENTER_X - i, MATRIX_CENTER_X + i); + uint8_t y = beatsin8((17 - i) * 2, MATRIX_CENTER_Y - i, MATRIX_CENTER_Y + i); + + effects.drawBackgroundFastLEDPixelCRGB(x, y, color); + } + + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternIncrementalDrift2.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternIncrementalDrift2.h new file mode 100644 index 0000000..03312f6 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternIncrementalDrift2.h @@ -0,0 +1,64 @@ +/* +* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternIncrementalDrift2_H +#define PatternIncrementalDrift2_H + +class PatternIncrementalDrift2 : public Drawable { + public: + PatternIncrementalDrift2() { + name = (char *)"Incremental Drift Rose"; + } + + unsigned int drawFrame() { + uint8_t dim = beatsin8(2, 170, 250); + effects.DimAll(dim); effects.ShowFrame(); + + for (int i = 2; i < VPANEL_H / 2; ++i) + //for (uint8_t i = 0; i < 32; i++) + { + CRGB color; + + uint8_t x = 0; + uint8_t y = 0; + + if (i < 16) { + x = beatcos8((i + 1) * 2, i, VPANEL_W - i); + y = beatsin8((i + 1) * 2, i, VPANEL_H - i); + color = effects.ColorFromCurrentPalette(i * 14); + } + else + { + x = beatsin8((32 - i) * 2, VPANEL_W - i, i + 1); + y = beatcos8((32 - i) * 2, VPANEL_H - i, i + 1); + color = effects.ColorFromCurrentPalette((31 - i) * 14); + } + + effects.drawBackgroundFastLEDPixelCRGB(x, y, color); + } + + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternInfinity.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternInfinity.h new file mode 100644 index 0000000..c99f329 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternInfinity.h @@ -0,0 +1,61 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternInfinity_H + +class PatternInfinity : public Drawable { +public: + PatternInfinity() { + name = (char *)"Infinity"; + } + + unsigned int drawFrame() { + // dim all pixels on the display slightly + // to 250/255 (98%) of their current brightness + blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, 250); + // effects.DimAll(250); effects.ShowFrame(); + + + // the Effects class has some sample oscillators + // that move from 0 to 255 at different speeds + effects.MoveOscillators(); + + // the horizontal position of the head of the infinity sign + // oscillates from 0 to the maximum horizontal and back + int x = (VPANEL_W - 1) - effects.p[1]; + + // the vertical position of the head oscillates + // from 8 to 23 and back (hard-coded for a 32x32 matrix) + int y = map8(sin8(effects.osci[3]), 8, 23); + + // the hue oscillates from 0 to 255, overflowing back to 0 + byte hue = sin8(effects.osci[5]); + + // draw a pixel at x,y using a color from the current palette + effects.Pixel(x, y, hue); + + effects.ShowFrame(); + return 30; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternInvaders.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternInvaders.h new file mode 100644 index 0000000..98f3200 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternInvaders.h @@ -0,0 +1,154 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Inspired by 'Space Invader Generator': https://the8bitpimp.wordpress.com/2013/05/07/space-invader-generator + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternInvaders_H +#define PatternInvaders_H + +class PatternInvadersSmall : public Drawable { + private: + uint8_t x = 1; + uint8_t y = 1; + + public: + PatternInvadersSmall() { + name = (char *)"Invaders Small"; + } + + void start() { + matrix->fillScreen(0); + } + + unsigned int drawFrame() { + CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255)); + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 5; j++) { + CRGB color = CRGB::Black; + + if (random(0, 2) == 1) color = color1; + + effects.drawBackgroundFastLEDPixelCRGB(x + i, y + j, color); + + if (i < 2) + effects.drawBackgroundFastLEDPixelCRGB(x + (4 - i), y + j, color); + } + } + + x += 6; + if (x > 25) { + x = 1; + y += 6; + } + + if (y > 25) y = x = 1; + + effects.ShowFrame(); + + return 125; + } +}; + +class PatternInvadersMedium : public Drawable { + private: + uint8_t x = 0; + uint8_t y = 0; + + public: + PatternInvadersMedium() { + name = (char *)"Invaders Medium"; + } + + void start() { + matrix->fillScreen(0); + } + + unsigned int drawFrame() { + CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255)); + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 5; j++) { + CRGB color = CRGB::Black; + + if (random(0, 2) == 1) color = color1; + + matrix->fillRect(x + (i * 2), y + (j * 2), x + (i * 2 + 1), y + (j * 2 + 1), color); + + if (i < 2) + matrix->fillRect(x + (8 - i * 2), y + (j * 2), x + (9 - i * 2), y + (j * 2 + 1), color); + } + } + + x += 11; + if (x > 22) { + x = 0; + y += 11; + } + + if (y > 22) y = x = 0; + + effects.ShowFrame(); + + return 500; + } +}; + +class PatternInvadersLarge : public Drawable { + private: + + public: + PatternInvadersLarge() { + name = (char *)"Invaders Large"; + } + + void start() { + matrix->fillScreen(0); + } + + unsigned int drawFrame() { + matrix->fillScreen(0); + + CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255)); + + for (int x = 0; x < 3; x++) { + for (int y = 0; y < 5; y++) { + CRGB color = CRGB::Black; + + if (random(0, 2) == 1) { + color = color1; + } + + matrix->fillRect(1 + x * 6, 1 + y * 6, 5 + x * 6, 5 + y * 6, color); + + if (x < 2) + matrix->fillRect(1 + (4 - x) * 6, 1 + y * 6, 5 + (4 - x) * 6, 5 + y * 6, color); + } + } + + effects.ShowFrame(); + + return 2000; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternLife.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternLife.h new file mode 100644 index 0000000..8074e40 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternLife.h @@ -0,0 +1,129 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from Andrew: http://pastebin.com/f22bfe94d + * which, in turn, was "Adapted from the Life example on the Processing.org site" + * + * Made much more colorful by J.B. Langston: https://github.com/jblang/aurora/commit/6db5a884e3df5d686445c4f6b669f1668841929b + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternLife_H +#define PatternLife_H + +class Cell { +public: + byte alive : 1; + byte prev : 1; + byte hue: 6; + byte brightness; +}; + +class PatternLife : public Drawable { +private: + Cell world[VPANEL_W][VPANEL_H]; + unsigned int density = 50; + int generation = 0; + + void randomFillWorld() { + for (int i = 0; i < VPANEL_W; i++) { + for (int j = 0; j < VPANEL_H; j++) { + if (random(100) < density) { + world[i][j].alive = 1; + world[i][j].brightness = 255; + } + else { + world[i][j].alive = 0; + world[i][j].brightness = 0; + } + world[i][j].prev = world[i][j].alive; + world[i][j].hue = 0; + } + } + } + + int neighbours(int x, int y) { + return (world[(x + 1) % VPANEL_W][y].prev) + + (world[x][(y + 1) % VPANEL_H].prev) + + (world[(x + VPANEL_W - 1) % VPANEL_W][y].prev) + + (world[x][(y + VPANEL_H - 1) % VPANEL_H].prev) + + (world[(x + 1) % VPANEL_W][(y + 1) % VPANEL_H].prev) + + (world[(x + VPANEL_W - 1) % VPANEL_W][(y + 1) % VPANEL_H].prev) + + (world[(x + VPANEL_W - 1) % VPANEL_W][(y + VPANEL_H - 1) % VPANEL_H].prev) + + (world[(x + 1) % VPANEL_W][(y + VPANEL_H - 1) % VPANEL_H].prev); + } + +public: + PatternLife() { + name = (char *)"Life"; + } + + unsigned int drawFrame() { + if (generation == 0) { + effects.ClearFrame(); + + randomFillWorld(); + } + + // Display current generation + for (int i = 0; i < VPANEL_W; i++) { + for (int j = 0; j < VPANEL_H; j++) { + effects.leds[XY(i, j)] = effects.ColorFromCurrentPalette(world[i][j].hue * 4, world[i][j].brightness); + } + } + + // Birth and death cycle + for (int x = 0; x < VPANEL_W; x++) { + for (int y = 0; y < VPANEL_H; y++) { + // Default is for cell to stay the same + if (world[x][y].brightness > 0 && world[x][y].prev == 0) + world[x][y].brightness *= 0.9; + int count = neighbours(x, y); + if (count == 3 && world[x][y].prev == 0) { + // A new cell is born + world[x][y].alive = 1; + world[x][y].hue += 2; + world[x][y].brightness = 255; + } else if ((count < 2 || count > 3) && world[x][y].prev == 1) { + // Cell dies + world[x][y].alive = 0; + } + } + } + + // Copy next generation into place + for (int x = 0; x < VPANEL_W; x++) { + for (int y = 0; y < VPANEL_H; y++) { + world[x][y].prev = world[x][y].alive; + } + } + + + generation++; + if (generation >= 256) + generation = 0; + + effects.ShowFrame(); + + return 60; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternMaze.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternMaze.h new file mode 100644 index 0000000..b4e26a9 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternMaze.h @@ -0,0 +1,264 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Many thanks to Jamis Buck for the documentation of the Growing Tree maze generation algorithm: http://weblog.jamisbuck.org/2011/1/27/maze-generation-growing-tree-algorithm + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternMaze_H +#define PatternMaze_H + +class PatternMaze : public Drawable { +private: + enum Directions { + None = 0, + Up = 1, + Down = 2, + Left = 4, + Right = 8, + }; + + struct Point{ + int x; + int y; + + static Point New(int x, int y) { + Point point; + point.x = x; + point.y = y; + return point; + } + + Point Move(Directions direction) { + switch (direction) + { + case Up: + return New(x, y - 1); + + case Down: + return New(x, y + 1); + + case Left: + return New(x - 1, y); + + case Right: + default: + return New(x + 1, y); + } + } + + static Directions Opposite(Directions direction) { + switch (direction) { + case Up: + return Down; + + case Down: + return Up; + + case Left: + return Right; + + case Right: + default: + return Left; + } + } + }; + +// int width = 16; +// int height = 16; + + static const int width = VPANEL_W / 2; + static const int height = VPANEL_H / 2; + + + Directions grid[width][height]; + + Point point; + + Point cells[256]; + int cellCount = 0; + + int algorithm = 0; + int algorithmCount = 1; + + byte hue = 0; + byte hueOffset = 0; + + Directions directions[4] = { Up, Down, Left, Right }; + + void removeCell(int index) {// shift cells after index down one + for (int i = index; i < cellCount - 1; i++) { + cells[i] = cells[i + 1]; + } + + cellCount--; + } + + void shuffleDirections() { + for (int a = 0; a < 4; a++) + { + int r = random(a, 4); + Directions temp = directions[a]; + directions[a] = directions[r]; + directions[r] = temp; + } + } + + Point createPoint(int x, int y) { + Point point; + point.x = x; + point.y = y; + return point; + } + + CRGB chooseColor(int index) { + byte h = index + hueOffset; + + switch (algorithm) { + case 0: + default: + return effects.ColorFromCurrentPalette(h); + + case 1: + return effects.ColorFromCurrentPalette(hue++); + } + } + + int chooseIndex(int max) { + switch (algorithm) { + case 0: + default: + // choose newest (recursive backtracker) + return max - 1; + + case 1: + // choose random(Prim's) + return random(max); + + // case 2: + // // choose oldest (not good, so disabling) + // return 0; + } + } + + void generateMaze() { + while (cellCount > 1) { + drawNextCell(); + } + } + + void drawNextCell() { + int index = chooseIndex(cellCount); + + if (index < 0) + return; + + point = cells[index]; + + Point imagePoint = createPoint(point.x * 2, point.y * 2); + + //effects.drawBackgroundFastLEDPixelCRGB(imagePoint.x, imagePoint.y, CRGB(CRGB::Gray)); + + shuffleDirections(); + + CRGB color = chooseColor(index); + + for (int i = 0; i < 4; i++) { + Directions direction = directions[i]; + + Point newPoint = point.Move(direction); + if (newPoint.x >= 0 && newPoint.y >= 0 && newPoint.x < width && newPoint.y < height && grid[newPoint.y][newPoint.x] == None) { + grid[point.y][point.x] = (Directions) ((int) grid[point.y][point.x] | (int) direction); + grid[newPoint.y][newPoint.x] = (Directions) ((int) grid[newPoint.y][newPoint.x] | (int) point.Opposite(direction)); + + Point newImagePoint = imagePoint.Move(direction); + + effects.drawBackgroundFastLEDPixelCRGB(newImagePoint.x, newImagePoint.y, color); + + cellCount++; + cells[cellCount - 1] = newPoint; + + index = -1; + break; + } + } + + if (index > -1) { + Point finishedPoint = cells[index]; + imagePoint = createPoint(finishedPoint.x * 2, finishedPoint.y * 2); + effects.drawBackgroundFastLEDPixelCRGB(imagePoint.x, imagePoint.y, color); + + removeCell(index); + } + } + +public: + PatternMaze() { + name = (char *)"Maze"; + } + + unsigned int drawFrame() { + if (cellCount < 1) { + + effects.ClearFrame(); + + // reset the maze grid + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + grid[y][x] = None; + } + } + + int x = random(width); + int y = random(height); + + cells[0] = createPoint(x, y); + + cellCount = 1; + + hue = 0; + hueOffset = random(0, 256); + + } + + drawNextCell(); + + if (cellCount < 1) { + algorithm++; + if (algorithm >= algorithmCount) + algorithm = 0; + + return 0; + } + + effects.ShowFrame(); + + return 0; + } + + void start() { + effects.ClearFrame(); + cellCount = 0; + hue = 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternMunch.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternMunch.h new file mode 100644 index 0000000..092dca1 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternMunch.h @@ -0,0 +1,73 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Munch pattern created by J.B. Langston: https://github.com/jblang/aurora/blob/master/PatternMunch.h + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternMunch_H +#define PatternMunch_H + + +class PatternMunch : public Drawable { +private: + byte count = 0; + byte dir = 1; + byte flip = 0; + byte generation = 0; + +public: + PatternMunch() { + name = (char *)"Munch"; + } + + unsigned int drawFrame() { + + for (uint16_t x = 0; x < VPANEL_W; x++) { + for (uint16_t y = 0; y < VPANEL_H; y++) { + effects.leds[XY16(x, y)] = (x ^ y ^ flip) < count ? effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) : CRGB::Black; + + // The below is more pleasant + // effects.leds[XY(x, y)] = effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) ; + } + } + + count += dir; + + if (count <= 0 || count >= VPANEL_W) { + dir = -dir; + } + + if (count <= 0) { + if (flip == 0) + flip = VPANEL_W-1; + else + flip = 0; + } + + generation++; + + // show it ffs! + effects.ShowFrame(); + return 60; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternNoiseSmearing.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternNoiseSmearing.h new file mode 100644 index 0000000..2d6723a --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternNoiseSmearing.h @@ -0,0 +1,338 @@ +/* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Portions of this code are adapted from "Noise Smearing" by Stefan Petrick: https://gist.githubusercontent.com/embedded-creations/5cd47d83cb0e04f4574d/raw/ebf6a82b4755d55cfba3bf6598f7b19047f89daf/NoiseSmearing.ino +* Copyright (c) 2014 Stefan Petrick +* http://www.stefan-petrick.de/wordpress_beta +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternNoiseSmearing_H +#define PatternNoiseSmearing_H + +byte patternNoiseSmearingHue = 0; + +class PatternMultipleStream : public Drawable { +public: + PatternMultipleStream() { + name = (char *)"MultipleStream"; + } + + // this pattern draws two points to the screen based on sin/cos if a counter + // (comment out NoiseSmearWithRadius to see pattern of pixels) + // these pixels are smeared by a large radius, giving a lot of movement + // the image is dimmed before each drawing to not saturate the screen with color + // the smear has an offset so the pixels usually have a trail leading toward the upper left + unsigned int drawFrame() { + static unsigned long counter = 0; +#if 0 + // this counter lets put delays between each frame and still get the same animation + counter++; +#else + // this counter updates in real time and can't be slowed down for debugging + counter = millis() / 10; +#endif + + byte x1 = 4 + sin8(counter * 2) / 10; + byte x2 = 8 + sin8(counter * 2) / 16; + byte y2 = 8 + cos8((counter * 2) / 3) / 16; + + effects.leds[XY(x1, x2)] = effects.ColorFromCurrentPalette(patternNoiseSmearingHue); + effects.leds[XY(x2, y2)] = effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 128); + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(8); + effects.MoveFractionalNoiseX(); + + effects.MoveY(8); + effects.MoveFractionalNoiseY(); + + patternNoiseSmearingHue++; + + return 0; + } +}; + +class PatternMultipleStream2 : public Drawable { +public: + PatternMultipleStream2() { + name = (char *)"MultipleStream2"; + } + + unsigned int drawFrame() { + effects.DimAll(230); effects.ShowFrame(); + + byte xx = 4 + sin8(millis() / 9) / 10; + byte yy = 4 + cos8(millis() / 10) / 10; + effects.leds[XY(xx, yy)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue); + + xx = 8 + sin8(millis() / 10) / 16; + yy = 8 + cos8(millis() / 7) / 16; + effects.leds[XY(xx, yy)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 80); + + effects.leds[XY(15, 15)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 160); + + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + effects.MoveFractionalNoiseY(4); + + effects.MoveY(3); + effects.MoveFractionalNoiseX(4); + + patternNoiseSmearingHue++; + + return 0; + } +}; + +class PatternMultipleStream3 : public Drawable { +public: + PatternMultipleStream3() { + name = (char *)"MultipleStream3"; + } + + unsigned int drawFrame() { + //CLS(); + effects.DimAll(235); effects.ShowFrame(); + + for (uint8_t i = 3; i < 32; i = i + 4) { + effects.leds[XY(i, 15)] += effects.ColorFromCurrentPalette(i * 8); + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + effects.MoveFractionalNoiseY(4); + + effects.MoveY(3); + effects.MoveFractionalNoiseX(4); + + effects.ShowFrame(); + + return 1; + } +}; + +class PatternMultipleStream4 : public Drawable { +public: + PatternMultipleStream4() { + name = (char *)"MultipleStream4"; + } + + unsigned int drawFrame() { + + //CLS(); + effects.DimAll(235); effects.ShowFrame(); + + effects.leds[XY(15, 15)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue); + + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(8); + effects.MoveFractionalNoiseX(); + + effects.MoveY(8); + effects.MoveFractionalNoiseY(); + + patternNoiseSmearingHue++; + + return 0; + } +}; + +class PatternMultipleStream5 : public Drawable { +public: + PatternMultipleStream5() { + name = (char *)"MultipleStream5"; + } + + unsigned int drawFrame() { + + //CLS(); + effects.DimAll(235); effects.ShowFrame(); + + + for (uint8_t i = 3; i < 32; i = i + 4) { + effects.leds[XY(i, 31)] += effects.ColorFromCurrentPalette(i * 8); + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + effects.MoveFractionalNoiseY(4); + + effects.MoveY(4); + effects.MoveFractionalNoiseX(4); + + return 0; + } +}; + +class PatternMultipleStream8 : public Drawable { +public: + PatternMultipleStream8() { + name = (char *)"MultipleStream8"; + } + + unsigned int drawFrame() { + effects.DimAll(230); effects.ShowFrame(); + + // draw grid of rainbow dots on top of the dimmed image + for (uint8_t y = 1; y < 32; y = y + 6) { + for (uint8_t x = 1; x < 32; x = x + 6) { + + effects.leds[XY(x, y)] += effects.ColorFromCurrentPalette((x * y) / 4); + } + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + effects.MoveFractionalNoiseX(4); + + effects.MoveY(3); + effects.MoveFractionalNoiseY(4); + + return 0; + } +}; + +class PatternPaletteSmear : public Drawable { +public: + PatternPaletteSmear() { + name = (char *)"PaletteSmear"; + } + + unsigned int drawFrame() { + + effects.DimAll(170); effects.ShowFrame(); + + // draw a rainbow color palette + for (uint8_t y = 0; y < VPANEL_H; y++) { + for (uint8_t x = 0; x < VPANEL_W; x++) { + effects.leds[XY(x, y)] += effects.ColorFromCurrentPalette(x * 8, y * 8 + 7); + } + } + + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + + effects.FillNoise(); + + effects.MoveX(3); + //effects.MoveFractionalNoiseY(4); + + effects.MoveY(3); + effects.MoveFractionalNoiseX(4); + effects.ShowFrame(); + + return 0; + } +}; + +class PatternRainbowFlag : public Drawable { +public: + PatternRainbowFlag() { + name = (char *)"RainbowFlag"; + } + + unsigned int drawFrame() { + effects.DimAll(10); effects.ShowFrame(); + + CRGB rainbow[7] = { + CRGB::Red, + CRGB::Orange, + CRGB::Yellow, + CRGB::Green, + CRGB::Blue, + CRGB::Violet + }; + + uint8_t y = 2; + + for (uint8_t c = 0; c < 6; c++) { + for (uint8_t j = 0; j < 5; j++) { + for (uint8_t x = 0; x < VPANEL_W; x++) { + effects.leds[XY(x, y)] += rainbow[c]; + } + + y++; + if (y >= VPANEL_H) + break; + } + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + effects.MoveFractionalNoiseY(4); + + effects.MoveY(3); + effects.MoveFractionalNoiseX(4); + + return 0; + } +}; +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternPendulumWave.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternPendulumWave.h new file mode 100644 index 0000000..985e15a --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternPendulumWave.h @@ -0,0 +1,66 @@ +/* +* +* Inspired by and based on a loading animation for Prismata by Lunarch Studios: +* http://www.reddit.com/r/gifs/comments/2on8si/connecting_to_server_so_mesmerizing/cmow0sz +* +* Lunarch Studios Inc. hereby publishes the Actionscript 3 source code pasted in this +* comment under the Creative Commons CC0 1.0 Universal Public Domain Dedication. +* Lunarch Studios Inc. waives all rights to the work worldwide under copyright law, +* including all related and neighboring rights, to the extent allowed by law. +* You can copy, modify, distribute and perform the work, even for commercial purposes, +* all without asking permission. +* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternPendulumWave_H +#define PatternPendulumWave_H + +#define WAVE_BPM 25 +#define AMP_BPM 2 +#define SKEW_BPM 4 +#define WAVE_TIMEMINSKEW VPANEL_W/8 +#define WAVE_TIMEMAXSKEW VPANEL_W/2 + +class PatternPendulumWave : public Drawable { + public: + PatternPendulumWave() { + name = (char *)"Pendulum Wave"; + } + + unsigned int drawFrame() { + effects.ClearFrame(); + + for (int x = 0; x < VPANEL_W; ++x) + { + uint16_t amp = beatsin16(AMP_BPM, VPANEL_H/8, VPANEL_H-1); + uint16_t offset = (VPANEL_H - beatsin16(AMP_BPM, 0, VPANEL_H))/2; + + uint8_t y = beatsin16(WAVE_BPM, 0, amp, x*beatsin16(SKEW_BPM, WAVE_TIMEMINSKEW, WAVE_TIMEMAXSKEW)) + offset; + + effects.drawBackgroundFastLEDPixelCRGB(x, y, effects.ColorFromCurrentPalette(x * 7)); + } + effects.ShowFrame(); + return 20; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternPlasma.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternPlasma.h new file mode 100644 index 0000000..dcecc97 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternPlasma.h @@ -0,0 +1,66 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from LedEffects Plasma by Robert Atkins: https://bitbucket.org/ratkins/ledeffects/src/26ed3c51912af6fac5f1304629c7b4ab7ac8ca4b/Plasma.cpp?at=default + * Copyright (c) 2013 Robert Atkins + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternPlasma_H +#define PatternPlasma_H + +class PatternPlasma : public Drawable { +private: + int time = 0; + int cycles = 0; + +public: + PatternPlasma() { + name = (char *)"Plasma"; + } + + unsigned int drawFrame() { + for (int x = 0; x < VPANEL_W; x++) { + for (int y = 0; y < VPANEL_H; y++) { + int16_t v = 0; + uint8_t wibble = sin8(time); + v += sin16(x * wibble * 6 + time); + v += cos16(y * (128 - wibble) * 6 + time); + v += sin16(y * x * cos8(-time) / 8); + + effects.Pixel(x, y, (v >> 8) + 127); + } + } + + time += 1; + cycles++; + + if (cycles >= 2048) { + time = 0; + cycles = 0; + } + + effects.ShowFrame(); + + return 30; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternPulse.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternPulse.h new file mode 100644 index 0000000..8992a4d --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternPulse.h @@ -0,0 +1,82 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Based at least in part on someone else's work that I can no longer find. + * Please let me know if you recognize any of this code! + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternPulse_H +#define PatternPulse_H + +class PatternPulse : public Drawable { + private: + int hue; + int centerX = 0; + int centerY = 0; + int step = -1; + int maxSteps = 16; + float fadeRate = 0.8; + int diff; + + public: + PatternPulse() { + name = (char *)"Pulse"; + } + + unsigned int drawFrame() { + effects.DimAll(235); + + if (step == -1) { + centerX = random(32); + centerY = random(32); + hue = random(256); // 170; + step = 0; + } + + if (step == 0) { + matrix.drawCircle(centerX, centerY, step, effects.ColorFromCurrentPalette(hue)); + step++; + } + else { + if (step < maxSteps) { + // initial pulse + matrix.drawCircle(centerX, centerY, step, effects.ColorFromCurrentPalette(hue, pow(fadeRate, step - 2) * 255)); + + // secondary pulse + if (step > 3) { + matrix.drawCircle(centerX, centerY, step - 3, effects.ColorFromCurrentPalette(hue, pow(fadeRate, step - 2) * 255)); + } + step++; + } + else { + step = -1; + } + } + + effects.standardNoiseSmearing(); + + effects.ShowFrame(); + + return 30; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternRadar.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternRadar.h new file mode 100644 index 0000000..602078b --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternRadar.h @@ -0,0 +1,56 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternRadar_H + +class PatternRadar : public Drawable { + private: + byte theta = 0; + byte hueoffset = 0; + + public: + PatternRadar() { + name = (char *)"Radar"; + } + + unsigned int drawFrame() { + effects.DimAll(254); effects.ShowFrame(); + + for (int offset = 0; offset < MATRIX_CENTER_X; offset++) { + byte hue = 255 - (offset * 16 + hueoffset); + CRGB color = effects.ColorFromCurrentPalette(hue); + uint8_t x = mapcos8(theta, offset, (VPANEL_W - 1) - offset); + uint8_t y = mapsin8(theta, offset, (VPANEL_H - 1) - offset); + uint16_t xy = XY(x, y); + effects.leds[xy] = color; + + EVERY_N_MILLIS(25) { + theta += 2; + hueoffset += 1; + } + } + + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSimplexNoise.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSimplexNoise.h new file mode 100644 index 0000000..3810ec0 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSimplexNoise.h @@ -0,0 +1,79 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/blob/master/examples/Noise/Noise.ino + * Copyright (c) 2013 FastLED + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternSimplexNoise_H +#define PatternSimplexNoise_H + +class PatternSimplexNoise : public Drawable { + public: + PatternSimplexNoise() { + name = (char *)"Noise"; + } + + void start() { + // Initialize our coordinates to some random values + noise_x = random16(); + noise_y = random16(); + noise_z = random16(); + } + + unsigned int drawFrame() { +#if FASTLED_VERSION >= 3001000 + // a new parameter set every 15 seconds + EVERY_N_SECONDS(15) { + noise_x = random16(); + noise_y = random16(); + noise_z = random16(); + } +#endif + + uint32_t speed = 100; + + effects.FillNoise(); + ShowNoiseLayer(0, 1, 0); + + // noise_x += speed; + noise_y += speed; + noise_z += speed; + + effects.ShowFrame(); + + return 30; + } + + // show just one layer + void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) { + for (uint16_t i = 0; i < VPANEL_W; i++) { + for (uint16_t j = 0; j < VPANEL_H; j++) { + uint8_t pixel = noise[i][j]; + + // assign a color depending on the actual palette + effects.leds[XY16(i, j)] = effects.ColorFromCurrentPalette(colorrepeat * (pixel + colorshift), pixel); + } + } + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSnake.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSnake.h new file mode 100644 index 0000000..00895ab --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSnake.h @@ -0,0 +1,145 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from LedEffects Snake by Robert Atkins: https://bitbucket.org/ratkins/ledeffects/src/26ed3c51912af6fac5f1304629c7b4ab7ac8ca4b/Snake.cpp?at=default + * Copyright (c) 2013 Robert Atkins + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternSnake_H +#define PatternSnake_H + +class PatternSnake : public Drawable { +private: + static const byte SNAKE_LENGTH = 16; + + CRGB colors[SNAKE_LENGTH]; + uint8_t initialHue; + + enum Direction { + UP, DOWN, LEFT, RIGHT + }; + + struct Pixel { + uint8_t x; + uint8_t y; + }; + + struct Snake { + Pixel pixels[SNAKE_LENGTH]; + + Direction direction; + + void newDirection() { + switch (direction) { + case UP: + case DOWN: + direction = random(0, 2) == 1 ? RIGHT : LEFT; + break; + + case LEFT: + case RIGHT: + direction = random(0, 2) == 1 ? DOWN : UP; + + default: + break; + } + } + + void shuffleDown() { + for (byte i = SNAKE_LENGTH - 1; i > 0; i--) { + pixels[i] = pixels[i - 1]; + } + } + + void reset() { + direction = UP; + for (int i = 0; i < SNAKE_LENGTH; i++) { + pixels[i].x = 0; + pixels[i].y = 0; + } + } + + void move() { + switch (direction) { + case UP: + pixels[0].y = (pixels[0].y + 1) % VPANEL_H; + break; + case LEFT: + pixels[0].x = (pixels[0].x + 1) % VPANEL_W; + break; + case DOWN: + pixels[0].y = pixels[0].y == 0 ? VPANEL_H - 1 : pixels[0].y - 1; + break; + case RIGHT: + pixels[0].x = pixels[0].x == 0 ? VPANEL_W - 1 : pixels[0].x - 1; + break; + } + } + + void draw(CRGB colors[SNAKE_LENGTH]) { + for (byte i = 0; i < SNAKE_LENGTH; i++) { + effects.leds[XY(pixels[i].x, pixels[i].y)] = colors[i] %= (255 - i * (255 / SNAKE_LENGTH)); + } + } + }; + + static const int snakeCount = 6; + Snake snakes[snakeCount]; + +public: + PatternSnake() { + name = (char *)"Snake"; + for (int i = 0; i < snakeCount; i++) { + Snake* snake = &snakes[i]; + snake->reset(); + } + } + + void start() + { + effects.ClearFrame(); + } + + unsigned int drawFrame() { + + + fill_palette(colors, SNAKE_LENGTH, initialHue++, 5, effects.currentPalette, 255, LINEARBLEND); + + for (int i = 0; i < snakeCount; i++) { + Snake* snake = &snakes[i]; + + snake->shuffleDown(); + + if (random(10) > 7) { + snake->newDirection(); + } + + snake->move(); + snake->draw(colors); + } + + effects.ShowFrame(); + + return 30; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSpark.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSpark.h new file mode 100644 index 0000000..059d97c --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSpark.h @@ -0,0 +1,113 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/tree/master/examples/Fire2012WithPalette + * Copyright (c) 2013 FastLED + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternSpark_H +#define PatternSpark_H + +class PatternSpark : public Drawable { + private: + + public: + PatternSpark() { + name = (char *)"Spark"; + } + + // There are two main parameters you can play with to control the look and + // feel of your fire: COOLING (used in step 1 above), and SPARKING (used + // in step 3 above). + // + // COOLING: How much does the air cool as it rises? + // Less cooling = taller flames. More cooling = shorter flames. + // Default 55, suggested range 20-100 + uint8_t cooling = 100; + + // SPARKING: What chance (out of 255) is there that a new spark will be lit? + // Higher chance = more roaring fire. Lower chance = more flickery fire. + // Default 120, suggested range 50-200. + uint8_t sparking = 50; + + unsigned int drawFrame() { + // Add entropy to random number generator; we use a lot of it. + random16_add_entropy( random16()); + + effects.DimAll(235); effects.ShowFrame(); + + for (uint8_t x = 0; x < VPANEL_W; x++) { + // Step 1. Cool down every cell a little + for (int y = 0; y < VPANEL_H; y++) { + int xy = XY(x, y); + heat[xy] = qsub8(heat[xy], random8(0, ((cooling * 10) / VPANEL_H) + 2)); + } + + // Step 2. Heat from each cell drifts 'up' and diffuses a little + for (int y = 0; y < VPANEL_H; y++) { + heat[XY(x, y)] = (heat[XY(x, y + 1)] + heat[XY(x, y + 2)] + heat[XY(x, y + 2)]) / 3; + } + + // Step 2. Randomly ignite new 'sparks' of heat + if (random8() < sparking) { + uint8_t xt = random8(MATRIX_CENTRE_X - 2, MATRIX_CENTER_X + 3); + + int xy = XY(xt, VPANEL_H - 1); + heat[xy] = qadd8(heat[xy], random8(160, 255)); + } + + // Step 4. Map from heat cells to LED colors + for (int y = 0; y < VPANEL_H; y++) { + int xy = XY(x, y); + byte colorIndex = heat[xy]; + + // Recommend that you use values 0-240 rather than + // the usual 0-255, as the last 15 colors will be + // 'wrapping around' from the hot end to the cold end, + // which looks wrong. + colorIndex = scale8(colorIndex, 240); + + // override color 0 to ensure a black background? + if (colorIndex != 0) + // effects.leds[xy] = CRGB::Black; + // else + effects.leds[xy] = effects.ColorFromCurrentPalette(colorIndex); + } + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + effects.MoveFractionalNoiseX(4); + + effects.ShowFrame(); + + return 15; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSpin.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSpin.h new file mode 100644 index 0000000..c3497e7 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSpin.h @@ -0,0 +1,100 @@ +/* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternSpin_H + + + +class PatternSpin : public Drawable { +public: + PatternSpin() { + name = (char *)"Spin"; + } + + float degrees = 0; + float radius = 16; + + float speedStart = 1; + float velocityStart = 0.6; + + float maxSpeed = 30; + + float speed = speedStart; + float velocity = velocityStart; + + void start() { + speed = speedStart; + velocity = velocityStart; + degrees = 0; + } + + unsigned int drawFrame() { + effects.DimAll(190); effects.ShowFrame(); + + CRGB color = effects.ColorFromCurrentPalette(speed * 8); + + // start position + int x; + int y; + + // target position + float targetDegrees = degrees + speed; + float targetRadians = radians(targetDegrees); + int targetX = (int) (MATRIX_CENTER_X + radius * cos(targetRadians)); + int targetY = (int) (MATRIX_CENTER_Y - radius * sin(targetRadians)); + + float tempDegrees = degrees; + + do{ + float radians = radians(tempDegrees); + x = (int) (MATRIX_CENTER_X + radius * cos(radians)); + y = (int) (MATRIX_CENTER_Y - radius * sin(radians)); + + effects.drawBackgroundFastLEDPixelCRGB(x, y, color); + effects.drawBackgroundFastLEDPixelCRGB(y, x, color); + + tempDegrees += 1; + if (tempDegrees >= 360) + tempDegrees = 0; + } while (x != targetX || y != targetY); + + degrees += speed; + + // add velocity to the particle each pass around the accelerator + if (degrees >= 360) { + degrees = 0; + speed += velocity; + if (speed <= speedStart) { + speed = speedStart; + velocity *= -1; + } + else if (speed > maxSpeed){ + speed = maxSpeed - velocity; + velocity *= -1; + } + } + + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSpiral.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSpiral.h new file mode 100644 index 0000000..64ef15d --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSpiral.h @@ -0,0 +1,138 @@ +/* + * Portions of this code are adapted from "Funky Clouds" by Stefan Petrick: + * https://gist.github.com/anonymous/876f908333cd95315c35 + * + * Copyright (c) 2014 Stefan Petrick + * http://www.stefan-petrick.de/wordpress_beta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternSpiral_H +#define PatternSpiral_H + +class PatternSpiral : public Drawable { +private: + // Timer stuff (Oscillators) + struct timer { + unsigned long takt; + unsigned long lastMillis; + unsigned long count; + int delta; + byte up; + byte down; + }; + timer multiTimer[5]; + + int timers = sizeof(multiTimer) / sizeof(multiTimer[0]); + + // counts all variables with different speeds linear up and down + void UpdateTimers() + { + unsigned long now = millis(); + for (int i = 0; i < timers; i++) + { + while (now - multiTimer[i].lastMillis >= multiTimer[i].takt) + { + multiTimer[i].lastMillis += multiTimer[i].takt; + multiTimer[i].count = multiTimer[i].count + multiTimer[i].delta; + if ((multiTimer[i].count == multiTimer[i].up) || (multiTimer[i].count == multiTimer[i].down)) + { + multiTimer[i].delta = -multiTimer[i].delta; + } + } + } + } + +public: + PatternSpiral() { + name = (char *)"Spiral"; + } + + void start() { + // set all counting directions positive for the beginning + for (int i = 0; i < timers; i++) multiTimer[i].delta = 1; + + // set range (up/down), speed (takt=ms between steps) and starting point of all oscillators + + unsigned long now = millis(); + + multiTimer[0].lastMillis = now; + multiTimer[0].takt = 42; //x1 + multiTimer[0].up = VPANEL_W - 1; + multiTimer[0].down = 0; + multiTimer[0].count = 0; + + multiTimer[1].lastMillis = now; + multiTimer[1].takt = 55; //y1 + multiTimer[1].up = VPANEL_H - 1; + multiTimer[1].down = 0; + multiTimer[1].count = 0; + + multiTimer[2].lastMillis = now; + multiTimer[2].takt = 3; //color + multiTimer[2].up = 255; + multiTimer[2].down = 0; + multiTimer[2].count = 0; + + multiTimer[3].lastMillis = now; + multiTimer[3].takt = 71; //x2 + multiTimer[3].up = VPANEL_W - 1; + multiTimer[3].down = 0; + multiTimer[3].count = 0; + + multiTimer[4].lastMillis = now; + multiTimer[4].takt = 89; //y2 + multiTimer[4].up = VPANEL_H - 1; + multiTimer[4].down = 0; + multiTimer[4].count = 0; + } + + unsigned int drawFrame() { + // manage the Oscillators + UpdateTimers(); + + // draw just a line defined by 5 oscillators + effects.BresenhamLine( + multiTimer[3].count, // x1 + multiTimer[4].count, // y1 + multiTimer[0].count, // x2 + multiTimer[1].count, // y2 + multiTimer[2].count); // color + + // manipulate the screen buffer + // with fixed parameters (could be oscillators too) + // Params: center x, y, radius, scale color down + // --> NOTE: Affects always a SQUARE with an odd length + // effects.SpiralStream(15, 15, 10, 128); + + effects.SpiralStream(31, 15, 64, 128); // for 64 pixel wide matrix! + // effects.SpiralStream(47, 15, 10, 128); // for 64 pixel wide matrix! + + // why not several times?! + // effects.SpiralStream(16, 6, 6, 128); + // effects.SpiralStream(10, 24, 10, 128); + + // increase the contrast + effects.DimAll(250); effects.ShowFrame(); + + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSpiro.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSpiro.h new file mode 100644 index 0000000..4b91e12 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSpiro.h @@ -0,0 +1,112 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternSpiro_H + +class PatternSpiro : public Drawable { + private: + byte theta1 = 0; + byte theta2 = 0; + byte hueoffset = 0; + + uint8_t radiusx = VPANEL_W / 4; + uint8_t radiusy = VPANEL_H / 4; + uint8_t minx = MATRIX_CENTER_X - radiusx; + uint8_t maxx = MATRIX_CENTER_X + radiusx + 1; + uint8_t miny = MATRIX_CENTER_Y - radiusy; + uint8_t maxy = MATRIX_CENTER_Y + radiusy + 1; + + uint8_t spirocount = 1; + uint8_t spirooffset = 256 / spirocount; + boolean spiroincrement = true; + + boolean handledChange = false; + + public: + PatternSpiro() { + name = (char *)"Spiro"; + } + + void start(){ + effects.ClearFrame(); + }; + + unsigned int drawFrame() { + blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, 192); + + boolean change = false; + + for (int i = 0; i < spirocount; i++) { + uint8_t x = mapsin8(theta1 + i * spirooffset, minx, maxx); + uint8_t y = mapcos8(theta1 + i * spirooffset, miny, maxy); + + uint8_t x2 = mapsin8(theta2 + i * spirooffset, x - radiusx, x + radiusx); + uint8_t y2 = mapcos8(theta2 + i * spirooffset, y - radiusy, y + radiusy); + + CRGB color = effects.ColorFromCurrentPalette(hueoffset + i * spirooffset, 128); + effects.leds[XY(x2, y2)] += color; + + if((x2 == MATRIX_CENTER_X && y2 == MATRIX_CENTER_Y) || + (x2 == MATRIX_CENTRE_X && y2 == MATRIX_CENTRE_Y)) change = true; + } + + theta2 += 1; + + EVERY_N_MILLIS(25) { + theta1 += 1; + } + + EVERY_N_MILLIS(100) { + if (change && !handledChange) { + handledChange = true; + + if (spirocount >= VPANEL_W || spirocount == 1) spiroincrement = !spiroincrement; + + if (spiroincrement) { + if(spirocount >= 4) + spirocount *= 2; + else + spirocount += 1; + } + else { + if(spirocount > 4) + spirocount /= 2; + else + spirocount -= 1; + } + + spirooffset = 256 / spirocount; + } + + if(!change) handledChange = false; + } + + EVERY_N_MILLIS(33) { + hueoffset += 1; + } + + effects.ShowFrame(); + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSwirl.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSwirl.h new file mode 100644 index 0000000..49f3273 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternSwirl.h @@ -0,0 +1,79 @@ +/* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Portions of this code are adapted from SmartMatrixSwirl by Mark Kriegsman: https://gist.github.com/kriegsman/5adca44e14ad025e6d3b +* https://www.youtube.com/watch?v=bsGBT-50cts +* Copyright (c) 2014 Mark Kriegsman +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternSwirl_H + +class PatternSwirl : public Drawable { + private: + const uint8_t borderWidth = 2; + + public: + PatternSwirl() { + name = (char *)"Swirl"; + } + + void start() { + effects.ClearFrame(); + } + + unsigned int drawFrame() { + // Apply some blurring to whatever's already on the matrix + // Note that we never actually clear the matrix, we just constantly + // blur it repeatedly. Since the blurring is 'lossy', there's + // an automatic trend toward black -- by design. + uint8_t blurAmount = beatsin8(2, 10, 255); + +#if FASTLED_VERSION >= 3001000 + blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, blurAmount); +#else + effects.DimAll(blurAmount); +#endif + + // Use two out-of-sync sine waves + uint8_t i = beatsin8(256/VPANEL_H, borderWidth, VPANEL_W - borderWidth); + uint8_t j = beatsin8(2048/VPANEL_W, borderWidth, VPANEL_H - borderWidth); + + // Also calculate some reflections + uint8_t ni = (VPANEL_W - 1) - i; + uint8_t nj = (VPANEL_H - 1) - j; + + // The color of each point shifts over time, each at a different speed. + uint16_t ms = millis(); + effects.leds[XY(i, j)] += effects.ColorFromCurrentPalette(ms / 11); + //effects.leds[XY(j, i)] += effects.ColorFromCurrentPalette(ms / 13); // this doesn't work for non-square matrices + effects.leds[XY(ni, nj)] += effects.ColorFromCurrentPalette(ms / 17); + //effects.leds[XY(nj, ni)] += effects.ColorFromCurrentPalette(ms / 29); // this doesn't work for non-square matrices + effects.leds[XY(i, nj)] += effects.ColorFromCurrentPalette(ms / 37); + effects.leds[XY(ni, j)] += effects.ColorFromCurrentPalette(ms / 41); + + + effects.ShowFrame(); + return 0; + + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternTest.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternTest.h new file mode 100644 index 0000000..7a4a07d --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternTest.h @@ -0,0 +1,20 @@ + +#ifndef PatternTest_H +#define PatternTest_H + +class PatternTest : public Drawable { + private: + + public: + PatternTest() { + name = (char *)"Test Pattern"; + } + + unsigned int drawFrame() { + + matrix->fillScreen(matrix->color565(128, 0, 0)); + return 1000; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternWave.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternWave.h new file mode 100644 index 0000000..90e7448 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/PatternWave.h @@ -0,0 +1,120 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternWave_H +#define PatternWave_H + +class PatternWave : public Drawable { +private: + byte thetaUpdate = 0; + byte thetaUpdateFrequency = 0; + byte theta = 0; + + byte hueUpdate = 0; + byte hueUpdateFrequency = 0; + byte hue = 0; + + byte rotation = 0; + + uint8_t scale = 256 / VPANEL_W; + + uint8_t maxX = VPANEL_W - 1; + uint8_t maxY = VPANEL_H - 1; + + uint8_t waveCount = 1; + +public: + PatternWave() { + name = (char *)"Wave"; + } + + void start() { + rotation = random(0, 4); + waveCount = random(1, 3); + + } + + unsigned int drawFrame() { + int n = 0; + + switch (rotation) { + case 0: + for (int x = 0; x < VPANEL_W; x++) { + n = quadwave8(x * 2 + theta) / scale; + effects.drawBackgroundFastLEDPixelCRGB(x, n, effects.ColorFromCurrentPalette(x + hue)); + if (waveCount == 2) + effects.drawBackgroundFastLEDPixelCRGB(x, maxY - n, effects.ColorFromCurrentPalette(x + hue)); + } + break; + + case 1: + for (int y = 0; y < VPANEL_H; y++) { + n = quadwave8(y * 2 + theta) / scale; + effects.drawBackgroundFastLEDPixelCRGB(n, y, effects.ColorFromCurrentPalette(y + hue)); + if (waveCount == 2) + effects.drawBackgroundFastLEDPixelCRGB(maxX - n, y, effects.ColorFromCurrentPalette(y + hue)); + } + break; + + case 2: + for (int x = 0; x < VPANEL_W; x++) { + n = quadwave8(x * 2 - theta) / scale; + effects.drawBackgroundFastLEDPixelCRGB(x, n, effects.ColorFromCurrentPalette(x + hue)); + if (waveCount == 2) + effects.drawBackgroundFastLEDPixelCRGB(x, maxY - n, effects.ColorFromCurrentPalette(x + hue)); + } + break; + + case 3: + for (int y = 0; y < VPANEL_H; y++) { + n = quadwave8(y * 2 - theta) / scale; + effects.drawBackgroundFastLEDPixelCRGB(n, y, effects.ColorFromCurrentPalette(y + hue)); + if (waveCount == 2) + effects.drawBackgroundFastLEDPixelCRGB(maxX - n, y, effects.ColorFromCurrentPalette(y + hue)); + } + break; + } + + effects.DimAll(254); + effects.ShowFrame(); + + if (thetaUpdate >= thetaUpdateFrequency) { + thetaUpdate = 0; + theta++; + } + else { + thetaUpdate++; + } + + if (hueUpdate >= hueUpdateFrequency) { + hueUpdate = 0; + hue++; + } + else { + hueUpdate++; + } + + return 0; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Patterns.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Patterns.h new file mode 100644 index 0000000..398d57b --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Patterns.h @@ -0,0 +1,297 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Patterns_H +#define Patterns_H + +#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) + +#include "Vector.h" +#include "Boid.h" +#include "Attractor.h" + +/* + * Note from mrfaptastic: + * + * Commented out patterns are due to the fact they either didn't work properly with a non-square display, + * or from my personal opinion, are crap. + */ + +#include "PatternTest.h" +//#include "PatternNoiseSmearing.h" // Doesn't seem to work, omitting. +#include "PatternSpiro.h" +#include "PatternRadar.h" +#include "PatternSwirl.h" +#include "PatternPendulumWave.h" +#include "PatternFlowField.h" +#include "PatternIncrementalDrift.h" +#include "PatternIncrementalDrift2.h" // Doesn't seem to work, omitting. +#include "PatternMunch.h" +#include "PatternElectricMandala.h" +//#include "PatternSpin.h" // Doesn't seem to work, omitting. +#include "PatternSimplexNoise.h" +#include "PatternWave.h" +#include "PatternAttract.h" +//#include "PatternBounce.h" // Doesn't seem to work, omitting. +#include "PatternFlock.h" +#include "PatternInfinity.h" +#include "PatternPlasma.h" +#include "PatternSnake.h" +#include "PatternInvaders.h" +//#include "PatternCube.h" // Doesn't seem to work, omitting. +//#include "PatternFire.h" // Doesn't seem to work, omitting. +#include "PatternLife.h" +#include "PatternMaze.h" +//#include "PatternPulse.h" // Doesn't seem to work, omitting. +//#include "PatternSpark.h" // Doesn't seem to work, omitting. +#include "PatternSpiral.h" + +class Patterns : public Playlist { + private: + PatternTest patternTest; + // PatternRainbowFlag rainbowFlag; // doesn't work + // PatternPaletteSmear paletteSmear; + // PatternMultipleStream multipleStream; // doesn't work + // PatternMultipleStream2 multipleStream2; // doesn't work + // PatternMultipleStream3 multipleStream3; // doesn't work + // PatternMultipleStream4 multipleStream4; // doesn't work + // PatternMultipleStream5 multipleStream5; // doesn't work + // PatternMultipleStream8 multipleStream8; // doesn't work + PatternSpiro spiro; + // PatternRadar radar; + PatternSwirl swirl; + PatternPendulumWave pendulumWave; + PatternFlowField flowField; + PatternIncrementalDrift incrementalDrift; + PatternIncrementalDrift2 incrementalDrift2; + PatternMunch munch; + PatternElectricMandala electricMandala; + // PatternSpin spin; + PatternSimplexNoise simplexNoise; + PatternWave wave; + PatternAttract attract; + // PatternBounce bounce; + PatternFlock flock; + PatternInfinity infinity; + PatternPlasma plasma; + PatternInvadersSmall invadersSmall; + // PatternInvadersMedium invadersMedium; + // PatternInvadersLarge invadersLarge; + PatternSnake snake; + // PatternCube cube; + // PatternFire fire; + PatternLife life; + PatternMaze maze; + // PatternPulse pulse; + // PatternSpark spark; + PatternSpiral spiral; + + int currentIndex = 0; + Drawable* currentItem; + + int getCurrentIndex() { + return currentIndex; + } + + const static int PATTERN_COUNT = 14; + + Drawable* shuffledItems[PATTERN_COUNT]; + + Drawable* items[PATTERN_COUNT] = { + // &patternTest, // ok + &spiro, // cool + // &paletteSmear, // fail + // &multipleStream, // fail + // &multipleStream8,// fail + // &multipleStream5,// fail + // &multipleStream3,// fail + // &radar, // fail + // &multipleStream4, // fail + // &multipleStream2, // fail + &life, // ok + &flowField, + &pendulumWave, //11 ok + + &incrementalDrift, //12 ok + &incrementalDrift2, // 13 fail + &munch, // 14 ok + // &electricMandala, // 15 ok, but ugly (vortigont) + // &spin, // 16 ok but repetitive + // &simplexNoise, // 17 - cool! + // &wave, // 18 ok (can't work with 256+ matrix due to uint8_t vars) + // &rainbowFlag, //20 // fail + &attract, // 21 ok + // &swirl, // 22 ok, but ugly (vortigont) + // &bounce, // bouncing line crap + &flock, // works + &infinity, // works + &plasma, // works + // &invadersSmall, // works ish, but ugly (vortigont) + // &invadersMedium, // fail + // &invadersLarge, // fail + &snake, // ok + // &cube, // works ish + // &fire, // ok ish + &maze, // ok + // &pulse,// fail + // &spark, // same as fire + &spiral, // ok + }; + + public: + Patterns() { + // add the items to the shuffledItems array + for (int a = 0; a < PATTERN_COUNT; a++) { + shuffledItems[a] = items[a]; + } + + shuffleItems(); + + this->currentItem = items[0]; + this->currentItem->start(); + } + + char* Drawable::name = (char *)"Patterns"; + + void stop() { + if (currentItem) + currentItem->stop(); + } + + void start() { + if (currentItem) + currentItem->start(); + } + + void move(int step) { + currentIndex += step; + + if (currentIndex >= PATTERN_COUNT) currentIndex = 0; + else if (currentIndex < 0) currentIndex = PATTERN_COUNT - 1; + + if (effects.paletteIndex == effects.RandomPaletteIndex) + effects.RandomPalette(); + + moveTo(currentIndex); + + //if (!isTimeAvailable && currentItem == &analogClock) + // move(step); + } + + void moveRandom(int step) { + currentIndex += step; + + if (currentIndex >= PATTERN_COUNT) currentIndex = 0; + else if (currentIndex < 0) currentIndex = PATTERN_COUNT - 1; + + if (effects.paletteIndex == effects.RandomPaletteIndex) + effects.RandomPalette(); + + if (currentItem) + currentItem->stop(); + + currentItem = shuffledItems[currentIndex]; + + if (currentItem) + currentItem->start(); + + // if (!isTimeAvailable && currentItem == &analogClock) + // moveRandom(step); + } + + void shuffleItems() { + for (int a = 0; a < PATTERN_COUNT; a++) + { + int r = random(a, PATTERN_COUNT); + Drawable* temp = shuffledItems[a]; + shuffledItems[a] = shuffledItems[r]; + shuffledItems[r] = temp; + } + } + + + unsigned int drawFrame() { + return currentItem->drawFrame(); + } + + void listPatterns() { + Serial.println(F("{")); + Serial.print(F(" \"count\": ")); + Serial.print(PATTERN_COUNT); + Serial.println(","); + Serial.println(F(" \"results\": [")); + + for (int i = 0; i < PATTERN_COUNT; i++) { + Serial.print(F(" \"")); + Serial.print(i, DEC); + Serial.print(F(": ")); + Serial.print(items[i]->name); + if (i == PATTERN_COUNT - 1) + Serial.println(F("\"")); + else + Serial.println(F("\",")); + } + + Serial.println(" ]"); + Serial.println("}"); + } + + char * getCurrentPatternName() + { + return currentItem->name; + } + + void moveTo(int index) { + if (currentItem) + currentItem->stop(); + + currentIndex = index; + + currentItem = items[currentIndex]; + + if (currentItem) + currentItem->start(); + } + + bool setPattern(String name) { + for (int i = 0; i < PATTERN_COUNT; i++) { + if (name.compareTo(items[i]->name) == 0) { + moveTo(i); + return true; + } + } + + return false; + } + + + bool setPattern(int index) { + if (index >= PATTERN_COUNT || index < 0) + return false; + + moveTo(index); + + return true; + } +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Playlist.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Playlist.h new file mode 100644 index 0000000..29c0c87 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Playlist.h @@ -0,0 +1,39 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Playlist_H +#define Playlist_H + +class Playlist : public Drawable { +public: + virtual bool isPlaylist() { + return true; + } + + boolean isCurrentItemFinished = true; + + virtual void move(int step) = 0; + virtual void moveRandom(int step) = 0; + virtual int getCurrentIndex(); +}; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Vector.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Vector.h new file mode 100644 index 0000000..8acbadc --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/ChainedPanelsAuroraDemo/Vector.h @@ -0,0 +1,169 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Vector_H +#define Vector_H + +template +class Vector2 { +public: + T x, y; + + Vector2() :x(0), y(0) {} + Vector2(T x, T y) : x(x), y(y) {} + Vector2(const Vector2& v) : x(v.x), y(v.y) {} + + Vector2& operator=(const Vector2& v) { + x = v.x; + y = v.y; + return *this; + } + + bool isEmpty() { + return x == 0 && y == 0; + } + + bool operator==(Vector2& v) { + return x == v.x && y == v.y; + } + + bool operator!=(Vector2& v) { + return !(x == y); + } + + Vector2 operator+(Vector2& v) { + return Vector2(x + v.x, y + v.y); + } + Vector2 operator-(Vector2& v) { + return Vector2(x - v.x, y - v.y); + } + + Vector2& operator+=(Vector2& v) { + x += v.x; + y += v.y; + return *this; + } + Vector2& operator-=(Vector2& v) { + x -= v.x; + y -= v.y; + return *this; + } + + Vector2 operator+(double s) { + return Vector2(x + s, y + s); + } + Vector2 operator-(double s) { + return Vector2(x - s, y - s); + } + Vector2 operator*(double s) { + return Vector2(x * s, y * s); + } + Vector2 operator/(double s) { + return Vector2(x / s, y / s); + } + + Vector2& operator+=(double s) { + x += s; + y += s; + return *this; + } + Vector2& operator-=(double s) { + x -= s; + y -= s; + return *this; + } + Vector2& operator*=(double s) { + x *= s; + y *= s; + return *this; + } + Vector2& operator/=(double s) { + x /= s; + y /= s; + return *this; + } + + void set(T x, T y) { + this->x = x; + this->y = y; + } + + void rotate(double deg) { + double theta = deg / 180.0 * M_PI; + double c = cos(theta); + double s = sin(theta); + double tx = x * c - y * s; + double ty = x * s + y * c; + x = tx; + y = ty; + } + + Vector2& normalize() { + if (length() == 0) return *this; + *this *= (1.0 / length()); + return *this; + } + + float dist(Vector2 v) const { + Vector2 d(v.x - x, v.y - y); + return d.length(); + } + float length() const { + return sqrt(x * x + y * y); + } + + float mag() const { + return length(); + } + + float magSq() { + return (x * x + y * y); + } + + void truncate(double length) { + double angle = atan2f(y, x); + x = length * cos(angle); + y = length * sin(angle); + } + + Vector2 ortho() const { + return Vector2(y, -x); + } + + static float dot(Vector2 v1, Vector2 v2) { + return v1.x * v2.x + v1.y * v2.y; + } + static float cross(Vector2 v1, Vector2 v2) { + return (v1.x * v2.y) - (v1.y * v2.x); + } + + void limit(float max) { + if (magSq() > max*max) { + normalize(); + *this *= max; + } + } +}; + +typedef Vector2 PVector; + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/Four_Scan_Panel/Four_Scan_Panel.ino b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/Four_Scan_Panel/Four_Scan_Panel.ino new file mode 100644 index 0000000..5086b62 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/Four_Scan_Panel/Four_Scan_Panel.ino @@ -0,0 +1,153 @@ +/************************************************************************* + * Description: + * + * The underlying implementation of the ESP32-HUB75-MatrixPanel-I2S-DMA only + * supports output to HALF scan panels - which means outputting + * two lines at the same time, 16 or 32 rows apart if a 32px or 64px high panel + * respectively. + * This cannot be changed at the DMA layer as it would require a messy and complex + * rebuild of the library's internals. + * + * However, it is possible to connect QUARTER (i.e. FOUR lines updated in parallel) + * scan panels to this same library and + * 'trick' the output to work correctly on these panels by way of adjusting the + * pixel co-ordinates that are 'sent' to the ESP32-HUB75-MatrixPanel-I2S-DMA + * library. + * + **************************************************************************/ +#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h" + +/* Use the Virtual Display class to re-map co-ordinates such that they draw + * correctly on a 32x16 1/8 Scan panel (or chain of such panels). + */ +#include "ESP32-VirtualMatrixPanel-I2S-DMA.h" + + + // Panel configuration + #define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module. + #define PANEL_RES_Y 32 // Number of pixels tall of each INDIVIDUAL panel module. + + + #define NUM_ROWS 1 // Number of rows of chained INDIVIDUAL PANELS + #define NUM_COLS 2 // Number of INDIVIDUAL PANELS per ROW + + // ^^^ NOTE: DEFAULT EXAMPLE SETUP IS FOR A CHAIN OF TWO x 1/8 SCAN PANELS + + // Change this to your needs, for details on VirtualPanel pls read the PDF! + #define SERPENT true + #define TOPDOWN false + + // placeholder for the matrix object + MatrixPanel_I2S_DMA *dma_display = nullptr; + + // placeholder for the virtual display object + VirtualMatrixPanel *FourScanPanel = nullptr; + + /****************************************************************************** + * Setup! + ******************************************************************************/ + void setup() + { + delay(250); + + Serial.begin(115200); + Serial.println(""); Serial.println(""); Serial.println(""); + Serial.println("*****************************************************"); + Serial.println("* 1/8 Scan Panel Demonstration *"); + Serial.println("*****************************************************"); + +/* + // 62x32 1/8 Scan Panels don't have a D and E pin! + + HUB75_I2S_CFG::i2s_pins _pins = { + R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, + A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, + LAT_PIN, OE_PIN, CLK_PIN + }; +*/ + HUB75_I2S_CFG mxconfig( + PANEL_RES_X*2, // DO NOT CHANGE THIS + PANEL_RES_Y/2, // DO NOT CHANGE THIS + NUM_ROWS*NUM_COLS // DO NOT CHANGE THIS + //,_pins // Uncomment to enable custom pins + ); + + mxconfig.clkphase = false; // Change this if you see pixels showing up shifted wrongly by one column the left or right. + + //mxconfig.driver = HUB75_I2S_CFG::FM6126A; // in case that we use panels based on FM6126A chip, we can set it here before creating MatrixPanel_I2S_DMA object + + // OK, now we can create our matrix object + dma_display = new MatrixPanel_I2S_DMA(mxconfig); + + // let's adjust default brightness to about 75% + dma_display->setBrightness8(96); // range is 0-255, 0 - 0%, 255 - 100% + + // Allocate memory and start DMA display + if( not dma_display->begin() ) + Serial.println("****** !KABOOM! I2S memory allocation failed ***********"); + + + dma_display->clearScreen(); + delay(500); + + // create FourScanPanellay object based on our newly created dma_display object + FourScanPanel = new VirtualMatrixPanel((*dma_display), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y); + + // THE IMPORTANT BIT BELOW! + FourScanPanel->setPhysicalPanelScanRate(FOUR_SCAN_32PX_HIGH); + } + + + void loop() { + + // What the panel sees from the DMA engine! + for (int i=PANEL_RES_X*2+10; i< PANEL_RES_X*(NUM_ROWS*NUM_COLS)*2; i++) + { + dma_display->drawLine(i, 0, i, 7, dma_display->color565(255, 0, 0)); // red + delay(10); + } + + dma_display->clearScreen(); + delay(1000); +/* + // Try again using the pixel / dma memory remapper + for (int i=PANEL_RES_X+5; i< (PANEL_RES_X*2)-1; i++) + { + FourScanPanel->drawLine(i, 0, i, 7, dma_display->color565(0, 0, 255)); // blue + delay(10); + } +*/ + + // Try again using the pixel / dma memory remapper + int offset = PANEL_RES_X*((NUM_ROWS*NUM_COLS)-1); + for (int i=0; i< PANEL_RES_X; i++) + { + FourScanPanel->drawLine(i+offset, 0, i+offset, 7, dma_display->color565(0, 0, 255)); // blue + FourScanPanel->drawLine(i+offset, 8, i+offset, 15, dma_display->color565(0, 128,0)); // g + FourScanPanel->drawLine(i+offset, 16, i+offset, 23, dma_display->color565(128, 0,0)); // red + FourScanPanel->drawLine(i+offset, 24, i+offset, 31, dma_display->color565(0, 128, 128)); // blue + delay(10); + } + + delay(1000); + + + // Print on each chained panel 1/8 module! + // This only really works for a single horizontal chain + for (int i = 0; i < NUM_ROWS*NUM_COLS; i++) + { + FourScanPanel->setTextColor(FourScanPanel->color565(255, 255, 255)); + FourScanPanel->setCursor(i*PANEL_RES_X+7, FourScanPanel->height()/3); + + // Red text inside red rect (2 pix in from edge) + FourScanPanel->print("Panel " + String(i+1)); + FourScanPanel->drawRect(1,1, FourScanPanel->width()-2, FourScanPanel->height()-2, FourScanPanel->color565(255,0,0)); + + // White line from top left to bottom right + FourScanPanel->drawLine(0,0, FourScanPanel->width()-1, FourScanPanel->height()-1, FourScanPanel->color565(255,255,255)); + } + + delay(2000); + dma_display->clearScreen(); + + } // end loop diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/Four_Scan_Panel/README.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/Four_Scan_Panel/README.md new file mode 100644 index 0000000..7df7617 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/Four_Scan_Panel/README.md @@ -0,0 +1,7 @@ +# Using this library with 32x16 1/8 Scan Panels + +## Problem +ESP32-HUB75-MatrixPanel-I2S-DMA library will not display output correctly with 'Four Scan' or 1/8 scan panels such [as this](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/154) by default. + +## Solution +It is possible to connect 1/8 scan panels to this library and 'trick' the output to work correctly on these panels by way of adjusting the pixel co-ordinates that are 'sent' to the underlying ESP32-HUB75-MatrixPanel-I2S-DMA library (in this example, it is the 'dmaOutput' class). diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/HueValueSpectrum/HueValueSpectrum.ino b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/HueValueSpectrum/HueValueSpectrum.ino new file mode 100644 index 0000000..897275e --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/HueValueSpectrum/HueValueSpectrum.ino @@ -0,0 +1,80 @@ +#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module. +#define PANEL_RES_Y 32 // Number of pixels tall of each INDIVIDUAL panel module. +#define PANEL_CHAIN 1 // Total number of panels chained one to another + +#include + +MatrixPanel_I2S_DMA *dma_display = nullptr; + +void setup() { + + Serial.begin(112500); + + + HUB75_I2S_CFG::i2s_pins _pins={ + 25, //R1_PIN, + 26, //G1_PIN, + 27, //B1_PIN, + 14, //R2_PIN, + 12, //G2_PIN, + 13, //B2_PIN, + 23, //A_PIN, + 19, //B_PIN, + 5, //C_PIN, + 17, //D_PIN, + 18, //E_PIN, + 4, //LAT_PIN, + 15, //OE_PIN, + 16, //CLK_PIN + }; + HUB75_I2S_CFG mxconfig( + PANEL_RES_X, // Module width + PANEL_RES_Y, // Module height + PANEL_CHAIN //, // chain length + //_pins // pin mapping -- uncomment if providing own custom pin mapping as per above. + ); + //mxconfig.clkphase = false; + //mxconfig.driver = HUB75_I2S_CFG::FM6126A; + + // Display Setup + dma_display = new MatrixPanel_I2S_DMA(mxconfig); + dma_display->begin(); + dma_display->clearScreen(); +} + +void loop() { + // Canvas loop + float t = (float) ((millis()%4000)/4000.f); + float tt = (float) ((millis()%16000)/16000.f); + + for(int x = 0; x < (PANEL_RES_X*PANEL_CHAIN); x++) + { + // calculate the overal shade + float f = (((sin(tt-(float)x/PANEL_RES_Y/32.)*2.f*PI)+1)/2)*255; + // calculate hue spectrum into rgb + float r = max(min(cosf(2.f*PI*(t+((float)x/PANEL_RES_Y+0.f)/3.f))+0.5f,1.f),0.f); + float g = max(min(cosf(2.f*PI*(t+((float)x/PANEL_RES_Y+1.f)/3.f))+0.5f,1.f),0.f); + float b = max(min(cosf(2.f*PI*(t+((float)x/PANEL_RES_Y+2.f)/3.f))+0.5f,1.f),0.f); + + // iterate pixels for every row + for(int y = 0; y < PANEL_RES_Y; y++){ + if(y*2 < PANEL_RES_Y){ + // top-middle part of screen, transition of value + float t = (2.f*y+1)/PANEL_RES_Y; + dma_display->drawPixelRGB888(x,y, + (r*t)*f, + (g*t)*f, + (b*t)*f + ); + }else{ + // middle to bottom of screen, transition of saturation + float t = (2.f*(PANEL_RES_Y-y)-1)/PANEL_RES_Y; + dma_display->drawPixelRGB888(x,y, + (r*t+1-t)*f, + (g*t+1-t)*f, + (b*t+1-t)*f + ); + } + } + } +} diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/Julia_Set_Demo/Julia_Set_Demo.ino b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/Julia_Set_Demo/Julia_Set_Demo.ino new file mode 100644 index 0000000..9193006 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/Julia_Set_Demo/Julia_Set_Demo.ino @@ -0,0 +1,158 @@ +#define PANEL_RES_X 128 // Number of pixels wide of each INDIVIDUAL panel module. +#define PANEL_RES_Y 64 // Number of pixels tall of each INDIVIDUAL panel module. +#define PANEL_CHAIN 1 // Total number of panels chained one to another +#define USE_FLOATHACK // To boost float performance, comment if this doesn't work. + +#include + +MatrixPanel_I2S_DMA *dma_display = nullptr; + +// inspired by +// https://en.wikipedia.org/wiki/Fast_inverse_square_root +#ifdef USE_FLOATHACK +// cast float as int32_t + int32_t intfloat(float n){ return *(int32_t *)&n; } +// cast int32_t as float + float floatint(int32_t n){ return *(float *)&n; } +// fast approx sqrt(x) + float floatsqrt(float n){ return floatint(0x1fbb4000+(intfloat(n)>>1)); } +// fast approx 1/x + float floatinv(float n){ return floatint(0x7f000000-intfloat(n)); } +// fast approx log2(x) + float floatlog2(float n){ return (float)((intfloat(n)<<1)-0x7f000000)*5.9604645e-08f; } +#else + float floatinv(float n){ return 1.f/n;} + float floatsqrt(float n){ return std::sqrt(n); } + float floatlog2(float n){ return std::log2f(n); } +#endif + +//////////////////////////////////////// +// Escape time mandelbrot set function, +// with arbitrary start point zx, zy +// and arbitrary seed point ax, ay +// +// For julia set +// zx = pos_x, zy = pos_y; +// ax = seed_x, ay = seed_y; +// +// For mandelbrot set +// zx = 0, zy = 0; +// ax = pos_x, ay = pos_y; +// +const float bailOut = 4; // Escape radius +const int32_t itmult = 1<<10; // Color speed +// +// https://en.wikipedia.org/wiki/Mandelbrot_set +int32_t iteratefloat(float ax, float ay, float zx, float zy, uint16_t mxIT) { + float zzl = 0; + for (int it = 0; it=bailOut){ + if(it>0){ + // calculate smooth coloring + float zza = floatlog2(zzl); + float zzb = floatlog2(zzx+zzy); + float zzc = floatlog2(bailOut); + float zzd = (zzc-zza)*floatinv(zzb-zza); + return it*itmult+zzd*itmult; + } + }; + // z -> z*z + c + zy = 2.f*zx*zy+ay; + zx = zzx-zzy+ax; + zzl = zzx+zzy; + } + return 0; +} + +float sint[256]; // precalculated sin table, for performance reasons + +// Palette color taken from: +// https://editor.p5js.org/Kouzerumatsukite/sketches/DwTiq9D01 +// color palette originally made by piano_miles, written in p5js +// hsv2rgb(IT, cos(4096*it)/2+0.5, 1-sin(2048*it)/2-0.5) +void drawPixelPalette(int x, int y, uint32_t m){ + float r = 0.f, g = 0.f, b = 0.f; + if(m){ + char n = m>> 4 ; + float l =abs(sint[m>> 2&255] )*255.f ; + float s = (sint[m &255]+ 1.f)*0.5f ; + r = (max(min(sint[n &255]+0.5f,1.f),0.f)*s+(1-s))*l; + g = (max(min(sint[n+ 85&255]+0.5f,1.f),0.f)*s+(1-s))*l; + b = (max(min(sint[n+170&255]+0.5f,1.f),0.f)*s+(1-s))*l; + } + dma_display->drawPixelRGB888(x,y,r,g,b); +} + +void drawCanvas() { + uint32_t lastMicros = micros(); + double t = (double)lastMicros/8000000; + double k = sin(t*3.212/2)*sin(t*3.212/2)/16+1; + float cosk = (k-cos(t))/2; + float xoff = (cos(t)*cosk+k/2-0.25); + float yoff = (sin(t)*cosk ); + for(uint8_t y=0;ybegin(); + dma_display->clearScreen(); + dma_display->setBrightness(64); + setCpuFrequencyMhz(240); + + for(int i=0;i<256;i++){ + sint[i] = sinf(i/256.f*2.f*PI); + } + + xTaskCreatePinnedToCore(\ + Task1code, /* Function to implement the task */\ + "Task1", /* Name of the task */\ + 10000, /* Stack size in words */\ + NULL, /* Task input parameter */\ + 4, /* Priority of the task */\ + NULL, /* Task handle. */\ + 0); /* Core where the task should run */ + + Serial.begin(115200); +} + +uint64_t lastMillis=0; +void loop() { + if(millis()-lastMillis>=1000){ + // log frame rate to serial + Serial.print("fps: "); + Serial.println(frameCounts); + lastMillis += 1000; + frameCounts=0; + } +} diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/README.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/README.md new file mode 100644 index 0000000..ac988f6 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/README.md @@ -0,0 +1,18 @@ +# Test Patterns + +Simple solid colors, gradients and test line patterns, could be used to test matrices for proper operation, flickering and estimate fillrate timings. + +It is also used in CI test builds to check different build flags scenarios. + +Should be build and uploaded as a [platformio](https://platformio.org/) project + + +To build with Arduino's framework use +``` +pio run -t upload +``` + +To build using ESP32 IDF with arduino's component use +``` +pio run -t upload -e idfarduino +``` diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/platformio.ini b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/platformio.ini new file mode 100644 index 0000000..185513a --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/platformio.ini @@ -0,0 +1,23 @@ +[platformio] +default_envs = esp32 +description = HUB75 ESP32 I2S DMA test patterns example +;src_dir = src + +[env] +platform = espressif32 +board = wemos_d1_mini32 +lib_deps = + fastled/FastLED + Wire + adafruit/Adafruit BusIO + adafruit/Adafruit GFX Library + https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA.git +upload_speed = 460800 +monitor_speed = 115200 +monitor_filters = esp32_exception_decoder + +[env:esp32] +framework = arduino + +[env:esp32idf] +framework = arduino, espidf diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/sdkconfig.defaults b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/sdkconfig.defaults new file mode 100644 index 0000000..ee16cd3 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/sdkconfig.defaults @@ -0,0 +1,19 @@ +# Override some defaults to enable Arduino framework +CONFIG_ENABLE_ARDUINO_DEPENDS=y +CONFIG_AUTOSTART_ARDUINO=y +CONFIG_ARDUINO_RUN_CORE1=y +CONFIG_ARDUINO_RUNNING_CORE=1 +CONFIG_ARDUINO_EVENT_RUN_CORE1=y +CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 +CONFIG_ARDUINO_UDP_RUN_CORE1=y +CONFIG_ARDUINO_UDP_RUNNING_CORE=1 +CONFIG_DISABLE_HAL_LOCKS=y +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1 +CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y +CONFIG_ARDUHAL_PARTITION_SCHEME="default" +CONFIG_AUTOCONNECT_WIFI=y +CONFIG_ARDUINO_SELECTIVE_WiFi=y +CONFIG_MBEDTLS_PSK_MODES=y +CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y +CONFIG_FREERTOS_HZ=1000 \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/src/CMakeLists.txt b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/src/CMakeLists.txt new file mode 100644 index 0000000..483bc0c --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/src/CMakeLists.txt @@ -0,0 +1,6 @@ +# This file was automatically generated for projects +# without default 'CMakeLists.txt' file. + +FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*) + +idf_component_register(SRCS ${app_sources}) diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/src/main.cpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/src/main.cpp new file mode 100644 index 0000000..4e0edb1 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/src/main.cpp @@ -0,0 +1,455 @@ +// How to use this library with a FM6126 panel, thanks goes to: +// https://github.com/hzeller/rpi-rgb-led-matrix/issues/746 + +#ifdef IDF_BUILD +#include +#include +#include +#include +#include "sdkconfig.h" +#endif + +#include +#include "xtensa/core-macros.h" +#ifdef VIRTUAL_PANE +#include +#else +#include +#endif +#include "main.h" + +// HUB75E pinout +// R1 | G1 +// B1 | GND +// R2 | G2 +// B2 | E +// A | B +// C | D +// CLK| LAT +// OE | GND + +/* Default library pin configuration for the reference + you can redefine only ones you need later on object creation +#define R1 25 +#define G1 26 +#define BL1 27 +#define R2 14 +#define G2 12 +#define BL2 13 +#define CH_A 23 +#define CH_B 19 +#define CH_C 5 +#define CH_D 17 +#define CH_E -1 // assign to any available pin if using panels with 1/32 scan +#define CLK 16 +#define LAT 4 +#define OE 15 +*/ + +// Configure for your panel(s) as appropriate! +#define PIN_E 32 +#define PANEL_WIDTH 64 +#define PANEL_HEIGHT 64 // Panel height of 64 will required PIN_E to be defined. + +#ifdef VIRTUAL_PANE + #define PANELS_NUMBER 4 // Number of chained panels, if just a single panel, obviously set to 1 +#else + #define PANELS_NUMBER 2 // Number of chained panels, if just a single panel, obviously set to 1 +#endif + +#define PANE_WIDTH PANEL_WIDTH * PANELS_NUMBER +#define PANE_HEIGHT PANEL_HEIGHT +#define NUM_LEDS PANE_WIDTH*PANE_HEIGHT + +#ifdef VIRTUAL_PANE + #define NUM_ROWS 2 // Number of rows of chained INDIVIDUAL PANELS + #define NUM_COLS 2 // Number of INDIVIDUAL PANELS per ROW + #define PANEL_CHAIN NUM_ROWS*NUM_COLS // total number of panels chained one to another + // Change this to your needs, for details on VirtualPanel pls read the PDF! + #define SERPENT true + #define TOPDOWN false +#endif + + +#ifdef VIRTUAL_PANE +VirtualMatrixPanel *matrix = nullptr; +MatrixPanel_I2S_DMA *chain = nullptr; +#else +MatrixPanel_I2S_DMA *matrix = nullptr; +#endif +// patten change delay +#define PATTERN_DELAY 2000 + +uint16_t time_counter = 0, cycles = 0, fps = 0; +unsigned long fps_timer; + +// gradient buffer +CRGB *ledbuff; +// + +unsigned long t1, t2, s1=0, s2=0, s3=0; +uint32_t ccount1, ccount2; + +uint8_t color1 = 0, color2 = 0, color3 = 0; +uint16_t x,y; + +const char *str = "* ESP32 I2S DMA *"; + +void setup(){ + + Serial.begin(BAUD_RATE); + Serial.println("Starting pattern test..."); + + // redefine pins if required + //HUB75_I2S_CFG::i2s_pins _pins={R1, G1, BL1, R2, G2, BL2, CH_A, CH_B, CH_C, CH_D, CH_E, LAT, OE, CLK}; + HUB75_I2S_CFG mxconfig(PANEL_WIDTH, PANEL_HEIGHT, PANELS_NUMBER); + + mxconfig.gpio.e = PIN_E; + mxconfig.driver = HUB75_I2S_CFG::FM6126A; // for panels using FM6126A chips + +#ifndef VIRTUAL_PANE + matrix = new MatrixPanel_I2S_DMA(mxconfig); + matrix->begin(); + matrix->setBrightness8(255); +#else + chain = new MatrixPanel_I2S_DMA(mxconfig); + chain->begin(); + chain->setBrightness8(255); + // create VirtualDisplay object based on our newly created dma_display object + matrix = new VirtualMatrixPanel((*chain), NUM_ROWS, NUM_COLS, PANEL_WIDTH, PANEL_HEIGHT, CHAIN_TOP_LEFT_DOWN); +#endif + + ledbuff = (CRGB *)malloc(NUM_LEDS * sizeof(CRGB)); // allocate buffer for some tests + buffclear(ledbuff); +} + +uint8_t wheelval = 0; +void loop(){ + + Serial.printf("Cycle: %d\n", ++cycles); + +#ifndef NO_GFX + drawText(wheelval++); +#endif + + Serial.print("Estimating clearScreen() - "); + ccount1 = XTHAL_GET_CCOUNT(); + matrix->clearScreen(); + ccount1 = XTHAL_GET_CCOUNT() - ccount1; + Serial.printf("%d ticks\n", ccount1); + delay(PATTERN_DELAY); + +/* +// Power supply tester +// slowly fills matrix with white, stressing PSU + for (int y=0; y!=PANE_HEIGHT; ++y){ + for (int x=0; x!=PANE_WIDTH; ++x){ + matrix->drawPixelRGB888(x, y, 255,255,255); + //matrix->drawPixelRGB888(x, y-1, 255,0,0); // pls, be gentle :) + delay(10); + } + } + delay(5000); +*/ + +#ifndef VIRTUAL_PANE + // simple solid colors + Serial.println("Fill screen: RED"); + matrix->fillScreenRGB888(255, 0, 0); + delay(PATTERN_DELAY); + Serial.println("Fill screen: GREEN"); + matrix->fillScreenRGB888(0, 255, 0); + delay(PATTERN_DELAY); + Serial.println("Fill screen: BLUE"); + matrix->fillScreenRGB888(0, 0, 255); + delay(PATTERN_DELAY); +#endif + + for (uint8_t i=5; i; --i){ + Serial.print("Estimating single drawPixelRGB888(r, g, b) ticks: "); + color1 = random8(); + ccount1 = XTHAL_GET_CCOUNT(); + matrix->drawPixelRGB888(i,i, color1, color1, color1); + ccount1 = XTHAL_GET_CCOUNT() - ccount1; + Serial.printf("%d ticks\n", ccount1); + } + +// Clearing CRGB ledbuff + Serial.print("Estimating ledbuff clear time: "); + t1 = micros(); + ccount1 = XTHAL_GET_CCOUNT(); + buffclear(ledbuff); + ccount1 = XTHAL_GET_CCOUNT() - ccount1; + t2 = micros()-t1; + Serial.printf("%lu us, %u ticks\n\n", t2, ccount1); + +#ifndef VIRTUAL_PANE + // Bare fillscreen(r, g, b) + Serial.print("Estimating fillscreenRGB888(r, g, b) time: "); + t1 = micros(); + ccount1 = XTHAL_GET_CCOUNT(); + matrix->fillScreenRGB888(64, 64, 64); // white + ccount2 = XTHAL_GET_CCOUNT() - ccount1; + t2 = micros()-t1; + s1+=t2; + Serial.printf("%lu us, avg: %lu, ccnt: %d\n", t2, s1/cycles, ccount2); + delay(PATTERN_DELAY); +#endif + + Serial.print("Estimating full-screen fillrate with looped drawPixelRGB888(): "); + y = PANE_HEIGHT; + t1 = micros(); + ccount1 = XTHAL_GET_CCOUNT(); + do { + --y; + uint16_t x = PANE_WIDTH; + do { + --x; + matrix->drawPixelRGB888( x, y, 0, 0, 0); + } while(x); + } while(y); + ccount1 = XTHAL_GET_CCOUNT() - ccount1; + t2 = micros()-t1; + Serial.printf("%lu us, %u ticks\n", t2, ccount1); + + + +// created random color gradient in ledbuff + uint8_t color1 = 0; + uint8_t color2 = random8(); + uint8_t color3 = 0; + + for (uint16_t i = 0; ifillRect(0, 0, PANE_WIDTH, PANE_HEIGHT, 0, 224, 0); + t2 = micros()-t1; + Serial.printf("%lu us\n", t2); + delay(PATTERN_DELAY); + + + Serial.print("Chessboard with fillRect(): "); // шахматка + matrix->fillScreen(0); + x =0, y = 0; + color1 = random8(); + color2 = random8(); + color3 = random8(); + bool toggle=0; + t1 = micros(); + do { + do{ + matrix->fillRect(x, y, 8, 8, color1, color2, color3); + x+=16; + }while(x < PANE_WIDTH); + y+=8; + toggle = !toggle; + x = toggle ? 8 : 0; + }while(y < PANE_HEIGHT); + t2 = micros()-t1; + Serial.printf("%lu us\n", t2); + delay(PATTERN_DELAY); +#endif + +// ======== V-Lines ========== + Serial.println("Estimating V-lines with drawPixelRGB888(): "); // + matrix->fillScreen(0); + color1 = random8(); + color2 = random8(); + x = y = 0; + t1 = micros(); + ccount1 = XTHAL_GET_CCOUNT(); + do { + y=0; + do{ + matrix->drawPixelRGB888(x, y, color1, color2, color3); + } while(++y != PANE_HEIGHT); + x+=2; + } while(x != PANE_WIDTH); + ccount1 = XTHAL_GET_CCOUNT() - ccount1; + t2 = micros()-t1; + Serial.printf("%lu us, %u ticks\n", t2, ccount1); + delay(PATTERN_DELAY); + +#ifndef NO_FAST_FUNCTIONS + Serial.println("Estimating V-lines with vlineDMA(): "); // + matrix->fillScreen(0); + color2 = random8(); + x = y = 0; + t1 = micros(); + ccount1 = XTHAL_GET_CCOUNT(); + do { + matrix->drawFastVLine(x, y, PANE_HEIGHT, color1, color2, color3); + x+=2; + } while(x != PANE_WIDTH); + ccount1 = XTHAL_GET_CCOUNT() - ccount1; + t2 = micros()-t1; + Serial.printf("%lu us, %u ticks\n", t2, ccount1); + delay(PATTERN_DELAY); + + Serial.println("Estimating V-lines with fillRect(): "); // + matrix->fillScreen(0); + color1 = random8(); + color2 = random8(); + x = y = 0; + t1 = micros(); + ccount1 = XTHAL_GET_CCOUNT(); + do { + matrix->fillRect(x, y, 1, PANE_HEIGHT, color1, color2, color3); + x+=2; + } while(x != PANE_WIDTH); + ccount1 = XTHAL_GET_CCOUNT() - ccount1; + t2 = micros()-t1; + Serial.printf("%lu us, %u ticks\n", t2, ccount1); + delay(PATTERN_DELAY); +#endif + + + +// ======== H-Lines ========== + Serial.println("Estimating H-lines with drawPixelRGB888(): "); // + matrix->fillScreen(0); + color2 = random8(); + x = y = 0; + t1 = micros(); + ccount1 = XTHAL_GET_CCOUNT(); + do { + x=0; + do{ + matrix->drawPixelRGB888(x, y, color1, color2, color3); + } while(++x != PANE_WIDTH); + y+=2; + } while(y != PANE_HEIGHT); + ccount1 = XTHAL_GET_CCOUNT() - ccount1; + t2 = micros()-t1; + Serial.printf("%lu us, %u ticks\n", t2, ccount1); + delay(PATTERN_DELAY); + +#ifndef NO_FAST_FUNCTIONS + Serial.println("Estimating H-lines with hlineDMA(): "); + matrix->fillScreen(0); + color2 = random8(); + color3 = random8(); + x = y = 0; + t1 = micros(); + ccount1 = XTHAL_GET_CCOUNT(); + do { + matrix->drawFastHLine(x, y, PANE_WIDTH, color1, color2, color3); + y+=2; + } while(y != PANE_HEIGHT); + ccount1 = XTHAL_GET_CCOUNT() - ccount1; + t2 = micros()-t1; + Serial.printf("%lu us, %u ticks\n", t2, ccount1); + delay(PATTERN_DELAY); + + Serial.println("Estimating H-lines with fillRect(): "); // + matrix->fillScreen(0); + color2 = random8(); + color3 = random8(); + x = y = 0; + t1 = micros(); + ccount1 = XTHAL_GET_CCOUNT(); + do { + matrix->fillRect(x, y, PANE_WIDTH, 1, color1, color2, color3); + y+=2; + } while(y != PANE_HEIGHT); + ccount1 = XTHAL_GET_CCOUNT() - ccount1; + t2 = micros()-t1; + Serial.printf("%lu us, %u ticks\n", t2, ccount1); + delay(PATTERN_DELAY); +#endif + + + + + Serial.println("\n====\n"); + + // take a rest for a while + delay(10000); +} + + +void buffclear(CRGB *buf){ + memset(buf, 0x00, NUM_LEDS * sizeof(CRGB)); // flush buffer to black +} + +void IRAM_ATTR mxfill(CRGB *leds){ + uint16_t y = PANE_HEIGHT; + do { + --y; + uint16_t x = PANE_WIDTH; + do { + --x; + uint16_t _pixel = y * PANE_WIDTH + x; + matrix->drawPixelRGB888( x, y, leds[_pixel].r, leds[_pixel].g, leds[_pixel].b); + } while(x); + } while(y); +} +// + +/** + * The one for 256+ matrices + * otherwise this: + * for (uint8_t i = 0; i < MATRIX_WIDTH; i++) {} + * turns into an infinite loop + */ +uint16_t XY16( uint16_t x, uint16_t y) +{ + if (xsetTextSize(1); // size 1 == 8 pixels high + matrix->setTextWrap(false); // Don't wrap at end of line - will do ourselves + + matrix->setCursor(5, 5); // start at top left, with 5,5 pixel of spacing + uint8_t w = 0; + + for (w=0; wsetTextColor(colorWheel((w*32)+colorWheelOffset)); + matrix->print(str[w]); + } +} +#endif + +uint16_t colorWheel(uint8_t pos) { + if(pos < 85) { + return matrix->color565(pos * 3, 255 - pos * 3, 0); + } else if(pos < 170) { + pos -= 85; + return matrix->color565(255 - pos * 3, 0, pos * 3); + } else { + pos -= 170; + return matrix->color565(0, pos * 3, 255 - pos * 3); + } +} diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/src/main.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/src/main.h new file mode 100644 index 0000000..a1310f4 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/PIO_TestPatterns/src/main.h @@ -0,0 +1,10 @@ + +#include + +#define BAUD_RATE 115200 // serial debug port baud rate + +void buffclear(CRGB *buf); +uint16_t XY16( uint16_t x, uint16_t y); +void mxfill(CRGB *leds); +uint16_t colorWheel(uint8_t pos); +void drawText(int colorWheelOffset); \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/README.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/README.md new file mode 100644 index 0000000..5197413 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/README.md @@ -0,0 +1,14 @@ +| Example Name |Description | +|--|--| +|1_SimpleTestShapes |Example for new starters - how to display basic shapes. | +|2_PatternPlasma |Example for new starters - how to display a cool plasma pattern. | +|3_FM6126Panel |Example for new starters - how to initialise FM6126/FM6126A panels with this library. +|AnimatedGIFPanel |Using Larry Bank's GIF Decoder to display animated GIFs. | +|AuroraDemo |Simple example demonstrating various animated effects. | +|BitmapIcons |Simple example of how to display a bitmap image to the display. | +|ChainedPanels |Popular example on how to use the 'VirtualMatrixPanel' class to chain multiple LED Matrix Panels to form a much bigger display! Refer to the README within this example's folder! | +|ChainedPanelsAuroraDemo |As above, but showing a large trippy plasma animation. | +|ChainedPanelsScreenBuffer |Using the same 'VirtualMatrixPanel' class but also implementing a FastLED off-screen pixel buffer to do cool stuff. | +|One_Quarter_1_4_ScanPanel |Using this library with a 32w x 16h 1/4 Scan LED Matrix Panel. Custom co-ordinate remapping logic required. NOT WORKING. | +|One_Eighth_1_8_ScanPanel |Using this library with a 64w x 32h 1/8 Scan LED Matrix Panel. Custom co-ordinate remapping logic required. +|PIO_TestPatterns |Non-Arduino example of how to display basic shapes. | diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/CMakeLists.txt b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/CMakeLists.txt new file mode 100644 index 0000000..192eccb --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/CMakeLists.txt @@ -0,0 +1,10 @@ +# This is a boilerplate top-level project CMakeLists.txt file. +# This is the primary file which CMake uses to learn how to build the project. +# +# Most of the important stuff happens in the 'main' directory. +# +# See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html#example-project for more details. +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(with-gfx) diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/README.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/README.md new file mode 100644 index 0000000..07565f9 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/README.md @@ -0,0 +1,17 @@ +# ESP-IDF Example With Adafruit GFX Library + +This folder contains example code for using this library with `esp-idf` and the [Adafruit GFX library](https://github.com/adafruit/Adafruit-GFX-Library). + +First, follow the [Getting Started Guide for ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html) to install ESP-IDF onto your computer. + +When you are ready to start your first project with this library, follow folow these steps: + + 1. Copy the files in this folder (and sub folders) into a new directory for your project. + 1. Clone the required repositories: + ``` + git clone https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA.git components/ESP32-HUB75-MatrixPanel-I2S-DMA + git clone https://github.com/adafruit/Adafruit-GFX-Library.git components/Adafruit-GFX-Library + git clone https://github.com/adafruit/Adafruit_BusIO.git components/Adafruit_BusIO + git clone https://github.com/espressif/arduino-esp32.git components/arduino + ``` + 1. Build your project: `idf.py build` diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/main/CMakeLists.txt b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/main/CMakeLists.txt new file mode 100644 index 0000000..16901f0 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRC_DIRS "." ${SRCDIRS} + INCLUDE_DIRS ${INCLUDEDIRS} + REQUIRES ESP32-HUB75-MatrixPanel-I2S-DMA + ) diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/main/main.cpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/main/main.cpp new file mode 100644 index 0000000..7672dc5 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/main/main.cpp @@ -0,0 +1,14 @@ +#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h" + +MatrixPanel_I2S_DMA *dma_display = nullptr; + +extern "C" void app_main() { + HUB75_I2S_CFG mxconfig(/* width = */ 64, /* height = */ 64, /* chain = */ 1); + + dma_display = new MatrixPanel_I2S_DMA(mxconfig); + dma_display->begin(); + dma_display->setBrightness8(80); + dma_display->clearScreen(); + // `println` is only available when the Adafruit GFX library is used. + dma_display->println("Test message"); +} diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/sdkconfig.defaults b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/sdkconfig.defaults new file mode 100644 index 0000000..879d223 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/with-gfx/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_FREERTOS_HZ=1000 diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/CMakeLists.txt b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/CMakeLists.txt new file mode 100644 index 0000000..9fbb7f4 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/CMakeLists.txt @@ -0,0 +1,10 @@ +# This is a boilerplate top-level project CMakeLists.txt file. +# This is the primary file which CMake uses to learn how to build the project. +# +# Most of the important stuff happens in the 'main' directory. +# +# See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html#example-project for more details. +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(without-gfx) diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/README.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/README.md new file mode 100644 index 0000000..f428b23 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/README.md @@ -0,0 +1,14 @@ +# ESP-IDF Example Without Adafruit GFX Library + +This folder contains example code for using this library with `esp-idf`. + +First, follow the [Getting Started Guide for ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html) to install ESP-IDF onto your computer. + +When you are ready to start your first project with this library, follow folow these steps: + + 1. Copy the files in this folder (and sub folders) into a new directory for your project. + 1. Clone the required repositories: + ``` + git clone https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA.git components/ESP32-HUB75-MatrixPanel-I2S-DMA + ``` + 1. Build your project: `idf.py build` diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/main/CMakeLists.txt b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/main/CMakeLists.txt new file mode 100644 index 0000000..16901f0 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRC_DIRS "." ${SRCDIRS} + INCLUDE_DIRS ${INCLUDEDIRS} + REQUIRES ESP32-HUB75-MatrixPanel-I2S-DMA + ) diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/main/main.cpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/main/main.cpp new file mode 100644 index 0000000..c44b49c --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/main/main.cpp @@ -0,0 +1,12 @@ +#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h" + +MatrixPanel_I2S_DMA *dma_display = nullptr; + +extern "C" void app_main() { + HUB75_I2S_CFG mxconfig(/* width = */ 64, /* height = */ 64, /* chain = */ 1); + + dma_display = new MatrixPanel_I2S_DMA(mxconfig); + dma_display->begin(); + dma_display->setBrightness8(80); + dma_display->clearScreen(); +} diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/sdkconfig.defaults b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/sdkconfig.defaults new file mode 100644 index 0000000..57aec4a --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/examples/esp-idf/without-gfx/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_ESP32_HUB75_USE_GFX=n diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/image.jpg b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/image.jpg new file mode 100644 index 0000000..f0c9cbe Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/image.jpg differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/keywords.txt b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/keywords.txt new file mode 100644 index 0000000..b6ccefa --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/keywords.txt @@ -0,0 +1,18 @@ +RGB64x32MatrixPanel_I2S_DMA KEYWORD1 +MatrixPanel_I2S_DMA KEYWORD1 +Layer KEYWORD1 +fillScreen KEYWORD2 +clearScreen KEYWORD2 +fillScreenRGB888 KEYWORD2 +drawPixelRGB565 KEYWORD2 +drawPixelRGB888 KEYWORD2 +drawPixelRGB24 KEYWORD2 +drawIcon KEYWORD2 +color444 KEYWORD2 +color565 KEYWORD2 +color333 KEYWORD2 +flipDMABuffer KEYWORD2 +showDMABuffer KEYWORD2 +setPanelBrightness KEYWORD2 +setMinRefreshRate KEYWORD2 +RGB24 KEYWORD1 \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/library.json b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/library.json new file mode 100644 index 0000000..0258475 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/library.json @@ -0,0 +1,41 @@ +{ + "name": "ESP32 HUB75 LED MATRIX PANEL DMA Display", + "version": "3.0.10", + "description": "An Adafruit GFX compatible library for LED matrix modules which uses DMA for ultra-fast refresh rates and therefore very low CPU usage.", + "keywords": "hub75, esp32, esp32s2, esp32s3, display, dma, rgb matrix", + "repository": { + "type": "git", + "url": "https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA.git" + }, + "authors": { + "name": "Mr Faptastic", + "url": "https://github.com/mrfaptastic/" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "platforms": [ + "espressif32" + ], + "headers": [ + "ESP32-HUB75-MatrixPanel-I2S-DMA.h", "ESP32-VirtualMatrixPanel-I2S-DMA.h" + ], + "examples": [ + { + "name": "SimpleTestShapes", + "base": "examples/1_SimpleTestShapes", + "files": [ + "1_SimpleTestShapes.ino" + ] + }, + { + "name": "Plasma Pattern", + "base": "examples/2_PatternPlasma", + "files": [ + "2_PatternPlasma.ino", + "README.md" + ] + } + ] +} diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/library.properties b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/library.properties new file mode 100644 index 0000000..7e53da1 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/library.properties @@ -0,0 +1,9 @@ +name=ESP32 HUB75 LED MATRIX PANEL DMA Display +version= 3.0.10 +author=Faptastic +maintainer=Faptastic +sentence=HUB75 LED Matrix Library for ESP32, ESP32-S2 and ESP32-S3 +paragraph=An Adafruit GFX compatible library for LED matrix modules which uses DMA for ultra-fast refresh rates and therefore very low CPU usage. +category=Display +url=https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA +architectures=esp32,esp32s2,esp32s3 diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp new file mode 100644 index 0000000..0ee3fa2 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp @@ -0,0 +1,980 @@ +#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h" + +#if defined(SPIRAM_DMA_BUFFER) +// Sprite_TM saves the day again... +// https://www.esp32.com/viewtopic.php?f=2&t=30584 +#include "rom/cache.h" +#endif + +/* This replicates same function in rowBitStruct, but due to induced inlining it might be MUCH faster + * when used in tight loops while method from struct could be flushed out of instruction cache between + * loop cycles do NOT forget about buff_id param if using this. + */ +// #define getRowDataPtr(row, _dpth, buff_id) &(dma_buff.rowBits[row]->data[_dpth * dma_buff.rowBits[row]->width + buff_id*(dma_buff.rowBits[row]->width * dma_buff.rowBits[row]->colour_depth)]) + +// BufferID is now ignored, seperate global pointer pointer! +#define getRowDataPtr(row, _dpth, buff_id) &(fb->rowBits[row]->data[_dpth * fb->rowBits[row]->width]) + +/* We need to update the correct uint16_t in the rowBitStruct array, that gets sent out in parallel + * 16 bit parallel mode - Save the calculated value to the bitplane memory in reverse order to account for I2S Tx FIFO mode1 ordering + * Irrelevant for ESP32-S2 the way the FIFO ordering works is different - refer to page 679 of S2 technical reference manual + */ +#if defined(ESP32_THE_ORIG) +#define ESP32_TX_FIFO_POSITION_ADJUST(x_coord) (((x_coord)&1U) ? (x_coord - 1) : (x_coord + 1)) +#else +#define ESP32_TX_FIFO_POSITION_ADJUST(x_coord) x_coord +#endif + +/* This library is designed to take an 8 bit / 1 byte value (0-255) for each R G B colour sub-pixel. + * The PIXEL_COLOR_DEPTH_BITS should always be '8' as a result. + * However, if the library is to be used with lower colour depth (i.e. 6 bit colour), then we need to ensure the 8-bit value passed to the colour masking + * is adjusted accordingly to ensure the LSB's are shifted left to MSB, by the difference. Otherwise the colours will be all screwed up. + */ +#define PIXEL_COLOR_MASK_BIT(color_depth_index, mask_offset) (1 << (color_depth_index + mask_offset)) + +bool MatrixPanel_I2S_DMA::allocateDMAmemory() +{ + + ESP_LOGI("I2S-DMA", "Free heap: %d", heap_caps_get_free_size(MALLOC_CAP_INTERNAL)); + ESP_LOGI("I2S-DMA", "Free SPIRAM: %d", heap_caps_get_free_size(MALLOC_CAP_SPIRAM)); + + // Alright, theoretically we should be OK, so let us do this, so + // lets allocate a chunk of memory for each row (a row could span multiple panels if chaining is in place) + ESP_LOGI("I2S-DMA", "allocating rowBitStructs with pixel_color_depth_bits of %d", m_cfg.getPixelColorDepthBits()); + // iterate through number of rows, allocate memory for each + size_t allocated_fb_memory = 0; + + int fbs_required = (m_cfg.double_buff) ? 2 : 1; + for (int fb = 0; fb < (fbs_required); fb++) + { + frame_buffer[fb].rowBits.reserve(ROWS_PER_FRAME); + + for (int malloc_num = 0; malloc_num < ROWS_PER_FRAME; malloc_num++) + { + auto ptr = std::make_shared(PIXELS_PER_ROW, m_cfg.getPixelColorDepthBits(), m_cfg.double_buff); + + if (ptr->data == nullptr) + { + ESP_LOGE("I2S-DMA", "CRITICAL ERROR: Not enough memory for requested colour depth! Please reduce pixel_color_depth_bits value.\r\n"); + ESP_LOGE("I2S-DMA", "Could not allocate rowBitStruct %d!.\r\n", malloc_num); + + return false; + // TODO: should we release all previous rowBitStructs here??? + } + + allocated_fb_memory += ptr->getColorDepthSize(); // byte required to display all colour depths for the rows shown at the same time + frame_buffer[fb].rowBits.emplace_back(ptr); // save new rowBitStruct pointer into rows vector + ++frame_buffer[fb].rows; + } + } + ESP_LOGI("I2S-DMA", "Allocating %d bytes memory for DMA BCM framebuffer(s).", allocated_fb_memory); + + // calculate the lowest LSBMSB_TRANSITION_BIT value that will fit in memory that will meet or exceed the configured refresh rate + +//#define FORCE_COLOR_DEPTH 1 + +#if !defined(FORCE_COLOR_DEPTH) + + ESP_LOGI("I2S-DMA", "Minimum visual refresh rate (scan rate from panel top to bottom) requested: %d Hz", m_cfg.min_refresh_rate); + + while (1) + { + int psPerClock = 1000000000000UL / m_cfg.i2sspeed; + int nsPerLatch = ((PIXELS_PER_ROW + CLKS_DURING_LATCH) * psPerClock) / 1000; + + // add time to shift out LSBs + LSB-MSB transition bit - this ignores fractions... + int nsPerRow = m_cfg.getPixelColorDepthBits() * nsPerLatch; + + // add time to shift out MSBs + for (int i = lsbMsbTransitionBit + 1; i < m_cfg.getPixelColorDepthBits(); i++) + nsPerRow += (1 << (i - lsbMsbTransitionBit - 1)) * (m_cfg.getPixelColorDepthBits() - i) * nsPerLatch; + + int nsPerFrame = nsPerRow * ROWS_PER_FRAME; + int actualRefreshRate = 1000000000UL / (nsPerFrame); + calculated_refresh_rate = actualRefreshRate; + + ESP_LOGW("I2S-DMA", "lsbMsbTransitionBit of %d gives %d Hz refresh rate.", lsbMsbTransitionBit, actualRefreshRate); + + if (actualRefreshRate > m_cfg.min_refresh_rate) + break; + + if (lsbMsbTransitionBit < m_cfg.getPixelColorDepthBits() - 1) + lsbMsbTransitionBit++; + else + break; + } + + if (lsbMsbTransitionBit > 0) + { + ESP_LOGW("I2S-DMA", "lsbMsbTransitionBit of %d used to achieve refresh rate of %d Hz. Percieved colour depth to the eye may be reduced.", lsbMsbTransitionBit, m_cfg.min_refresh_rate); + } + + ESP_LOGI("I2S-DMA", "DMA has pixel_color_depth_bits of %d", m_cfg.getPixelColorDepthBits() - lsbMsbTransitionBit); + +#endif + + /*** + * Step 2a: lsbMsbTransition bit is now finalised - recalculate the DMA descriptor count required, which is used for + * memory allocation of the DMA linked list memory structure. + */ + int numDMAdescriptorsPerRow = 1; + for (int i = lsbMsbTransitionBit + 1; i < m_cfg.getPixelColorDepthBits(); i++) + { + numDMAdescriptorsPerRow += (1 << (i - lsbMsbTransitionBit - 1)); + } + + ESP_LOGI("I2S-DMA", "Recalculated number of DMA descriptors per row: %d", numDMAdescriptorsPerRow); + + // Refer to 'DMA_LL_PAYLOAD_SPLIT' code in configureDMA() below to understand why this exists. + // numDMAdescriptorsPerRow is also used to calculate descount which is super important in i2s_parallel_config_t SoC DMA setup. + if (frame_buffer[0].rowBits[0]->getColorDepthSize() > DMA_MAX) + { + + ESP_LOGW("I2S-DMA", "rowBits struct is too large to fit in one DMA transfer payload, splitting required. Adding %d DMA descriptors\n", m_cfg.getPixelColorDepthBits() - 1); + + numDMAdescriptorsPerRow += m_cfg.getPixelColorDepthBits() - 1; + // Note: If numDMAdescriptorsPerRow is even just one descriptor too large, DMA linked list will not correctly loop. + } + + /*** + * Step 3: Allocate memory for DMA linked list, linking up each framebuffer row in sequence for GPIO output. + */ + + // malloc the DMA linked list descriptors that i2s_parallel will need + int desccount = numDMAdescriptorsPerRow * ROWS_PER_FRAME; + + if (m_cfg.double_buff) + { + dma_bus.enable_double_dma_desc(); + } + + dma_bus.allocate_dma_desc_memory(desccount); + + // point FB we can write to, to 0 / dmadesc_a + fb = &frame_buffer[0]; + + // Just os we know + initialized = true; + + return true; + +} // end allocateDMAmemory() + + + +/* +// Version 2.0 March 2023 +int MatrixPanel_I2S_DMA::create_descriptor_links(void *data, size_t size, bool dmadesc_b, bool countonly) +{ + int len = size; + uint8_t *data2 = (uint8_t *)data; + + int n = 0; + while (len) + { + int dmalen = len; + if (dmalen > DMA_MAX) + dmalen = DMA_MAX; + + if (!countonly) + dma_bus.create_dma_desc_link(data2, dmalen, dmadesc_b); + + len -= dmalen; + data2 += dmalen; + n++; + } + + return n; +} +*/ +void MatrixPanel_I2S_DMA::configureDMA(const HUB75_I2S_CFG &_cfg) +{ + + // lldesc_t *previous_dmadesc_a = 0; + // lldesc_t *previous_dmadesc_b = 0; + int current_dmadescriptor_offset = 0; + + // HACK: If we need to split the payload in 1/2 so that it doesn't breach DMA_MAX, lets do it by the colour_depth. + /* + int num_dma_payload_colour_depths = m_cfg.getPixelColorDepthBits(); + if (frame_buffer[0].rowBits[0]->getColorDepthSize() > DMA_MAX) + { + num_dma_payload_colour_depths = 1; + } + */ + + + // Fill DMA linked lists for both frames (as in, halves of the HUB75 panel) in sequence (top to bottom) + for (int row = 0; row < ROWS_PER_FRAME; row++) + { + // first set of data is LSB through MSB, single pass (IF TOTAL SIZE < DMA_MAX) - all colour bits are displayed once, which takes care of everything below and including LSBMSB_TRANSITION_BIT + // NOTE: size must be less than DMA_MAX - worst case for library: 16-bpp with 256 pixels per row would exceed this, need to break into two + // link_dma_desc(&dmadesc_a[current_dmadescriptor_offset], previous_dmadesc_a, dma_buff.rowBits[row]->getDataPtr(), dma_buff.rowBits[row]->size(num_dma_payload_colour_depths)); + // previous_dmadesc_a = &dmadesc_a[current_dmadescriptor_offset]; + + dma_bus.create_dma_desc_link(frame_buffer[0].rowBits[row]->getDataPtr(0, 0), frame_buffer[0].rowBits[row]->getColorDepthSize(), false); + + if (m_cfg.double_buff) + { + dma_bus.create_dma_desc_link(frame_buffer[1].rowBits[row]->getDataPtr(0, 1), frame_buffer[1].rowBits[row]->getColorDepthSize(), true); + } + + current_dmadescriptor_offset++; + + // If the number of pixels per row is too great for the size of a DMA payload, so we need to split what we were going to send above. + if (frame_buffer[0].rowBits[0]->getColorDepthSize() > DMA_MAX) + { + + for (int cd = 1; cd < m_cfg.getPixelColorDepthBits(); cd++) + { + dma_bus.create_dma_desc_link(frame_buffer[0].rowBits[row]->getDataPtr(cd, 0), frame_buffer[0].rowBits[row]->getColorDepthSize(1), false); + + if (m_cfg.double_buff) + { + dma_bus.create_dma_desc_link(frame_buffer[1].rowBits[row]->getDataPtr(cd, 1), frame_buffer[1].rowBits[row]->getColorDepthSize(1), true); + } + + current_dmadescriptor_offset++; + + } // additional linked list items + } // row depth struct + + for (int i = lsbMsbTransitionBit + 1; i < m_cfg.getPixelColorDepthBits(); i++) + { + // binary time division setup: we need 2 of bit (LSBMSB_TRANSITION_BIT + 1) four of (LSBMSB_TRANSITION_BIT + 2), etc + // because we sweep through to MSB each time, it divides the number of times we have to sweep in half (saving linked list RAM) + // we need 2^(i - LSBMSB_TRANSITION_BIT - 1) == 1 << (i - LSBMSB_TRANSITION_BIT - 1) passes from i to MSB + + for (int k = 0; k < (1 << (i - lsbMsbTransitionBit - 1)); k++) + { + dma_bus.create_dma_desc_link(frame_buffer[0].rowBits[row]->getDataPtr(i, 0), frame_buffer[0].rowBits[row]->getColorDepthSize(1), false); + + if (m_cfg.double_buff) + { + dma_bus.create_dma_desc_link(frame_buffer[1].rowBits[row]->getDataPtr(i, 1), frame_buffer[1].rowBits[row]->getColorDepthSize(1), true); + } + + current_dmadescriptor_offset++; + + } // end colour depth ^ 2 linked list + } // end colour depth loop + + } // end frame rows + + ESP_LOGI("I2S-DMA", "%d DMA descriptors linked to buffer data.", current_dmadescriptor_offset); + + // + // Setup DMA and Output to GPIO + // + auto bus_cfg = dma_bus.config(); // バス設定用の構造体を取得します。 + + bus_cfg.bus_freq = m_cfg.i2sspeed; + bus_cfg.pin_wr = m_cfg.gpio.clk; + bus_cfg.invert_pclk = m_cfg.clkphase; + + bus_cfg.pin_d0 = m_cfg.gpio.r1; + bus_cfg.pin_d1 = m_cfg.gpio.g1; + bus_cfg.pin_d2 = m_cfg.gpio.b1; + bus_cfg.pin_d3 = m_cfg.gpio.r2; + bus_cfg.pin_d4 = m_cfg.gpio.g2; + bus_cfg.pin_d5 = m_cfg.gpio.b2; + bus_cfg.pin_d6 = m_cfg.gpio.lat; + bus_cfg.pin_d7 = m_cfg.gpio.oe; + bus_cfg.pin_d8 = m_cfg.gpio.a; + bus_cfg.pin_d9 = m_cfg.gpio.b; + bus_cfg.pin_d10 = m_cfg.gpio.c; + bus_cfg.pin_d11 = m_cfg.gpio.d; + bus_cfg.pin_d12 = m_cfg.gpio.e; + bus_cfg.pin_d13 = -1; + bus_cfg.pin_d14 = -1; + bus_cfg.pin_d15 = -1; + +#if defined(SPIRAM_DMA_BUFFER) + bus_cfg.psram_clk_override = true; +#endif + + dma_bus.config(bus_cfg); + + dma_bus.init(); + + dma_bus.dma_transfer_start(); + + flipDMABuffer(); // display back buffer 0, draw to 1, ignored if double buffering isn't enabled. + + // i2s_parallel_send_dma(ESP32_I2S_DEVICE, &dmadesc_a[0]); + ESP_LOGI("I2S-DMA", "DMA setup completed"); + +} // end initMatrixDMABuff + +/* There are 'bits' set in the frameStruct that we simply don't need to set every single time we change a pixel / DMA buffer co-ordinate. + * For example, the bits that determine the address lines, we don't need to set these every time. Once they're in place, and assuming we + * don't accidentally clear them, then we don't need to set them again. + * So to save processing, we strip this logic out to the absolute bare minimum, which is toggling only the R,G,B pixels (bits) per co-ord. + * + * Critical dependency: That 'updateMatrixDMABuffer(uint8_t red, uint8_t green, uint8_t blue)' has been run at least once over the + * entire frameBuffer to ensure all the non R,G,B bitmasks are in place (i.e. like OE, Address Lines etc.) + * + * Note: If you change the brightness with setBrightness() you MUST then clearScreen() and repaint / flush the entire framebuffer. + */ + +/** @brief - Update pixel at specific co-ordinate in the DMA buffer + * this is the main method used to update DMA buffer on pixel-by-pixel level so it must be fast, real fast! + * Let's put it into IRAM to avoid situations when it could be flushed out of instruction cache + * and had to be read from spi-flash over and over again. + * Yes, it is always a tradeoff between memory/speed/size, but compared to DMA-buffer size is not a big deal + * + * Note: Cannot pass a negative co-ord as it makes no sense in the DMA bit array lookup. + */ +void IRAM_ATTR MatrixPanel_I2S_DMA::updateMatrixDMABuffer(uint16_t x_coord, uint16_t y_coord, uint8_t red, uint8_t green, uint8_t blue) +{ + if (!initialized) + return; + + /* 1) Check that the co-ordinates are within range, or it'll break everything big time. + * Valid co-ordinates are from 0 to (MATRIX_XXXX-1) + */ + if (x_coord >= PIXELS_PER_ROW || y_coord >= m_cfg.mx_height) + { + return; + } + + /* LED Brightness Compensation. Because if we do a basic "red & mask" for example, + * we'll NEVER send the dimmest possible colour, due to binary skew. + * i.e. It's almost impossible for colour_depth_idx of 0 to be sent out to the MATRIX unless the 'value' of a colour is exactly '1' + * https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/ + */ + uint16_t red16, green16, blue16; +#ifndef NO_CIE1931 + red16 = lumConvTab[red]; + green16 = lumConvTab[green]; + blue16 = lumConvTab[blue]; +#else + red16 = red << 8 | red; + green16 = green << 8 | green; + blue16 = blue << 8 | blue; +#endif + + /* When using the drawPixel, we are obviously only changing the value of one x,y position, + * however, the two-scan panels paint TWO lines at the same time + * and this reflects the parallel in-DMA-memory data structure of uint16_t's that are getting + * pumped out at high speed. + * + * So we need to ensure we persist the bits (8 of them) of the uint16_t for the row we aren't changing. + * + * The DMA buffer order has also been reversed (refer to the last code in this function) + * so we have to check for this and check the correct position of the MATRIX_DATA_STORAGE_TYPE + * data. + */ + x_coord = ESP32_TX_FIFO_POSITION_ADJUST(x_coord); + + uint16_t _colourbitclear = BITMASK_RGB1_CLEAR, _colourbitoffset = 0; + + if (y_coord >= ROWS_PER_FRAME) + { // if we are drawing to the bottom part of the panel + _colourbitoffset = BITS_RGB2_OFFSET; + _colourbitclear = BITMASK_RGB2_CLEAR; + y_coord -= ROWS_PER_FRAME; + } + + // Iterating through colour depth bits, which we assume are 8 bits per RGB subpixel (24bpp) + uint8_t colour_depth_idx = m_cfg.getPixelColorDepthBits(); + do + { + --colour_depth_idx; + + uint16_t mask = PIXEL_COLOR_MASK_BIT(colour_depth_idx, MASK_OFFSET); + uint16_t RGB_output_bits = 0; + + /* Per the .h file, the order of the output RGB bits is: + * BIT_B2, BIT_G2, BIT_R2, BIT_B1, BIT_G1, BIT_R1 */ + RGB_output_bits |= (bool)(blue16 & mask); // --B + RGB_output_bits <<= 1; + RGB_output_bits |= (bool)(green16 & mask); // -BG + RGB_output_bits <<= 1; + RGB_output_bits |= (bool)(red16 & mask); // BGR + RGB_output_bits <<= _colourbitoffset; // shift colour bits to the required position + + // Get the contents at this address, + // it would represent a vector pointing to the full row of pixels for the specified colour depth bit at Y coordinate + ESP32_I2S_DMA_STORAGE_TYPE *p = getRowDataPtr(y_coord, colour_depth_idx, back_buffer_id); + + // We need to update the correct uint16_t word in the rowBitStruct array pointing to a specific pixel at X - coordinate + p[x_coord] &= _colourbitclear; // reset RGB bits + p[x_coord] |= RGB_output_bits; // set new RGB bits + +#if defined(SPIRAM_DMA_BUFFER) + Cache_WriteBack_Addr((uint32_t)&p[x_coord], sizeof(ESP32_I2S_DMA_STORAGE_TYPE)); +#endif + + } while (colour_depth_idx); // end of colour depth loop (8) +} // updateMatrixDMABuffer (specific co-ords change) + +/* Update the entire buffer with a single specific colour - quicker */ +void MatrixPanel_I2S_DMA::updateMatrixDMABuffer(uint8_t red, uint8_t green, uint8_t blue) +{ + if (!initialized) + return; + + /* https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/ */ + uint16_t red16, green16, blue16; +#ifndef NO_CIE1931 + red16 = lumConvTab[red]; + green16 = lumConvTab[green]; + blue16 = lumConvTab[blue]; +#else + red16 = red << 8; + green16 = green << 8; + blue16 = blue << 8; +#endif + + for (uint8_t colour_depth_idx = 0; colour_depth_idx < m_cfg.getPixelColorDepthBits(); colour_depth_idx++) // colour depth - 8 iterations + { + // let's precalculate RGB1 and RGB2 bits than flood it over the entire DMA buffer + uint16_t RGB_output_bits = 0; + + uint16_t mask = PIXEL_COLOR_MASK_BIT(colour_depth_idx, MASK_OFFSET); + + /* Per the .h file, the order of the output RGB bits is: + * BIT_B2, BIT_G2, BIT_R2, BIT_B1, BIT_G1, BIT_R1 */ + RGB_output_bits |= (bool)(blue16 & mask); // --B + RGB_output_bits <<= 1; + RGB_output_bits |= (bool)(green16 & mask); // -BG + RGB_output_bits <<= 1; + RGB_output_bits |= (bool)(red16 & mask); // BGR + + // Duplicate and shift across so we have have 6 populated bits of RGB1 and RGB2 pin values suitable for DMA buffer + RGB_output_bits |= RGB_output_bits << BITS_RGB2_OFFSET; // BGRBGR + + // Serial.printf("Fill with: 0x%#06x\n", RGB_output_bits); + + // iterate rows + int matrix_frame_parallel_row = fb->rowBits.size(); + do + { + --matrix_frame_parallel_row; + + // The destination for the pixel row bitstream + ESP32_I2S_DMA_STORAGE_TYPE *p = getRowDataPtr(matrix_frame_parallel_row, colour_depth_idx, back_buffer_id); + + // iterate pixels in a row + int x_coord = fb->rowBits[matrix_frame_parallel_row]->width; + do + { + --x_coord; + p[x_coord] &= BITMASK_RGB12_CLEAR; // reset colour bits + p[x_coord] |= RGB_output_bits; // set new colour bits + +#if defined(SPIRAM_DMA_BUFFER) + Cache_WriteBack_Addr((uint32_t)&p[x_coord], sizeof(ESP32_I2S_DMA_STORAGE_TYPE)); +#endif + + } while (x_coord); + + } while (matrix_frame_parallel_row); // end row iteration + } // colour depth loop (8) +} // updateMatrixDMABuffer (full frame paint) + +/** + * @brief - clears and reinitializes colour/control data in DMA buffs + * When allocated, DMA buffs might be dirty, so we need to blank it and initialize ABCDE,LAT,OE control bits. + * Those control bits are constants during the entire DMA sweep and never changed when updating just pixel colour data + * so we could set it once on DMA buffs initialization and forget. + * This effectively clears buffers to blank BLACK and makes it ready to display output. + * (Brightness control via OE bit manipulation is another case) - this must be done as well seperately! + */ +void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id) +{ + if (!initialized) + return; + + frameStruct *fb = &frame_buffer[_buff_id]; + + // we start with iterating all rows in dma_buff structure + int row_idx = fb->rowBits.size(); + do + { + --row_idx; + + ESP32_I2S_DMA_STORAGE_TYPE *row = fb->rowBits[row_idx]->getDataPtr(0, -1); // set pointer to the HEAD of a buffer holding data for the entire matrix row + + ESP32_I2S_DMA_STORAGE_TYPE abcde = (ESP32_I2S_DMA_STORAGE_TYPE)row_idx; + abcde <<= BITS_ADDR_OFFSET; // shift row y-coord to match ABCDE bits in vector from 8 to 12 + + // get last pixel index in a row of all colourdepths + int x_pixel = fb->rowBits[row_idx]->width * fb->rowBits[row_idx]->colour_depth; + // Serial.printf(" from pixel %d, ", x_pixel); + + // fill all x_pixels except colour_index[0] (LSB) ones, this also clears all colour data to 0's black + do + { + --x_pixel; + + if (m_cfg.driver == HUB75_I2S_CFG::SM5266P) + { + // modifications here for row shift register type SM5266P + // https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/164 + row[x_pixel] = abcde & (0x18 << BITS_ADDR_OFFSET); // mask out the bottom 3 bits which are the clk di bk inputs + } + else if (m_cfg.driver == HUB75_I2S_CFG::DP3246_SM5368) + { + row[ESP32_TX_FIFO_POSITION_ADJUST(x_pixel)] = 0x0000; + } + else + { + row[ESP32_TX_FIFO_POSITION_ADJUST(x_pixel)] = abcde; + } + + } while (x_pixel != fb->rowBits[row_idx]->width && x_pixel); + + // colour_index[0] (LSB) x_pixels must be "marked" with a previous's row address, 'cause it is used to display + // previous row while we pump in LSB's for a new row + abcde = ((ESP32_I2S_DMA_STORAGE_TYPE)row_idx - 1) << BITS_ADDR_OFFSET; + do + { + --x_pixel; + + if (m_cfg.driver == HUB75_I2S_CFG::SM5266P) + { + // modifications here for row shift register type SM5266P + // https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/164 + row[x_pixel] = abcde & (0x18 << BITS_ADDR_OFFSET); // mask out the bottom 3 bits which are the clk di bk inputs + } + else if (m_cfg.driver == HUB75_I2S_CFG::DP3246_SM5368) + { + row[ESP32_TX_FIFO_POSITION_ADJUST(x_pixel)] = 0x0000; + } + else + { + row[ESP32_TX_FIFO_POSITION_ADJUST(x_pixel)] = abcde; + } + + } while (x_pixel); + + // modifications here for row shift register type SM5266P + // https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/164 + if (m_cfg.driver == HUB75_I2S_CFG::SM5266P) + { + uint16_t serialCount; + uint16_t latch; + x_pixel = fb->rowBits[row_idx]->width - 16; // come back 8*2 pixels to allow for 8 writes + serialCount = 8; + do + { + serialCount--; + latch = row[x_pixel] | (((((ESP32_I2S_DMA_STORAGE_TYPE)row_idx) % 8) == serialCount) << 1) << BITS_ADDR_OFFSET; // data on 'B' + row[x_pixel++] = latch | (0x05 << BITS_ADDR_OFFSET); // clock high on 'A'and BK high for update + row[x_pixel++] = latch | (0x04 << BITS_ADDR_OFFSET); // clock low on 'A'and BK high for update + } while (serialCount); + } // end SM5266P + + // row selection for SM5368 shift regs with ABC-only addressing. A is row clk, B is BK and C is row data + if (m_cfg.driver == HUB75_I2S_CFG::DP3246_SM5368) + { + x_pixel = fb->rowBits[row_idx]->width - 1; // last pixel in first block) + uint16_t c = (row_idx == 0) ? BIT_C : 0x0000; // set row data (C) when row==0, then push through shift regs for all other rows + row[ESP32_TX_FIFO_POSITION_ADJUST(x_pixel - 1)] |= c; // set row data + row[ESP32_TX_FIFO_POSITION_ADJUST(x_pixel + 0)] |= c | BIT_A | BIT_B; // set row clk and bk, carry row data + } // end DP3246_SM5368 + + // let's set LAT/OE control bits for specific pixels in each colour_index subrows + // Need to consider the original ESP32's (WROOM) DMA TX FIFO reordering of bytes... + uint8_t colouridx = fb->rowBits[row_idx]->colour_depth; + do + { + --colouridx; + + // switch pointer to a row for a specific colour index + row = fb->rowBits[row_idx]->getDataPtr(colouridx, -1); + + // DP3246 needs the latch high for 3 clock cycles, so start 2 cycles earlier + if (m_cfg.driver == HUB75_I2S_CFG::DP3246_SM5368) + { + row[ESP32_TX_FIFO_POSITION_ADJUST(fb->rowBits[row_idx]->width - 3)] |= BIT_LAT; // DP3246 needs 3 clock cycle latch + row[ESP32_TX_FIFO_POSITION_ADJUST(fb->rowBits[row_idx]->width - 2)] |= BIT_LAT; // DP3246 needs 3 clock cycle latch + } // DP3246_SM5368 + + row[ESP32_TX_FIFO_POSITION_ADJUST(fb->rowBits[row_idx]->width - 1)] |= BIT_LAT; // -1 pixel to compensate array index starting at 0 + + // ESP32_TX_FIFO_POSITION_ADJUST(dma_buff.rowBits[row_idx]->width - 1) + + // need to disable OE before/after latch to hide row transition + // Should be one clock or more before latch, otherwise can get ghosting + uint8_t _blank = m_cfg.latch_blanking; + do + { + --_blank; + + row[ESP32_TX_FIFO_POSITION_ADJUST(0 + _blank)] |= BIT_OE; // disable output + row[ESP32_TX_FIFO_POSITION_ADJUST(fb->rowBits[row_idx]->width - 1)] |= BIT_OE; // disable output + row[ESP32_TX_FIFO_POSITION_ADJUST(fb->rowBits[row_idx]->width - _blank - 1)] |= BIT_OE; // (LAT pulse is (width-2) -1 pixel to compensate array index starting at 0 + + } while (_blank); + + } while (colouridx); + +#if defined(SPIRAM_DMA_BUFFER) + Cache_WriteBack_Addr((uint32_t)row, fb->rowBits[row_idx]->getColorDepthSize()); +#endif + + } while (row_idx); +} + +/** + * @brief - reset OE bits in DMA buffer in a way to control brightness + * @param brt - brightness level from 0 to 255 - NOT MATRIX_WIDTH + * @param _buff_id - buffer id to control + */ +void MatrixPanel_I2S_DMA::brtCtrlOEv2(uint8_t brt, const int _buff_id) +{ + + if (!initialized) + return; + + frameStruct *fb = &frame_buffer[_buff_id]; + + uint8_t _blank = m_cfg.latch_blanking; // don't want to inadvertantly blast over this + uint8_t _depth = fb->rowBits[0]->colour_depth; + uint16_t _width = fb->rowBits[0]->width; + + // start with iterating all rows in dma_buff structure + int row_idx = fb->rowBits.size(); + do + { + --row_idx; + + // let's set OE control bits for specific pixels in each color_index subrows + uint8_t colouridx = _depth; + do + { + --colouridx; + + char bitplane = (2 * _depth - colouridx) % _depth; + char bitshift = (_depth - lsbMsbTransitionBit - 1) >> 1; + + char rightshift = std::max(bitplane - bitshift - 2, 0); + // calculate the OE disable period by brightness, and also blanking + int brightness_in_x_pixels = ((_width - _blank) * brt) >> (7 + rightshift); + brightness_in_x_pixels = (brightness_in_x_pixels >> 1) | (brightness_in_x_pixels & 1); + + // switch pointer to a row for a specific color index + ESP32_I2S_DMA_STORAGE_TYPE *row = fb->rowBits[row_idx]->getDataPtr(colouridx, _buff_id); + + // define range of Output Enable on the center of the row + int x_coord_max = (_width + brightness_in_x_pixels + 1) >> 1; + int x_coord_min = (_width - brightness_in_x_pixels + 0) >> 1; + int x_coord = _width; + do + { + --x_coord; + + // (the check is already including "blanking" ) + if (x_coord >= x_coord_min && x_coord < x_coord_max) + { + row[ESP32_TX_FIFO_POSITION_ADJUST(x_coord)] &= BITMASK_OE_CLEAR; + } + else + { + row[ESP32_TX_FIFO_POSITION_ADJUST(x_coord)] |= BIT_OE; // Disable output after this point. + } + + } while (x_coord); + + } while (colouridx); + +// switch pointer to a row for a specific colour index +#if defined(SPIRAM_DMA_BUFFER) + ESP32_I2S_DMA_STORAGE_TYPE *row_hack = fb->rowBits[row_idx]->getDataPtr(0, _buff_id); + //Cache_WriteBack_Addr((uint32_t)row_hack, sizeof(ESP32_I2S_DMA_STORAGE_TYPE) * ((fb->rowBits[row_idx]->width * fb->rowBits[row_idx]->colour_depth) - 1)); + Cache_WriteBack_Addr((uint32_t)row_hack, fb->rowBits[row_idx]->getColorDepthSize()); +#endif + } while (row_idx); +} + +/* + * overload for compatibility + */ + +bool MatrixPanel_I2S_DMA::begin(int r1, int g1, int b1, int r2, int g2, int b2, int a, int b, int c, int d, int e, int lat, int oe, int clk) +{ + if (initialized) + return true; + // RGB + m_cfg.gpio.r1 = r1; + m_cfg.gpio.g1 = g1; + m_cfg.gpio.b1 = b1; + m_cfg.gpio.r2 = r2; + m_cfg.gpio.g2 = g2; + m_cfg.gpio.b2 = b2; + + // Line Select + m_cfg.gpio.a = a; + m_cfg.gpio.b = b; + m_cfg.gpio.c = c; + m_cfg.gpio.d = d; + m_cfg.gpio.e = e; + + // Clock & Control + m_cfg.gpio.lat = lat; + m_cfg.gpio.oe = oe; + m_cfg.gpio.clk = clk; + + return begin(); +} + +bool MatrixPanel_I2S_DMA::begin(const HUB75_I2S_CFG &cfg) +{ + if (initialized) + return true; + + if (!setCfg(cfg)) + return false; + + return begin(); +} + +/** + * @brief - Sets how many clock cycles to blank OE before/after LAT signal change + * @param uint8_t pulses - clocks before/after OE + * default is DEFAULT_LAT_BLANKING + * Max is MAX_LAT_BLANKING + * @returns - new value for m_cfg.latch_blanking + */ +uint8_t MatrixPanel_I2S_DMA::setLatBlanking(uint8_t pulses) +{ + if (pulses > MAX_LAT_BLANKING) + pulses = MAX_LAT_BLANKING; + + if (!pulses) + pulses = DEFAULT_LAT_BLANKING; + + m_cfg.latch_blanking = pulses; + + // remove brightness var for now. + // setPanelBrightness(brightness); // set brightness to reset OE bits to the values matching new LAT blanking setting + return m_cfg.latch_blanking; +} + +#ifndef NO_FAST_FUNCTIONS +/** + * @brief - update DMA buff drawing horizontal line at specified coordinates + * @param x_coord - line start coordinate x + * @param y_coord - line start coordinate y + * @param l - line length + * @param r,g,b, - RGB888 colour + */ +void MatrixPanel_I2S_DMA::hlineDMA(int16_t x_coord, int16_t y_coord, int16_t l, uint8_t red, uint8_t green, uint8_t blue) +{ + if (!initialized) + return; + + if ((x_coord + l) < 1 || y_coord < 0 || l < 1 || x_coord >= PIXELS_PER_ROW || y_coord >= m_cfg.mx_height) + return; + + l = x_coord < 0 ? l + x_coord : l; + x_coord = x_coord < 0 ? 0 : x_coord; + + l = ((x_coord + l) >= PIXELS_PER_ROW) ? (PIXELS_PER_ROW - x_coord) : l; + + // if (x_coord+l > PIXELS_PER_ROW) + // l = PIXELS_PER_ROW - x_coord + 1; // reset width to end of row + + /* LED Brightness Compensation */ + uint16_t red16, green16, blue16; +#ifndef NO_CIE1931 + red16 = lumConvTab[red]; + green16 = lumConvTab[green]; + blue16 = lumConvTab[blue]; +#else + red16 = red << 8; + green16 = green << 8; + blue16 = blue << 8; +#endif + + uint16_t _colourbitclear = BITMASK_RGB1_CLEAR, _colourbitoffset = 0; + + if (y_coord >= ROWS_PER_FRAME) + { // if we are drawing to the bottom part of the panel + _colourbitoffset = BITS_RGB2_OFFSET; + _colourbitclear = BITMASK_RGB2_CLEAR; + y_coord -= ROWS_PER_FRAME; + } + + // Iterating through colour depth bits (8 iterations) + uint8_t colour_depth_idx = m_cfg.getPixelColorDepthBits(); + do + { + --colour_depth_idx; + + // let's precalculate RGB1 and RGB2 bits than flood it over the entire DMA buffer + uint16_t RGB_output_bits = 0; + // uint8_t mask = (1 << colour_depth_idx COLOR_DEPTH_LESS_THAN_8BIT_ADJUST); + // #if PIXEL_COLOR_DEPTH_BITS < 8 + // uint8_t mask = (1 << (colour_depth_idx+MASK_OFFSET)); // expect 24 bit colour (8 bits per RGB subpixel) + // #else + // uint8_t mask = (1 << (colour_depth_idx)); // expect 24 bit colour (8 bits per RGB subpixel) + // #endif + uint16_t mask = PIXEL_COLOR_MASK_BIT(colour_depth_idx, MASK_OFFSET); + + /* Per the .h file, the order of the output RGB bits is: + * BIT_B2, BIT_G2, BIT_R2, BIT_B1, BIT_G1, BIT_R1 */ + RGB_output_bits |= (bool)(blue16 & mask); // --B + RGB_output_bits <<= 1; + RGB_output_bits |= (bool)(green16 & mask); // -BG + RGB_output_bits <<= 1; + RGB_output_bits |= (bool)(red16 & mask); // BGR + RGB_output_bits <<= _colourbitoffset; // shift color bits to the required position + + // Get the contents at this address, + // it would represent a vector pointing to the full row of pixels for the specified colour depth bit at Y coordinate + ESP32_I2S_DMA_STORAGE_TYPE *p = fb->rowBits[y_coord]->getDataPtr(colour_depth_idx, back_buffer_id); + // inlined version works slower here, dunno why :( + // ESP32_I2S_DMA_STORAGE_TYPE *p = getRowDataPtr(y_coord, colour_depth_idx, back_buffer_id); + + int16_t _l = l; + do + { // iterate pixels in a row + int16_t _x = x_coord + --_l; + + /* + #if defined(ESP32_THE_ORIG) + // Save the calculated value to the bitplane memory in reverse order to account for I2S Tx FIFO mode1 ordering + uint16_t &v = p[_x & 1U ? --_x : ++_x]; + #else + // ESP 32 doesn't need byte flipping for TX FIFO. + uint16_t &v = p[_x]; + #endif + */ + uint16_t &v = p[ESP32_TX_FIFO_POSITION_ADJUST(_x)]; + + v &= _colourbitclear; // reset colour bits + v |= RGB_output_bits; // set new colour bits + } while (_l); // iterate pixels in a row + } while (colour_depth_idx); // end of colour depth loop (8) +} // hlineDMA() + +/** + * @brief - update DMA buff drawing vertical line at specified coordinates + * @param x_coord - line start coordinate x + * @param y_coord - line start coordinate y + * @param l - line length + * @param r,g,b, - RGB888 colour + */ +void MatrixPanel_I2S_DMA::vlineDMA(int16_t x_coord, int16_t y_coord, int16_t l, uint8_t red, uint8_t green, uint8_t blue) +{ + if (!initialized) + return; + + if (x_coord < 0 || (y_coord + l) < 1 || l < 1 || x_coord >= PIXELS_PER_ROW || y_coord >= m_cfg.mx_height) + return; + + l = y_coord < 0 ? l + y_coord : l; + y_coord = y_coord < 0 ? 0 : y_coord; + + // check for a length that goes beyond the height of the screen! Array out of bounds dma memory changes = screwed output #163 + l = ((y_coord + l) >= m_cfg.mx_height) ? (m_cfg.mx_height - y_coord) : l; + // if (y_coord + l > m_cfg.mx_height) + /// l = m_cfg.mx_height - y_coord + 1; // reset width to end of col + + /* LED Brightness Compensation */ + uint16_t red16, green16, blue16; +#ifndef NO_CIE1931 + red16 = lumConvTab[red]; + green16 = lumConvTab[green]; + blue16 = lumConvTab[blue]; +#else + red16 = red << 8; + green16 = green << 8; + blue16 = blue << 8; +#endif + + /* + #if defined(ESP32_THE_ORIG) + // Save the calculated value to the bitplane memory in reverse order to account for I2S Tx FIFO mode1 ordering + x_coord & 1U ? --x_coord : ++x_coord; + #endif + */ + x_coord = ESP32_TX_FIFO_POSITION_ADJUST(x_coord); + + uint8_t colour_depth_idx = m_cfg.getPixelColorDepthBits(); + do + { // Iterating through colour depth bits (8 iterations) + --colour_depth_idx; + + // let's precalculate RGB1 and RGB2 bits than flood it over the entire DMA buffer + // uint8_t mask = (1 << colour_depth_idx COLOR_DEPTH_LESS_THAN_8BIT_ADJUST); + // #if PIXEL_COLOR_DEPTH_BITS < 8 + // uint8_t mask = (1 << (colour_depth_idx+MASK_OFFSET)); // expect 24 bit colour (8 bits per RGB subpixel) + // #else + // uint8_t mask = (1 << (colour_depth_idx)); // expect 24 bit colour (8 bits per RGB subpixel) + // #endif + + uint16_t mask = PIXEL_COLOR_MASK_BIT(colour_depth_idx, MASK_OFFSET); + uint16_t RGB_output_bits = 0; + + /* Per the .h file, the order of the output RGB bits is: + * BIT_B2, BIT_G2, BIT_R2, BIT_B1, BIT_G1, BIT_R1 */ + RGB_output_bits |= (bool)(blue16 & mask); // --B + RGB_output_bits <<= 1; + RGB_output_bits |= (bool)(green16 & mask); // -BG + RGB_output_bits <<= 1; + RGB_output_bits |= (bool)(red16 & mask); // BGR + + int16_t _l = 0, _y = y_coord; + uint16_t _colourbitclear = BITMASK_RGB1_CLEAR; + do + { // iterate pixels in a column + + if (_y >= ROWS_PER_FRAME) + { // if y-coord overlapped bottom-half panel + _y -= ROWS_PER_FRAME; + _colourbitclear = BITMASK_RGB2_CLEAR; + RGB_output_bits <<= BITS_RGB2_OFFSET; + } + + // Get the contents at this address, + // it would represent a vector pointing to the full row of pixels for the specified colour depth bit at Y coordinate + // ESP32_I2S_DMA_STORAGE_TYPE *p = getRowDataPtr(_y, colour_depth_idx, back_buffer_id); + ESP32_I2S_DMA_STORAGE_TYPE *p = fb->rowBits[_y]->getDataPtr(colour_depth_idx, back_buffer_id); + + p[x_coord] &= _colourbitclear; // reset RGB bits + p[x_coord] |= RGB_output_bits; // set new RGB bits + ++_y; + } while (++_l != l); // iterate pixels in a col + } while (colour_depth_idx); // end of colour depth loop (8) +} // vlineDMA() + +/** + * @brief - update DMA buff drawing a rectangular at specified coordinates + * this works much faster than multiple consecutive per-pixel calls to updateMatrixDMABuffer() + * @param int16_t x, int16_t y - coordinates of a top-left corner + * @param int16_t w, int16_t h - width and height of a rectangular, min is 1 px + * @param uint8_t r - RGB888 colour + * @param uint8_t g - RGB888 colour + * @param uint8_t b - RGB888 colour + */ +void MatrixPanel_I2S_DMA::fillRectDMA(int16_t x, int16_t y, int16_t w, int16_t h, uint8_t r, uint8_t g, uint8_t b) +{ + + // h-lines are >2 times faster than v-lines + // so will use it only for tall rects with h >2w + if (h > 2 * w) + { + // draw using v-lines + do + { + --w; + vlineDMA(x + w, y, h, r, g, b); + } while (w); + } + else + { + // draw using h-lines + do + { + --h; + hlineDMA(x, y + h, w, r, g, b); + } while (h); + } +} + +#endif // NO_FAST_FUNCTIONS diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/ESP32-HUB75-MatrixPanel-I2S-DMA.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/ESP32-HUB75-MatrixPanel-I2S-DMA.h new file mode 100644 index 0000000..6fcca10 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/ESP32-HUB75-MatrixPanel-I2S-DMA.h @@ -0,0 +1,1029 @@ +#ifndef _ESP32_RGB_64_32_MATRIX_PANEL_I2S_DMA +#define _ESP32_RGB_64_32_MATRIX_PANEL_I2S_DMA +/***************************************************************************************/ +/* Core ESP32 hardware / idf includes! */ +#include +#include +#include +#include +#include "esp_attr.h" + +// #include +#include "platforms/platform_detect.hpp" + +#ifdef USE_GFX_ROOT +#include +#include "GFX.h" // Adafruit GFX core class -> https://github.com/mrfaptastic/GFX_Root +#elif !defined NO_GFX +#include "Adafruit_GFX.h" // Adafruit class with all the other stuff +#endif + +/******************************************************************************************* + * COMPILE-TIME OPTIONS - MUST BE PROVIDED as part of PlatformIO project build_flags. * + * Changing the values just here won't work - as defines needs to persist beyond the scope * + * of just this file. * + *******************************************************************************************/ +/* Do NOT build additional methods optimized for fast drawing, + * i.e. Adafruits drawFastHLine, drawFastVLine, etc... */ +// #define NO_FAST_FUNCTIONS + +// #define NO_CIE1931 + +/* Physical / Chained HUB75(s) RGB pixel WIDTH and HEIGHT. + * + * This library has been tested with a 64x32 and 64x64 RGB panels. + * If you want to chain two or more of these horizontally to make a 128x32 panel + * you can do so with the cable and then set the CHAIN_LENGTH to '2'. + * + * Also, if you use a 64x64 panel, then set the MATRIX_HEIGHT to '64' and an E_PIN; it will work! + * + * All of this is memory permitting of course (dependant on your sketch etc.) ... + * + */ +#ifndef MATRIX_WIDTH +#define MATRIX_WIDTH 64 // Single panel of 64 pixel width +#endif + +#ifndef MATRIX_HEIGHT +#define MATRIX_HEIGHT 32 // CHANGE THIS VALUE to 64 IF USING 64px HIGH panel(s) with E PIN +#endif + +#ifndef CHAIN_LENGTH +#define CHAIN_LENGTH 1 // Number of modules chained together, i.e. 4 panels chained result in virtualmatrix 64x4=256 px long +#endif + +// Interesting Fact: We end up using a uint16_t to send data in parallel to the HUB75... but +// given we only map to 14 physical output wires/bits, we waste 2 bits. + +/***************************************************************************************/ +/* Do not change definitions below unless you pretty sure you know what you are doing! */ + +// keeping a check sine it was possibe to set it previously +#ifdef MATRIX_ROWS_IN_PARALLEL +#pragma message "You are not supposed to set MATRIX_ROWS_IN_PARALLEL. Setting it back to default." +#undef MATRIX_ROWS_IN_PARALLEL +#endif +#define MATRIX_ROWS_IN_PARALLEL 2 + +// 8bit per RGB color = 24 bit/per pixel, +// can be extended to offer deeper colors, or +// might be reduced to save DMA RAM +#ifdef PIXEL_COLOUR_DEPTH_BITS +#define PIXEL_COLOR_DEPTH_BITS PIXEL_COLOUR_DEPTH_BITS +#endif + +// support backwarts compatibility +#ifdef PIXEL_COLOR_DEPTH_BITS +#define PIXEL_COLOR_DEPTH_BITS_DEFAULT PIXEL_COLOR_DEPTH_BITS +#else +#define PIXEL_COLOR_DEPTH_BITS_DEFAULT 8 +#endif + +#define PIXEL_COLOR_DEPTH_BITS_MAX 12 + +/***************************************************************************************/ +/* Definitions below should NOT be ever changed without rewriting library logic */ +#define ESP32_I2S_DMA_STORAGE_TYPE uint16_t // DMA output of one uint16_t at a time. +#define CLKS_DURING_LATCH 0 // Not (yet) used. + +// Panel Upper half RGB (numbering according to order in DMA gpio_bus configuration) +#define BITS_RGB1_OFFSET 0 // Start point of RGB_X1 bits +#define BIT_R1 (1 << 0) +#define BIT_G1 (1 << 1) +#define BIT_B1 (1 << 2) + +// Panel Lower half RGB +#define BITS_RGB2_OFFSET 3 // Start point of RGB_X2 bits +#define BIT_R2 (1 << 3) +#define BIT_G2 (1 << 4) +#define BIT_B2 (1 << 5) + +// Panel Control Signals +#define BIT_LAT (1 << 6) +#define BIT_OE (1 << 7) + +// Panel GPIO Pin Addresses (A, B, C, D etc..) +#define BITS_ADDR_OFFSET 8 // Start point of address bits +#define BIT_A (1 << 8) +#define BIT_B (1 << 9) +#define BIT_C (1 << 10) +#define BIT_D (1 << 11) +#define BIT_E (1 << 12) + +// BitMasks are pre-computed based on the above #define's for performance. +#define BITMASK_RGB1_CLEAR (0b1111111111111000) // inverted bitmask for R1G1B1 bit in pixel vector +#define BITMASK_RGB2_CLEAR (0b1111111111000111) // inverted bitmask for R2G2B2 bit in pixel vector +#define BITMASK_RGB12_CLEAR (0b1111111111000000) // inverted bitmask for R1G1B1R2G2B2 bit in pixel vector +#define BITMASK_CTRL_CLEAR (0b1110000000111111) // inverted bitmask for control bits ABCDE,LAT,OE in pixel vector +#define BITMASK_OE_CLEAR (0b1111111101111111) // inverted bitmask for control bit OE in pixel vector + +// How many clock cycles to blank OE before/after LAT signal change, default is 2 clocks +#define DEFAULT_LAT_BLANKING 2 + +// Max clock cycles to blank OE before/after LAT signal change +#define MAX_LAT_BLANKING 4 + +/***************************************************************************************/ + +/** @brief - Structure holds raw DMA data to drive TWO full rows of pixels spanning through all chained modules + * Note: sizeof(data) must be multiple of 32 bits, as ESP32 DMA linked list buffer address pointer must be word-aligned + */ +struct rowBitStruct +{ + const size_t width; + const uint8_t colour_depth; + const bool double_buff; + ESP32_I2S_DMA_STORAGE_TYPE *data; + + /** @brief + * Returns size (in bytes) of row of data vectorfor a SINGLE buff for the number of colour depths requested + * + * default - Returns full data vector size for a SINGLE buff. + * You should only pass either PIXEL_COLOR_DEPTH_BITS or '1' to this + * + */ + size_t getColorDepthSize(uint8_t _dpth = 0) + { + if (!_dpth) + _dpth = colour_depth; + return width * _dpth * sizeof(ESP32_I2S_DMA_STORAGE_TYPE); + }; + + /** @brief + * Returns pointer to the row's data vector beginning at pixel[0] for _dpth colour bit + * + * NOTE: this call might be very slow in loops. Due to poor instruction caching in esp32 it might be required a reread from flash + * every loop cycle, better use inlined #define instead in such cases + */ + // inline ESP32_I2S_DMA_STORAGE_TYPE* getDataPtr(const uint8_t _dpth=0, const bool buff_id=0) { return &(data[_dpth*width + buff_id*(width*colour_depth)]); }; + + // BUFFER ID VALUE IS NOW IGNORED!!!! + inline ESP32_I2S_DMA_STORAGE_TYPE *getDataPtr(const uint8_t _dpth = 0, const bool buff_id = 0) { return &(data[_dpth * width]); }; + + // constructor - allocates DMA-capable memory to hold the struct data + rowBitStruct(const size_t _width, const uint8_t _depth, const bool _dbuff) : width(_width), colour_depth(_depth), double_buff(_dbuff) + { + + // #if defined(SPIRAM_FRAMEBUFFER) && defined (CONFIG_IDF_TARGET_ESP32S3) +#if defined(SPIRAM_DMA_BUFFER) + + // data = (ESP32_I2S_DMA_STORAGE_TYPE *)heap_caps_aligned_alloc(64, size()+size()*double_buff, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + // No longer have double buffer in the same struct - have a different struct + data = (ESP32_I2S_DMA_STORAGE_TYPE *)heap_caps_aligned_alloc(64, getColorDepthSize(), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); +#else + // data = (ESP32_I2S_DMA_STORAGE_TYPE *)heap_caps_malloc( size()+size()*double_buff, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + + // No longer have double buffer in the same struct - have a different struct + data = (ESP32_I2S_DMA_STORAGE_TYPE *)heap_caps_malloc(getColorDepthSize(), MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + +#endif + } + ~rowBitStruct() { delete data; } +}; + +/* frameStruct + * Note: A 'frameStruct' contains ALL the data for a full-frame (i.e. BOTH 2x16-row frames are + * are contained in parallel within the one uint16_t that is sent in parallel to the HUB75). + * + * This structure isn't actually allocated in one memory block anymore, as the library now allocates + * memory per row (per rowBits) instead. + */ +struct frameStruct +{ + uint8_t rows = 0; // number of rows held in current frame, not used actually, just to keep the idea of struct + std::vector> rowBits; +}; + +/***************************************************************************************/ +// C/p'ed from https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/ +// Example calculator: https://gist.github.com/mathiasvr/19ce1d7b6caeab230934080ae1f1380e +// need to make sure this would end up in RAM for fastest access +#ifndef NO_CIE1931 +/* +static const uint8_t DRAM_ATTR lumConvTab[]={ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 17, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28, 29, 30, 30, 31, 31, 32, 33, 33, 34, 35, 35, 36, 37, 38, 38, 39, 40, 41, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84, 86, 87, 88, 90, 91, 92, 93, 95, 96, 98, 99, 100, 102, 103, 105, 106, 107, 109, 110, 112, 113, 115, 116, 118, 120, 121, 123, 124, 126, 128, 129, 131, 133, 134, 136, 138, 139, 141, 143, 145, 146, 148, 150, 152, 154, 156, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 192, 194, 196, 198, 200, 203, 205, 207, 209, 212, 214, 216, 218, 221, 223, 226, 228, 230, 233, 235, 238, 240, 243, 245, 248, 250, 253, 255, 255}; +*/ +// This is 16-bit version of the table, +// the constants taken from the example in the article above, each entries subtracted from 65535: +static const uint16_t DRAM_ATTR lumConvTab[] = { + 0, 27, 56, 84, 113, 141, 170, 198, 227, 255, 284, 312, 340, 369, 397, 426, + 454, 483, 511, 540, 568, 597, 626, 657, 688, 720, 754, 788, 824, 860, 898, 936, + 976, 1017, 1059, 1102, 1146, 1191, 1238, 1286, 1335, 1385, 1436, 1489, 1543, 1598, 1655, 1713, + 1772, 1833, 1895, 1958, 2023, 2089, 2156, 2225, 2296, 2368, 2441, 2516, 2592, 2670, 2750, 2831, + 2914, 2998, 3084, 3171, 3260, 3351, 3443, 3537, 3633, 3731, 3830, 3931, 4034, 4138, 4245, 4353, + 4463, 4574, 4688, 4803, 4921, 5040, 5161, 5284, 5409, 5536, 5665, 5796, 5929, 6064, 6201, 6340, + 6482, 6625, 6770, 6917, 7067, 7219, 7372, 7528, 7687, 7847, 8010, 8174, 8341, 8511, 8682, 8856, + 9032, 9211, 9392, 9575, 9761, 9949, 10139, 10332, 10527, 10725, 10925, 11127, 11332, 11540, 11750, 11963, + 12178, 12395, 12616, 12839, 13064, 13292, 13523, 13757, 13993, 14231, 14473, 14717, 14964, 15214, 15466, 15722, + 15980, 16240, 16504, 16771, 17040, 17312, 17587, 17865, 18146, 18430, 18717, 19006, 19299, 19595, 19894, 20195, + 20500, 20808, 21119, 21433, 21750, 22070, 22393, 22720, 23049, 23382, 23718, 24057, 24400, 24745, 25094, 25446, + 25802, 26160, 26522, 26888, 27256, 27628, 28004, 28382, 28765, 29150, 29539, 29932, 30328, 30727, 31130, 31536, + 31946, 32360, 32777, 33197, 33622, 34049, 34481, 34916, 35354, 35797, 36243, 36692, 37146, 37603, 38064, 38528, + 38996, 39469, 39945, 40424, 40908, 41395, 41886, 42382, 42881, 43383, 43890, 44401, 44916, 45434, 45957, 46484, + 47014, 47549, 48088, 48630, 49177, 49728, 50283, 50842, 51406, 51973, 52545, 53120, 53700, 54284, 54873, 55465, + 56062, 56663, 57269, 57878, 58492, 59111, 59733, 60360, 60992, 61627, 62268, 62912, 63561, 64215, 64873, 65535}; +#endif + +/** @brief - configuration values for HUB75_I2S driver + * This structure holds configuration vars that are used as + * an initialization values when creating an instance of MatrixPanel_I2S_DMA object. + * All params have it's default values. + */ +struct HUB75_I2S_CFG +{ + + /** + * Enumeration of hardware-specific chips + * used to drive matrix modules + */ + enum shift_driver + { + SHIFTREG = 0, + FM6124, + FM6126A, + ICN2038S, + MBI5124, + SM5266P, + DP3246_SM5368 + }; + + /** + * I2S clock speed selector + */ + enum clk_speed + { + HZ_8M = 8000000, + HZ_10M = 10000000, + HZ_15M = 15000000, + HZ_20M = 20000000 + }; + + // + // Members must be in order of declaration or it breaks Arduino compiling due to strict checking. + // + + // physical width of a single matrix panel module (in pixels, usually it is 64 ;) ) + uint16_t mx_width; + + // physical height of a single matrix panel module (in pixels, usually almost always it is either 32 or 64) + uint16_t mx_height; + + // number of chained panels regardless of the topology, default 1 - a single matrix module + uint16_t chain_length; + + // GPIO Mapping + struct i2s_pins + { + int8_t r1, g1, b1, r2, g2, b2, a, b, c, d, e, lat, oe, clk; + } gpio; + + // Matrix driver chip type - default is a plain shift register + shift_driver driver; + + // use DMA double buffer (twice as much RAM required) + bool double_buff; + + // I2S clock speed + clk_speed i2sspeed; + + // How many clock cycles to blank OE before/after LAT signal change, default is 1 clock + uint8_t latch_blanking; + + /** + * I2S clock phase + * 0 - data lines are clocked with negative edge + * Clk /¯\_/¯\_/ + * LAT __/¯¯¯\__ + * EO ¯¯¯¯¯¯\___ + * + * 1 - data lines are clocked with positive edge (default now as of 10 June 2021) + * https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/130 + * Clk \_/¯\_/¯\ + * LAT __/¯¯¯\__ + * EO ¯¯¯¯¯¯\__ + * + */ + bool clkphase; + + // Minimum refresh / scan rate needs to be configured on start due to LSBMSB_TRANSITION_BIT calculation in allocateDMAmemory() + uint8_t min_refresh_rate; + + // struct constructor + HUB75_I2S_CFG( + uint16_t _w = MATRIX_WIDTH, + uint16_t _h = MATRIX_HEIGHT, + uint16_t _chain = CHAIN_LENGTH, + i2s_pins _pinmap = { + R1_PIN_DEFAULT, G1_PIN_DEFAULT, B1_PIN_DEFAULT, R2_PIN_DEFAULT, G2_PIN_DEFAULT, B2_PIN_DEFAULT, + A_PIN_DEFAULT, B_PIN_DEFAULT, C_PIN_DEFAULT, D_PIN_DEFAULT, E_PIN_DEFAULT, + LAT_PIN_DEFAULT, OE_PIN_DEFAULT, CLK_PIN_DEFAULT}, + shift_driver _drv = SHIFTREG, bool _dbuff = false, clk_speed _i2sspeed = HZ_15M, + uint8_t _latblk = DEFAULT_LAT_BLANKING, // Anything > 1 seems to cause artefacts on ICS panels + bool _clockphase = true, uint16_t _min_refresh_rate = 60, uint8_t _pixel_color_depth_bits = PIXEL_COLOR_DEPTH_BITS_DEFAULT) : mx_width(_w), mx_height(_h), chain_length(_chain), gpio(_pinmap), driver(_drv), double_buff(_dbuff), i2sspeed(_i2sspeed), latch_blanking(_latblk), clkphase(_clockphase), min_refresh_rate(_min_refresh_rate) + { + setPixelColorDepthBits(_pixel_color_depth_bits); + } + + // pixel_color_depth_bits must be between 12 and 2, and mask_offset needs to be calculated accordently + // so they have to be private with getter (and setter) + void setPixelColorDepthBits(uint8_t _pixel_color_depth_bits) + { + if (_pixel_color_depth_bits > PIXEL_COLOR_DEPTH_BITS_MAX || _pixel_color_depth_bits < 2) + { + + if (_pixel_color_depth_bits > PIXEL_COLOR_DEPTH_BITS_MAX) + { + pixel_color_depth_bits = PIXEL_COLOR_DEPTH_BITS_MAX; + } + else + { + pixel_color_depth_bits = 2; + } + ESP_LOGW("HUB75_I2S_CFG", "Invalid pixel_color_depth_bits (%d): 2 <= pixel_color_depth_bits <= %d, choosing nearest valid %d", _pixel_color_depth_bits, PIXEL_COLOR_DEPTH_BITS_MAX, pixel_color_depth_bits); + } + else + { + pixel_color_depth_bits = _pixel_color_depth_bits; + } + } + + uint8_t getPixelColorDepthBits() const + { + return pixel_color_depth_bits; + } + +private: + // these were priviously handeld as defines (PIXEL_COLOR_DEPTH_BITS, MASK_OFFSET) + // to make it changable after compilation, it is now part of the config + uint8_t pixel_color_depth_bits; +}; // end of structure HUB75_I2S_CFG + +/***************************************************************************************/ +#ifdef USE_GFX_ROOT +class MatrixPanel_I2S_DMA : public GFX +{ +#elif !defined NO_GFX +class MatrixPanel_I2S_DMA : public Adafruit_GFX +{ +#else +class MatrixPanel_I2S_DMA +{ +#endif + + // ------- PUBLIC ------- +public: + /** + * MatrixPanel_I2S_DMA + * + * default predefined values are used for matrix configuration + * + */ + MatrixPanel_I2S_DMA() +#ifdef USE_GFX_ROOT + : GFX(MATRIX_WIDTH, MATRIX_HEIGHT) +#elif !defined NO_GFX + : Adafruit_GFX(MATRIX_WIDTH, MATRIX_HEIGHT) +#endif + { + } + + /** + * MatrixPanel_I2S_DMA + * + * @param {HUB75_I2S_CFG} opts : structure with matrix configuration + * + */ + MatrixPanel_I2S_DMA(const HUB75_I2S_CFG &opts) +#ifdef USE_GFX_ROOT + : GFX(opts.mx_width * opts.chain_length, opts.mx_height) +#elif !defined NO_GFX + : Adafruit_GFX(opts.mx_width * opts.chain_length, opts.mx_height) +#endif + { + setCfg(opts); + } + + /* Propagate the DMA pin configuration, allocate DMA buffs and start data output, initially blank */ + bool begin() + { + + if (initialized) + return true; // we don't do this twice or more! + if (!config_set) + return false; + + ESP_LOGI("begin()", "Using GPIO %d for R1_PIN", m_cfg.gpio.r1); + ESP_LOGI("begin()", "Using GPIO %d for G1_PIN", m_cfg.gpio.g1); + ESP_LOGI("begin()", "Using GPIO %d for B1_PIN", m_cfg.gpio.b1); + ESP_LOGI("begin()", "Using GPIO %d for R2_PIN", m_cfg.gpio.r2); + ESP_LOGI("begin()", "Using GPIO %d for G2_PIN", m_cfg.gpio.g2); + ESP_LOGI("begin()", "Using GPIO %d for B2_PIN", m_cfg.gpio.b2); + ESP_LOGI("begin()", "Using GPIO %d for A_PIN", m_cfg.gpio.a); + ESP_LOGI("begin()", "Using GPIO %d for B_PIN", m_cfg.gpio.b); + ESP_LOGI("begin()", "Using GPIO %d for C_PIN", m_cfg.gpio.c); + ESP_LOGI("begin()", "Using GPIO %d for D_PIN", m_cfg.gpio.d); + ESP_LOGI("begin()", "Using GPIO %d for E_PIN", m_cfg.gpio.e); + ESP_LOGI("begin()", "Using GPIO %d for LAT_PIN", m_cfg.gpio.lat); + ESP_LOGI("begin()", "Using GPIO %d for OE_PIN", m_cfg.gpio.oe); + ESP_LOGI("begin()", "Using GPIO %d for CLK_PIN", m_cfg.gpio.clk); + + // initialize some specific panel drivers + if (m_cfg.driver) + shiftDriver(m_cfg); + +#if defined(SPIRAM_DMA_BUFFER) + // Trick library into dropping colour depth slightly when using PSRAM. + // Actual output clockrate override occurs in configureDMA + m_cfg.i2sspeed = HUB75_I2S_CFG::HZ_8M; +#endif + + /* As DMA buffers are dynamically allocated, we must allocated in begin() + * Ref: https://github.com/espressif/arduino-esp32/issues/831 + */ + if (!allocateDMAmemory()) + { + return false; + } // couldn't even get the basic ram required. + + // Flush the DMA buffers prior to configuring DMA - Avoid visual artefacts on boot. + resetbuffers(); // Must fill the DMA buffer with the initial output bit sequence or the panel will display garbage + + // Setup the ESP32 DMA Engine. Sprite_TM built this stuff. + configureDMA(m_cfg); // DMA and I2S configuration and setup + + // showDMABuffer(); // show backbuf_id of 0 + + if (!initialized) + { + ESP_LOGE("being()", "MatrixPanel_I2S_DMA::begin() failed!"); + } + + return initialized; + } + + // Obj destructor + virtual ~MatrixPanel_I2S_DMA() + { + dma_bus.release(); + } + + /* + * overload for compatibility + */ + bool begin(int r1, int g1 = G1_PIN_DEFAULT, int b1 = B1_PIN_DEFAULT, int r2 = R2_PIN_DEFAULT, int g2 = G2_PIN_DEFAULT, int b2 = B2_PIN_DEFAULT, int a = A_PIN_DEFAULT, int b = B_PIN_DEFAULT, int c = C_PIN_DEFAULT, int d = D_PIN_DEFAULT, int e = E_PIN_DEFAULT, int lat = LAT_PIN_DEFAULT, int oe = OE_PIN_DEFAULT, int clk = CLK_PIN_DEFAULT); + bool begin(const HUB75_I2S_CFG &cfg); + + // Adafruit's BASIC DRAW API (565 colour format) + virtual void drawPixel(int16_t x, int16_t y, uint16_t color); // overwrite adafruit implementation + virtual void fillScreen(uint16_t color); // overwrite adafruit implementation + + /** + * A wrapper to fill whatever selected DMA buffer / screen with black + */ + inline void clearScreen() { updateMatrixDMABuffer(0, 0, 0); }; + +#ifndef NO_FAST_FUNCTIONS + /** + * @brief - override Adafruit's FastVLine + * this works faster than multiple consecutive pixel by pixel drawPixel() call + */ + virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) + { + uint8_t r, g, b; + color565to888(color, r, g, b); + + int16_t w = 1; + transform(x, y, w, h); + if (h > w) + vlineDMA(x, y, h, r, g, b); + else + hlineDMA(x, y, w, r, g, b); + + } + // rgb888 overload + virtual inline void drawFastVLine(int16_t x, int16_t y, int16_t h, uint8_t r, uint8_t g, uint8_t b) + { + int16_t w = 1; + transform(x, y, w, h); + if (h > w) + vlineDMA(x, y, h, r, g, b); + else + hlineDMA(x, y, w, r, g, b); + }; + + /** + * @brief - override Adafruit's FastHLine + * this works faster than multiple consecutive pixel by pixel drawPixel() call + */ + virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) + { + uint8_t r, g, b; + color565to888(color, r, g, b); + + int16_t h = 1; + transform(x, y, w, h); + if (h > w) + vlineDMA(x, y, h, r, g, b); + else + hlineDMA(x, y, w, r, g, b); + + } + // rgb888 overload + virtual inline void drawFastHLine(int16_t x, int16_t y, int16_t w, uint8_t r, uint8_t g, uint8_t b) + { + int16_t h = 1; + transform(x, y, w, h); + if (h > w) + vlineDMA(x, y, h, r, g, b); + else + hlineDMA(x, y, w, r, g, b); + }; + + /** + * @brief - override Adafruit's fillRect + * this works much faster than multiple consecutive per-pixel drawPixel() calls + */ + virtual void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) + { + uint8_t r, g, b; + color565to888(color, r, g, b); + + transform(x, y, w, h); + fillRectDMA(x, y, w, h, r, g, b); + + } + // rgb888 overload + virtual inline void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint8_t r, uint8_t g, uint8_t b) + { + + transform(x, y, w, h); + fillRectDMA(x, y, w, h, r, g, b); + + } +#endif + + void fillScreenRGB888(uint8_t r, uint8_t g, uint8_t b); + void drawPixelRGB888(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b); + +#ifdef USE_GFX_ROOT + // 24bpp FASTLED CRGB colour struct support + void fillScreen(CRGB color); + void drawPixel(int16_t x, int16_t y, CRGB color); +#endif + + void drawIcon(int *ico, int16_t x, int16_t y, int16_t cols, int16_t rows); + + // Colour 444 is a 4 bit scale, so 0 to 15, colour 565 takes a 0-255 bit value, so scale up by 255/15 (i.e. 17)! + static uint16_t color444(uint8_t r, uint8_t g, uint8_t b) { return color565(r * 17, g * 17, b * 17); } + + // Converts RGB888 to RGB565 + static uint16_t color565(uint8_t r, uint8_t g, uint8_t b); // This is what is used by Adafruit GFX! + + // Converts RGB333 to RGB565 + static uint16_t color333(uint8_t r, uint8_t g, uint8_t b); // This is what is used by Adafruit GFX! Not sure why they have a capital 'C' for this particular function. + + /** + * @brief - convert RGB565 to RGB888 + * @param uint16_t colour - RGB565 input colour + * @param uint8_t &r, &g, &b - refs to variables where converted colors would be emplaced + */ + static void color565to888(const uint16_t color, uint8_t &r, uint8_t &g, uint8_t &b); + + inline void flipDMABuffer() + { + if (!m_cfg.double_buff) + { + return; + } + + dma_bus.flip_dma_output_buffer(back_buffer_id); + + //back_buffer_id ^= 1; + back_buffer_id = back_buffer_id^1; + fb = &frame_buffer[back_buffer_id]; + + + + } + + /** + * @param uint8_t b - 8-bit brightness value + */ + void setBrightness(const uint8_t b) + { + if (!initialized) + { + ESP_LOGI("setBrightness()", "Tried to set output brightness before begin()"); + return; + } + + brightness = b; + brtCtrlOEv2(b, 0); + + if (m_cfg.double_buff) + { + brtCtrlOEv2(b, 1); + } + } + + /** + * @param uint8_t b - 8-bit brightness value + */ + void setPanelBrightness(const uint8_t b) + { + setBrightness(b); + } + + /** + * this is just a wrapper to control brightness + * with an 8-bit value (0-255), very popular in FastLED-based sketches :) + * @param uint8_t b - 8-bit brightness value + */ + void setBrightness8(const uint8_t b) + { + setBrightness(b); + // setPanelBrightness(b * PIXELS_PER_ROW / 256); + } + + /** + * @brief - Sets how many clock cycles to blank OE before/after LAT signal change + * @param uint8_t pulses - clocks before/after OE + * default is DEFAULT_LAT_BLANKING + * Max is MAX_LAT_BLANKING + * @returns - new value for m_cfg.latch_blanking + */ + uint8_t setLatBlanking(uint8_t pulses); + + /** + * Get a class configuration struct + * + */ + const HUB75_I2S_CFG &getCfg() const { return m_cfg; }; + + inline bool setCfg(const HUB75_I2S_CFG &cfg) + { + if (initialized) + return false; + + m_cfg = cfg; + PIXELS_PER_ROW = m_cfg.mx_width * m_cfg.chain_length; + ROWS_PER_FRAME = m_cfg.mx_height / MATRIX_ROWS_IN_PARALLEL; + MASK_OFFSET = 16 - m_cfg.getPixelColorDepthBits(); + + config_set = true; + return true; + } + + /** + * Stop the ESP32 DMA Engine. Screen will forever be black until next ESP reboot. + */ + void stopDMAoutput() + { + resetbuffers(); + // i2s_parallel_stop_dma(ESP32_I2S_DEVICE); + dma_bus.dma_transfer_stop(); + } + + // ------- PROTECTED ------- + // those might be useful for child classes, like VirtualMatrixPanel +protected: + /** + * @brief - clears and reinitializes colour/control data in DMA buffs + * When allocated, DMA buffs might be dirty, so we need to blank it and initialize ABCDE,LAT,OE control bits. + * Those control bits are constants during the entire DMA sweep and never changed when updating just pixel colour data + * so we could set it once on DMA buffs initialization and forget. + * This effectively clears buffers to blank BLACK and makes it ready to display output. + * (Brightness control via OE bit manipulation is another case) + */ + void clearFrameBuffer(bool _buff_id); + + /* Update a specific pixel in the DMA buffer to a colour */ + void updateMatrixDMABuffer(uint16_t x, uint16_t y, uint8_t red, uint8_t green, uint8_t blue); + + /* Update the entire DMA buffer (aka. The RGB Panel) a certain colour (wipe the screen basically) */ + void updateMatrixDMABuffer(uint8_t red, uint8_t green, uint8_t blue); + + /** + * wipes DMA buffer(s) and reset all colour/service bits + */ + inline void resetbuffers() + { + clearFrameBuffer(0); + brtCtrlOEv2(brightness, 0); + + if (m_cfg.double_buff) { + + clearFrameBuffer(1); + brtCtrlOEv2(brightness, 1); + + } + } + +#ifndef NO_FAST_FUNCTIONS + /** + * @brief - update DMA buff drawing horizontal line at specified coordinates + * @param x_ccord - line start coordinate x + * @param y_ccord - line start coordinate y + * @param l - line length + * @param r,g,b, - RGB888 colour + */ + void hlineDMA(int16_t x_coord, int16_t y_coord, int16_t l, uint8_t red, uint8_t green, uint8_t blue); + + /** + * @brief - update DMA buff drawing horizontal line at specified coordinates + * @param x_ccord - line start coordinate x + * @param y_ccord - line start coordinate y + * @param l - line length + * @param r,g,b, - RGB888 colour + */ + void vlineDMA(int16_t x_coord, int16_t y_coord, int16_t l, uint8_t red, uint8_t green, uint8_t blue); + + /** + * @brief - update DMA buff drawing a rectangular at specified coordinates + * uses Fast H/V line draw internally, works faster than multiple consecutive pixel by pixel calls to updateMatrixDMABuffer() + * @param int16_t x, int16_t y - coordinates of a top-left corner + * @param int16_t w, int16_t h - width and height of a rectangular, min is 1 px + * @param uint8_t r - RGB888 colour + * @param uint8_t g - RGB888 colour + * @param uint8_t b - RGB888 colour + */ + void fillRectDMA(int16_t x_coord, int16_t y_coord, int16_t w, int16_t h, uint8_t r, uint8_t g, uint8_t b); +#endif + + // ------- PRIVATE ------- +private: + /* Calculate the memory available for DMA use, do some other stuff, and allocate accordingly */ + bool allocateDMAmemory(); + + /* Setup the DMA Link List chain and initiate the ESP32 DMA engine */ + void configureDMA(const HUB75_I2S_CFG &opts); + + /** + * pre-init procedures for specific drivers + * + */ + void shiftDriver(const HUB75_I2S_CFG &opts); + + /** + * @brief - FM6124-family chips initialization routine + */ + void fm6124init(const HUB75_I2S_CFG &_cfg); + + /** + * @brief - DP3246-family chips initialization routine + */ + void dp3246init(const HUB75_I2S_CFG& _cfg); + + /** + * @brief - reset OE bits in DMA buffer in a way to control brightness + * @param brt - brightness level from 0 to row_width + * @param _buff_id - buffer id to control + */ + // void brtCtrlOE(int brt, const bool _buff_id=0); + + /** + * @brief - reset OE bits in DMA buffer in a way to control brightness + * @param brt - brightness level from 0 to row_width + * @param _buff_id - buffer id to control + */ + void brtCtrlOEv2(uint8_t brt, const int _buff_id = 0); + + /** + * @brief - transforms coordinates according to orientation + * @param x - x position origin + * @param y - y position origin + * @param w - rectangular width + * @param h - rectangular height + */ + void transform(int16_t &x, int16_t &y, int16_t &w, int16_t &h) + { +#ifndef NO_GFX + int16_t t; + switch (rotation) + { + case 1: + t = _height - 1 - y - (h - 1); + y = x; + x = t; + t = h; + h = w; + w = t; + return; + case 2: + x = _width - 1 - x - (w - 1); + y = _height - 1 - y - (h - 1); + return; + case 3: + t = y; + y = _width - 1 - x - (w - 1); + x = t; + t = h; + h = w; + w = t; + return; + } +#endif + }; + +public: + /** + * Contains the resulting refresh rate (scan rate) that will be achieved + * based on the i2sspeed, colour depth and min_refresh_rate requested. + */ + int calculated_refresh_rate = 0; + +protected: + Bus_Parallel16 dma_bus; + +private: + + // Matrix i2s settings + HUB75_I2S_CFG m_cfg; + + /* Pixel data is organized from LSB to MSB sequentially by row, from row 0 to row matrixHeight/matrixRowsInParallel + * (two rows of pixels are refreshed in parallel) + * Memory is allocated (malloc'd) by the row, and not in one massive chunk, for flexibility. + * The whole DMA framebuffer is just a vector of pointers to structs with ESP32_I2S_DMA_STORAGE_TYPE arrays + * Since it's dimensions is unknown prior to class initialization, we just declare it here as empty struct and will do all allocations later. + * Refer to rowBitStruct to get the idea of it's internal structure + */ + frameStruct frame_buffer[2]; + frameStruct *fb; // What framebuffer we are writing pixel changes to? (pointer to either frame_buffer[0] or frame_buffer[1] basically ) used within updateMatrixDMABuffer(...) + + volatile int back_buffer_id = 0; // If using double buffer, which one is NOT active (ie. being displayed) to write too? + int brightness = 128; // If you get ghosting... reduce brightness level. ((60/64)*255) seems to be the limit before ghosting on a 64 pixel wide physical panel for some panels. + int lsbMsbTransitionBit = 0; // For colour depth calculations + + /* ESP32-HUB75-MatrixPanel-I2S-DMA functioning constants + * we should not those once object instance initialized it's DMA structs + * they weree const, but this lead to bugs, when the default constructor was called. + * So now they could be changed, but shouldn't. Maybe put a cpp lock around it, so it can't be changed after initialisation + */ + uint16_t PIXELS_PER_ROW = m_cfg.mx_width * m_cfg.chain_length; // number of pixels in a single row of all chained matrix modules (WIDTH of a combined matrix chain) + uint8_t ROWS_PER_FRAME = m_cfg.mx_height / MATRIX_ROWS_IN_PARALLEL; // RPF - rows per frame, either 16 or 32 depending on matrix module + uint8_t MASK_OFFSET = 16 - m_cfg.getPixelColorDepthBits(); + + // Other private variables + bool initialized = false; + bool config_set = false; + +}; // end Class header + +/***************************************************************************************/ +// https://stackoverflow.com/questions/5057021/why-are-c-inline-functions-in-the-header +/* 2. functions declared in the header must be marked inline because otherwise, every translation unit which includes the header will contain a definition of the function, and the linker will complain about multiple definitions (a violation of the One Definition Rule). The inline keyword suppresses this, allowing multiple translation units to contain (identical) definitions. */ + +/** + * @brief - convert RGB565 to RGB888 + * @param uint16_t colour - RGB565 input colour + * @param uint8_t &r, &g, &b - refs to variables where converted colours would be emplaced + */ +inline void MatrixPanel_I2S_DMA::color565to888(const uint16_t color, uint8_t &r, uint8_t &g, uint8_t &b) +{ + r = (color >> 8) & 0xf8; + g = (color >> 3) & 0xfc; + b = (color << 3); + r |= r >> 5; + g |= g >> 6; + b |= b >> 5; +} + +inline void MatrixPanel_I2S_DMA::drawPixel(int16_t x, int16_t y, uint16_t color) // adafruit virtual void override +{ + uint8_t r, g, b; + color565to888(color, r, g, b); + + int16_t w = 1, h = 1; + transform(x, y, w, h); + updateMatrixDMABuffer(x, y, r, g, b); +} + +inline void MatrixPanel_I2S_DMA::fillScreen(uint16_t color) // adafruit virtual void override +{ + uint8_t r, g, b; + color565to888(color, r, g, b); + + updateMatrixDMABuffer(r, g, b); // RGB only (no pixel coordinate) version of 'updateMatrixDMABuffer' +} + +inline void MatrixPanel_I2S_DMA::drawPixelRGB888(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b) +{ + int16_t w = 1, h = 1; + transform(x, y, w, h); + updateMatrixDMABuffer(x, y, r, g, b); +} + +inline void MatrixPanel_I2S_DMA::fillScreenRGB888(uint8_t r, uint8_t g, uint8_t b) +{ + updateMatrixDMABuffer(r, g, b); // RGB only (no pixel coordinate) version of 'updateMatrixDMABuffer' +} + +#ifdef USE_GFX_ROOT +// Support for CRGB values provided via FastLED +inline void MatrixPanel_I2S_DMA::drawPixel(int16_t x, int16_t y, CRGB color) +{ + int16_t w = 1, h = 1; + transform(x, y, w, h); + updateMatrixDMABuffer(x, y, color.red, color.green, color.blue); +} + +inline void MatrixPanel_I2S_DMA::fillScreen(CRGB color) +{ + updateMatrixDMABuffer(color.red, color.green, color.blue); +} +#endif + +// Pass 8-bit (each) R,G,B, get back 16-bit packed colour +// https://github.com/squix78/ILI9341Buffer/blob/master/ILI9341_SPI.cpp +inline uint16_t MatrixPanel_I2S_DMA::color565(uint8_t r, uint8_t g, uint8_t b) +{ + return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); +} + +// Promote 3/3/3 RGB to Adafruit_GFX 5/6/5 RRRrrGGGgggBBBbb +inline uint16_t MatrixPanel_I2S_DMA::color333(uint8_t r, uint8_t g, uint8_t b) +{ + return ((r & 0x7) << 13) | ((r & 0x6) << 10) | ((g & 0x7) << 8) | ((g & 0x7) << 5) | ((b & 0x7) << 2) | ((b & 0x6) >> 1); +} + +inline void MatrixPanel_I2S_DMA::drawIcon(int *ico, int16_t x, int16_t y, int16_t cols, int16_t rows) +{ + /* drawIcon draws a C style bitmap. + // Example 10x5px bitmap of a yellow sun + // + int half_sun [50] = { + 0x0000, 0x0000, 0x0000, 0xffe0, 0x0000, 0x0000, 0xffe0, 0x0000, 0x0000, 0x0000, + 0x0000, 0xffe0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffe0, 0x0000, + 0x0000, 0x0000, 0x0000, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x0000, 0x0000, 0x0000, + 0xffe0, 0x0000, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x0000, 0xffe0, + 0x0000, 0x0000, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x0000, 0x0000, + }; + + MatrixPanel_I2S_DMA matrix; + + matrix.drawIcon (half_sun, 0,0,10,5); + */ + + int i, j; + for (i = 0; i < rows; i++) + { + for (j = 0; j < cols; j++) + { + drawPixel(x + j, y + i, (uint16_t)ico[i * cols + j]); + } + } +} + +#endif + +// Credits: Louis Beaudoin +// and Sprite_TM: https://www.esp32.com/viewtopic.php?f=17&t=3188 and https://www.esp32.com/viewtopic.php?f=13&t=3256 + +/* + + This is example code to driver a p3(2121)64*32 -style RGB LED display. These types of displays do not have memory and need to be refreshed + continuously. The display has 2 RGB inputs, 4 inputs to select the active line, a pixel clock input, a latch enable input and an output-enable + input. The display can be seen as 2 64x16 displays consisting of the upper half and the lower half of the display. Each half has a separate + RGB pixel input, the rest of the inputs are shared. + + Each display half can only show one line of RGB pixels at a time: to do this, the RGB data for the line is input by setting the RGB input pins + to the desired value for the first pixel, giving the display a clock pulse, setting the RGB input pins to the desired value for the second pixel, + giving a clock pulse, etc. Do this 64 times to clock in an entire row. The pixels will not be displayed yet: until the latch input is made high, + the display will still send out the previously clocked in line. Pulsing the latch input high will replace the displayed data with the data just + clocked in. + + The 4 line select inputs select where the currently active line is displayed: when provided with a binary number (0-15), the latched pixel data + will immediately appear on this line. Note: While clocking in data for a line, the *previous* line is still displayed, and these lines should + be set to the value to reflect the position the *previous* line is supposed to be on. + + Finally, the screen has an OE input, which is used to disable the LEDs when latching new data and changing the state of the line select inputs: + doing so hides any artefacts that appear at this time. The OE line is also used to dim the display by only turning it on for a limited time every + line. + + All in all, an image can be displayed by 'scanning' the display, say, 100 times per second. The slowness of the human eye hides the fact that + only one line is showed at a time, and the display looks like every pixel is driven at the same time. + + Now, the RGB inputs for these types of displays are digital, meaning each red, green and blue subpixel can only be on or off. This leads to a + colour palette of 8 pixels, not enough to display nice pictures. To get around this, we use binary code modulation. + + Binary code modulation is somewhat like PWM, but easier to implement in our case. First, we define the time we would refresh the display without + binary code modulation as the 'frame time'. For, say, a four-bit binary code modulation, the frame time is divided into 15 ticks of equal length. + + We also define 4 subframes (0 to 3), defining which LEDs are on and which LEDs are off during that subframe. (Subframes are the same as a + normal frame in non-binary-coded-modulation mode, but are showed faster.) From our (non-monochrome) input image, we take the (8-bit: bit 7 + to bit 0) RGB pixel values. If the pixel values have bit 7 set, we turn the corresponding LED on in subframe 3. If they have bit 6 set, + we turn on the corresponding LED in subframe 2, if bit 5 is set subframe 1, if bit 4 is set in subframe 0. + + Now, in order to (on average within a frame) turn a LED on for the time specified in the pixel value in the input data, we need to weigh the + subframes. We have 15 pixels: if we show subframe 3 for 8 of them, subframe 2 for 4 of them, subframe 1 for 2 of them and subframe 1 for 1 of + them, this 'automatically' happens. (We also distribute the subframes evenly over the ticks, which reduces flicker.) + + In this code, we use the I2S peripheral in parallel mode to achieve this. Essentially, first we allocate memory for all subframes. This memory + contains a sequence of all the signals (2xRGB, line select, latch enable, output enable) that need to be sent to the display for that subframe. + Then we ask the I2S-parallel driver to set up a DMA chain so the subframes are sent out in a sequence that satisfies the requirement that + subframe x has to be sent out for (2^x) ticks. Finally, we fill the subframes with image data. + + We use a front buffer/back buffer technique here to make sure the display is refreshed in one go and drawing artefacts do not reach the display. + In practice, for small displays this is not really necessarily. + +*/ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/ESP32-HUB75-MatrixPanel-leddrivers.cpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/ESP32-HUB75-MatrixPanel-leddrivers.cpp new file mode 100644 index 0000000..b4d768b --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/ESP32-HUB75-MatrixPanel-leddrivers.cpp @@ -0,0 +1,191 @@ +/* + Various LED Driver chips might need some specific code for initialisation/control logic + +*/ + +#include + +#ifdef ARDUINO_ARCH_ESP32 + #include +#else + #define LOW 0 + #define HIGH 1 +#endif +#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h" + +#define CLK_PULSE gpio_set_level((gpio_num_t) _cfg.gpio.clk, HIGH); gpio_set_level((gpio_num_t) _cfg.gpio.clk, LOW); + +/** + * @brief - pre-init procedures for specific led-drivers + * this method is called before DMA/I2S setup while GPIOs + * aint yet assigned for DMA operation + * + */ +void MatrixPanel_I2S_DMA::shiftDriver(const HUB75_I2S_CFG& _cfg){ + switch (_cfg.driver){ + case HUB75_I2S_CFG::ICN2038S: + case HUB75_I2S_CFG::FM6124: + case HUB75_I2S_CFG::FM6126A: + fm6124init(_cfg); + break; + case HUB75_I2S_CFG::DP3246_SM5368: + dp3246init(_cfg); + break; + case HUB75_I2S_CFG::MBI5124: + /* MBI5124 chips must be clocked with positive-edge, since it's LAT signal + * resets on clock's rising edge while high + * https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/files/5952216/5a542453754da.pdf + */ + m_cfg.clkphase=true; + break; + case HUB75_I2S_CFG::SHIFTREG: + default: + break; + } +} + + +void MatrixPanel_I2S_DMA::fm6124init(const HUB75_I2S_CFG& _cfg) { + + ESP_LOGI("LEDdrivers", "MatrixPanel_I2S_DMA - initializing FM6124 driver..."); + + bool REG1[16] = {0,0,0,0,0, 1,1,1,1,1,1, 0,0,0,0,0}; // this sets global matrix brightness power + bool REG2[16] = {0,0,0,0,0, 0,0,0,0,1,0, 0,0,0,0,0}; // a single bit enables the matrix output + + for (uint8_t _pin:{_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2, _cfg.gpio.clk, _cfg.gpio.lat, _cfg.gpio.oe}){ + gpio_reset_pin((gpio_num_t)_pin); // some pins are not in gpio mode after reset => https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html#gpio-summary + gpio_set_direction((gpio_num_t) _pin, GPIO_MODE_OUTPUT); + gpio_set_level((gpio_num_t) _pin, LOW); + } + + gpio_set_level((gpio_num_t) _cfg.gpio.oe, HIGH); // Disable Display + + // Send Data to control register REG1 + // this sets the matrix brightness actually + for (int l = 0; l < PIXELS_PER_ROW; l++){ + for (uint8_t _pin:{_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2}) + gpio_set_level((gpio_num_t) _pin, REG1[l%16]); // we have 16 bits shifters and write the same value all over the matrix array + + if (l > PIXELS_PER_ROW - 12){ // pull the latch 11 clocks before the end of matrix so that REG1 starts counting to save the value + gpio_set_level((gpio_num_t) _cfg.gpio.lat, HIGH); + } + CLK_PULSE + } + + // drop the latch and save data to the REG1 all over the FM6124 chips + gpio_set_level((gpio_num_t) _cfg.gpio.lat, LOW); + + // Send Data to control register REG2 (enable LED output) + for (int l = 0; l < PIXELS_PER_ROW; l++){ + for (uint8_t _pin:{_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2}) + gpio_set_level((gpio_num_t) _pin, REG2[l%16]); // we have 16 bits shifters and we write the same value all over the matrix array + + if (l > PIXELS_PER_ROW - 13){ // pull the latch 12 clocks before the end of matrix so that reg2 stars counting to save the value + gpio_set_level((gpio_num_t) _cfg.gpio.lat, HIGH); + } + CLK_PULSE + } + + // drop the latch and save data to the REG1 all over the FM6126 chips + gpio_set_level((gpio_num_t) _cfg.gpio.lat, LOW); + + // blank data regs to keep matrix clear after manipulations + for (uint8_t _pin:{_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2}) + gpio_set_level((gpio_num_t) _pin, LOW); + + for (int l = 0; l < PIXELS_PER_ROW; ++l){ + CLK_PULSE + } + + gpio_set_level((gpio_num_t) _cfg.gpio.lat, HIGH); + CLK_PULSE + gpio_set_level((gpio_num_t) _cfg.gpio.lat, LOW); + gpio_set_level((gpio_num_t) _cfg.gpio.oe, LOW); // Enable Display + CLK_PULSE +} + +void MatrixPanel_I2S_DMA::dp3246init(const HUB75_I2S_CFG& _cfg) { + + ESP_LOGI("LEDdrivers", "MatrixPanel_I2S_DMA - initializing DP3246 driver..."); + + // DP3246 needs positive clock edge + m_cfg.clkphase = true; + + // 15:13 3 000 reserved + // 12:9 4 0000 OE widening (= OE_ADD * 6ns) + // 8 1 0 reserved + // 7:0 8 11111111 Iout = (Igain+1)/256 * 17.6 / Rext + bool REG1[16] = { 0,0,0, 0,0,0,0, 0, 1,1,1,1,1,1,1,1 }; // MSB first + + // 15:11 5 11111 Blanking potential selection, step 77mV, 00000: VDD-0.8V + // 10:8 3 111 Constant current source output inflection point selection + // 7 1 0 Disable dead pixel removel, 1: Enable + // 6 1 0 0->1: (OPEN_DET rising edge) start detection, 0: reset to ready-to-detect state + // 5 1 0 0: Enable black screen power saving, 1: Turn off the black screen to save energy + // 4 1 0 0: Do not enable the fading function, 1: Enable the fade function + // 3 1 0 Reserved + // 2:0 3 000 000: single edge pass, others: double edge transfer + bool REG2[16] = { 1,1,1,1,1, 1,1,1, 0, 0, 0, 0, 0, 0,0,0 }; // MSB first + + for (uint8_t _pin : {_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2, _cfg.gpio.clk, _cfg.gpio.lat, _cfg.gpio.oe}) { + gpio_reset_pin((gpio_num_t)_pin); // some pins are not in gpio mode after reset => https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html#gpio-summary + gpio_set_direction((gpio_num_t)_pin, GPIO_MODE_OUTPUT); + gpio_set_level((gpio_num_t)_pin, LOW); + } + + gpio_set_level((gpio_num_t)_cfg.gpio.oe, HIGH); // disable Display + + // clear registers - this seems to help with reliability + for (int l = 0; l < PIXELS_PER_ROW; ++l) { + if (l == PIXELS_PER_ROW - 3) { // DP3246 wants the latch dropped for 3 clk cycles + gpio_set_level((gpio_num_t)_cfg.gpio.lat, HIGH); + } + CLK_PULSE + } + + gpio_set_level((gpio_num_t)_cfg.gpio.lat, LOW); + + // Send Data to control register REG1 + for (int l = 0; l < PIXELS_PER_ROW; l++) { + for (uint8_t _pin : {_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2}) + gpio_set_level((gpio_num_t)_pin, REG1[l % 16]); // we have 16 bits shifters and write the same value all over the matrix array + + if (l == PIXELS_PER_ROW - 11) { // pull the latch 11 clocks before the end of matrix so that REG1 starts counting to save the value + gpio_set_level((gpio_num_t)_cfg.gpio.lat, HIGH); + } + CLK_PULSE + } + + // drop the latch and save data to the REG1 all over the DP3246 chips + gpio_set_level((gpio_num_t)_cfg.gpio.lat, LOW); + + // Send Data to control register REG2 + for (int l = 0; l < PIXELS_PER_ROW; l++) { + for (uint8_t _pin : {_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2}) + gpio_set_level((gpio_num_t)_pin, REG2[l % 16]); // we have 16 bits shifters and we write the same value all over the matrix array + + if (l == PIXELS_PER_ROW - 12) { // pull the latch 12 clocks before the end of matrix so that REG2 starts counting to save the value + gpio_set_level((gpio_num_t)_cfg.gpio.lat, HIGH); + } + CLK_PULSE + } + + // drop the latch and save data to the REG2 all over the DP3246 chips + gpio_set_level((gpio_num_t)_cfg.gpio.lat, LOW); + CLK_PULSE + + // blank data regs to keep matrix clear after manipulations + for (uint8_t _pin : {_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2}) + gpio_set_level((gpio_num_t)_pin, LOW); + + for (int l = 0; l < PIXELS_PER_ROW; ++l) { + if (l == PIXELS_PER_ROW - 3) { // DP3246 wants the latch dropped for 3 clk cycles + gpio_set_level((gpio_num_t)_cfg.gpio.lat, HIGH); + } + CLK_PULSE + } + + gpio_set_level((gpio_num_t)_cfg.gpio.lat, LOW); + gpio_set_level((gpio_num_t)_cfg.gpio.oe, LOW); // enable Display + CLK_PULSE +} \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/ESP32-VirtualMatrixPanel-I2S-DMA.h b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/ESP32-VirtualMatrixPanel-I2S-DMA.h new file mode 100644 index 0000000..2738599 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/ESP32-VirtualMatrixPanel-I2S-DMA.h @@ -0,0 +1,554 @@ +#ifndef _ESP32_VIRTUAL_MATRIX_PANEL_I2S_DMA +#define _ESP32_VIRTUAL_MATRIX_PANEL_I2S_DMA + +/******************************************************************* + Class contributed by Brian Lough, and expanded by Faptastic. + + Originally designed to allow CHAINING of panels together to create + a 'bigger' display of panels. i.e. Chaining 4 panels into a 2x2 + grid. + + However, the function of this class has expanded now to also manage + the output for + + 1) TWO scan panels = Two rows updated in parallel. + * 64px high panel = sometimes referred to as 1/32 scan + * 32px high panel = sometimes referred to as 1/16 scan + * 16px high panel = sometimes referred to as 1/8 scan + + 2) FOUR scan panels = Four rows updated in parallel + * 32px high panel = sometimes referred to as 1/8 scan + * 16px high panel = sometimes referred to as 1/4 scan + + YouTube: https://www.youtube.com/brianlough + Tindie: https://www.tindie.com/stores/brianlough/ + Twitter: https://twitter.com/witnessmenow + *******************************************************************/ + +#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h" +#ifndef NO_GFX +#include +#endif + +// #include + +struct VirtualCoords +{ + int16_t x; + int16_t y; + int16_t virt_row; // chain of panels row + int16_t virt_col; // chain of panels col + + VirtualCoords() : x(0), y(0) + { + } +}; + +enum PANEL_SCAN_RATE +{ + NORMAL_TWO_SCAN, + NORMAL_ONE_SIXTEEN, // treated as the same + FOUR_SCAN_32PX_HIGH, + FOUR_SCAN_16PX_HIGH, + FOUR_SCAN_64PX_HIGH +}; + +// Chaining approach... From the perspective of the DISPLAY / LED side of the chain of panels. +enum PANEL_CHAIN_TYPE +{ + CHAIN_NONE, + CHAIN_TOP_LEFT_DOWN, + CHAIN_TOP_RIGHT_DOWN, + CHAIN_BOTTOM_LEFT_UP, + CHAIN_BOTTOM_RIGHT_UP, + CHAIN_TOP_LEFT_DOWN_ZZ, /// ZigZag chaining. Might need a big ass cable to do this, all panels right way up. + CHAIN_TOP_RIGHT_DOWN_ZZ, + CHAIN_BOTTOM_RIGHT_UP_ZZ, + CHAIN_BOTTOM_LEFT_UP_ZZ +}; + +#ifdef USE_GFX_ROOT +class VirtualMatrixPanel : public GFX +#elif !defined NO_GFX +class VirtualMatrixPanel : public Adafruit_GFX +#else +class VirtualMatrixPanel +#endif +{ + +public: + VirtualMatrixPanel(MatrixPanel_I2S_DMA &disp, int _vmodule_rows, int _vmodule_cols, int _panelResX, int _panelResY, PANEL_CHAIN_TYPE _panel_chain_type = CHAIN_NONE) +#ifdef USE_GFX_ROOT + : GFX(_vmodule_cols * _panelResX, _vmodule_rows * _panelResY) +#elif !defined NO_GFX + : Adafruit_GFX(_vmodule_cols * _panelResX, _vmodule_rows * _panelResY) +#endif + { + this->display = &disp; + + panel_chain_type = _panel_chain_type; + + panelResX = _panelResX; + panelResY = _panelResY; + + vmodule_rows = _vmodule_rows; + vmodule_cols = _vmodule_cols; + + virtualResX = vmodule_cols * _panelResX; + virtualResY = vmodule_rows * _panelResY; + + dmaResX = panelResX * vmodule_rows * vmodule_cols - 1; + + /* Virtual Display width() and height() will return a real-world value. For example: + * Virtual Display width: 128 + * Virtual Display height: 64 + * + * So, not values that at 0 to X-1 + */ + + coords.x = coords.y = -1; // By default use an invalid co-ordinates that will be rejected by updateMatrixDMABuffer + } + + // equivalent methods of the matrix library so it can be just swapped out. + void drawPixel(int16_t x, int16_t y, uint16_t color); // overwrite adafruit implementation + void fillScreen(uint16_t color); // overwrite adafruit implementation + void setRotation(uint8_t rotate); // overwrite adafruit implementation + + void fillScreenRGB888(uint8_t r, uint8_t g, uint8_t b); + void clearScreen() { display->clearScreen(); } + void drawPixelRGB888(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b); + +#ifdef USE_GFX_ROOT + // 24bpp FASTLED CRGB colour struct support + void fillScreen(CRGB color); + void drawPixel(int16_t x, int16_t y, CRGB color); +#endif + + uint16_t color444(uint8_t r, uint8_t g, uint8_t b) + { + return display->color444(r, g, b); + } + uint16_t color565(uint8_t r, uint8_t g, uint8_t b) { return display->color565(r, g, b); } + uint16_t color333(uint8_t r, uint8_t g, uint8_t b) { return display->color333(r, g, b); } + + void flipDMABuffer() { display->flipDMABuffer(); } + void drawDisplayTest(); + + void setPhysicalPanelScanRate(PANEL_SCAN_RATE rate); + void setZoomFactor(int scale); + +private: + MatrixPanel_I2S_DMA *display; + + PANEL_CHAIN_TYPE panel_chain_type; + PANEL_SCAN_RATE panel_scan_rate = NORMAL_TWO_SCAN; + + virtual VirtualCoords getCoords(int16_t x, int16_t y); + VirtualCoords coords; + + int16_t virtualResX; + int16_t virtualResY; + + int16_t _virtualResX; ///< Display width as modified by current rotation + int16_t _virtualResY; ///< Display height as modified by current rotation + + int16_t vmodule_rows; + int16_t vmodule_cols; + + int16_t panelResX; + int16_t panelResY; + + int16_t dmaResX; // The width of the chain in pixels (as the DMA engine sees it) + + int _rotate = 0; + + int _scale_factor = 0; + +}; // end Class header + +/** + * Calculate virtual->real co-ordinate mapping to underlying single chain of panels connected to ESP32. + * Updates the private class member variable 'coords', so no need to use the return value. + * Not thread safe, but not a concern for ESP32 sketch anyway... I think. + */ +inline VirtualCoords VirtualMatrixPanel::getCoords(int16_t virt_x, int16_t virt_y) +{ + +#if !defined NO_GFX + // I don't give any support if Adafruit GFX isn't being used. + + if (virt_x < 0 || virt_x >= _width || virt_y < 0 || virt_y >= _height) // _width and _height are defined in the adafruit constructor + { // Co-ordinates go from 0 to X-1 remember! otherwise they are out of range! + coords.x = coords.y = -1; // By defalt use an invalid co-ordinates that will be rejected by updateMatrixDMABuffer + return coords; + } +#else + + if (virt_x < 0 || virt_x >= _virtualResX || virt_y < 0 || virt_y >= _virtualResY) // _width and _height are defined in the adafruit constructor + { // Co-ordinates go from 0 to X-1 remember! otherwise they are out of range! + coords.x = coords.y = -1; // By defalt use an invalid co-ordinates that will be rejected by updateMatrixDMABuffer + return coords; + } + +#endif + + // Do we want to rotate? + switch (_rotate) { + case 0: //no rotation, do nothing + break; + + case (1): //90 degree rotation + { + int16_t temp_x = virt_x; + virt_x = virt_y; + virt_y = virtualResY - 1 - temp_x; + break; + } + + case (2): //180 rotation + { + virt_x = virtualResX - 1 - virt_x; + virt_y = virtualResY - 1 - virt_y; + break; + } + + case (3): //270 rotation + { + int16_t temp_x = virt_x; + virt_x = virtualResX - 1 - virt_y; + virt_y = temp_x; + break; + } + } + + int row = (virt_y / panelResY); // 0 indexed + switch (panel_chain_type) + { + case (CHAIN_TOP_RIGHT_DOWN): + { + if ((row % 2) == 1) + { // upside down panel + + // Serial.printf("Condition 1, row %d ", row); + + // reversed for the row + coords.x = dmaResX - virt_x - (row * virtualResX); + + // y co-ord inverted within the panel + coords.y = panelResY - 1 - (virt_y % panelResY); + } + else + { + // Serial.printf("Condition 2, row %d ", row); + coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x; + coords.y = (virt_y % panelResY); + } + } + break; + + case (CHAIN_TOP_RIGHT_DOWN_ZZ): + { + // Right side up. Starting from top right all the way down. + // Connected in a Zig Zag manner = some long ass cables being used potentially + + // Serial.printf("Condition 2, row %d ", row); + coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x; + coords.y = (virt_y % panelResY); + } + break; + + case (CHAIN_TOP_LEFT_DOWN): // OK -> modulus opposite of CHAIN_TOP_RIGHT_DOWN + { + if ((row % 2) == 0) + { // reversed panel + + // Serial.printf("Condition 1, row %d ", row); + coords.x = dmaResX - virt_x - (row * virtualResX); + + // y co-ord inverted within the panel + coords.y = panelResY - 1 - (virt_y % panelResY); + } + else + { + // Serial.printf("Condition 2, row %d ", row); + coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x; + coords.y = (virt_y % panelResY); + } + } + break; + + case (CHAIN_TOP_LEFT_DOWN_ZZ): + { + // Serial.printf("Condition 2, row %d ", row); + coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x; + coords.y = (virt_y % panelResY); + } + break; + + case (CHAIN_BOTTOM_LEFT_UP): // + { + row = vmodule_rows - row - 1; + + if ((row % 2) == 1) + { + // Serial.printf("Condition 1, row %d ", row); + coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x; + coords.y = (virt_y % panelResY); + } + else + { // inverted panel + + // Serial.printf("Condition 2, row %d ", row); + coords.x = dmaResX - (row * virtualResX) - virt_x; + coords.y = panelResY - 1 - (virt_y % panelResY); + } + } + break; + + case (CHAIN_BOTTOM_LEFT_UP_ZZ): // + { + row = vmodule_rows - row - 1; + // Serial.printf("Condition 1, row %d ", row); + coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x; + coords.y = (virt_y % panelResY); + } + break; + + case (CHAIN_BOTTOM_RIGHT_UP): // OK -> modulus opposite of CHAIN_BOTTOM_LEFT_UP + { + row = vmodule_rows - row - 1; + + if ((row % 2) == 0) + { // right side up + + // Serial.printf("Condition 1, row %d ", row); + // refersed for the row + coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x; + coords.y = (virt_y % panelResY); + } + else + { // inverted panel + + // Serial.printf("Condition 2, row %d ", row); + coords.x = dmaResX - (row * virtualResX) - virt_x; + coords.y = panelResY - 1 - (virt_y % panelResY); + } + } + break; + + case (CHAIN_BOTTOM_RIGHT_UP_ZZ): + { + // Right side up. Starting bottom right all the way up. + // Connected in a Zig Zag manner = some long ass cables being used potentially + + row = vmodule_rows - row - 1; + // Serial.printf("Condition 2, row %d ", row); + coords.x = ((vmodule_rows - (row + 1)) * virtualResX) + virt_x; + coords.y = (virt_y % panelResY); + } + break; + + // Q: 1 row!? Why? + // A: In cases people are only using virtual matrix panel for panels of non-standard scan rates. + default: + coords.x = virt_x; coords.y = virt_y; + break; + + } // end switch + + + /* START: Pixel remapping AGAIN to convert TWO parallel scanline output that the + * the underlying hardware library is designed for (because + * there's only 2 x RGB pins... and convert this to 1/4 or something + */ + + if ((panel_scan_rate == FOUR_SCAN_32PX_HIGH) || (panel_scan_rate == FOUR_SCAN_64PX_HIGH)) + { + + if (panel_scan_rate == FOUR_SCAN_64PX_HIGH) + { + // https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/issues/345#issuecomment-1510401192 + if ((virt_y & 8) != ((virt_y & 16) >> 1)) { virt_y = (virt_y & 0b11000) ^ 0b11000 + (virt_y & 0b11100111); } + } + + + /* Convert Real World 'VirtualMatrixPanel' co-ordinates (i.e. Real World pixel you're looking at + on the panel or chain of panels, per the chaining configuration) to a 1/8 panels + double 'stretched' and 'squished' coordinates which is what needs to be sent from the + DMA buffer. + + Note: Look at the FourScanPanel example code and you'll see that the DMA buffer is setup + as if the panel is 2 * W and 0.5 * H ! + */ + + if ((virt_y & 8) == 0) + { + coords.x += ((coords.x / panelResX) + 1) * panelResX; // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer + } + else + { + coords.x += (coords.x / panelResX) * panelResX; // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer + } + + // http://cpp.sh/4ak5u + // Real number of DMA y rows is half reality + // coords.y = (y / 16)*8 + (y & 0b00000111); + coords.y = (virt_y >> 4) * 8 + (virt_y & 0b00000111); + } + else if (panel_scan_rate == FOUR_SCAN_16PX_HIGH) + { + if ((virt_y & 8) == 0) + { + coords.x += (panelResX >> 2) * (((coords.x & 0xFFF0) >> 4) + 1); // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer + } + else + { + coords.x += (panelResX >> 2) * (((coords.x & 0xFFF0) >> 4)); // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer + } + + if (virt_y < 32) + coords.y = (virt_y >> 4) * 8 + (virt_y & 0b00000111); + else + { + coords.y = ((virt_y - 32) >> 4) * 8 + (virt_y & 0b00000111); + coords.x += 256; + } + } + + return coords; +} + +inline void VirtualMatrixPanel::drawPixel(int16_t x, int16_t y, uint16_t color) +{ // adafruit virtual void override + + if (_scale_factor > 1) // only from 2 and beyond + { + int16_t scaled_x_start_pos = x * _scale_factor; + int16_t scaled_y_start_pos = y * _scale_factor; + + for (int16_t x = 0; x < _scale_factor; x++) { + for (int16_t y = 0; y < _scale_factor; y++) { + VirtualCoords result = this->getCoords(scaled_x_start_pos+x, scaled_y_start_pos+y); + // Serial.printf("Requested virtual x,y coord (%d, %d), got phyical chain coord of (%d,%d)\n", x,y, coords.x, coords.y); + this->display->drawPixel(result.x, result.y, color); + } + } + } + else + { + this->getCoords(x, y); + // Serial.printf("Requested virtual x,y coord (%d, %d), got phyical chain coord of (%d,%d)\n", x,y, coords.x, coords.y); + this->display->drawPixel(coords.x, coords.y, color); + } +} + +inline void VirtualMatrixPanel::fillScreen(uint16_t color) +{ // adafruit virtual void override + this->display->fillScreen(color); +} + +inline void VirtualMatrixPanel::fillScreenRGB888(uint8_t r, uint8_t g, uint8_t b) +{ + this->display->fillScreenRGB888(r, g, b); +} + +inline void VirtualMatrixPanel::drawPixelRGB888(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b) +{ + this->getCoords(x, y); + this->display->drawPixelRGB888(coords.x, coords.y, r, g, b); +} + +#ifdef USE_GFX_ROOT +// Support for CRGB values provided via FastLED +inline void VirtualMatrixPanel::drawPixel(int16_t x, int16_t y, CRGB color) +{ + this->getCoords(x, y); + this->display->drawPixel(coords.x, coords.y, color); +} + +inline void VirtualMatrixPanel::fillScreen(CRGB color) +{ + this->display->fillScreen(color); +} +#endif + +inline void VirtualMatrixPanel::setRotation(uint8_t rotate) +{ + if(rotate < 4 && rotate >= 0) + _rotate = rotate; + + // Change the _width and _height variables used by the underlying adafruit gfx library. + // Actual pixel rotation / mapping is done in the getCoords function. + rotation = (rotate & 3); + switch (rotation) { + case 0: // nothing + case 2: // 180 + _virtualResX = virtualResX; + _virtualResY = virtualResY; + +#if !defined NO_GFX + _width = virtualResX; // adafruit base class + _height = virtualResY; // adafruit base class +#endif + break; + case 1: + case 3: + _virtualResX = virtualResY; + _virtualResY = virtualResX; + +#if !defined NO_GFX + _width = virtualResY; // adafruit base class + _height = virtualResX; // adafruit base class +#endif + break; + } + + +} + +inline void VirtualMatrixPanel::setPhysicalPanelScanRate(PANEL_SCAN_RATE rate) +{ + panel_scan_rate = rate; +} + +inline void VirtualMatrixPanel::setZoomFactor(int scale) +{ + if(scale < 5 && scale > 0) + _scale_factor = scale; + +} + +#ifndef NO_GFX +inline void VirtualMatrixPanel::drawDisplayTest() +{ + // Write to the underlying panels only via the dma_display instance. + this->display->setFont(&FreeSansBold12pt7b); + this->display->setTextColor(this->display->color565(255, 255, 0)); + this->display->setTextSize(1); + + for (int panel = 0; panel < vmodule_cols * vmodule_rows; panel++) + { + int top_left_x = (panel == 0) ? 0 : (panel * panelResX); + this->display->drawRect(top_left_x, 0, panelResX, panelResY, this->display->color565(0, 255, 0)); + this->display->setCursor((panel * panelResX) + 2, panelResY - 4); + this->display->print((vmodule_cols * vmodule_rows) - panel); + } +} +#endif + +/* +// need to recreate this one, as it wouldn't work to just map where it starts. +inline void VirtualMatrixPanel::drawIcon (int *ico, int16_t x, int16_t y, int16_t icon_cols, int16_t icon_rows) { + int i, j; + for (i = 0; i < icon_rows; i++) { + for (j = 0; j < icon_cols; j++) { + // This is a call to this libraries version of drawPixel + // which will map each pixel, which is what we want. + //drawPixelRGB565 (x + j, y + i, ico[i * module_cols + j]); + drawPixel (x + j, y + i, ico[i * icon_cols + j]); + } + } +} +*/ + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32/RGB_HUB75_PINS.png b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32/RGB_HUB75_PINS.png new file mode 100644 index 0000000..2dc609e Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32/RGB_HUB75_PINS.png differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32/esp32-default-pins.hpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32/esp32-default-pins.hpp new file mode 100644 index 0000000..5ee94b9 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32/esp32-default-pins.hpp @@ -0,0 +1,18 @@ +#pragma once + +#define R1_PIN_DEFAULT 25 +#define G1_PIN_DEFAULT 26 +#define B1_PIN_DEFAULT 27 +#define R2_PIN_DEFAULT 14 +#define G2_PIN_DEFAULT 12 +#define B2_PIN_DEFAULT 13 + +#define A_PIN_DEFAULT 23 +#define B_PIN_DEFAULT 19 +#define C_PIN_DEFAULT 5 +#define D_PIN_DEFAULT 17 +#define E_PIN_DEFAULT -1 // IMPORTANT: Change to a valid pin if using a 64x64px panel. + +#define LAT_PIN_DEFAULT 4 +#define OE_PIN_DEFAULT 15 +#define CLK_PIN_DEFAULT 16 diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32/esp32_i2s_parallel_dma.cpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32/esp32_i2s_parallel_dma.cpp new file mode 100644 index 0000000..e9d45d3 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32/esp32_i2s_parallel_dma.cpp @@ -0,0 +1,612 @@ +/*----------------------------------------------------------------------------/ + Lovyan GFX - Graphics library for embedded devices. + +Original Source: + https://github.com/lovyan03/LovyanGFX/ + +Licence: + [FreeBSD](https://github.com/lovyan03/LovyanGFX/blob/master/license.txt) + +Author: + [lovyan03](https://twitter.com/lovyan03) + +Contributors: + [ciniml](https://github.com/ciniml) + [mongonta0716](https://github.com/mongonta0716) + [tobozo](https://github.com/tobozo) + +Modified heavily for the ESP32 HUB75 DMA library by: + [mrfaptastic](https://github.com/mrfaptastic) + +/----------------------------------------------------------------------------*/ +#include +#if defined (CONFIG_IDF_TARGET_ESP32) || defined (CONFIG_IDF_TARGET_ESP32S2) + +#include "esp32_i2s_parallel_dma.hpp" + +#if defined (CONFIG_IDF_TARGET_ESP32S2) + #pragma message "Compiling for ESP32-S2" +#else + #pragma message "Compiling for original ESP32 (released 2016)" +#endif + +#include +#if (ESP_IDF_VERSION_MAJOR == 5) +#include +#else +#include +#endif +#include +#include //includes struct and reg + + +#if defined (ARDUINO_ARCH_ESP32) +#include +#endif + +#include +#include + +// Get CPU freq function. +#include + + + volatile bool previousBufferFree = true; + + static void IRAM_ATTR i2s_isr(void* arg) { + + // From original Sprite_TM Code + //REG_WRITE(I2S_INT_CLR_REG(1), (REG_READ(I2S_INT_RAW_REG(1)) & 0xffffffc0) | 0x3f); + + // Clear flag so we can get retriggered + SET_PERI_REG_BITS(I2S_INT_CLR_REG(ESP32_I2S_DEVICE), I2S_OUT_EOF_INT_CLR_V, 1, I2S_OUT_EOF_INT_CLR_S); + + // at this point, the previously active buffer is free, go ahead and write to it + previousBufferFree = true; + } + + bool DRAM_ATTR i2s_parallel_is_previous_buffer_free() { + return previousBufferFree; + } + + + // Static + i2s_dev_t* getDev() + { + #if defined (CONFIG_IDF_TARGET_ESP32S2) + return &I2S0; + #else + return (ESP32_I2S_DEVICE == 0) ? &I2S0 : &I2S1; + #endif + + } + + // Static + void _gpio_pin_init(int pin) + { + if (pin >= 0) + { + gpio_pad_select_gpio(pin); + //gpio_hi(pin); + gpio_set_direction((gpio_num_t)pin, GPIO_MODE_OUTPUT); + gpio_set_drive_capability((gpio_num_t)pin, (gpio_drive_cap_t)3); // esp32s3 as well? + } + } + + inline int i2s_parallel_get_memory_width(int port, int width) { + switch(width) { + case 8: + + #if !defined (CONFIG_IDF_TARGET_ESP32S2) + + // Only I2S1 on the legacy ESP32 WROOM MCU supports space saving single byte 8 bit parallel access + if(port == 1) + { + return 1; + } else { + return 2; + } + #else + return 1; + #endif + + case 16: + return 2; + case 24: + return 4; + default: + return -ESP_ERR_INVALID_ARG; + } + } + + + void Bus_Parallel16::config(const config_t& cfg) + { + ESP_LOGI("ESP32/S2", "Performing config for ESP32 or ESP32-S2"); + _cfg = cfg; + _dev = getDev(); + } + + bool Bus_Parallel16::init(void) // The big one that gets everything setup. + { + ESP_LOGI("ESP32/S2", "Performing DMA bus init() for ESP32 or ESP32-S2"); + + if(_cfg.parallel_width < 8 || _cfg.parallel_width >= 24) { + return false; + } + + auto dev = _dev; + volatile int iomux_signal_base; + volatile int iomux_clock; + int irq_source; + + // Initialize I2S0 peripheral + if (ESP32_I2S_DEVICE == I2S_NUM_0) + { + periph_module_reset(PERIPH_I2S0_MODULE); + periph_module_enable(PERIPH_I2S0_MODULE); + + iomux_clock = I2S0O_WS_OUT_IDX; + irq_source = ETS_I2S0_INTR_SOURCE; + + switch(_cfg.parallel_width) { + case 8: + case 16: + iomux_signal_base = I2S0O_DATA_OUT8_IDX; + break; + case 24: + iomux_signal_base = I2S0O_DATA_OUT0_IDX; + break; + default: + return ESP_ERR_INVALID_ARG; + } + } + + #if !defined (CONFIG_IDF_TARGET_ESP32S2) + // Can't compile if I2S1 if it doesn't exist with that hardware's IDF.... + else { + periph_module_reset(PERIPH_I2S1_MODULE); + periph_module_enable(PERIPH_I2S1_MODULE); + iomux_clock = I2S1O_WS_OUT_IDX; + irq_source = ETS_I2S1_INTR_SOURCE; + + switch(_cfg.parallel_width) { + case 16: + iomux_signal_base = I2S1O_DATA_OUT8_IDX; + break; + case 8: + case 24: + iomux_signal_base = I2S1O_DATA_OUT0_IDX; + break; + default: + return ESP_ERR_INVALID_ARG; + } + } + #endif + + // Setup GPIOs + int bus_width = _cfg.parallel_width; + + // Clock output GPIO setup + _gpio_pin_init(_cfg.pin_rd); // not used + _gpio_pin_init(_cfg.pin_wr); // clock + _gpio_pin_init(_cfg.pin_rs); // not used + + // Data output GPIO setup + int8_t* pins = _cfg.pin_data; + + for(int i = 0; i < bus_width; i++) + _gpio_pin_init(pins[i]); + + // Route clock signal to clock pin + gpio_matrix_out(_cfg.pin_wr, iomux_clock, _cfg.invert_pclk, 0); // inverst clock if required + + for (size_t i = 0; i < bus_width; i++) { + + if (pins[i] >= 0) { + gpio_matrix_out(pins[i], iomux_signal_base + i, false, false); + } + } + + ////////////////////////////// Clock configuration ////////////////////////////// + + unsigned int freq = (_cfg.bus_freq); + ESP_LOGD("ESP32/S2", "Requested output clock frequency: %u Mhz", (unsigned int)(freq/1000000)); + + // What is the current CPU frequency? + + // Calculate clock divider for ESP32-S2 + #if defined (CONFIG_IDF_TARGET_ESP32S2) + + // Right shift (>> 1) and divide 160mhz in half to 80Mhz for the calc due to the fact + // that later we must have tx_bck_div_num = 2 for both esp32 and esp32-s2 + + //static uint32_t pll_160M_clock_d2 = 160 * 1000 * 1000 >> 1; + + // I2S_CLKM_DIV_NUM 2=40MHz / 3=27MHz / 4=20MHz / 5=16MHz / 8=10MHz / 10=8MHz + //auto _div_num = std::min(255u, 1 + ((pll_160M_clock_d2) / (1 + freq))); + unsigned int _div_num = (unsigned int) (160000000L / freq / i2s_parallel_get_memory_width(ESP32_I2S_DEVICE, 16)); // 16 bits in parallel + + if(_div_num < 2 || _div_num > 0xFF) { + // return ESP_ERR_INVALID_ARG; + _div_num = 8; + } + + + ESP_LOGD("ESP32", "i2s pll_160M_clock_d2 clkm_div_num is: %u", _div_num); + + // I2S_CLK_SEL Set this bit to select I2S module clock source. + // 0: No clock. 1: APLL_CLK. 2: PLL_160M_CLK. 3: No clock. (R/W) + dev->clkm_conf.clk_sel = 2; + dev->clkm_conf.clkm_div_a = 1; // Clock denominator + dev->clkm_conf.clkm_div_b = 0; // Clock numerator + dev->clkm_conf.clkm_div_num = _div_num; + dev->clkm_conf.clk_en = 1; + + // Calc + unsigned int output_freq = (unsigned int)(160000000L/_div_num); + + // Calculate clock divider for Original ESP32 + #else + + // Note: clkm_div_num must only be set here AFTER clkm_div_b, clkm_div_a, etc. Or weird things happen! + // On original ESP32, max I2S DMA parallel speed is 20Mhz. + + // 160Mhz is only assured when the CPU clock is 240Mhz on the ESP32... + // [esp32-hal-cpu.c:244] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz + + //static uint32_t pll_d2_clock = (source_freq/2) * 1000 * 1000 >> 1; + + // I2S_CLKM_DIV_NUM 2=40MHz / 3=27MHz / 4=20MHz / 5=16MHz / 8=10MHz / 10=8MHz + //auto _div_num = std::min(255u, 1 + ((pll_d2_clock) / (1 + freq))); + + unsigned int _div_num = (unsigned int) (80000000L / freq / i2s_parallel_get_memory_width(ESP32_I2S_DEVICE, 16)); // 16 bits in parallel + if(_div_num < 2 || _div_num > 0xFF) { + // return ESP_ERR_INVALID_ARG; + _div_num = 4; + } + + ///auto _div_num = 80000000L/freq; + + ESP_LOGD("ESP32", "i2s pll_d2_clock clkm_div_num is: %u", _div_num); + + dev->clkm_conf.clka_en=1; // Use the 80mhz system clock (PLL_D2_CLK) when '0' + dev->clkm_conf.clkm_div_a = 1; // Clock denominator + dev->clkm_conf.clkm_div_b = 0; // Clock numerator + dev->clkm_conf.clkm_div_num = _div_num; + + unsigned int output_freq = (unsigned int)(80000000L/_div_num); + + #endif + + + output_freq = output_freq + 0; // work around arudino 'unused var' issue if debug isn't enabled. + ESP_LOGI("ESP32/S2", "Output frequency is %u Mhz??", (unsigned int)(output_freq/1000000/i2s_parallel_get_memory_width(ESP32_I2S_DEVICE, 16))); + + + // Setup i2s clock + dev->sample_rate_conf.val = 0; + + // Third stage config, width of data to be written to IO (I think this should always be the actual data width?) + dev->sample_rate_conf.rx_bits_mod = bus_width; + dev->sample_rate_conf.tx_bits_mod = bus_width; + + // Serial clock + // ESP32 and ESP32-S2 TRM clearly say that "Note that I2S_TX_BCK_DIV_NUM[5:0] must not be configured as 1." + dev->sample_rate_conf.rx_bck_div_num = 2; + dev->sample_rate_conf.tx_bck_div_num = 2; + + ////////////////////////////// END CLOCK CONFIGURATION ///////////////////////////////// + + // I2S conf2 reg + dev->conf2.val = 0; + dev->conf2.lcd_en = 1; + dev->conf2.lcd_tx_wrx2_en=0; + dev->conf2.lcd_tx_sdx2_en=0; + + // I2S conf reg + dev->conf.val = 0; + + #if defined (CONFIG_IDF_TARGET_ESP32S2) + dev->conf.tx_dma_equal=1; // esp32-s2 only + dev->conf.pre_req_en=1; // esp32-s2 only - enable I2S to prepare data earlier? wtf? + #endif + + // Now start setting up DMA FIFO + dev->fifo_conf.val = 0; + dev->fifo_conf.rx_data_num = 32; // Thresholds. + dev->fifo_conf.tx_data_num = 32; + dev->fifo_conf.dscr_en = 1; + + #if !defined (CONFIG_IDF_TARGET_ESP32S2) + + // Enable "One datum will be written twice in LCD mode" - for some reason, + // if we don't do this in 8-bit mode, data is updated on half-clocks not clocks + if(_cfg.parallel_width == 8) + dev->conf2.lcd_tx_wrx2_en=1; + + // Not really described for non-pcm modes, although datasheet states it should be set correctly even for LCD mode + // First stage config. Configures how data is loaded into fifo + if(_cfg.parallel_width == 24) { + // Mode 0, single 32-bit channel, linear 32 bit load to fifo + dev->fifo_conf.tx_fifo_mod = 3; + } else { + // Mode 1, single 16-bit channel, load 16 bit sample(*) into fifo and pad to 32 bit with zeros + // *Actually a 32 bit read where two samples are read at once. Length of fifo must thus still be word-aligned + dev->fifo_conf.tx_fifo_mod = 1; + } + + // Dictated by ESP32 datasheet + dev->fifo_conf.rx_fifo_mod_force_en = 1; + dev->fifo_conf.tx_fifo_mod_force_en = 1; + + // Second stage config + dev->conf_chan.val = 0; + + // 16-bit single channel data + dev->conf_chan.tx_chan_mod = 1; + dev->conf_chan.rx_chan_mod = 1; + + #endif + + // Reset FIFO + dev->conf.rx_fifo_reset = 1; + + #if defined (CONFIG_IDF_TARGET_ESP32S2) + while(dev->conf.rx_fifo_reset_st); // esp32-s2 only + #endif + + dev->conf.rx_fifo_reset = 0; + dev->conf.tx_fifo_reset = 1; + + #if defined (CONFIG_IDF_TARGET_ESP32S2) + while(dev->conf.tx_fifo_reset_st); // esp32-s2 only + #endif + dev->conf.tx_fifo_reset = 0; + + + // Reset DMA + dev->lc_conf.in_rst = 1; + dev->lc_conf.in_rst = 0; + dev->lc_conf.out_rst = 1; + dev->lc_conf.out_rst = 0; + + dev->lc_conf.ahbm_rst = 1; + dev->lc_conf.ahbm_rst = 0; + + dev->in_link.val = 0; + dev->out_link.val = 0; + + + // Device reset + dev->conf.rx_reset=1; + dev->conf.tx_reset=1; + dev->conf.rx_reset=0; + dev->conf.tx_reset=0; + + dev->conf1.val = 0; + dev->conf1.tx_stop_en = 0; + dev->timing.val = 0; + + + // If we have double buffering, then allocate an interrupt service routine function + // that can be used for I2S0/I2S1 created interrupts. + + // Setup I2S Interrupt + SET_PERI_REG_BITS(I2S_INT_ENA_REG(ESP32_I2S_DEVICE), I2S_OUT_EOF_INT_ENA_V, 1, I2S_OUT_EOF_INT_ENA_S); + + // Allocate a level 1 intterupt: lowest priority, as ISR isn't urgent and may take a long time to complete + esp_intr_alloc(irq_source, (int)(ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_LEVEL1), i2s_isr, NULL, NULL); + + + #if defined (CONFIG_IDF_TARGET_ESP32S2) + ESP_LOGD("ESP32-S2", "init() GPIO and clock configuration set for ESP32-S2"); + #else + ESP_LOGD("ESP32-ORIG", "init() GPIO and clock configuration set for ESP32"); + #endif + + return true; + } + + + void Bus_Parallel16::release(void) + { + if (_dmadesc_a) + { + heap_caps_free(_dmadesc_a); + _dmadesc_a = nullptr; + _dmadesc_count = 0; + } + + if (_dmadesc_b) + { + heap_caps_free(_dmadesc_b); + _dmadesc_b = nullptr; + _dmadesc_count = 0; + } + } + + void Bus_Parallel16::enable_double_dma_desc(void) + { + _double_dma_buffer = true; + } + + // Need this to work for double buffers etc. + bool Bus_Parallel16::allocate_dma_desc_memory(size_t len) + { + if (_dmadesc_a) heap_caps_free(_dmadesc_a); // free all dma descrptios previously + + _dmadesc_count = len; + _dmadesc_last = len-1; + + ESP_LOGI("ESP32/S2", "Allocating memory for %d DMA descriptors.", (int)len); + + _dmadesc_a= (HUB75_DMA_DESCRIPTOR_T*)heap_caps_malloc(sizeof(HUB75_DMA_DESCRIPTOR_T) * len, MALLOC_CAP_DMA); + + if (_dmadesc_a == nullptr) + { + ESP_LOGE("ESP32/S2", "ERROR: Couldn't malloc _dmadesc_a. Not enough memory."); + return false; + } + + + if (_double_dma_buffer) + { + if (_dmadesc_b) heap_caps_free(_dmadesc_b); // free all dma descrptios previously + + ESP_LOGD("ESP32/S2", "Allocating the second buffer (double buffer enabled)."); + + _dmadesc_b = (HUB75_DMA_DESCRIPTOR_T*)heap_caps_malloc(sizeof(HUB75_DMA_DESCRIPTOR_T) * len, MALLOC_CAP_DMA); + + if (_dmadesc_b == nullptr) + { + ESP_LOGE("ESP32/S2", "ERROR: Couldn't malloc _dmadesc_b. Not enough memory."); + _double_dma_buffer = false; + return false; + } + } + + _dmadesc_a_idx = 0; + _dmadesc_b_idx = 0; + + ESP_LOGD("ESP32/S2", "Allocating %d bytes of memory for DMA descriptors.", (int)sizeof(HUB75_DMA_DESCRIPTOR_T) * len); + + // New - Temporary blank descriptor for transitions between DMA buffer + _dmadesc_blank = (HUB75_DMA_DESCRIPTOR_T*)heap_caps_malloc(sizeof(HUB75_DMA_DESCRIPTOR_T) * 1, MALLOC_CAP_DMA); + _dmadesc_blank->size = 1024*2; + _dmadesc_blank->length = 1024*2; + _dmadesc_blank->buf = (uint8_t*) _blank_data; + _dmadesc_blank->eof = 1; + _dmadesc_blank->sosf = 0; + _dmadesc_blank->owner = 1; + _dmadesc_blank->qe.stqe_next = (lldesc_t*) _dmadesc_blank; + _dmadesc_blank->offset = 0; + + return true; + + } + + void Bus_Parallel16::create_dma_desc_link(void *data, size_t size, bool dmadesc_b) + { + static constexpr size_t MAX_DMA_LEN = (4096-4); + + if (size > MAX_DMA_LEN) + { + size = MAX_DMA_LEN; + ESP_LOGW("ESP32/S2", "Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!"); + } + + if ( !dmadesc_b ) + { + if ( (_dmadesc_a_idx+1) > _dmadesc_count) { + ESP_LOGE("ESP32/S2", "Attempted to create more DMA descriptors than allocated memory for. Expecting a maximum of %u DMA descriptors", (unsigned int)_dmadesc_count); + return; + } + } + + volatile lldesc_t *dmadesc; + volatile lldesc_t *next; + bool eof = false; + + if ( (dmadesc_b == true) ) // for primary buffer + { + dmadesc = &_dmadesc_b[_dmadesc_b_idx]; + + next = (_dmadesc_b_idx < (_dmadesc_last) ) ? &_dmadesc_b[_dmadesc_b_idx+1]:_dmadesc_b; + eof = (_dmadesc_b_idx == (_dmadesc_last)); + } + else + { + dmadesc = &_dmadesc_a[_dmadesc_a_idx]; + + // https://stackoverflow.com/questions/47170740/c-negative-array-index + next = (_dmadesc_a_idx < (_dmadesc_last) ) ? _dmadesc_a + _dmadesc_a_idx+1:_dmadesc_a; + eof = (_dmadesc_a_idx == (_dmadesc_last)); + } + + if ( _dmadesc_a_idx == (_dmadesc_last) ) { + ESP_LOGW("ESP32/S2", "Creating final DMA descriptor and linking back to 0."); + } + + dmadesc->size = size; + dmadesc->length = size; + dmadesc->buf = (uint8_t*) data; + dmadesc->eof = eof; + dmadesc->sosf = 0; + dmadesc->owner = 1; + dmadesc->qe.stqe_next = (lldesc_t*) next; + dmadesc->offset = 0; + + if ( (dmadesc_b == true) ) { // for primary buffer + _dmadesc_b_idx++; + } else { + _dmadesc_a_idx++; + } + + } // end create_dma_desc_link + + void Bus_Parallel16::dma_transfer_start() + { + auto dev = _dev; + + // Configure DMA burst mode + dev->lc_conf.val = I2S_OUT_DATA_BURST_EN | I2S_OUTDSCR_BURST_EN; + + // Set address of DMA descriptor, start with buffer 0 / 'a' + dev->out_link.addr = (uint32_t) _dmadesc_a; + + // Start DMA operation + dev->out_link.stop = 0; + dev->out_link.start = 1; + + dev->conf.tx_start = 1; + + + } // end + + + void Bus_Parallel16::dma_transfer_stop() + { + auto dev = _dev; + + // Stop all ongoing DMA operations + dev->out_link.stop = 1; + dev->out_link.start = 0; + dev->conf.tx_start = 0; + + } // end + + + void Bus_Parallel16::flip_dma_output_buffer(int buffer_id) // pass by reference so we can change in main matrixpanel class + { + + // Setup interrupt handler which is focussed only on the (page 322 of Tech. Ref. Manual) + // "I2S_OUT_EOF_INT: Triggered when rxlink has finished sending a packet" (when dma linked list with eof = 1 is hit) + + if ( buffer_id == 1) { + + _dmadesc_a[_dmadesc_last].qe.stqe_next = &_dmadesc_b[0]; // Start sending out _dmadesc_b (or buffer 1) + + //fix _dmadesc_ loop issue #407 + //need to connect the up comming _dmadesc_ not the old one + _dmadesc_b[_dmadesc_last].qe.stqe_next = &_dmadesc_b[0]; + + } else { + + _dmadesc_b[_dmadesc_last].qe.stqe_next = &_dmadesc_a[0]; + _dmadesc_a[_dmadesc_last].qe.stqe_next = &_dmadesc_a[0]; + + } + + previousBufferFree = false; + //while (i2s_parallel_is_previous_buffer_free() == false) {} + while (!previousBufferFree); + + + + + } // end flip + + + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32/esp32_i2s_parallel_dma.hpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32/esp32_i2s_parallel_dma.hpp new file mode 100644 index 0000000..7b9185f --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32/esp32_i2s_parallel_dma.hpp @@ -0,0 +1,161 @@ +/*----------------------------------------------------------------------------/ + Lovyan GFX - Graphics library for embedded devices. + +Original Source: + https://github.com/lovyan03/LovyanGFX/ + +Licence: + [FreeBSD](https://github.com/lovyan03/LovyanGFX/blob/master/license.txt) + +Author: + [lovyan03](https://twitter.com/lovyan03) + +Contributors: + [ciniml](https://github.com/ciniml) + [mongonta0716](https://github.com/mongonta0716) + [tobozo](https://github.com/tobozo) + + Modified heavily for the ESP32 HUB75 DMA library by: + [mrfaptastic](https://github.com/mrfaptastic) + +------------------------------------------------------------------------------ + + Putin’s Russia and its genocide in Ukraine is a disgrace to humanity. + + https://www.reddit.com/r/ukraine/comments/xfuc6v/more_than_460_graves_have_already_been_found_in/ + + Xi Jinping and his communist China’s silence on the war in Ukraine says everything about + how China condones such genocide, especially if it's against 'the west' (aka. decency). + + Whilst the good people at Espressif probably have nothing to do with this, the unfortunate + reality is libraries like this increase the popularity of Chinese silicon chips, which + indirectly funds (through CCP state taxes) the growth and empowerment of such a despot government. + + Global democracy, decency and security is put at risk with every Chinese silicon chip that is bought. + +/----------------------------------------------------------------------------*/ + +#pragma once + +#include // memcpy +#include +#include + +#include +#include +//#include +#include +#include +#if (ESP_IDF_VERSION_MAJOR == 5) +#include //includes struct and reg +#else +#include +#include +#endif + +#include //includes struct and reg + + +#define DMA_MAX (4096-4) + +// The type used for this SoC +#define HUB75_DMA_DESCRIPTOR_T lldesc_t + + +#if defined (CONFIG_IDF_TARGET_ESP32S2) +#define ESP32_I2S_DEVICE I2S_NUM_0 +#else +#define ESP32_I2S_DEVICE I2S_NUM_1 +#endif + +//---------------------------------------------------------------------------- + +void IRAM_ATTR irq_hndlr(void* arg); +i2s_dev_t* getDev(); + +//---------------------------------------------------------------------------- + + class Bus_Parallel16 + { + public: + Bus_Parallel16() + { + + } + + struct config_t + { + // max 20MHz (when in 16 bit / 2 byte mode) + uint32_t bus_freq = 10000000; + int8_t pin_wr = -1; // + int8_t pin_rd = -1; + int8_t pin_rs = -1; // D/C + bool invert_pclk = false; + int8_t parallel_width = 16; // do not change + union + { + int8_t pin_data[16]; + struct + { + int8_t pin_d0; + int8_t pin_d1; + int8_t pin_d2; + int8_t pin_d3; + int8_t pin_d4; + int8_t pin_d5; + int8_t pin_d6; + int8_t pin_d7; + int8_t pin_d8; + int8_t pin_d9; + int8_t pin_d10; + int8_t pin_d11; + int8_t pin_d12; + int8_t pin_d13; + int8_t pin_d14; + int8_t pin_d15; + }; + }; + }; + + const config_t& config(void) const { return _cfg; } + void config(const config_t& config); + + bool init(void) ; + void release(void) ; + + void enable_double_dma_desc(); + bool allocate_dma_desc_memory(size_t len); + + void create_dma_desc_link(void *memory, size_t size, bool dmadesc_b = false); + + void dma_transfer_start(); + void dma_transfer_stop(); + + void flip_dma_output_buffer(int buffer_id); + + private: + + void _init_pins() { }; + + config_t _cfg; + + bool _double_dma_buffer = false; + //bool _dmadesc_a_active = true; + + uint32_t _dmadesc_count = 0; // number of dma decriptors + uint32_t _dmadesc_last = 0; + + uint32_t _dmadesc_a_idx = 0; + uint32_t _dmadesc_b_idx = 0; + + HUB75_DMA_DESCRIPTOR_T* _dmadesc_a = nullptr; + HUB75_DMA_DESCRIPTOR_T* _dmadesc_b = nullptr; + + HUB75_DMA_DESCRIPTOR_T* _dmadesc_blank = nullptr; + uint16_t _blank_data[1024] = {0}; + + volatile i2s_dev_t* _dev; + + + + }; diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s2/esp32s2-default-pins.hpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s2/esp32s2-default-pins.hpp new file mode 100644 index 0000000..202b1c5 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s2/esp32s2-default-pins.hpp @@ -0,0 +1,16 @@ +#pragma once + +#define R1_PIN_DEFAULT 45 +#define G1_PIN_DEFAULT 42 +#define B1_PIN_DEFAULT 41 +#define R2_PIN_DEFAULT 40 +#define G2_PIN_DEFAULT 39 +#define B2_PIN_DEFAULT 38 +#define A_PIN_DEFAULT 37 +#define B_PIN_DEFAULT 36 +#define C_PIN_DEFAULT 35 +#define D_PIN_DEFAULT 34 +#define E_PIN_DEFAULT -1 // required for 1/32 scan panels, like 64x64. Any available pin would do, i.e. IO32 +#define LAT_PIN_DEFAULT 26 +#define OE_PIN_DEFAULT 21 +#define CLK_PIN_DEFAULT 33 diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/ESP32-S3-DevKitC-1-pin-layout.png b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/ESP32-S3-DevKitC-1-pin-layout.png new file mode 100644 index 0000000..c4391b3 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/ESP32-S3-DevKitC-1-pin-layout.png differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/Readme.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/Readme.md new file mode 100644 index 0000000..29cfbd3 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/Readme.md @@ -0,0 +1,24 @@ +https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/external-ram.html + +Restrictions + +External RAM use has the following restrictions: + +When flash cache is disabled (for example, if the flash is being written to), the external RAM also becomes inaccessible; any reads from or writes to it will lead to an illegal cache access exception. This is also the reason why ESP-IDF does not by default allocate any task stacks in external RAM (see below). + + External RAM cannot be used as a place to store DMA transaction descriptors or as a buffer for a DMA transfer to read from or write into. Therefore when External RAM is enabled, any buffer that will be used in combination with DMA must be allocated using heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL) and can be freed using a standard free() call. + +*Note, although ESP32-S3 has hardware support for DMA to/from external RAM, this is not yet supported in ESP-IDF.* + +External RAM uses the same cache region as the external flash. This means that frequently accessed variables in external RAM can be read and modified almost as quickly as in internal ram. However, when accessing large chunks of data (>32 KB), the cache can be insufficient, and speeds will fall back to the access speed of the external RAM. Moreover, accessing large chunks of data can “push out” cached flash, possibly making the execution of code slower afterwards. + +In general, external RAM will not be used as task stack memory. xTaskCreate() and similar functions will always allocate internal memory for stack and task TCBs. + +Reserved Pins on ESP32-S3: + +![Reserved Pins](ReservedPinsForPSRAM.PNG) + +Devkit Layout: + +![ESP32-S3 DevKit layout](ESP32-S3-DevKitC-1-pin-layout.png) + diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/ReservedPinsForPSRAM.PNG b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/ReservedPinsForPSRAM.PNG new file mode 100644 index 0000000..994fda8 Binary files /dev/null and b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/ReservedPinsForPSRAM.PNG differ diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/esp32s3-default-pins.hpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/esp32s3-default-pins.hpp new file mode 100644 index 0000000..57d8aae --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/esp32s3-default-pins.hpp @@ -0,0 +1,18 @@ +#pragma once + +// Avoid and QSPI pins + +#define R1_PIN_DEFAULT 4 +#define G1_PIN_DEFAULT 5 +#define B1_PIN_DEFAULT 6 +#define R2_PIN_DEFAULT 7 +#define G2_PIN_DEFAULT 15 +#define B2_PIN_DEFAULT 16 +#define A_PIN_DEFAULT 18 +#define B_PIN_DEFAULT 8 +#define C_PIN_DEFAULT 3 +#define D_PIN_DEFAULT 42 +#define E_PIN_DEFAULT -1 // required for 1/32 scan panels, like 64x64. Any available pin would do, i.e. IO32 +#define LAT_PIN_DEFAULT 40 +#define OE_PIN_DEFAULT 2 +#define CLK_PIN_DEFAULT 41 diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/gdma_lcd_parallel16.cpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/gdma_lcd_parallel16.cpp new file mode 100644 index 0000000..7bb390d --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/gdma_lcd_parallel16.cpp @@ -0,0 +1,450 @@ +/********************************************************************************************* + Simple example of using the ESP32-S3's LCD peripheral for general-purpose + (non-LCD) parallel data output with DMA. Connect 8 LEDs (or logic analyzer), + cycles through a pattern among them at about 1 Hz. + This code is ONLY for the ESP32-S3, NOT the S2, C3 or original ESP32. + None of this is authoritative canon, just a lot of trial error w/datasheet + and register poking. Probably more robust ways of doing this still TBD. + + + FULL CREDIT goes to AdaFruit and https://github.com/PaintYourDragon + + https://blog.adafruit.com/2022/06/21/esp32uesday-more-s3-lcd-peripheral-hacking-with-code/ + + https://github.com/adafruit/Adafruit_Protomatter/blob/master/src/arch/esp32-s3.h + + PLEASE SUPPORT THEM! + + ********************************************************************************************/ +#if __has_include () +// Stop compile errors: /src/platforms/esp32s3/gdma_lcd_parallel16.hpp:64:10: fatal error: hal/lcd_ll.h: No such file or directory + #pragma message "Compiling for ESP32-S3" + + #ifdef ARDUINO_ARCH_ESP32 + #include + #endif + + #include "gdma_lcd_parallel16.hpp" + #include "esp_attr.h" + +/* + dma_descriptor_t desc; // DMA descriptor for testing + + uint8_t data[8][312]; // Transmit buffer (2496 bytes total) + uint16_t* dmabuff2; +*/ + + DRAM_ATTR volatile bool previousBufferFree = true; + + // End-of-DMA-transfer callback + IRAM_ATTR bool gdma_on_trans_eof_callback(gdma_channel_handle_t dma_chan, + gdma_event_data_t *event_data, void *user_data) { + + // This DMA callback seems to trigger a moment before the last data has + // issued (buffering between DMA & LCD peripheral?), so pause a moment + // before stopping LCD data out. The ideal delay may depend on the LCD + // clock rate...this one was determined empirically by monitoring on a + // logic analyzer. YMMV. + esp_rom_delay_us(100); + // The LCD peripheral stops transmitting at the end of the DMA xfer, but + // clear the lcd_start flag anyway -- we poll it in loop() to decide when + // the transfer has finished, and the same flag is set later to trigger + // the next transfer. + + //LCD_CAM.lcd_user.lcd_start = 0; + + previousBufferFree = true; + + return true; + } + + lcd_cam_dev_t* getDev() + { + return &LCD_CAM; + } + + // ------------------------------------------------------------------------------ + + void Bus_Parallel16::config(const config_t& cfg) + { + _cfg = cfg; + //auto port = cfg.port; + _dev = getDev(); + } + + + //https://github.com/adafruit/Adafruit_Protomatter/blob/master/src/arch/esp32-s3.h + bool Bus_Parallel16::init(void) + { + ///dmabuff2 = (uint16_t*)heap_caps_malloc(sizeof(uint16_t) * 64*32, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + + // LCD_CAM peripheral isn't enabled by default -- MUST begin with this: + periph_module_enable(PERIPH_LCD_CAM_MODULE); + periph_module_reset(PERIPH_LCD_CAM_MODULE); + + // Reset LCD bus + LCD_CAM.lcd_user.lcd_reset = 1; + esp_rom_delay_us(1000); + +// uint32_t lcd_clkm_div_num = ((160000000 + 1) / _cfg.bus_freq); +// ESP_LOGI("", "Clock divider is %d", lcd_clkm_div_num); + + // Configure LCD clock. Since this program generates human-perceptible + // output and not data for LED matrices or NeoPixels, use almost the + // slowest LCD clock rate possible. The S3-mini module used on Feather + // ESP32-S3 has a 40 MHz crystal. A 2-stage clock division of 1:16000 + // is applied (250*64), yielding 2,500 Hz. Still much too fast for + // human eyes, so later we set up the data to repeat each output byte + // many times over. + //LCD_CAM.lcd_clock.clk_en = 0; // Enable peripheral clock + + // LCD_CAM_LCD_CLK_SEL Select LCD module source clock. 0: clock source is disabled. 1: XTAL_CLK. 2: PLL_D2_CLK. 3: PLL_F160M_CLK. (R/W) + LCD_CAM.lcd_clock.lcd_clk_sel = 3; // Use 160Mhz Clock Source + + LCD_CAM.lcd_clock.lcd_ck_out_edge = 0; // PCLK low in 1st half cycle + LCD_CAM.lcd_clock.lcd_ck_idle_edge = 0; // PCLK low idle + + LCD_CAM.lcd_clock.lcd_clkcnt_n = 1; // Should never be zero + + //LCD_CAM.lcd_clock.lcd_clk_equ_sysclk = 0; // PCLK = CLK / (CLKCNT_N+1) + LCD_CAM.lcd_clock.lcd_clk_equ_sysclk = 1; // PCLK = CLK / 1 (... so 160Mhz still) + + + // https://esp32.com/viewtopic.php?f=5&t=24459&start=80#p94487 + /* Re: ESP32-S3 LCD and I2S FULL documentation + * by ESP_Sprite » Fri Mar 25, 2022 2:06 am + * + * Are you sure you are staying within the limits of the psram throughput? If GDMA can't fetch data fast + * enough it leads to corruption. Also keep in mind that worst case scenario, the gdma can only use half of + * the bandwidth of the psram peripheral (as it's round-robin shared with the CPUs). + */ + + // Fastest speed I can get with Octoal PSRAM to work before nothing shows. Based on manual testing. + // If using an ESP32-S3 with slower (half the bandwidth) Q-SPI (Quad), then the divisor will need to be '20' (8Mhz) which wil be flickery! + if (_cfg.psram_clk_override) + { + ESP_LOGI("S3", "DMA buffer is on PSRAM. Limiting clockspeed...."); + //LCD_CAM.lcd_clock.lcd_clkm_div_num = 10; //16mhz is the fasted the Octal PSRAM can support it seems from faptastic's testing using an N8R8 variant (Octal SPI PSRAM). + + // https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA/issues/441#issuecomment-1513631890 + LCD_CAM.lcd_clock.lcd_clkm_div_num = 12; // 13Mhz is the fastest when the DMA memory is needed to service other peripherals as well. + } + else + { + + auto freq = (_cfg.bus_freq); + + auto _div_num = 8; // 20Mhz + if (freq < 20000000L) { + _div_num = 12; // 13Mhz + } + else if (freq > 20000000L) { + _div_num = 6; // 26Mhz --- likely to have noise without a good connection + } + + //LCD_CAM.lcd_clock.lcd_clkm_div_num = lcd_clkm_div_num; + LCD_CAM.lcd_clock.lcd_clkm_div_num = _div_num; //3; + + } + + ESP_LOGI("S3", "Clock divider is %d", (int)LCD_CAM.lcd_clock.lcd_clkm_div_num); + ESP_LOGD("S3", "Resulting output clock frequency: %d Mhz", (int)(160000000L/LCD_CAM.lcd_clock.lcd_clkm_div_num)); + + + LCD_CAM.lcd_clock.lcd_clkm_div_a = 1; // 0/1 fractional divide + LCD_CAM.lcd_clock.lcd_clkm_div_b = 0; + + // See section 26.3.3.1 of the ESP32­S3 Technical Reference Manual + // for information on other clock sources and dividers. + + // Configure LCD frame format. This is where we fiddle the peripheral + // to provide generic 8-bit output rather than actually driving an LCD. + // There's also a 16-bit mode but that's not shown here. + LCD_CAM.lcd_ctrl.lcd_rgb_mode_en = 0; // i8080 mode (not RGB) + LCD_CAM.lcd_rgb_yuv.lcd_conv_bypass = 0; // Disable RGB/YUV converter + LCD_CAM.lcd_misc.lcd_next_frame_en = 0; // Do NOT auto-frame + + LCD_CAM.lcd_misc.lcd_bk_en = 1; // https://esp32.com/viewtopic.php?t=24459&start=60#p91835 + + LCD_CAM.lcd_data_dout_mode.val = 0; // No data delays + LCD_CAM.lcd_user.lcd_always_out_en = 1; // Enable 'always out' mode + LCD_CAM.lcd_user.lcd_8bits_order = 0; // Do not swap bytes + LCD_CAM.lcd_user.lcd_bit_order = 0; // Do not reverse bit order + LCD_CAM.lcd_user.lcd_2byte_en = 1; // 8-bit data mode + LCD_CAM.lcd_user.lcd_dummy = 1; // Dummy phase(s) @ LCD start + LCD_CAM.lcd_user.lcd_dummy_cyclelen = 1; // 1+1 dummy phase + LCD_CAM.lcd_user.lcd_cmd = 0; // No command at LCD start + // "Dummy phases" are initial LCD peripheral clock cycles before data + // begins transmitting when requested. After much testing, determined + // that at least one dummy phase MUST be enabled for DMA to trigger + // reliably. A problem with dummy phase(s) is if we're also using the + // LCD_PCLK_IDX signal (not used in this code, but Adafruit_Protomatter + // does)...the clock signal will start a couple of pulses before data, + // which may or may not be problematic in some situations. You can + // disable the dummy phase but need to keep the LCD TX FIFO primed + // in that case, which gets complex. + // always_out_en is set above to allow aribtrary-length transfers, + // else lcd_dout_cyclelen is used...but is limited to 8K. Long (>4K) + // transfers need DMA linked lists, not used here but mentioned later. + + // Route 8 LCD data signals to GPIO pins + int8_t* pins = _cfg.pin_data; + + for(int i = 0; i < 16; i++) + { + if (pins[i] >= 0) { // -1 value will CRASH the ESP32! + esp_rom_gpio_connect_out_signal(pins[i], LCD_DATA_OUT0_IDX + i, false, false); + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[pins[i]], PIN_FUNC_GPIO); + gpio_set_drive_capability((gpio_num_t)pins[i], (gpio_drive_cap_t)3); + } + } + + /* + const struct { + int8_t pin; + uint8_t signal; + } mux[] = { + { 43, LCD_DATA_OUT0_IDX }, // These are 8 consecutive pins down one + { 42, LCD_DATA_OUT1_IDX }, // side of the ESP32-S3 Feather. The ESP32 + { 2, LCD_DATA_OUT2_IDX }, // has super flexible pin MUX capabilities, + { 9, LCD_DATA_OUT3_IDX }, // so any signal can go to any pin! + { 10, LCD_DATA_OUT4_IDX }, + { 11, LCD_DATA_OUT5_IDX }, + { 12, LCD_DATA_OUT6_IDX }, + { 13, LCD_DATA_OUT7_IDX }, + }; + for (int i = 0; i < 8; i++) { + esp_rom_gpio_connect_out_signal(mux[i].pin, LCD_DATA_OUT0_IDX + i, false, false); + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[mux[i].pin], PIN_FUNC_GPIO); + gpio_set_drive_capability((gpio_num_t)mux[i].pin, (gpio_drive_cap_t)3); + } +*/ + // Clock + esp_rom_gpio_connect_out_signal(_cfg.pin_wr, LCD_PCLK_IDX, _cfg.invert_pclk, false); + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[_cfg.pin_wr], PIN_FUNC_GPIO); + gpio_set_drive_capability((gpio_num_t)_cfg.pin_wr, (gpio_drive_cap_t)3); + + // This program has a known fixed-size data buffer (2496 bytes) that fits + // in a single DMA descriptor (max 4095 bytes). Large transfers would + // require a linked list of descriptors, but here it's just one... + +/* + desc.dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; + desc.dw0.suc_eof = 0; // Last descriptor + desc.next = &desc; // No linked list +*/ + + // Remaining descriptor elements are initialized before each DMA transfer. + + // Allocate DMA channel and connect it to the LCD peripheral + static gdma_channel_alloc_config_t dma_chan_config = { + .sibling_chan = NULL, + .direction = GDMA_CHANNEL_DIRECTION_TX, + .flags = { + .reserve_sibling = 0 + } + }; + gdma_new_channel(&dma_chan_config, &dma_chan); + gdma_connect(dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_LCD, 0)); + static gdma_strategy_config_t strategy_config = { + .owner_check = false, + .auto_update_desc = false + }; + gdma_apply_strategy(dma_chan, &strategy_config); + + gdma_transfer_ability_t ability = { + .sram_trans_align = 32, + .psram_trans_align = 64, + }; + gdma_set_transfer_ability(dma_chan, &ability); + + // Enable DMA transfer callback + static gdma_tx_event_callbacks_t tx_cbs = { + // .on_trans_eof is literally the only gdma tx event type available + .on_trans_eof = gdma_on_trans_eof_callback + }; + gdma_register_tx_event_callbacks(dma_chan, &tx_cbs, NULL); + + + // This uses a busy loop to wait for each DMA transfer to complete... + // but the whole point of DMA is that one's code can do other work in + // the interim. The CPU is totally free while the transfer runs! + while (LCD_CAM.lcd_user.lcd_start); // Wait for DMA completion callback + + // After much experimentation, each of these steps is required to get + // a clean start on the next LCD transfer: + gdma_reset(dma_chan); // Reset DMA to known state + esp_rom_delay_us(1000); + + LCD_CAM.lcd_user.lcd_dout = 1; // Enable data out + LCD_CAM.lcd_user.lcd_update = 1; // Update registers + LCD_CAM.lcd_misc.lcd_afifo_reset = 1; // Reset LCD TX FIFO + + + return true; // no return val = illegal instruction + } + + + void Bus_Parallel16::release(void) + { + if (_i80_bus) + { + esp_lcd_del_i80_bus(_i80_bus); + } + if (_dmadesc_a) + { + heap_caps_free(_dmadesc_a); + _dmadesc_a = nullptr; + _dmadesc_count = 0; + } + + } + + void Bus_Parallel16::enable_double_dma_desc(void) + { + ESP_LOGI("S3", "Enabled support for secondary DMA buffer."); + _double_dma_buffer = true; + } + + // Need this to work for double buffers etc. + bool Bus_Parallel16::allocate_dma_desc_memory(size_t len) + { + if (_dmadesc_a) heap_caps_free(_dmadesc_a); // free all dma descrptios previously + _dmadesc_count = len; + + ESP_LOGD("S3", "Allocating %d bytes memory for DMA descriptors.", (int)sizeof(HUB75_DMA_DESCRIPTOR_T) * len); + + _dmadesc_a= (HUB75_DMA_DESCRIPTOR_T*)heap_caps_malloc(sizeof(HUB75_DMA_DESCRIPTOR_T) * len, MALLOC_CAP_DMA); + + if (_dmadesc_a == nullptr) + { + ESP_LOGE("S3", "ERROR: Couldn't malloc _dmadesc_a. Not enough memory."); + return false; + } + + if (_double_dma_buffer) + { + _dmadesc_b= (HUB75_DMA_DESCRIPTOR_T*)heap_caps_malloc(sizeof(HUB75_DMA_DESCRIPTOR_T) * len, MALLOC_CAP_DMA); + + if (_dmadesc_b == nullptr) + { + ESP_LOGE("S3", "ERROR: Couldn't malloc _dmadesc_b. Not enough memory."); + _double_dma_buffer = false; + } + } + + /// override static + _dmadesc_a_idx = 0; + _dmadesc_b_idx = 0; + + return true; + + } + + void Bus_Parallel16::create_dma_desc_link(void *data, size_t size, bool dmadesc_b) + { + static constexpr size_t MAX_DMA_LEN = (4096-4); + + if (size > MAX_DMA_LEN) { + size = MAX_DMA_LEN; + ESP_LOGW("S3", "Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!"); + } + + if ( dmadesc_b == true) + { + + _dmadesc_b[_dmadesc_b_idx].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; + //_dmadesc_b[_dmadesc_b_idx].dw0.suc_eof = 0; + _dmadesc_b[_dmadesc_b_idx].dw0.suc_eof = (_dmadesc_b_idx == (_dmadesc_count-1)); + _dmadesc_b[_dmadesc_b_idx].dw0.size = _dmadesc_b[_dmadesc_b_idx].dw0.length = size; //sizeof(data); + _dmadesc_b[_dmadesc_b_idx].buffer = data; //data; + + if (_dmadesc_b_idx == _dmadesc_count-1) { + _dmadesc_b[_dmadesc_b_idx].next = (dma_descriptor_t *) &_dmadesc_b[0]; + } + else { + _dmadesc_b[_dmadesc_b_idx].next = (dma_descriptor_t *) &_dmadesc_b[_dmadesc_b_idx+1]; + } + + _dmadesc_b_idx++; + + + } + else + { + + if ( _dmadesc_a_idx >= _dmadesc_count) + { + ESP_LOGE("S3", "Attempted to create more DMA descriptors than allocated. Expecting max %u descriptors.", (unsigned int)_dmadesc_count); + return; + } + + _dmadesc_a[_dmadesc_a_idx].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; + //_dmadesc_a[_dmadesc_a_idx].dw0.suc_eof = 0; + _dmadesc_a[_dmadesc_a_idx].dw0.suc_eof = (_dmadesc_a_idx == (_dmadesc_count-1)); + _dmadesc_a[_dmadesc_a_idx].dw0.size = _dmadesc_a[_dmadesc_a_idx].dw0.length = size; //sizeof(data); + _dmadesc_a[_dmadesc_a_idx].buffer = data; //data; + + if (_dmadesc_a_idx == _dmadesc_count-1) { + _dmadesc_a[_dmadesc_a_idx].next = (dma_descriptor_t *) &_dmadesc_a[0]; + } + else { + _dmadesc_a[_dmadesc_a_idx].next = (dma_descriptor_t *) &_dmadesc_a[_dmadesc_a_idx+1]; + } + + _dmadesc_a_idx++; + + + } + + } // end create_dma_desc_link + + void Bus_Parallel16::dma_transfer_start() + { + gdma_start(dma_chan, (intptr_t)&_dmadesc_a[0]); // Start DMA w/updated descriptor(s) + esp_rom_delay_us(100); // Must 'bake' a moment before... + LCD_CAM.lcd_user.lcd_start = 1; // Trigger LCD DMA transfer + + } // end + + void Bus_Parallel16::dma_transfer_stop() + { + + LCD_CAM.lcd_user.lcd_reset = 1; // Trigger LCD DMA transfer + LCD_CAM.lcd_user.lcd_update = 1; // Trigger LCD DMA transfer + + gdma_stop(dma_chan); + + } // end + + + void Bus_Parallel16::flip_dma_output_buffer(int back_buffer_id) + { + + // if ( _double_dma_buffer == false) return; + + if ( back_buffer_id == 1) // change across to everything 'b'' + { + _dmadesc_a[_dmadesc_count-1].next = (dma_descriptor_t *) &_dmadesc_b[0]; + _dmadesc_b[_dmadesc_count-1].next = (dma_descriptor_t *) &_dmadesc_b[0]; + } + else + { + _dmadesc_b[_dmadesc_count-1].next = (dma_descriptor_t *) &_dmadesc_a[0]; + _dmadesc_a[_dmadesc_count-1].next = (dma_descriptor_t *) &_dmadesc_a[0]; + } + + //current_back_buffer_id ^= 1; + + previousBufferFree = false; + + //while (i2s_parallel_is_previous_buffer_free() == false) {} + while (!previousBufferFree); + + + + + } // end flip + + +#endif diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/gdma_lcd_parallel16.hpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/gdma_lcd_parallel16.hpp new file mode 100644 index 0000000..9324c30 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/esp32s3/gdma_lcd_parallel16.hpp @@ -0,0 +1,178 @@ +/* + Simple example of using the ESP32-S3's LCD peripheral for general-purpose + (non-LCD) parallel data output with DMA. Connect 8 LEDs (or logic analyzer), + cycles through a pattern among them at about 1 Hz. + This code is ONLY for the ESP32-S3, NOT the S2, C3 or original ESP32. + None of this is authoritative canon, just a lot of trial error w/datasheet + and register poking. Probably more robust ways of doing this still TBD. + + + FULL CREDIT goes to AdaFruit + + https://blog.adafruit.com/2022/06/21/esp32uesday-more-s3-lcd-peripheral-hacking-with-code/ + + PLEASE SUPPORT THEM! + + + Putin’s Russia and its genocide in Ukraine is a disgrace to humanity. + + https://www.reddit.com/r/ukraine/comments/xfuc6v/more_than_460_graves_have_already_been_found_in/ + + +/---------------------------------------------------------------------------- + +*/ + +#pragma once + +#if __has_include () + +#include +#include + +//#include +#include + +#include +#include + +#include +#include + + +#include +#include + + + +#include +#include + +#include + +/* +#if (ESP_IDF_VERSION_MAJOR == 5) +#include +#else +#include +#endif +*/ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + + +#if __has_include () + #include +#else + #include +#endif + +#if __has_include() + #include +#endif + +#define DMA_MAX (4096-4) + +// The type used for this SoC +#define HUB75_DMA_DESCRIPTOR_T dma_descriptor_t + + +//---------------------------------------------------------------------------- + + class Bus_Parallel16 + { + public: + Bus_Parallel16() + { + + } + + struct config_t + { + // LCD_CAM peripheral number. No need to change (only 0 for ESP32-S3.) + //int port = 0; + + // max 40MHz (when in 16 bit / 2 byte mode) + uint32_t bus_freq = 10000000; + int8_t pin_wr = -1; + int8_t pin_rd = -1; + int8_t pin_rs = -1; // D/C + bool invert_pclk = false; + bool psram_clk_override = false; + union + { + int8_t pin_data[16]; + struct + { + int8_t pin_d0; + int8_t pin_d1; + int8_t pin_d2; + int8_t pin_d3; + int8_t pin_d4; + int8_t pin_d5; + int8_t pin_d6; + int8_t pin_d7; + int8_t pin_d8; + int8_t pin_d9; + int8_t pin_d10; + int8_t pin_d11; + int8_t pin_d12; + int8_t pin_d13; + int8_t pin_d14; + int8_t pin_d15; + }; + }; + }; + + const config_t& config(void) const { return _cfg; } + void config(const config_t& config); + + bool init(void) ; + + void release(void) ; + + void enable_double_dma_desc(); + bool allocate_dma_desc_memory(size_t len); + + void create_dma_desc_link(void *memory, size_t size, bool dmadesc_b = false); + + void dma_transfer_start(); + void dma_transfer_stop(); + + void flip_dma_output_buffer(int back_buffer_id); + + private: + + config_t _cfg; + + volatile lcd_cam_dev_t* _dev; + gdma_channel_handle_t dma_chan; + + uint32_t _dmadesc_count = 0; // number of dma decriptors + + uint32_t _dmadesc_a_idx = 0; + uint32_t _dmadesc_b_idx = 0; + + HUB75_DMA_DESCRIPTOR_T* _dmadesc_a = nullptr; + HUB75_DMA_DESCRIPTOR_T* _dmadesc_b = nullptr; + + bool _double_dma_buffer = false; + //bool _dmadesc_a_active = true; + + esp_lcd_i80_bus_handle_t _i80_bus; + + + }; + + +#endif \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/platform_detect.hpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/platform_detect.hpp new file mode 100644 index 0000000..9532c88 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/src/platforms/platform_detect.hpp @@ -0,0 +1,73 @@ +/*----------------------------------------------------------------------------/ +Original Source: + https://github.com/lovyan03/LovyanGFX/ + +Licence: + [FreeBSD](https://github.com/lovyan03/LovyanGFX/blob/master/license.txt) + +Author: + [lovyan03](https://twitter.com/lovyan03) + +Contributors: + [ciniml](https://github.com/ciniml) + [mongonta0716](https://github.com/mongonta0716) + [tobozo](https://github.com/tobozo) + +Modified heavily for the ESP32 HUB75 DMA library by: + [mrfaptastic](https://github.com/mrfaptastic) +/----------------------------------------------------------------------------*/ +#pragma once + +#if defined (ESP_PLATFORM) + + #include + + #if defined (CONFIG_IDF_TARGET_ESP32C3) + + #error "ERROR: ESP32C3 not supported." + + #elif defined (CONFIG_IDF_TARGET_ESP32S2) + + //#pragma message "Compiling for ESP32-S2" + #include "esp32/esp32_i2s_parallel_dma.hpp" + #include "esp32s2/esp32s2-default-pins.hpp" + + + #elif defined (CONFIG_IDF_TARGET_ESP32S3) + + //#pragma message "Compiling for ESP32-S3" + #include "esp32s3/gdma_lcd_parallel16.hpp" + #include "esp32s3/esp32s3-default-pins.hpp" + + #if defined(SPIRAM_FRAMEBUFFER) && defined (CONFIG_IDF_TARGET_ESP32S3) + #pragma message "Enabling use of PSRAM/SPIRAM based DMA Buffer" + #define SPIRAM_DMA_BUFFER 1 + + // Disable fast functions because I don't understand the interaction with DMA PSRAM and the CPU->DMA->SPIRAM Cache implications.. + #define NO_FAST_FUNCTIONS 1 + #endif + + #elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32H2) + + #error "ESP32 RISC-V devices do not have an LCD interface and are therefore not supported by this library." + + #elif defined (CONFIG_IDF_TARGET_ESP32) || defined(ESP32) + + // Assume an ESP32 (the original 2015 version) + // Same include as ESP32S3 + //#pragma message "Compiling for original ESP32 (released 2016)" + + #define ESP32_THE_ORIG 1 + //#include "esp32/esp32_i2s_parallel_dma.hpp" + //#include "esp32/esp32_i2s_parallel_dma.h" + #include "esp32/esp32_i2s_parallel_dma.hpp" + #include "esp32/esp32-default-pins.hpp" + + #else + #error "Unknown platform." + + #endif + + +#endif + diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/testing/README.md b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/testing/README.md new file mode 100644 index 0000000..fe6137f --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/testing/README.md @@ -0,0 +1,5 @@ +Sample app to simulate the VirtualMatrixPanel class for testing / optimisation, without having to test with physical panels. + +``` +g++ -o myapp.exe virtual.cpp +``` \ No newline at end of file diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/testing/baseline.hpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/testing/baseline.hpp new file mode 100644 index 0000000..43d13e7 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/testing/baseline.hpp @@ -0,0 +1,189 @@ + +/** + * Calculate virtual->real co-ordinate mapping to underlying single chain of panels connected to ESP32. + * Updates the private class member variable 'coords', so no need to use the return value. + * Not thread safe, but not a concern for ESP32 sketch anyway... I think. + */ +// DO NOT CHANGE +inline VirtualCoords VirtualMatrixPanelTest::getCoords_WorkingBaslineMarch2023(int16_t virt_x, int16_t virt_y) +{ + coords.x = coords.y = -1; // By defalt use an invalid co-ordinates that will be rejected by updateMatrixDMABuffer + + if (virt_x < 0 || virt_x >= virtualResX || virt_y < 0 || virt_y >= virtualResY) + { // Co-ordinates go from 0 to X-1 remember! otherwise they are out of range! + return coords; + } + + // Do we want to rotate? + if (_rotate) + { + int16_t temp_x = virt_x; + virt_x = virt_y; + virt_y = virtualResY - 1 - temp_x; + } + + int row = (virt_y / panelResY); // 0 indexed + switch(panel_chain_type) + { + + case (CHAIN_TOP_RIGHT_DOWN): + { + if ( (row % 2) == 1 ) + { // upside down panel + + //Serial.printf("Condition 1, row %d ", row); + + // refersed for the row + coords.x = dmaResX - virt_x - (row*virtualResX); + + // y co-ord inverted within the panel + coords.y = panelResY - 1 - (virt_y % panelResY); + + + } + else + { + //Serial.printf("Condition 2, row %d ", row); + + coords.x = ((vmodule_rows - (row+1))*virtualResX)+virt_x; + coords.y = virt_y % panelResY; + + } + + } + break; + + + case (CHAIN_TOP_LEFT_DOWN): // OK -> modulus opposite of CHAIN_TOP_RIGHT_DOWN + { + if ( (row % 2) == 0 ) + { // refersed panel + + //Serial.printf("Condition 1, row %d ", row); + coords.x = dmaResX - virt_x - (row*virtualResX); + + // y co-ord inverted within the panel + coords.y = panelResY - 1 - (virt_y % panelResY); + + } + else + { + //Serial.printf("Condition 2, row %d ", row); + coords.x = ((vmodule_rows - (row+1))*virtualResX)+virt_x; + coords.y = virt_y % panelResY; + + } + + } + break; + + + + + case (CHAIN_BOTTOM_LEFT_UP): // + { + row = vmodule_rows - row - 1; + + if ( (row % 2) == 1 ) + { + // Serial.printf("Condition 1, row %d ", row); + coords.x = ((vmodule_rows - (row+1))*virtualResX)+virt_x; + coords.y = virt_y % panelResY; + + } + else + { // inverted panel + + // Serial.printf("Condition 2, row %d ", row); + coords.x = dmaResX - (row*virtualResX) - virt_x; + coords.y = panelResY - 1 - (virt_y % panelResY); + } + + } + break; + + case (CHAIN_BOTTOM_RIGHT_UP): // OK -> modulus opposite of CHAIN_BOTTOM_LEFT_UP + { + row = vmodule_rows - row - 1; + + if ( (row % 2) == 0 ) + { // right side up + + // Serial.printf("Condition 1, row %d ", row); + // refersed for the row + coords.x = ((vmodule_rows - (row+1))*virtualResX)+virt_x; + coords.y = virt_y % panelResY; + + } + else + { // inverted panel + + // Serial.printf("Condition 2, row %d ", row); + coords.x = dmaResX - (row*virtualResX) - virt_x; + coords.y = panelResY - 1 - (virt_y % panelResY); + } + + } + break; + + + default: + return coords; + break; + + } // end switch + + + + /* START: Pixel remapping AGAIN to convert TWO parallel scanline output that the + * the underlying hardware library is designed for (because + * there's only 2 x RGB pins... and convert this to 1/4 or something + */ + if (panel_scan_rate == FOUR_SCAN_32PX_HIGH) + { + /* Convert Real World 'VirtualMatrixPanel' co-ordinates (i.e. Real World pixel you're looking at + on the panel or chain of panels, per the chaining configuration) to a 1/8 panels + double 'stretched' and 'squished' coordinates which is what needs to be sent from the + DMA buffer. + + Note: Look at the FourScanPanel example code and you'll see that the DMA buffer is setup + as if the panel is 2 * W and 0.5 * H ! + */ + + if ((virt_y & 8) == 0) + { + coords.x += ((coords.x / panelResX) + 1) * panelResX; // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer + } + else + { + coords.x += (coords.x / panelResX) * panelResX; // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer + } + + // http://cpp.sh/4ak5u + // Real number of DMA y rows is half reality + // coords.y = (y / 16)*8 + (y & 0b00000111); + coords.y = (virt_y >> 4) * 8 + (virt_y & 0b00000111); + + } + else if (panel_scan_rate == FOUR_SCAN_16PX_HIGH) + { + if ((virt_y & 8) == 0) + { + coords.x += (panelResX >> 2) * (((coords.x & 0xFFF0) >> 4) + 1); // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer + } + else + { + coords.x += (panelResX >> 2) * (((coords.x & 0xFFF0) >> 4)); // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer + } + + if (virt_y < 32) + coords.y = (virt_y >> 4) * 8 + (virt_y & 0b00000111); + else + { + coords.y = ((virt_y - 32) >> 4) * 8 + (virt_y & 0b00000111); + coords.x += 256; + } + } + + return coords; +} diff --git a/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/testing/virtual.cpp b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/testing/virtual.cpp new file mode 100644 index 0000000..168acb1 --- /dev/null +++ b/libraries/ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display/testing/virtual.cpp @@ -0,0 +1,459 @@ +#include +#include +#include + + +struct VirtualCoords +{ + int16_t x; + int16_t y; + int16_t virt_row; // chain of panels row + int16_t virt_col; // chain of panels col + + VirtualCoords() : x(0), y(0) + { + } +}; + +enum PANEL_SCAN_RATE +{ + NORMAL_TWO_SCAN, NORMAL_ONE_SIXTEEN, // treated as the same + FOUR_SCAN_32PX_HIGH, + FOUR_SCAN_16PX_HIGH +}; + +// Chaining approach... From the perspective of the DISPLAY / LED side of the chain of panels. +enum PANEL_CHAIN_TYPE +{ + CHAIN_TOP_LEFT_DOWN, + CHAIN_TOP_RIGHT_DOWN, + CHAIN_BOTTOM_LEFT_UP, + CHAIN_BOTTOM_RIGHT_UP, + CHAIN_TOP_RIGHT_DOWN_ZZ, /// ZigZag chaining. Might need a big ass cable to do this, all panels right way up. + CHAIN_BOTTOM_RIGHT_UP_ZZ +}; + + +class VirtualMatrixPanelTest +{ + +public: + VirtualMatrixPanelTest(int _vmodule_rows, int _vmodule_cols, int _panelResX, int _panelResY, PANEL_CHAIN_TYPE _panel_chain_type = CHAIN_TOP_RIGHT_DOWN) + { + + panelResX = _panelResX; + panelResY = _panelResY; + + vmodule_rows = _vmodule_rows; + vmodule_cols = _vmodule_cols; + + virtualResX = vmodule_cols * _panelResX; + virtualResY = vmodule_rows * _panelResY; + + dmaResX = panelResX * vmodule_rows * vmodule_cols; + + panel_chain_type = _panel_chain_type; + + /* Virtual Display width() and height() will return a real-world value. For example: + * Virtual Display width: 128 + * Virtual Display height: 64 + * + * So, not values that at 0 to X-1 + */ + + coords.x = coords.y = -1; // By default use an invalid co-ordinates that will be rejected by updateMatrixDMABuffer + + switch (panel_chain_type) { + case CHAIN_TOP_LEFT_DOWN: + chain_type_str = "CHAIN_TOP_LEFT_DOWN"; + break; + + case CHAIN_TOP_RIGHT_DOWN: + chain_type_str = "CHAIN_TOP_RIGHT_DOWN"; + break; + + case CHAIN_TOP_RIGHT_DOWN_ZZ: + chain_type_str = "CHAIN_TOP_RIGHT_DOWN_ZZ"; + break; + + case CHAIN_BOTTOM_RIGHT_UP: + chain_type_str = "CHAIN_BOTTOM_RIGHT_UP"; + break; + + case CHAIN_BOTTOM_LEFT_UP: + chain_type_str = "CHAIN_BOTTOM_LEFT_UP"; + break; + + default: + chain_type_str = "WTF!"; + break; + } + std::cout << "\n\n***************************************************************************\n"; + std::cout << "Chain type: " << chain_type_str << " "; + std::printf("Testing chain of panels of %d rows, %d columns, %d px by %d px resolution. \n\n", vmodule_rows, vmodule_cols, panelResX, panelResX, panelResY); + + + } + + // equivalent methods of the matrix library so it can be just swapped out. + void drawPixel(int16_t x, int16_t y, int16_t expected_x, int16_t expected_y); + + std::string chain_type_str = "UNKNOWN"; + + // Internal co-ord conversion function + VirtualCoords getCoords_Dev(int16_t x, int16_t y); + + VirtualCoords getCoords_WorkingBaslineMarch2023(int16_t x, int16_t y); + + VirtualCoords coords; + + +private: + + int16_t virtualResX; + int16_t virtualResY; + + int16_t vmodule_rows; + int16_t vmodule_cols; + + int16_t panelResX; + int16_t panelResY; + + int16_t dmaResX; // The width of the chain in pixels (as the DMA engine sees it) + + PANEL_CHAIN_TYPE panel_chain_type; + PANEL_SCAN_RATE panel_scan_rate = NORMAL_TWO_SCAN; + + bool _rotate = false; + +}; // end Class header + +#include "baseline.hpp" + +/** + * Development version for testing. + */ +inline VirtualCoords VirtualMatrixPanelTest::getCoords_Dev(int16_t virt_x, int16_t virt_y) +{ + coords.x = coords.y = -1; // By defalt use an invalid co-ordinates that will be rejected by updateMatrixDMABuffer + + if (virt_x < 0 || virt_x >= virtualResX || virt_y < 0 || virt_y >= virtualResY) + { // Co-ordinates go from 0 to X-1 remember! otherwise they are out of range! + return coords; + } + + // Do we want to rotate? + if (_rotate) + { + int16_t temp_x = virt_x; + virt_x = virt_y; + virt_y = virtualResY - 1 - temp_x; + } + + int row = (virt_y / panelResY); // 0 indexed + switch(panel_chain_type) + { + + case (CHAIN_TOP_RIGHT_DOWN): + { + if ( (row % 2) == 1 ) + { // upside down panel + + //Serial.printf("Condition 1, row %d ", row); + + // refersed for the row + coords.x = dmaResX - virt_x - (row*virtualResX); + + // y co-ord inverted within the panel + coords.y = panelResY - 1 - (virt_y % panelResY); + + + } + else + { + //Serial.printf("Condition 2, row %d ", row); + coords.x = ((vmodule_rows - (row+1))*virtualResX)+virt_x; + coords.y = virt_y % panelResY; + + } + + } + break; + + + case (CHAIN_TOP_LEFT_DOWN): // OK -> modulus opposite of CHAIN_TOP_RIGHT_DOWN + { + if ( (row % 2) == 0 ) + { // refersed panel + + //Serial.printf("Condition 1, row %d ", row); + coords.x = dmaResX - virt_x - (row*virtualResX); + + // y co-ord inverted within the panel + coords.y = panelResY - 1 - (virt_y % panelResY); + + } + else + { + //Serial.printf("Condition 2, row %d ", row); + coords.x = ((vmodule_rows - (row+1))*virtualResX)+virt_x; + coords.y = virt_y % panelResY; + + } + + } + break; + + + + + case (CHAIN_BOTTOM_LEFT_UP): // + { + row = vmodule_rows - row - 1; + + if ( (row % 2) == 1 ) + { + // Serial.printf("Condition 1, row %d ", row); + coords.x = ((vmodule_rows - (row+1))*virtualResX)+virt_x; + coords.y = virt_y % panelResY; + + } + else + { // inverted panel + + // Serial.printf("Condition 2, row %d ", row); + coords.x = dmaResX - (row*virtualResX) - virt_x; + coords.y = panelResY - 1 - (virt_y % panelResY); + } + + } + break; + + case (CHAIN_BOTTOM_RIGHT_UP): // OK -> modulus opposite of CHAIN_BOTTOM_LEFT_UP + { + row = vmodule_rows - row - 1; + + if ( (row % 2) == 0 ) + { // right side up + + // Serial.printf("Condition 1, row %d ", row); + // refersed for the row + coords.x = ((vmodule_rows - (row+1))*virtualResX)+virt_x; + coords.y = virt_y % panelResY; + + } + else + { // inverted panel + + // Serial.printf("Condition 2, row %d ", row); + coords.x = dmaResX - (row*virtualResX) - virt_x; + coords.y = panelResY - 1 - (virt_y % panelResY); + } + + } + break; + + case CHAIN_TOP_RIGHT_DOWN_ZZ: + { + // Right side up. Starting from top left all the way down. + // Connected in a Zig Zag manner = some long ass cables being used potentially + + //Serial.printf("Condition 2, row %d ", row); + coords.x = ((vmodule_rows - (row+1))*virtualResX)+virt_x; + coords.y = virt_y % panelResY; + + } + + case CHAIN_BOTTOM_RIGHT_UP_ZZ: + { + // Right side up. Starting from top left all the way down. + // Connected in a Zig Zag manner = some long ass cables being used potentially + + //Serial.printf("Condition 2, row %d ", row); + coords.x = (row*virtualResX)+virt_x; + coords.y = virt_y % panelResY; + + } + + + + + default: + return coords; + break; + + } // end switch + + + + /* START: Pixel remapping AGAIN to convert TWO parallel scanline output that the + * the underlying hardware library is designed for (because + * there's only 2 x RGB pins... and convert this to 1/4 or something + */ + if (panel_scan_rate == FOUR_SCAN_32PX_HIGH) + { + /* Convert Real World 'VirtualMatrixPanel' co-ordinates (i.e. Real World pixel you're looking at + on the panel or chain of panels, per the chaining configuration) to a 1/8 panels + double 'stretched' and 'squished' coordinates which is what needs to be sent from the + DMA buffer. + + Note: Look at the FourScanPanel example code and you'll see that the DMA buffer is setup + as if the panel is 2 * W and 0.5 * H ! + */ + + if ((virt_y & 8) == 0) + { + coords.x += ((coords.x / panelResX) + 1) * panelResX; // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer + } + else + { + coords.x += (coords.x / panelResX) * panelResX; // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer + } + + // http://cpp.sh/4ak5u + // Real number of DMA y rows is half reality + // coords.y = (y / 16)*8 + (y & 0b00000111); + coords.y = (virt_y >> 4) * 8 + (virt_y & 0b00000111); + + } + else if (panel_scan_rate == FOUR_SCAN_16PX_HIGH) + { + if ((virt_y & 8) == 0) + { + coords.x += (panelResX >> 2) * (((coords.x & 0xFFF0) >> 4) + 1); // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer + } + else + { + coords.x += (panelResX >> 2) * (((coords.x & 0xFFF0) >> 4)); // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer + } + + if (virt_y < 32) + coords.y = (virt_y >> 4) * 8 + (virt_y & 0b00000111); + else + { + coords.y = ((virt_y - 32) >> 4) * 8 + (virt_y & 0b00000111); + coords.x += 256; + } + } + + return coords; +} + +bool check(VirtualCoords expected, VirtualCoords result, int x = -1, int y = -1) +{ + + if ( result.x != expected.x || result.y != expected.y ) + { + std::printf("Requested (%d, %d) -> expecting physical (%d, %d) got (%d, %d).", x, y, expected.x, expected.y, result.x, result.y); + std::cout << "\t *** FAIL ***\n "; + std::cout << "\n"; + + return false; + } + else + { + return true; + } +} + + +main(int argc, char* argv[]) +{ + std::cout << "Starting Testing...\n"; + + std::list chain_t_test_list { CHAIN_TOP_LEFT_DOWN, CHAIN_TOP_RIGHT_DOWN, CHAIN_BOTTOM_LEFT_UP, CHAIN_BOTTOM_RIGHT_UP }; + + + // Draw pixel at virtual position 70x, 70y = + // x, y x, y + + // x == horizontal + // y = vert :-) + + // 192 x 192 pixel virtual display + int rows = 3; + int cols = 3; + int panel_width_x = 64; + int panel_height_y = 64; + + std::string panel_scan_type = "NORMAL_TWO_SCAN"; + + for (auto chain_t : chain_t_test_list) { + + + VirtualMatrixPanelTest test = VirtualMatrixPanelTest(rows,cols,panel_width_x,panel_height_y, chain_t); + int pass_counter = 0; + int fail_counter = 0; + for (int16_t x = 0; x < panel_width_x*cols; x++) + { + for (int16_t y = 0; y < panel_height_y*rows; y++) + { + VirtualCoords expected = test.getCoords_WorkingBaslineMarch2023(x,y); + VirtualCoords result = test.getCoords_Dev(x,y); + + bool chk_result = check(expected, result, x, y); + + if ( chk_result ) + { + fail_counter++; + } + else + { + pass_counter++; + } + } + } + + if ( fail_counter > 0) { + std::printf("ERROR: %d tests failed.\n", fail_counter); + } else{ + std::printf("SUCCESS: %d coord tests passed.\n", pass_counter); + } + + } // end chain type test list + + + std::cout << "Performing NON-SERPENTINE (ZIG ZAG) TEST"; + + rows = 3; + cols = 1; + panel_width_x = 64; + panel_height_y = 64; + + VirtualMatrixPanelTest test = VirtualMatrixPanelTest(rows,cols,panel_width_x,panel_height_y, CHAIN_TOP_RIGHT_DOWN_ZZ); + + // CHAIN_TOP_RIGHT_DOWN_ZZ test 1 + // (x,y) + VirtualCoords result = test.getCoords_Dev(0,0); + VirtualCoords expected; expected.x = 64*2; expected.y = 0; + std::printf("Expected physical (%d, %d) got (%d, %d).\n", expected.x, expected.y, result.x, result.y); + + // CHAIN_TOP_RIGHT_DOWN_ZZ test 2 + result = test.getCoords_Dev(10,64*3-1); + expected.x = 10; expected.y = 63; + std::printf("Expected physical (%d, %d) got (%d, %d).\n", expected.x, expected.y, result.x, result.y); + + + // CHAIN_TOP_RIGHT_DOWN_ZZ test 3 + result = test.getCoords_Dev(16,64*2-1); + expected.x = 80; expected.y = 63; + std::printf("Expected physical (%d, %d) got (%d, %d).\n", expected.x, expected.y, result.x, result.y); + + + + // CHAIN_BOTTOM_RIGHT_UP_ZZ test 4 + result = test.getCoords_Dev(0,0); + expected.x = 0; expected.y = 0; + std::printf("Expected physical (%d, %d) got (%d, %d).\n", expected.x, expected.y, result.x, result.y); + + // CHAIN_BOTTOM_RIGHT_UP_ZZ test 4 + result = test.getCoords_Dev(63,64); + expected.x = 64*2-1; expected.y = 0; + std::printf("Expected physical (%d, %d) got (%d, %d).\n", expected.x, expected.y, result.x, result.y); + + + + std::cout << "\n\n"; + + return 0; +} \ No newline at end of file diff --git a/libraries/_NTools/WeekNumber.h b/libraries/_NTools/WeekNumber.h new file mode 100644 index 0000000..a8305ac --- /dev/null +++ b/libraries/_NTools/WeekNumber.h @@ -0,0 +1,50 @@ +/***** Den Wochentag nach ISO 8601 (1 = Mo, 2 = Di, 3 = Mi, 4 = Do, 5 = Fr, 6 = Sa, 7 = So) berechnen *****/ +uint8_t GetWeekday(uint16_t y, uint8_t m, uint8_t d) { + static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; + y -= m < 3; + uint8_t wd = (y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7; + return (wd == 0 ? 7 : wd); +} + +/***** Testen, ob das Jahr ein Schaltjahr ist *****/ +bool IsLeapYear(uint16_t y) { + return !(y % 4) && ((y % 100) || !(y % 400)); // Schaltjahrberechnung (true = Schaltjahr, false = kein Schaltjahr) +} + +/***** die Anzahl der Tage (Tag des Jahres) berechnen *****/ +uint16_t GetDayOfYear(uint16_t y, uint8_t m, uint8_t d) { + static const uint16_t mdays[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + return d + mdays[m - 1] + (m >= 2 && IsLeapYear(y)); +} + +/***** Die Wochennummer nach ISO 8601 berechnen *****/ +uint8_t GetWeekNumber(uint16_t y, uint8_t m, uint8_t d) { + bool LeapYear; + uint16_t doy = GetDayOfYear(y, m, d); // Anzahl der Tage im Jahr ermitteln + uint8_t wd = GetWeekday(y, m, d); // Wochentag ermitteln + uint8_t wnr = (doy - wd + 7) / 7; // die Wochennummer berechnen + switch (wnr) { + case 0: // wenn die Wochennummer Null ergibt, dann liegt der Tag am Anfang des Jahres (1. Sonderfall) + wd = GetWeekday(y - 1, 12, 31); // den letzten Wochentag aus dem Vorjahr ermitteln + LeapYear = IsLeapYear(y - 1); // ermitteln, ob es sich beim Vorjahr um ein Schaltjahr handelt + break; // und nach dem Switch weitermachen... + case 52: // wenn die Wochennummer 52 ergibt, dann liegt der Tag am Ende des Jahres (2. Sonderfall) + wd = GetWeekday(y, 12, 31); // den letzten Wochentag aus diesem Jahr ermitteln + LeapYear = IsLeapYear(y); // ermitteln, ob es sich bei diesem Jahr um ein Schaltjahr handelt + break; // und nach dem Switch weitermachen... + default: // in den anderen Faellen kann die Funktion + return wnr; // hier verlassen und die Wochennummer zurueckgegeben werden + } + if (wd < 4) { // wenn der 31.12. vor dem Donnerstag liegt, dann... + wnr = 1; // ist das die erste Woche des Jahres + } else { // anderenfalls muss ermittelt werden, ob es eine 53. Woche gibt (3. Sonderfall) + /* wenn der letzte Wochentag auf einen Donnerstag oder, */ + /* in einem Schaltjahr, auf einen Donnerstag oder Freitag fällt, */ + /* dann ist das die 53. Woche, ansonsten die 52. Woche. */ + wnr = ((wd == 4) || (LeapYear && wd == 5)) ? 53 : 52; + } + return wnr; +} + + + diff --git a/libraries/_NToolsFonts/BundesSans10P.h b/libraries/_NToolsFonts/BundesSans10P.h new file mode 100644 index 0000000..63327d2 --- /dev/null +++ b/libraries/_NToolsFonts/BundesSans10P.h @@ -0,0 +1,203 @@ +const uint8_t BundesSans10pt7bBitmaps[] PROGMEM = { + 0x00, 0xD9, 0x24, 0x92, 0x48, 0x0F, 0x80, 0xFF, 0xFF, 0xA0, 0x11, 0x84, + 0x41, 0x11, 0xFF, 0x31, 0x0C, 0xC2, 0x30, 0x88, 0xFF, 0x88, 0x86, 0x21, + 0x88, 0x46, 0x00, 0x10, 0x20, 0x63, 0xFC, 0x38, 0x30, 0x30, 0x30, 0x38, + 0x38, 0x30, 0x30, 0x7B, 0xBE, 0x10, 0x20, 0x70, 0x6D, 0x84, 0x88, 0xC8, + 0x98, 0x89, 0x0D, 0xB0, 0x72, 0x00, 0x6E, 0x0D, 0xB0, 0x91, 0x19, 0x13, + 0x11, 0x31, 0xB6, 0x0E, 0x1E, 0x06, 0xC1, 0x8C, 0x31, 0x86, 0x20, 0x4C, + 0x0E, 0x31, 0xC6, 0x4C, 0x98, 0xD2, 0x0E, 0x61, 0xCE, 0xEC, 0xF9, 0xC0, + 0xFF, 0x80, 0x32, 0x44, 0xCC, 0x88, 0x88, 0x88, 0xCC, 0x44, 0x23, 0xC6, + 0x23, 0x31, 0x11, 0x11, 0x11, 0x13, 0x32, 0x6C, 0x10, 0x10, 0x92, 0xFF, + 0x18, 0x28, 0x66, 0x44, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, + 0x18, 0xF5, 0x80, 0xFC, 0xF0, 0x06, 0x08, 0x10, 0x60, 0x81, 0x06, 0x0C, + 0x10, 0x60, 0xC1, 0x06, 0x0C, 0x10, 0x60, 0xC1, 0x00, 0x3C, 0x66, 0x42, + 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x46, 0x7E, 0x3C, 0x18, + 0xF8, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, + 0x7C, 0xFE, 0x86, 0x06, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xFF, + 0xFF, 0x7D, 0xFD, 0x18, 0x30, 0x60, 0xC3, 0x1C, 0x0C, 0x0C, 0x1C, 0x3F, + 0xEF, 0x80, 0x06, 0x0E, 0x1E, 0x36, 0x66, 0xC6, 0x86, 0xFF, 0xFF, 0x06, + 0x06, 0x06, 0x06, 0x7E, 0x60, 0x60, 0x60, 0x60, 0x7C, 0x1E, 0x06, 0x03, + 0x03, 0x83, 0xFE, 0x7C, 0x1F, 0x30, 0x60, 0x40, 0xC0, 0xC0, 0xFE, 0xFE, + 0xC3, 0xC3, 0xC3, 0x63, 0x7E, 0x3C, 0xFF, 0x03, 0x02, 0x06, 0x04, 0x0C, + 0x08, 0x18, 0x18, 0x10, 0x30, 0x20, 0x60, 0x3C, 0x66, 0x42, 0xC3, 0x42, + 0x66, 0x3C, 0x7E, 0xE6, 0xC3, 0xC3, 0xC3, 0x7E, 0x3C, 0x7C, 0xEE, 0xC6, + 0xC3, 0xC3, 0xC3, 0xFF, 0x7F, 0x03, 0x03, 0x02, 0x06, 0xDC, 0xF8, 0xF0, + 0x00, 0xF0, 0xF0, 0x00, 0xF5, 0x80, 0x01, 0x07, 0x1C, 0x70, 0xC0, 0x60, + 0x18, 0x0E, 0x03, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0xE0, 0x38, 0x0E, 0x03, + 0x0E, 0x38, 0xE0, 0x80, 0x7B, 0x78, 0xC3, 0x0C, 0x63, 0x08, 0x60, 0x80, + 0x00, 0x30, 0xC0, 0x03, 0xE0, 0x30, 0xE3, 0x00, 0xC8, 0xE9, 0x67, 0xE5, + 0x31, 0x9C, 0xC6, 0x72, 0x11, 0xC8, 0x47, 0x21, 0x1C, 0x8C, 0xF3, 0x76, + 0x47, 0x71, 0x80, 0x03, 0x04, 0x07, 0xF0, 0x06, 0x00, 0x60, 0x0F, 0x00, + 0xB0, 0x09, 0x01, 0x98, 0x11, 0x81, 0x08, 0x3F, 0xC2, 0x0C, 0x60, 0x46, + 0x06, 0x40, 0x6C, 0x03, 0xFC, 0xCE, 0xC3, 0xC3, 0xC3, 0xC6, 0xF8, 0xC6, + 0xC3, 0xC3, 0xC3, 0xC3, 0xCE, 0xFC, 0x0F, 0x8F, 0x77, 0x05, 0x80, 0xC0, + 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x06, 0x01, 0x80, 0x3D, 0xC7, 0xE0, + 0xFC, 0x37, 0xCC, 0x1B, 0x06, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, + 0x3C, 0x1B, 0x0E, 0xDF, 0x3F, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, + 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0x83, 0x06, 0x0C, + 0x18, 0x30, 0x7F, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x00, 0x0F, 0x8F, 0x77, + 0x05, 0x80, 0xC0, 0x30, 0x0C, 0x03, 0x0F, 0xC3, 0xF0, 0x36, 0x0D, 0x83, + 0x3D, 0xC7, 0xE0, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3F, 0xFF, + 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x30, 0xF9, 0x08, 0x42, + 0x10, 0x84, 0x21, 0x08, 0x42, 0x7C, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, + 0xC6, 0x3B, 0xF8, 0xC1, 0xB0, 0xCC, 0x63, 0x10, 0xCC, 0x36, 0x0F, 0x03, + 0x60, 0xCC, 0x33, 0x0C, 0x63, 0x0C, 0xC3, 0x30, 0x70, 0xC1, 0x83, 0x06, + 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x06, 0x0F, 0xFF, 0xC0, 0xC0, 0x1C, + 0x03, 0xE0, 0x3E, 0x07, 0xA0, 0x7B, 0x05, 0xB0, 0xD9, 0x89, 0x99, 0x98, + 0x99, 0x8D, 0x18, 0xF1, 0x86, 0x18, 0x61, 0xC0, 0xF0, 0x3E, 0x0F, 0xC3, + 0xF0, 0xF6, 0x3C, 0x8F, 0x33, 0xC6, 0xF1, 0xBC, 0x3F, 0x07, 0xC1, 0xF0, + 0x30, 0x0F, 0x83, 0xDC, 0x60, 0x66, 0x06, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, + 0x03, 0xC0, 0x3C, 0x03, 0x60, 0x66, 0x06, 0x3D, 0xC0, 0xF8, 0xFC, 0xDE, + 0xC3, 0xC3, 0xC1, 0xC3, 0xC3, 0xC6, 0xFC, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, + 0x0F, 0x83, 0xDC, 0x60, 0x66, 0x06, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, + 0xC0, 0x3C, 0x03, 0x60, 0x66, 0x06, 0x3D, 0xC0, 0xF8, 0x00, 0xC0, 0x06, + 0x00, 0x30, 0xFC, 0x6F, 0x30, 0xD8, 0x6C, 0x36, 0x1B, 0x19, 0xF8, 0xCC, + 0x66, 0x31, 0x98, 0xCC, 0x36, 0x0C, 0x3E, 0x7E, 0xC0, 0xC0, 0xC0, 0x70, + 0x38, 0x1E, 0x06, 0x03, 0x03, 0x83, 0xFE, 0x7C, 0xFF, 0xE0, 0x80, 0x10, + 0x02, 0x00, 0x40, 0x08, 0x01, 0x00, 0x20, 0x04, 0x00, 0x80, 0x10, 0x02, + 0x00, 0x40, 0x08, 0x00, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, + 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x07, 0x7F, 0x8F, 0x80, 0xC0, 0x36, + 0x06, 0x60, 0x66, 0x04, 0x30, 0xC3, 0x0C, 0x10, 0x81, 0x98, 0x19, 0x80, + 0x90, 0x0F, 0x00, 0xE0, 0x06, 0x00, 0x60, 0xC0, 0xC0, 0xB0, 0x60, 0xD8, + 0x70, 0x6C, 0x3C, 0x22, 0x16, 0x11, 0x89, 0x18, 0xCC, 0xCC, 0x66, 0x64, + 0x12, 0x12, 0x0F, 0x0B, 0x07, 0x87, 0x83, 0x83, 0x80, 0xC0, 0xC0, 0x60, + 0x60, 0x60, 0xCC, 0x18, 0xC6, 0x08, 0x81, 0xB0, 0x14, 0x03, 0x80, 0x70, + 0x0E, 0x03, 0x60, 0xC4, 0x18, 0xC6, 0x0D, 0xC1, 0xC0, 0xC0, 0xEC, 0x19, + 0x82, 0x18, 0xC3, 0x10, 0x36, 0x06, 0x80, 0x70, 0x0C, 0x00, 0x80, 0x10, + 0x02, 0x00, 0x40, 0x08, 0x00, 0xFF, 0x80, 0x80, 0xC0, 0xC0, 0x60, 0x60, + 0x20, 0x30, 0x30, 0x18, 0x18, 0x0C, 0x0C, 0x07, 0xFC, 0xFB, 0x6D, 0xB6, + 0xDB, 0x6D, 0xB6, 0xDC, 0x81, 0x83, 0x02, 0x06, 0x0C, 0x08, 0x18, 0x30, + 0x20, 0x60, 0xC0, 0x81, 0x83, 0x02, 0x06, 0x0C, 0xED, 0xB6, 0xDB, 0x6D, + 0xB6, 0xDB, 0x7C, 0x10, 0x60, 0xE3, 0x44, 0xD8, 0xA1, 0x80, 0xFF, 0x80, + 0xC6, 0x30, 0x79, 0xD8, 0x10, 0x37, 0xFC, 0xE1, 0xC3, 0xDE, 0xEC, 0x40, + 0xC0, 0xC0, 0xC0, 0xC0, 0xDE, 0xF7, 0xC3, 0xC1, 0xC1, 0xC1, 0xC3, 0xC3, + 0xEE, 0x7C, 0x3C, 0xEF, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x76, 0x78, 0x01, + 0x03, 0x03, 0x03, 0x03, 0x3F, 0x77, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, + 0x77, 0x3F, 0x3C, 0xFF, 0x1E, 0x3F, 0xFF, 0xB0, 0x60, 0x7E, 0x7C, 0x00, + 0x3B, 0x50, 0x8F, 0xA1, 0x08, 0x42, 0x10, 0x84, 0x20, 0x1F, 0x9B, 0x98, + 0x4C, 0x26, 0x31, 0xF0, 0x80, 0x40, 0x30, 0x1F, 0xD0, 0x78, 0x37, 0x71, + 0xF0, 0x40, 0xC0, 0xC0, 0xC0, 0xC0, 0xDE, 0xF6, 0xC3, 0xC3, 0xC3, 0xC3, + 0xC3, 0xC3, 0xC3, 0xC3, 0xF0, 0xFF, 0xFF, 0xF0, 0x33, 0x00, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x6C, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0xC6, + 0xCC, 0xD8, 0xF0, 0xD8, 0xCC, 0xCC, 0xC6, 0xC3, 0xCC, 0xCC, 0xCC, 0xCC, + 0xCC, 0xCC, 0xC7, 0x70, 0xDE, 0xF7, 0xBD, 0xF0, 0xC3, 0x86, 0x1C, 0x30, + 0xE1, 0x87, 0x0C, 0x38, 0x61, 0xC3, 0x0E, 0x18, 0x40, 0xDE, 0xF6, 0xC3, + 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x3C, 0x7E, 0xC3, 0xC3, 0xC1, + 0xC1, 0xC3, 0xC3, 0x7E, 0x3C, 0xDE, 0xF7, 0xC3, 0xC1, 0xC1, 0xC1, 0xC1, + 0xC3, 0xEE, 0xFC, 0xC0, 0xC0, 0xC0, 0xC0, 0x3D, 0x77, 0xC3, 0xC3, 0xC3, + 0xC3, 0xC3, 0xC3, 0x77, 0x3F, 0x03, 0x03, 0x03, 0x03, 0xDF, 0xF1, 0x8C, + 0x63, 0x18, 0xC6, 0x00, 0x7B, 0xBC, 0x30, 0x70, 0xE0, 0xC3, 0xDF, 0xE0, + 0x42, 0x11, 0xF4, 0x21, 0x08, 0x42, 0x18, 0xF3, 0x80, 0xC3, 0xC3, 0xC3, + 0xC3, 0xC3, 0xC3, 0xC3, 0x43, 0x6F, 0x3B, 0xC1, 0x43, 0x63, 0x22, 0x22, + 0x36, 0x14, 0x14, 0x1C, 0x08, 0xC2, 0x0D, 0x0C, 0x26, 0x31, 0x88, 0xC6, + 0x23, 0x90, 0xDE, 0x41, 0x4A, 0x05, 0x38, 0x1C, 0x60, 0x21, 0x00, 0x63, + 0x66, 0x34, 0x1C, 0x18, 0x18, 0x1C, 0x26, 0x66, 0xC3, 0xC1, 0x63, 0x63, + 0x22, 0x22, 0x36, 0x14, 0x14, 0x1C, 0x08, 0x08, 0x18, 0xB0, 0xE0, 0xFC, + 0x18, 0x20, 0xC3, 0x06, 0x18, 0x20, 0xC1, 0xFC, 0x36, 0x64, 0x44, 0x44, + 0x48, 0xC4, 0x44, 0x44, 0x63, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xCC, 0x66, + 0x66, 0x66, 0x63, 0x66, 0x66, 0x66, 0x6C, 0x71, 0xFF, 0x8E +}; + +const GFXglyph BundesSans10pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 4, 0, 0 }, // 0x20 ' ' + { 1, 3, 14, 5, 1, -13 }, // 0x21 '!' + { 7, 4, 5, 6, 1, -13 }, // 0x22 '"' + { 10, 10, 13, 12, 1, -12 }, // 0x23 '#' + { 27, 7, 18, 9, 1, -15 }, // 0x24 '$' + { 43, 12, 14, 14, 1, -13 }, // 0x25 '%' + { 64, 11, 14, 12, 1, -13 }, // 0x26 '&' + { 84, 2, 5, 4, 1, -13 }, // 0x27 ''' + { 86, 4, 18, 5, 1, -14 }, // 0x28 '(' + { 95, 4, 18, 5, 0, -14 }, // 0x29 ')' + { 104, 8, 8, 9, 1, -13 }, // 0x2A '*' + { 112, 8, 9, 10, 1, -10 }, // 0x2B '+' + { 121, 2, 5, 4, 1, -1 }, // 0x2C ',' + { 123, 6, 1, 8, 1, -6 }, // 0x2D '-' + { 124, 2, 2, 4, 1, -1 }, // 0x2E '.' + { 125, 7, 18, 9, 1, -14 }, // 0x2F '/' + { 141, 8, 14, 10, 1, -13 }, // 0x30 '0' + { 155, 8, 13, 10, 1, -12 }, // 0x31 '1' + { 168, 8, 13, 10, 1, -12 }, // 0x32 '2' + { 181, 7, 14, 10, 1, -13 }, // 0x33 '3' + { 194, 8, 13, 10, 1, -12 }, // 0x34 '4' + { 207, 8, 13, 10, 1, -12 }, // 0x35 '5' + { 220, 8, 14, 10, 1, -13 }, // 0x36 '6' + { 234, 8, 13, 10, 1, -12 }, // 0x37 '7' + { 247, 8, 14, 10, 1, -13 }, // 0x38 '8' + { 261, 8, 14, 10, 1, -13 }, // 0x39 '9' + { 275, 2, 10, 5, 1, -9 }, // 0x3A ':' + { 278, 2, 13, 5, 1, -9 }, // 0x3B ';' + { 282, 8, 9, 10, 1, -9 }, // 0x3C '<' + { 291, 8, 4, 10, 1, -7 }, // 0x3D '=' + { 295, 8, 9, 10, 1, -9 }, // 0x3E '>' + { 304, 6, 14, 8, 1, -13 }, // 0x3F '?' + { 315, 14, 16, 16, 1, -12 }, // 0x40 '@' + { 343, 12, 14, 12, 0, -13 }, // 0x41 'A' + { 364, 8, 14, 11, 2, -13 }, // 0x42 'B' + { 378, 10, 14, 12, 1, -13 }, // 0x43 'C' + { 396, 10, 14, 13, 2, -13 }, // 0x44 'D' + { 414, 8, 14, 11, 2, -13 }, // 0x45 'E' + { 428, 7, 14, 10, 2, -13 }, // 0x46 'F' + { 441, 10, 14, 13, 1, -13 }, // 0x47 'G' + { 459, 10, 14, 14, 2, -13 }, // 0x48 'H' + { 477, 5, 14, 7, 1, -13 }, // 0x49 'I' + { 486, 5, 14, 7, 0, -13 }, // 0x4A 'J' + { 495, 10, 14, 12, 2, -13 }, // 0x4B 'K' + { 513, 7, 14, 10, 2, -13 }, // 0x4C 'L' + { 526, 12, 14, 16, 2, -13 }, // 0x4D 'M' + { 547, 10, 14, 14, 2, -13 }, // 0x4E 'N' + { 565, 12, 14, 14, 1, -13 }, // 0x4F 'O' + { 586, 8, 14, 11, 2, -13 }, // 0x50 'P' + { 600, 12, 17, 14, 1, -13 }, // 0x51 'Q' + { 626, 9, 14, 11, 2, -13 }, // 0x52 'R' + { 642, 8, 14, 10, 1, -13 }, // 0x53 'S' + { 656, 11, 14, 11, 0, -13 }, // 0x54 'T' + { 676, 10, 14, 13, 2, -13 }, // 0x55 'U' + { 694, 12, 14, 12, 0, -13 }, // 0x56 'V' + { 715, 17, 14, 18, 0, -13 }, // 0x57 'W' + { 745, 11, 14, 11, 0, -13 }, // 0x58 'X' + { 765, 11, 14, 11, 0, -13 }, // 0x59 'Y' + { 785, 9, 14, 11, 1, -13 }, // 0x5A 'Z' + { 801, 3, 18, 5, 1, -14 }, // 0x5B '[' + { 808, 7, 18, 9, 1, -14 }, // 0x5C '\' + { 824, 3, 18, 5, 1, -14 }, // 0x5D ']' + { 831, 7, 7, 9, 1, -13 }, // 0x5E '^' + { 838, 9, 1, 8, 0, 2 }, // 0x5F '_' + { 840, 4, 3, 4, 0, -13 }, // 0x60 '`' + { 842, 7, 10, 9, 1, -9 }, // 0x61 'a' + { 851, 8, 15, 10, 1, -14 }, // 0x62 'b' + { 866, 7, 10, 9, 1, -9 }, // 0x63 'c' + { 875, 8, 15, 10, 1, -14 }, // 0x64 'd' + { 890, 7, 10, 9, 1, -9 }, // 0x65 'e' + { 900, 5, 14, 6, 1, -13 }, // 0x66 'f' + { 909, 9, 14, 10, 0, -9 }, // 0x67 'g' + { 925, 8, 15, 10, 1, -14 }, // 0x68 'h' + { 940, 2, 14, 4, 1, -13 }, // 0x69 'i' + { 944, 4, 18, 4, -1, -13 }, // 0x6A 'j' + { 953, 8, 15, 9, 1, -14 }, // 0x6B 'k' + { 968, 4, 15, 5, 1, -14 }, // 0x6C 'l' + { 976, 13, 10, 16, 1, -9 }, // 0x6D 'm' + { 993, 8, 10, 10, 1, -9 }, // 0x6E 'n' + { 1003, 8, 10, 10, 1, -9 }, // 0x6F 'o' + { 1013, 8, 14, 10, 1, -9 }, // 0x70 'p' + { 1027, 8, 14, 10, 1, -9 }, // 0x71 'q' + { 1041, 5, 10, 7, 1, -9 }, // 0x72 'r' + { 1048, 6, 10, 8, 1, -9 }, // 0x73 's' + { 1056, 5, 13, 7, 1, -12 }, // 0x74 't' + { 1065, 8, 10, 10, 1, -9 }, // 0x75 'u' + { 1075, 8, 10, 9, 0, -9 }, // 0x76 'v' + { 1085, 14, 10, 14, 0, -9 }, // 0x77 'w' + { 1103, 8, 10, 9, 0, -9 }, // 0x78 'x' + { 1113, 8, 14, 9, 0, -9 }, // 0x79 'y' + { 1127, 7, 10, 8, 1, -9 }, // 0x7A 'z' + { 1136, 4, 18, 6, 1, -14 }, // 0x7B '{' + { 1145, 2, 18, 4, 1, -14 }, // 0x7C '|' + { 1150, 4, 18, 6, 1, -14 }, // 0x7D '}' + { 1159, 8, 3, 10, 1, -7 } // 0x7E '~' +}; + +const GFXfont BundesSans10pt7b PROGMEM = { + (uint8_t *)BundesSans10pt7bBitmaps, + (GFXglyph *)BundesSans10pt7bGlyphs, 0x20, 0x7E, 24 }; + +// Approx. 1833 bytes diff --git a/libraries/_NToolsFonts/BundesSans6P.h b/libraries/_NToolsFonts/BundesSans6P.h new file mode 100644 index 0000000..72a5094 --- /dev/null +++ b/libraries/_NToolsFonts/BundesSans6P.h @@ -0,0 +1,140 @@ +const uint8_t BundesSans6pt7bBitmaps[] PROGMEM = { + 0x00, 0xFD, 0xF8, 0x24, 0x49, 0xF9, 0x42, 0x9F, 0x92, 0x24, 0x4E, 0x98, + 0xC2, 0x19, 0xE4, 0xC5, 0x52, 0xA6, 0x82, 0xC5, 0x52, 0xC6, 0x72, 0x49, + 0x1A, 0xEA, 0x69, 0xBB, 0xE0, 0x6A, 0xAA, 0xA4, 0x89, 0x12, 0x49, 0x4A, + 0x00, 0x4D, 0x66, 0xB0, 0x44, 0xF4, 0x40, 0x58, 0xE0, 0x80, 0x08, 0x84, + 0x22, 0x10, 0x88, 0x42, 0x20, 0x69, 0x99, 0x99, 0x96, 0x6A, 0x22, 0x22, + 0x2F, 0xE9, 0x11, 0x24, 0xCF, 0xE1, 0x16, 0x11, 0x9E, 0x10, 0x8C, 0xA5, + 0x7C, 0x42, 0xF8, 0x8E, 0x11, 0x9E, 0x78, 0x8F, 0x99, 0x97, 0xF1, 0x12, + 0x24, 0x48, 0x69, 0x9E, 0xB9, 0x9E, 0x72, 0x62, 0x97, 0x84, 0x2E, 0x84, + 0x40, 0x16, 0x09, 0xB0, 0xC1, 0x80, 0xF0, 0xF0, 0x86, 0x13, 0xC0, 0xF1, + 0x13, 0x26, 0x02, 0x1C, 0x63, 0x9D, 0xA5, 0xA5, 0xA5, 0xA5, 0xBE, 0x80, + 0x7C, 0x10, 0x50, 0xA1, 0x47, 0xC8, 0x91, 0x41, 0xF4, 0x63, 0xE8, 0xC6, + 0x3E, 0x7F, 0x08, 0x20, 0x82, 0x0C, 0x1E, 0xF2, 0x38, 0x61, 0x86, 0x18, + 0xBC, 0xFC, 0x21, 0xE8, 0x42, 0x1F, 0xFC, 0x21, 0xE8, 0x42, 0x10, 0x3B, + 0x18, 0x20, 0x9E, 0x1C, 0x5E, 0x86, 0x18, 0x7F, 0x86, 0x18, 0x61, 0xE9, + 0x24, 0x97, 0x24, 0x92, 0x4E, 0x8E, 0x4A, 0x38, 0xA2, 0x48, 0xA3, 0x84, + 0x21, 0x08, 0x42, 0x1F, 0x83, 0xC3, 0xC3, 0xA5, 0xA5, 0xA9, 0x99, 0x99, + 0x87, 0x1A, 0x69, 0x96, 0x38, 0xE1, 0x79, 0x8A, 0x1C, 0x18, 0x30, 0xF1, + 0x3C, 0xF4, 0x63, 0x1F, 0x42, 0x10, 0x79, 0x8A, 0x1C, 0x18, 0x30, 0xF1, + 0x3C, 0x04, 0x0C, 0xF2, 0x28, 0xA2, 0xF2, 0x49, 0xA3, 0xF8, 0x84, 0x31, + 0x9F, 0xFC, 0x41, 0x04, 0x10, 0x41, 0x04, 0x86, 0x18, 0x61, 0x86, 0x1C, + 0x5E, 0x82, 0x89, 0x12, 0x22, 0x85, 0x06, 0x08, 0x84, 0x53, 0x14, 0xA5, + 0x2A, 0x52, 0x8C, 0xA3, 0x18, 0xC4, 0xC5, 0x22, 0x8C, 0x30, 0xA4, 0xB1, + 0xC5, 0x14, 0x8A, 0x30, 0x41, 0x04, 0x7C, 0x20, 0x84, 0x20, 0x84, 0x3F, + 0xEA, 0xAA, 0xAC, 0x82, 0x10, 0x82, 0x10, 0x82, 0x10, 0x82, 0xD5, 0x55, + 0x5C, 0x22, 0x95, 0x90, 0xF8, 0x90, 0x72, 0x82, 0xF8, 0xBC, 0x84, 0x21, + 0xE9, 0x46, 0x32, 0xE0, 0x78, 0x88, 0x8F, 0x11, 0x17, 0x99, 0x99, 0xF0, + 0x69, 0xF8, 0x87, 0x34, 0x4F, 0x44, 0x44, 0x40, 0x7D, 0x24, 0x9C, 0x41, + 0xE8, 0x9E, 0x88, 0x8F, 0x99, 0x99, 0x90, 0x9F, 0x80, 0x20, 0x12, 0x49, + 0x27, 0x00, 0x88, 0x89, 0xAC, 0xAA, 0x90, 0xAA, 0xAA, 0xC0, 0xFE, 0x91, + 0x91, 0x91, 0x91, 0x91, 0xF9, 0x99, 0x99, 0x74, 0xA3, 0x19, 0x38, 0xF4, + 0xA3, 0x19, 0x7A, 0x10, 0x79, 0x99, 0x9F, 0x11, 0xF2, 0x49, 0x00, 0x74, + 0x63, 0x1F, 0x44, 0xF4, 0x44, 0x47, 0x99, 0x99, 0x9F, 0x8A, 0x54, 0xA3, + 0x10, 0x99, 0x49, 0x4A, 0x56, 0x36, 0x24, 0xDA, 0x88, 0x45, 0x6C, 0x8A, + 0x54, 0xA2, 0x10, 0x98, 0x70, 0x88, 0x44, 0x7C, 0x29, 0x25, 0x12, 0x48, + 0x80, 0xFF, 0xE0, 0xC9, 0x24, 0x52, 0x4B, 0x00, 0xDB }; + +const GFXglyph BundesSans6pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 3, 0, 0 }, // 0x20 ' ' + { 1, 1, 8, 3, 1, -7 }, // 0x21 '!' + { 2, 2, 3, 4, 1, -7 }, // 0x22 '"' + { 3, 7, 8, 7, 0, -7 }, // 0x23 '#' + { 10, 4, 10, 6, 1, -8 }, // 0x24 '$' + { 15, 7, 8, 8, 1, -7 }, // 0x25 '%' + { 22, 6, 8, 7, 1, -7 }, // 0x26 '&' + { 28, 1, 3, 2, 1, -7 }, // 0x27 ''' + { 29, 2, 11, 3, 1, -8 }, // 0x28 '(' + { 32, 3, 11, 3, 0, -8 }, // 0x29 ')' + { 37, 4, 5, 6, 1, -7 }, // 0x2A '*' + { 40, 4, 5, 6, 1, -5 }, // 0x2B '+' + { 43, 2, 3, 3, 0, 0 }, // 0x2C ',' + { 44, 3, 1, 5, 1, -3 }, // 0x2D '-' + { 45, 1, 1, 3, 1, 0 }, // 0x2E '.' + { 46, 5, 11, 5, 0, -8 }, // 0x2F '/' + { 53, 4, 8, 6, 1, -7 }, // 0x30 '0' + { 57, 4, 8, 6, 1, -7 }, // 0x31 '1' + { 61, 4, 8, 6, 1, -7 }, // 0x32 '2' + { 65, 4, 8, 6, 1, -7 }, // 0x33 '3' + { 69, 5, 8, 6, 0, -7 }, // 0x34 '4' + { 74, 4, 8, 6, 1, -7 }, // 0x35 '5' + { 78, 4, 8, 6, 1, -7 }, // 0x36 '6' + { 82, 4, 8, 6, 1, -7 }, // 0x37 '7' + { 86, 4, 8, 6, 1, -7 }, // 0x38 '8' + { 90, 5, 8, 6, 0, -7 }, // 0x39 '9' + { 95, 1, 6, 3, 1, -5 }, // 0x3A ':' + { 96, 2, 8, 3, 0, -5 }, // 0x3B ';' + { 98, 5, 5, 6, 0, -5 }, // 0x3C '<' + { 102, 4, 3, 6, 1, -4 }, // 0x3D '=' + { 104, 4, 5, 6, 1, -5 }, // 0x3E '>' + { 107, 4, 8, 5, 0, -7 }, // 0x3F '?' + { 111, 8, 10, 10, 1, -7 }, // 0x40 '@' + { 121, 7, 8, 7, 0, -7 }, // 0x41 'A' + { 128, 5, 8, 7, 1, -7 }, // 0x42 'B' + { 133, 6, 8, 7, 1, -7 }, // 0x43 'C' + { 139, 6, 8, 8, 1, -7 }, // 0x44 'D' + { 145, 5, 8, 6, 1, -7 }, // 0x45 'E' + { 150, 5, 8, 6, 1, -7 }, // 0x46 'F' + { 155, 6, 8, 8, 1, -7 }, // 0x47 'G' + { 161, 6, 8, 8, 1, -7 }, // 0x48 'H' + { 167, 3, 8, 4, 1, -7 }, // 0x49 'I' + { 170, 3, 8, 4, 0, -7 }, // 0x4A 'J' + { 173, 6, 8, 7, 1, -7 }, // 0x4B 'K' + { 179, 5, 8, 6, 1, -7 }, // 0x4C 'L' + { 184, 8, 8, 10, 1, -7 }, // 0x4D 'M' + { 192, 6, 8, 8, 1, -7 }, // 0x4E 'N' + { 198, 7, 8, 8, 1, -7 }, // 0x4F 'O' + { 205, 5, 8, 7, 1, -7 }, // 0x50 'P' + { 210, 7, 10, 8, 1, -7 }, // 0x51 'Q' + { 219, 6, 8, 7, 1, -7 }, // 0x52 'R' + { 225, 4, 8, 6, 1, -7 }, // 0x53 'S' + { 229, 6, 8, 7, 0, -7 }, // 0x54 'T' + { 235, 6, 8, 8, 1, -7 }, // 0x55 'U' + { 241, 7, 8, 7, 0, -7 }, // 0x56 'V' + { 248, 10, 8, 11, 0, -7 }, // 0x57 'W' + { 258, 6, 8, 7, 0, -7 }, // 0x58 'X' + { 264, 6, 8, 6, 0, -7 }, // 0x59 'Y' + { 270, 6, 8, 7, 0, -7 }, // 0x5A 'Z' + { 276, 2, 11, 3, 1, -8 }, // 0x5B '[' + { 279, 5, 11, 5, 0, -8 }, // 0x5C '\' + { 286, 2, 11, 3, 0, -8 }, // 0x5D ']' + { 289, 5, 4, 5, 0, -7 }, // 0x5E '^' + { 292, 5, 1, 5, 0, 2 }, // 0x5F '_' + { 293, 2, 2, 2, 0, -8 }, // 0x60 '`' + { 294, 5, 6, 5, 0, -5 }, // 0x61 'a' + { 298, 5, 9, 6, 1, -8 }, // 0x62 'b' + { 304, 4, 6, 5, 1, -5 }, // 0x63 'c' + { 307, 4, 9, 6, 1, -8 }, // 0x64 'd' + { 312, 4, 6, 6, 1, -5 }, // 0x65 'e' + { 315, 4, 9, 4, 0, -8 }, // 0x66 'f' + { 320, 6, 8, 6, 0, -5 }, // 0x67 'g' + { 326, 4, 9, 6, 1, -8 }, // 0x68 'h' + { 331, 1, 9, 3, 1, -8 }, // 0x69 'i' + { 333, 3, 11, 3, -1, -8 }, // 0x6A 'j' + { 338, 4, 9, 6, 1, -8 }, // 0x6B 'k' + { 343, 2, 9, 3, 1, -8 }, // 0x6C 'l' + { 346, 8, 6, 9, 1, -5 }, // 0x6D 'm' + { 352, 4, 6, 6, 1, -5 }, // 0x6E 'n' + { 355, 5, 6, 6, 1, -5 }, // 0x6F 'o' + { 359, 5, 8, 6, 1, -5 }, // 0x70 'p' + { 364, 4, 8, 6, 1, -5 }, // 0x71 'q' + { 368, 3, 6, 4, 1, -5 }, // 0x72 'r' + { 371, 4, 6, 5, 0, -5 }, // 0x73 's' + { 374, 4, 8, 4, 0, -7 }, // 0x74 't' + { 378, 4, 6, 6, 1, -5 }, // 0x75 'u' + { 381, 5, 6, 5, 0, -5 }, // 0x76 'v' + { 385, 8, 6, 8, 0, -5 }, // 0x77 'w' + { 391, 5, 6, 5, 0, -5 }, // 0x78 'x' + { 395, 5, 8, 5, 0, -5 }, // 0x79 'y' + { 400, 5, 6, 5, 0, -5 }, // 0x7A 'z' + { 404, 3, 11, 3, 0, -8 }, // 0x7B '{' + { 409, 1, 11, 3, 1, -8 }, // 0x7C '|' + { 411, 3, 11, 3, 0, -8 }, // 0x7D '}' + { 416, 4, 2, 6, 1, -4 } }; // 0x7E '~' + +const GFXfont BundesSans6pt7b PROGMEM = { + (uint8_t *)BundesSans6pt7bBitmaps, + (GFXglyph *)BundesSans6pt7bGlyphs, + 0x20, 0x7E, 14 }; + +// Approx. 1089 bytes diff --git a/libraries/_NToolsFonts/NT7x10.h b/libraries/_NToolsFonts/NT7x10.h new file mode 100644 index 0000000..9f5e7d1 --- /dev/null +++ b/libraries/_NToolsFonts/NT7x10.h @@ -0,0 +1,125 @@ +const uint8_t NT7x10_Bitmaps[] PROGMEM = { + 0x00, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7D, 0xFF, 0x1E, + 0x3C, 0x78, 0xF1, 0xE3, 0xFE, 0xF8, 0x00, 0x13, 0x7F, 0x33, 0x33, 0x33, + 0x7D, 0xFF, 0x18, 0x30, 0xC3, 0x0C, 0x30, 0xFF, 0xFC, 0x00, 0x7D, 0xFC, + 0x18, 0x31, 0xC3, 0x81, 0x83, 0xFE, 0xF8, 0x00, 0xC7, 0x8F, 0x1E, 0x3F, + 0xEF, 0xC1, 0x83, 0x06, 0x0C, 0x00, 0xFF, 0xFB, 0x06, 0x0F, 0xDF, 0xC1, + 0x83, 0xFE, 0xF8, 0x00, 0x7D, 0xFF, 0x1E, 0x0F, 0xDF, 0xF1, 0xE3, 0xFE, + 0xF8, 0x00, 0xFF, 0xFC, 0x18, 0x30, 0xC1, 0x86, 0x0C, 0x30, 0x60, 0x00, + 0x7D, 0xFF, 0x1E, 0x37, 0xCF, 0xB1, 0xE3, 0xFE, 0xF8, 0x00, 0x7D, 0xFF, + 0x1E, 0x3F, 0xEF, 0xC1, 0xE3, 0xFE, 0xF8, 0x00, 0x0F, 0x0F, 0x00, 0xF0, + 0xF6, 0x0C, 0x33, 0x0C, 0xC3, 0x03, 0x0C, 0x0C, 0x30, 0xF0, 0xF0, 0xC3, + 0x03, 0x0C, 0x0C, 0x33, 0x0C, 0xC3, 0x00, 0xE0, 0x00, 0x00, 0x1E, 0xFF, + 0x3C, 0xF3, 0xFD, 0xF0, 0xC1, 0x83, 0x07, 0xEF, 0xF8, 0xF1, 0xE3, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0xEF, 0xE3, 0x18, 0xFB, 0x80, 0x06, 0x0C, 0x1B, + 0xFF, 0xF8, 0xF1, 0xE3, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x1E, 0xFF, 0x3F, + 0xB0, 0xFD, 0xE0, 0x77, 0x66, 0xFF, 0x66, 0x66, 0x00, 0x00, 0x1E, 0xFF, + 0x37, 0xC3, 0x7F, 0xE0, 0xC3, 0x0C, 0x3E, 0xFF, 0x3C, 0xF3, 0xCF, 0x30, + 0xF3, 0xFF, 0xF0, 0x33, 0x03, 0x33, 0x33, 0xBF, 0xC3, 0x0C, 0x33, 0xDF, + 0xEF, 0x36, 0xDF, 0x30, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, 0xFA, + 0xF5, 0xEB, 0xD7, 0xAC, 0x00, 0x00, 0x00, 0x3E, 0xFF, 0x3C, 0xF3, 0xCF, + 0x30, 0x00, 0x00, 0x1E, 0xFF, 0x3C, 0xF3, 0xFD, 0xE0, 0x00, 0x00, 0x1E, + 0xFF, 0x3C, 0xFE, 0xC3, 0x00, 0x00, 0x00, 0x1E, 0xFF, 0x3C, 0xDF, 0x0C, + 0x30, 0x00, 0x0F, 0xEC, 0xCC, 0xCC, 0x00, 0x00, 0x1F, 0xFF, 0x07, 0x83, + 0xFF, 0xE0, 0x66, 0xFF, 0x66, 0x66, 0x66, 0x00, 0x00, 0x33, 0xCF, 0x3C, + 0xF3, 0xFD, 0xE0, 0x00, 0x00, 0x33, 0xCF, 0x3C, 0xF3, 0x78, 0xC0, 0x00, + 0x00, 0x06, 0x3C, 0x7A, 0xF5, 0xEB, 0xFE, 0xD8, 0x00, 0x00, 0x00, 0x33, + 0xCC, 0xC3, 0x0C, 0xCF, 0x30, 0x00, 0x01, 0xBD, 0xEF, 0x7F, 0x33, 0x80, + 0x00, 0x00, 0x3F, 0xFC, 0x33, 0x98, 0xFF, 0xF0 +}; + +const GFXglyph NT7x10_Glyphs[] PROGMEM = { + { 0, 1, 1, 3, 0, -10 }, // 0x20 ' ' + { 0, 0, 0, 0, 0, 0 }, // 0x21 '!' + { 0, 0, 0, 0, 0, 0 }, // 0x22 '"' + { 0, 0, 0, 0, 0, 0 }, // 0x23 '#' + { 0, 0, 0, 0, 0, 0 }, // 0x24 '$' + { 0, 0, 0, 0, 0, 0 }, // 0x25 '%' + { 0, 0, 0, 0, 0, 0 }, // 0x26 '&' + { 0, 0, 0, 0, 0, 0 }, // 0x27 ''' + { 0, 0, 0, 0, 0, 0 }, // 0x28 '(' + { 0, 0, 0, 0, 0, 0 }, // 0x29 ')' + { 0, 0, 0, 0, 0, 0 }, // 0x2A '*' + { 0, 0, 0, 0, 0, 0 }, // 0x2B '+' + { 0, 0, 0, 0, 0, 0 }, // 0x2C ',' + { 1, 3, 10, 4, 0, -10 }, // 0x2D '-' + { 6, 2, 10, 3, 0, -10 }, // 0x2E '.' + { 0, 0, 0, 0, 0, 0 }, // 0x2F '/' + { 9, 7, 10, 8, 0, -10 }, // 0x30 '0' + { 19, 4, 10, 5, 0, -10 }, // 0x31 '1' + { 24, 7, 10, 8, 0, -10 }, // 0x32 '2' + { 34, 7, 10, 8, 0, -10 }, // 0x33 '3' + { 44, 7, 10, 8, 0, -10 }, // 0x34 '4' + { 54, 7, 10, 8, 0, -10 }, // 0x35 '5' + { 64, 7, 10, 8, 0, -10 }, // 0x36 '6' + { 74, 7, 10, 8, 0, -10 }, // 0x37 '7' + { 84, 7, 10, 8, 0, -10 }, // 0x38 '8' + { 94, 7, 10, 8, 0, -10 }, // 0x39 '9' + { 104, 2, 10, 3, 0, -10 }, // 0x3A ':' + { 107, 2, 8, 3, 0, -7 }, // 0x3B ';' + { 109, 6, 10, 7, 0, -10 }, // 0x3C '<' + { 117, 4, 3, 5, 0, -6 }, // 0x3D '=' + { 119, 6, 10, 7, 0, -10 }, // 0x3E '>' + { 0, 0, 0, 0, 0, 0 }, // 0x3F '?' + { 0, 0, 0, 0, 0, 0 }, // 0x40 '@' + { 0, 0, 0, 0, 0, 0 }, // 0x41 'A' + { 0, 0, 0, 0, 0, 0 }, // 0x42 'B' + { 0, 0, 0, 0, 0, 0 }, // 0x43 'C' + { 0, 0, 0, 0, 0, 0 }, // 0x44 'D' + { 0, 0, 0, 0, 0, 0 }, // 0x45 'E' + { 0, 0, 0, 0, 0, 0 }, // 0x46 'F' + { 0, 0, 0, 0, 0, 0 }, // 0x47 'G' + { 0, 0, 0, 0, 0, 0 }, // 0x48 'H' + { 0, 0, 0, 0, 0, 0 }, // 0x49 'I' + { 0, 0, 0, 0, 0, 0 }, // 0x4A 'J' + { 0, 0, 0, 0, 0, 0 }, // 0x4B 'K' + { 0, 0, 0, 0, 0, 0 }, // 0x4C 'L' + { 0, 0, 0, 0, 0, 0 }, // 0x4D 'M' + { 0, 0, 0, 0, 0, 0 }, // 0x4E 'N' + { 0, 0, 0, 0, 0, 0 }, // 0x4F 'O' + { 0, 0, 0, 0, 0, 0 }, // 0x50 'P' + { 0, 0, 0, 0, 0, 0 }, // 0x51 'Q' + { 0, 0, 0, 0, 0, 0 }, // 0x52 'R' + { 0, 0, 0, 0, 0, 0 }, // 0x53 'S' + { 0, 0, 0, 0, 0, 0 }, // 0x54 'T' + { 0, 0, 0, 0, 0, 0 }, // 0x55 'U' + { 0, 0, 0, 0, 0, 0 }, // 0x56 'V' + { 0, 0, 0, 0, 0, 0 }, // 0x57 'W' + { 0, 0, 0, 0, 0, 0 }, // 0x58 'X' + { 0, 0, 0, 0, 0, 0 }, // 0x59 'Y' + { 0, 0, 0, 0, 0, 0 }, // 0x5A 'Z' + { 0, 0, 0, 0, 0, 0 }, // 0x5B '[' + { 0, 0, 0, 0, 0, 0 }, // 0x5C '\' + { 0, 0, 0, 0, 0, 0 }, // 0x5D ']' + { 0, 0, 0, 0, 0, 0 }, // 0x5E '^' + { 127, 3, 1, 4, 0, 0 }, // 0x5F '_' + { 0, 0, 0, 0, 0, 0 }, // 0x60 '`' + { 128, 6, 10, 7, 0, -10 }, // 0x61 'a' + { 136, 7, 10, 8, 0, -10 }, // 0x62 'b' + { 146, 5, 10, 6, 0, -10 }, // 0x63 'c' + { 153, 7, 10, 8, 0, -10 }, // 0x64 'd' + { 163, 6, 10, 7, 0, -10 }, // 0x65 'e' + { 171, 4, 10, 5, 0, -10 }, // 0x66 'f' + { 176, 6, 10, 7, 0, -10 }, // 0x67 'g' + { 184, 6, 10, 7, 0, -10 }, // 0x68 'h' + { 192, 2, 10, 3, 0, -10 }, // 0x69 'i' + { 195, 4, 10, 5, 0, -10 }, // 0x6A 'j' + { 200, 6, 10, 7, 0, -10 }, // 0x6B 'k' + { 208, 2, 10, 3, 0, -10 }, // 0x6C 'l' + { 211, 7, 10, 8, 0, -10 }, // 0x6D 'm' + { 221, 6, 10, 7, 0, -10 }, // 0x6E 'n' + { 229, 6, 10, 7, 0, -10 }, // 0x6F 'o' + { 237, 6, 10, 7, 0, -10 }, // 0x70 'p' + { 245, 6, 10, 7, 0, -10 }, // 0x71 'q' + { 253, 4, 10, 5, 0, -10 }, // 0x72 'r' + { 258, 6, 10, 7, 0, -10 }, // 0x73 's' + { 266, 4, 10, 5, 0, -10 }, // 0x74 't' + { 271, 6, 10, 7, 0, -10 }, // 0x75 'u' + { 279, 6, 10, 7, 0, -10 }, // 0x76 'v' + { 287, 7, 10, 8, 0, -10 }, // 0x77 'w' + { 297, 6, 10, 7, 0, -10 }, // 0x78 'x' + { 305, 5, 10, 6, 0, -10 }, // 0x79 'y' + { 312, 6, 10, 7, 0, -10 } // 0x7A 'z' +}; + +const GFXfont NT7x10 PROGMEM = {(uint8_t *) NT7x10_Bitmaps, (GFXglyph *)NT7x10_Glyphs, 0x20, 0x7A, 10}; diff --git a/libraries/_NToolsFonts/TECH8p.h b/libraries/_NToolsFonts/TECH8p.h new file mode 100644 index 0000000..f48a8bc --- /dev/null +++ b/libraries/_NToolsFonts/TECH8p.h @@ -0,0 +1,147 @@ +const uint8_t TECH28pt7bBitmaps[] PROGMEM = { + 0x00, 0xFC, 0x7F, 0xF6, 0xFF, 0x50, 0xFB, 0xD0, 0x3D, 0xF4, 0x1F, 0x7D, + 0xC7, 0x10, 0x3D, 0xF4, 0x10, 0x41, 0xFF, 0xF0, 0x3D, 0xF4, 0x1F, 0x7D, + 0xFB, 0xD0, 0x01, 0x04, 0x10, 0x41, 0xF4, 0x7C, 0x6D, 0xBF, 0xDC, 0x36, + 0xFF, 0x7B, 0xD0, 0x3D, 0xF7, 0x1F, 0x7D, 0x30, 0xC0, 0x3D, 0xF4, 0xC3, + 0x0C, 0xF4, 0xFF, 0x0F, 0xF0, 0xF0, 0x04, 0x10, 0x1F, 0x73, 0xCC, 0x30, + 0x7B, 0xF0, 0x33, 0xCF, 0x3F, 0xFF, 0xFC, 0x7F, 0xFF, 0xFB, 0xF0, 0x1F, + 0xFF, 0x8F, 0xFF, 0xEB, 0xB0, 0x3B, 0xEC, 0x3E, 0xFB, 0xCF, 0x30, 0x3F, + 0xFC, 0x30, 0xC3, 0xFF, 0xF0, 0x3F, 0xFC, 0x7F, 0xFF, 0xC3, 0x00, 0x37, + 0xDF, 0x0F, 0xFF, 0xEB, 0xB0, 0x03, 0x0C, 0x30, 0xC3, 0x7B, 0xF0, 0x3F, + 0xFF, 0x3F, 0xFF, 0x7F, 0xF0, 0x3B, 0xEC, 0x30, 0xC3, 0xFF, 0xFF, 0x40, + 0x7C, 0x6D, 0xBF, 0xFF, 0x0F, 0xF0, 0xDC, 0x12, 0x7F, 0xFB, 0xF0, 0x1F, + 0xFF, 0x8C, 0x30, 0xFB, 0xD0, 0x1D, 0xF7, 0x0F, 0xFF, 0x7B, 0xF0, 0x3F, + 0xFF, 0x3C, 0xF3, 0xFB, 0xF0, 0x3F, 0xFF, 0x3F, 0xFF, 0x5F, 0x70, 0x30, + 0xC3, 0x0D, 0xF7, 0xEB, 0xB0, 0x33, 0xCF, 0x3E, 0xFB, 0x5F, 0x70, 0x37, + 0xDF, 0x0D, 0xF7, 0x5F, 0x70, 0x37, 0xDF, 0x0C, 0x30, 0x5F, 0x70, 0x37, + 0xDF, 0x1D, 0xF7, 0xCF, 0x30, 0x3F, 0xFF, 0x3C, 0xF3, 0xFF, 0xF0, 0x0C, + 0x30, 0xCF, 0xFF, 0x0C, 0x30, 0x03, 0x0C, 0x3E, 0xFB, 0xCF, 0x30, 0x3F, + 0xFF, 0x3C, 0xF3, 0xC3, 0x00, 0x30, 0xC3, 0x0D, 0xF7, 0xFE, 0x9F, 0xD8, + 0x00, 0xE6, 0x7C, 0xCF, 0x99, 0xF3, 0x3E, 0x67, 0xFB, 0xF0, 0x33, 0xCF, + 0x3C, 0xF3, 0x7B, 0xF0, 0x33, 0xCF, 0x3F, 0xFF, 0xFB, 0xF0, 0x37, 0xDF, + 0x0C, 0x30, 0x7B, 0xF0, 0x33, 0xCF, 0x3F, 0xFF, 0x30, 0xFB, 0xF0, 0x37, + 0xDF, 0x0D, 0xB7, 0x7F, 0xF0, 0x3F, 0xFC, 0x7F, 0xFF, 0xFF, 0xF0, 0x0C, + 0x30, 0xC3, 0x0C, 0xCF, 0x30, 0x33, 0xCF, 0x3F, 0xFF, 0xCF, 0x30, 0x33, + 0xCF, 0x3F, 0xCC, 0xCC, 0xF9, 0x9C, 0x00, 0x66, 0x7C, 0xCF, 0x99, 0xFF, + 0xBF, 0xF6, 0xCF, 0x30, 0x3F, 0xFF, 0x3C, 0xF3, 0xCF, 0x30, 0x33, 0xFF, + 0xF3, 0x0C, 0xFF, 0xF0, 0x1F, 0xFB, 0x8F, 0xFF, 0x7C, 0x6D, 0xBF, 0xC3, + 0x00, 0x3E, 0x34, 0xD0, 0x41, 0xDC, 0x36, 0xFF, 0xC3, 0x00, 0x3D, 0xF7, + 0x0F, 0x7D, 0xFF, 0xF4, 0x7B, 0xD0, 0x3D, 0xF7, 0x1C, 0x71, 0xFB, 0xD0, + 0x3D, 0xF7, 0x1F, 0x7D, 0x7F, 0xF0, 0x30, 0xC3, 0x0F, 0xFF, 0xFB, 0xD0, + 0x31, 0xC7, 0x1F, 0x7D, 0x7F, 0xF0, 0x3F, 0xFF, 0x0F, 0xFF, 0x7F, 0xF0, + 0x3F, 0xFF, 0x0C, 0x30, 0x7F, 0xF0, 0x37, 0xDF, 0x1F, 0xFF, 0xC7, 0x10, + 0x3D, 0xF7, 0x1C, 0x71, 0xF7, 0xD0, 0x0C, 0x30, 0xCF, 0x7D, 0x04, 0x10, + 0x01, 0x04, 0x1F, 0x7D, 0xC7, 0x10, 0x3D, 0xF7, 0x1C, 0x71, 0xC3, 0x00, + 0x30, 0xC3, 0x0F, 0x7D, 0xFF, 0x9F, 0xE8, 0x00, 0xE6, 0x3C, 0xC7, 0x98, + 0xF3, 0x1E, 0x63, 0xFB, 0xD0, 0x31, 0xC7, 0x1C, 0x71, 0x7B, 0xD0, 0x31, + 0xC7, 0x1F, 0x7D, 0xFB, 0xD0, 0x3D, 0xF7, 0x0C, 0x30, 0x7B, 0xD0, 0x31, + 0xC7, 0x1F, 0x7D, 0x30, 0xFB, 0xD0, 0x3D, 0xF7, 0x0C, 0xB3, 0x7F, 0xF0, + 0x3D, 0xF4, 0x1F, 0x7D, 0xF7, 0xD0, 0x0C, 0x30, 0xC3, 0x0C, 0xC7, 0x10, + 0x31, 0xC7, 0x1F, 0x7D, 0xC7, 0x10, 0x31, 0xC7, 0x1F, 0x4C, 0xCC, 0x79, + 0x8C, 0x00, 0x66, 0x3C, 0xC7, 0x98, 0xFF, 0xDF, 0xFA, 0xC7, 0x10, 0x3D, + 0x77, 0x1C, 0x71, 0xC7, 0x10, 0x31, 0xFF, 0xF3, 0x0C, 0xF7, 0xD0, 0x1D, + 0xFB, 0x0F, 0xFF, 0x7C, 0x6D, 0xBF, 0x00, 0xDC, 0x12, 0x7F, 0x00 }; + +const GFXglyph TECH28pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 5, 0, 0 }, // 0x20 ' ' + { 1, 3, 8, 4, 1, -11 }, // 0x21 '!' + { 4, 4, 3, 5, 1, -11 }, // 0x22 '"' + { 6, 6, 8, 8, 1, -11 }, // 0x23 '#' + { 12, 6, 8, 8, 1, -11 }, // 0x24 '$' + { 18, 6, 8, 8, 1, -11 }, // 0x25 '%' + { 24, 6, 8, 8, 1, -11 }, // 0x26 '&' + { 30, 2, 3, 3, 1, -11 }, // 0x27 ''' + { 31, 3, 8, 5, 1, -11 }, // 0x28 '(' + { 34, 3, 8, 5, 1, -11 }, // 0x29 ')' + { 37, 6, 8, 8, 1, -11 }, // 0x2A '*' + { 43, 6, 8, 8, 1, -11 }, // 0x2B '+' + { 49, 2, 3, 3, 1, -5 }, // 0x2C ',' + { 50, 4, 5, 5, 1, -8 }, // 0x2D '-' + { 53, 2, 2, 3, 1, -5 }, // 0x2E '.' + { 54, 6, 8, 8, 1, -11 }, // 0x2F '/' + { 60, 6, 8, 8, 1, -11 }, // 0x30 '0' + { 66, 3, 8, 4, 1, -11 }, // 0x31 '1' + { 69, 6, 8, 8, 1, -11 }, // 0x32 '2' + { 75, 6, 8, 8, 1, -11 }, // 0x33 '3' + { 81, 6, 8, 8, 1, -11 }, // 0x34 '4' + { 87, 6, 8, 8, 1, -11 }, // 0x35 '5' + { 93, 6, 8, 8, 1, -11 }, // 0x36 '6' + { 99, 6, 8, 8, 1, -11 }, // 0x37 '7' + { 105, 6, 8, 8, 1, -11 }, // 0x38 '8' + { 111, 6, 8, 8, 1, -11 }, // 0x39 '9' + { 117, 2, 4, 3, 1, -7 }, // 0x3A ':' + { 118, 2, 5, 3, 1, -7 }, // 0x3B ';' + { 120, 3, 8, 5, 1, -11 }, // 0x3C '<' + { 123, 4, 5, 5, 1, -9 }, // 0x3D '=' + { 126, 3, 8, 5, 1, -11 }, // 0x3E '>' + { 129, 6, 8, 8, 1, -11 }, // 0x3F '?' + { 135, 6, 8, 8, 1, -11 }, // 0x40 '@' + { 141, 6, 8, 8, 1, -11 }, // 0x41 'A' + { 147, 6, 8, 8, 1, -11 }, // 0x42 'B' + { 153, 6, 8, 8, 1, -11 }, // 0x43 'C' + { 159, 6, 8, 8, 1, -11 }, // 0x44 'D' + { 165, 6, 8, 8, 1, -11 }, // 0x45 'E' + { 171, 6, 8, 8, 1, -11 }, // 0x46 'F' + { 177, 6, 8, 8, 1, -11 }, // 0x47 'G' + { 183, 6, 8, 8, 1, -11 }, // 0x48 'H' + { 189, 6, 8, 8, 1, -11 }, // 0x49 'I' + { 195, 6, 8, 8, 1, -11 }, // 0x4A 'J' + { 201, 6, 8, 8, 1, -11 }, // 0x4B 'K' + { 207, 6, 8, 8, 1, -11 }, // 0x4C 'L' + { 213, 11, 8, 12, 1, -11 }, // 0x4D 'M' + { 224, 6, 8, 8, 1, -11 }, // 0x4E 'N' + { 230, 6, 8, 8, 1, -11 }, // 0x4F 'O' + { 236, 6, 8, 8, 1, -11 }, // 0x50 'P' + { 242, 6, 9, 8, 1, -11 }, // 0x51 'Q' + { 249, 6, 8, 8, 1, -11 }, // 0x52 'R' + { 255, 6, 8, 8, 1, -11 }, // 0x53 'S' + { 261, 6, 8, 8, 1, -11 }, // 0x54 'T' + { 267, 6, 8, 8, 1, -11 }, // 0x55 'U' + { 273, 6, 8, 8, 1, -11 }, // 0x56 'V' + { 279, 11, 8, 12, 1, -11 }, // 0x57 'W' + { 290, 6, 8, 8, 1, -11 }, // 0x58 'X' + { 296, 6, 8, 8, 1, -11 }, // 0x59 'Y' + { 302, 6, 8, 8, 1, -11 }, // 0x5A 'Z' + { 308, 3, 8, 5, 1, -11 }, // 0x5B '[' + { 311, 6, 8, 8, 1, -11 }, // 0x5C '\' + { 317, 3, 8, 5, 1, -11 }, // 0x5D ']' + { 320, 6, 8, 8, 1, -11 }, // 0x5E '^' + { 326, 8, 1, 8, 0, -3 }, // 0x5F '_' + { 327, 2, 3, 3, 1, -11 }, // 0x60 '`' + { 328, 6, 8, 8, 1, -11 }, // 0x61 'a' + { 334, 6, 8, 8, 1, -11 }, // 0x62 'b' + { 340, 6, 8, 8, 1, -11 }, // 0x63 'c' + { 346, 6, 8, 8, 1, -11 }, // 0x64 'd' + { 352, 6, 8, 8, 1, -11 }, // 0x65 'e' + { 358, 6, 8, 8, 1, -11 }, // 0x66 'f' + { 364, 6, 8, 8, 1, -11 }, // 0x67 'g' + { 370, 6, 8, 8, 1, -11 }, // 0x68 'h' + { 376, 6, 8, 8, 1, -11 }, // 0x69 'i' + { 382, 6, 8, 8, 1, -11 }, // 0x6A 'j' + { 388, 6, 8, 8, 1, -11 }, // 0x6B 'k' + { 394, 6, 8, 8, 1, -11 }, // 0x6C 'l' + { 400, 11, 8, 12, 1, -11 }, // 0x6D 'm' + { 411, 6, 8, 8, 1, -11 }, // 0x6E 'n' + { 417, 6, 8, 8, 1, -11 }, // 0x6F 'o' + { 423, 6, 8, 8, 1, -11 }, // 0x70 'p' + { 429, 6, 9, 8, 1, -11 }, // 0x71 'q' + { 436, 6, 8, 8, 1, -11 }, // 0x72 'r' + { 442, 6, 8, 8, 1, -11 }, // 0x73 's' + { 448, 6, 8, 8, 1, -11 }, // 0x74 't' + { 454, 6, 8, 8, 1, -11 }, // 0x75 'u' + { 460, 6, 8, 8, 1, -11 }, // 0x76 'v' + { 466, 11, 8, 12, 1, -11 }, // 0x77 'w' + { 477, 6, 8, 8, 1, -11 }, // 0x78 'x' + { 483, 6, 8, 8, 1, -11 }, // 0x79 'y' + { 489, 6, 8, 8, 1, -11 }, // 0x7A 'z' + { 495, 3, 8, 5, 1, -11 }, // 0x7B '{' + { 498, 1, 1, 3, 0, 0 }, // 0x7C '|' + { 499, 3, 8, 5, 1, -11 }, // 0x7D '}' + { 502, 1, 1, 5, 0, 0 } }; // 0x7E '~' + +const GFXfont TECH28pt7b PROGMEM = { + (uint8_t *)TECH28pt7bBitmaps, + (GFXglyph *)TECH28pt7bGlyphs, + 0x20, 0x7E, 16 }; + +// Approx. 1175 bytes diff --git a/libraries/_NToolsFonts/char10x16.h b/libraries/_NToolsFonts/char10x16.h new file mode 100644 index 0000000..f67ffed --- /dev/null +++ b/libraries/_NToolsFonts/char10x16.h @@ -0,0 +1,202 @@ +void Out10x16Char(char charater, uint8_t x, uint8_t y, uint8_t red,uint8_t green,uint8_t blue){ + switch (charater){ + case '0': + LineH(x+2,y,6,red,green,blue); + LineH(x+1,y+1,8,red,green,blue); + LineH(x,y+2,10,red,green,blue); + LineV(x,y+3,10,red,green,blue); + LineV(x+1,y+3,10,red,green,blue); + LineV(x+2,y+3,10,red,green,blue); + LineV(x+7,y+3,10,red,green,blue); + LineV(x+8,y+3,10,red,green,blue); + LineV(x+9,y+3,10,red,green,blue); + LineH(x,y+13,10,red,green,blue); + LineH(x+1,y+14,8,red,green,blue); + LineH(x+2,y+15,6,red,green,blue); + break; + case '1': + LineV(x+3,y+3,3,red,green,blue); + LineV(x+4,y+2,3,red,green,blue); + LineV(x+5,y+1,3,red,green,blue); + LineV(x+6,y,3,red,green,blue); + LineV(x+7,y,16,red,green,blue); + LineV(x+8,y,16,red,green,blue); + LineV(x+9,y,16,red,green,blue); + break; + case '2': + LineH(x+2,y,6,red,green,blue); + LineH(x+1,y+1,8,red,green,blue); + LineH(x,y+2,10,red,green,blue); + LineH(x,y+3,3,red,green,blue); + LineV(x+8,y+2,5,red,green,blue); + LineV(x+9,y+2,5,red,green,blue); + LineV(x+7,y+2,5,red,green,blue); + LineH(x+6,y+7,3,red,green,blue); + LineH(x+5,y+8,3,red,green,blue); + LineH(x+4,y+9,3,red,green,blue); + LineH(x+3,y+10,3,red,green,blue); + LineH(x+2,y+11,3,red,green,blue); + LineH(x+1,y+12,3,red,green,blue); + LineH(x,y+13,10,red,green,blue); + LineH(x,y+14,10,red,green,blue); + LineH(x,y+15,10,red,green,blue); + break; + case '3': + LineH(x+2,y,6,red,green,blue); + LineH(x+1,y+1,8,red,green,blue); + LineH(x,y+2,10,red,green,blue); + LineH(x,y+3,3,red,green,blue); + LineV(x+7,y+2,12,red,green,blue); + LineV(x+8,y+2,12,red,green,blue); + LineV(x+9,y+2,5,red,green,blue); + LineV(x+9,y+9,5,red,green,blue); + LineH(x+4,y+7,4,red,green,blue); + LineH(x+4,y+8,4,red,green,blue); + LineH(x,y+12,3,red,green,blue); + LineH(x,y+13,10,red,green,blue); + LineH(x+1,y+14,8,red,green,blue); + LineH(x+2,y+15,6,red,green,blue); + break; + case '4': + LineV(x,y,7,red,green,blue); + LineV(x+1,y,8,red,green,blue); + LineV(x+2,y,8,red,green,blue); + LineH(x+2,y+7,6,red,green,blue); + LineH(x+2,y+8,6,red,green,blue); + LineV(x+7,y,16,red,green,blue); + LineV(x+8,y,16,red,green,blue); + LineV(x+9,y,16,red,green,blue); + break; + case '5': + LineH(x+1,y,9,red,green,blue); + LineH(x,y+1,10,red,green,blue); + LineH(x,y+2,9,red,green,blue); + LineV(x,y+3,5,red,green,blue); + LineV(x+1,y+3,6,red,green,blue); + LineV(x+2,y+3,6,red,green,blue); + LineH(x+3,y+7,5,red,green,blue); + LineH(x+3,y+8,6,red,green,blue); + LineV(x+7,y+8,6,red,green,blue); + LineV(x+8,y+8,6,red,green,blue); + LineV(x+9,y+9,5,red,green,blue); + LineH(x,y+12,3,red,green,blue); + LineH(x,y+13,7,red,green,blue); + LineH(x+1,y+14,8,red,green,blue); + LineH(x+2,y+15,6,red,green,blue); + break; + case '6': + LineH(x+2,y,6,red,green,blue); + LineH(x+1,y+1,8,red,green,blue); + LineH(x,y+2,10,red,green,blue); + LineV(x,y+2,12,red,green,blue); + LineV(x+1,y+1,14,red,green,blue); + LineV(x+2,y+1,14,red,green,blue); + LineH(x+7,y+3,3,red,green,blue); + LineH(x+2,y+7,6,red,green,blue); + LineH(x+2,y+8,6,red,green,blue); + LineV(x+7,y+8,6,red,green,blue); + LineV(x+8,y+8,6,red,green,blue); + LineV(x+9,y+9,5,red,green,blue); + LineH(x,y+13,10,red,green,blue); + LineH(x+1,y+14,8,red,green,blue); + LineH(x+2,y+15,6,red,green,blue); + break; + case '7': + LineH(x+1,y,9,red,green,blue); + LineH(x,y+1,10,red,green,blue); + LineH(x,y+2,10,red,green,blue); + LineV(x+7,y+2,2,red,green,blue); + LineV(x+8,y+2,2,red,green,blue); + LineV(x+9,y+2,2,red,green,blue); + LineV(x+6,y+4,3,red,green,blue); + LineV(x+7,y+4,3,red,green,blue); + LineV(x+8,y+4,3,red,green,blue); + LineV(x+5,y+7,3,red,green,blue); + LineV(x+6,y+7,3,red,green,blue); + LineV(x+7,y+7,3,red,green,blue); + LineV(x+4,y+10,3,red,green,blue); + LineV(x+5,y+10,3,red,green,blue); + LineV(x+6,y+10,3,red,green,blue); + LineV(x+3,y+13,3,red,green,blue); + LineV(x+4,y+13,3,red,green,blue); + LineV(x+5,y+13,3,red,green,blue); + break; + case '8': + LineH(x+2,y,6,red,green,blue); + LineH(x+1,y+1,8,red,green,blue); + LineH(x,y+2,10,red,green,blue); + LineV(x,y+2,5,red,green,blue); + LineV(x+1,y+2,5,red,green,blue); + LineV(x+2,y+2,5,red,green,blue); + LineV(x,y+9,5,red,green,blue); + LineV(x+1,y+9,5,red,green,blue); + LineV(x+2,y+9,5,red,green,blue); + LineV(x+7,y+2,5,red,green,blue); + LineV(x+8,y+2,5,red,green,blue); + LineV(x+9,y+2,5,red,green,blue); + LineV(x+7,y+9,5,red,green,blue); + LineV(x+8,y+9,5,red,green,blue); + LineV(x+9,y+9,5,red,green,blue); + LineH(x+1,y+7,8,red,green,blue); + LineH(x+1,y+8,8,red,green,blue); + LineH(x,y+13,10,red,green,blue); + LineH(x+1,y+14,8,red,green,blue); + LineH(x+2,y+15,6,red,green,blue); + break; + case '9': + LineH(x+2,y,6,red,green,blue); + LineH(x+1,y+1,8,red,green,blue); + LineH(x,y+2,10,red,green,blue); + LineV(x,y+2,5,red,green,blue); + LineV(x+1,y+2,5,red,green,blue); + LineV(x+2,y+2,5,red,green,blue); + LineV(x+7,y+2,5,red,green,blue); + LineV(x+8,y+2,5,red,green,blue); + LineV(x+9,y+2,5,red,green,blue); + LineV(x+7,y+9,5,red,green,blue); + LineV(x+8,y+9,5,red,green,blue); + LineV(x+9,y+9,5,red,green,blue); + LineH(x+1,y+7,9,red,green,blue); + LineH(x+2,y+8,8,red,green,blue); + LineH(x,y+12,3,red,green,blue); + LineH(x,y+13,10,red,green,blue); + LineH(x+1,y+14,8,red,green,blue); + LineH(x+2,y+15,6,red,green,blue); + break; + case '.': + LineH(x,y+10,2,red,green,blue); + LineH(x,y+11,2,red,green,blue); + break; + case ':': + LineH(x,y+4,2,red,green,blue); + LineH(x,y+5,2,red,green,blue); + LineH(x,y+10,2,red,green,blue); + LineH(x,y+11,2,red,green,blue); + break; + case '>': + LineH(x+2,y+1,2,red,green,blue); + LineH(x+2,y+2,2,red,green,blue); + LineH(x+4,y+3,2,red,green,blue); + LineH(x+4,y+4,2,red,green,blue); + LineH(x+6,y+5,2,red,green,blue); + LineH(x+6,y+6,2,red,green,blue); + LineH(x+8,y+7,2,red,green,blue); + LineH(x+8,y+8,2,red,green,blue); + LineH(x+6,y+9,2,red,green,blue); + LineH(x+6,y+10,2,red,green,blue); + LineH(x+4,y+11,2,red,green,blue); + LineH(x+4,y+12,2,red,green,blue); + LineH(x+2,y+13,2,red,green,blue); + LineH(x+2,y+14,2,red,green,blue); + break; + case ' ': + for(uint8_t var= 0;var < 10;var++){ + LineV(x+var,y,16,0,0,0); + } + break; + case '-': + LineH(x+2,y+7,6,red,green,blue); + LineH(x+2,y+8,6,red,green,blue); + break; + } +} \ No newline at end of file diff --git a/libraries/_NToolsFonts/char10x16_light.h b/libraries/_NToolsFonts/char10x16_light.h new file mode 100644 index 0000000..821493c --- /dev/null +++ b/libraries/_NToolsFonts/char10x16_light.h @@ -0,0 +1,203 @@ +void Out10x16Char_light(char charater, uint8_t x, uint8_t y, uint8_t red,uint8_t green,uint8_t blue){ + switch (charater){ + case '0': + LineH(x+2,y,6,red,green,blue); + LineH(x+1,y+1,8,red,green,blue); + LineH(x,y+2,3,red,green,blue); + LineH(x+7,y+2,3,red,green,blue); + LineV(x,y+3,10,red,green,blue); + LineV(x+1,y+3,10,red,green,blue); + LineV(x+8,y+3,10,red,green,blue); + LineV(x+9,y+3,10,red,green,blue); + LineH(x,y+13,3,red,green,blue); + LineH(x+7,y+13,3,red,green,blue); + LineH(x+1,y+14,8,red,green,blue); + LineH(x+2,y+15,6,red,green,blue); + break; + case '1': + LineV(x+4,y+3,2,red,green,blue); + LineV(x+5,y+2,2,red,green,blue); + LineV(x+6,y+1,2,red,green,blue); + LineV(x+7,y,2,red,green,blue); + LineV(x+8,y,16,red,green,blue); + LineV(x+9,y,16,red,green,blue); + break; + case '2': + LineH(x+2,y,6,red,green,blue); + LineH(x+1,y+1,8,red,green,blue); + LineH(x,y+2,3,red,green,blue); + LineH(x+7,y+2,3,red,green,blue); + LineH(x,y+3,2,red,green,blue); + LineV(x+8,y+3,3,red,green,blue); + LineV(x+9,y+3,3,red,green,blue); + LineH(x+7,y+6,2,red,green,blue); + LineH(x+6,y+7,2,red,green,blue); + LineH(x+5,y+8,2,red,green,blue); + LineH(x+4,y+9,2,red,green,blue); + LineH(x+3,y+10,2,red,green,blue); + LineH(x+2,y+11,2,red,green,blue); + LineH(x+1,y+12,2,red,green,blue); + LineH(x,y+13,2,red,green,blue); + LineH(x,y+14,10,red,green,blue); + LineH(x,y+15,10,red,green,blue); + break; + case '3': + LineH(x+2,y,6,red,green,blue); + LineH(x+1,y+1,8,red,green,blue); + LineH(x,y+2,3,red,green,blue); + LineH(x,y+3,2,red,green,blue); + LineH(x+7,y+2,3,red,green,blue); + LineV(x+8,y+3,10,red,green,blue); + LineV(x+9,y+3,4,red,green,blue); + LineV(x+9,y+9,4,red,green,blue); + LineH(x+4,y+7,4,red,green,blue); + LineH(x+4,y+8,4,red,green,blue); + LineH(x,y+12,2,red,green,blue); + LineH(x,y+13,3,red,green,blue); + LineH(x+7,y+13,3,red,green,blue); + LineH(x+1,y+14,8,red,green,blue); + LineH(x+2,y+15,6,red,green,blue); + break; + case '4': + LineV(x,y,7,red,green,blue); + LineV(x+1,y,8,red,green,blue); + LineH(x+2,y+6,1,red,green,blue); + LineH(x+2,y+7,7,red,green,blue); + LineH(x+2,y+8,7,red,green,blue); + LineV(x+8,y,16,red,green,blue); + LineV(x+9,y,16,red,green,blue); + break; + case '5': + LineH(x+1,y,9,red,green,blue); + LineH(x,y+1,10,red,green,blue); + LineH(x,y+2,2,red,green,blue); + LineV(x,y+3,5,red,green,blue); + LineV(x+1,y+3,6,red,green,blue); + LineH(x+2,y+7,6,red,green,blue); + LineH(x+2,y+8,7,red,green,blue); + LineV(x+7,y+9,1,red,green,blue); + LineV(x+8,y+8,6,red,green,blue); + LineV(x+9,y+9,5,red,green,blue); + LineV(x+7,y+13,1,red,green,blue); + LineH(x,y+12,2,red,green,blue); + LineH(x,y+13,3,red,green,blue); + LineH(x+1,y+14,8,red,green,blue); + LineH(x+2,y+15,6,red,green,blue); + break; + case '6': + LineH(x+2,y,6,red,green,blue); + LineH(x+1,y+1,8,red,green,blue); + LineH(x,y+2,3,red,green,blue); + LineH(x+7,y+2,3,red,green,blue); + LineV(x,y+3,11,red,green,blue); + LineV(x+1,y+3,12,red,green,blue); + LineV(x+2,y+13,3,red,green,blue); + LineH(x+8,y+3,2,red,green,blue); + LineH(x+2,y+7,6,red,green,blue); + LineH(x+2,y+8,6,red,green,blue); + LineV(x+2,y+9,1,red,green,blue); + LineV(x+7,y+9,1,red,green,blue); + LineV(x+8,y+8,6,red,green,blue); + LineV(x+9,y+9,5,red,green,blue); + LineH(x+7,y+13,1,red,green,blue); + LineH(x+3,y+14,6,red,green,blue); + LineH(x+3,y+15,5,red,green,blue); + break; + case '7': + LineH(x+1,y,9,red,green,blue); + LineH(x,y+1,10,red,green,blue); + LineH(x,y+2,2,red,green,blue); + LineV(x+8,y+2,2,red,green,blue); + LineV(x+9,y+2,2,red,green,blue); + LineV(x+7,y+4,2,red,green,blue); + LineV(x+8,y+4,2,red,green,blue); + LineV(x+6,y+6,2,red,green,blue); + LineV(x+7,y+6,2,red,green,blue); + LineV(x+5,y+8,2,red,green,blue); + LineV(x+6,y+8,2,red,green,blue); + LineV(x+4,y+10,2,red,green,blue); + LineV(x+5,y+10,2,red,green,blue); + LineV(x+3,y+12,2,red,green,blue); + LineV(x+4,y+12,2,red,green,blue); + LineV(x+2,y+14,2,red,green,blue); + LineV(x+3,y+14,2,red,green,blue); + break; + case '8': + LineH(x+2,y,6,red,green,blue); + LineH(x+1,y+1,8,red,green,blue); + LineH(x+2,y+2,1,red,green,blue); + LineH(x+7,y+2,1,red,green,blue); + LineV(x,y+2,5,red,green,blue); + LineV(x+1,y+2,5,red,green,blue); + LineH(x+2,y+6,1,red,green,blue); + LineH(x+7,y+6,1,red,green,blue); + LineV(x,y+9,5,red,green,blue); + LineV(x+1,y+9,5,red,green,blue); + LineV(x+8,y+2,5,red,green,blue); + LineV(x+9,y+2,5,red,green,blue); + LineH(x+2,y+9,1,red,green,blue); + LineH(x+7,y+9,1,red,green,blue); + LineV(x+8,y+9,5,red,green,blue); + LineV(x+9,y+9,5,red,green,blue); + LineH(x+2,y+13,1,red,green,blue); + LineH(x+7,y+13,1,red,green,blue); + LineH(x+1,y+7,8,red,green,blue); + LineH(x+1,y+8,8,red,green,blue); + LineH(x+1,y+14,8,red,green,blue); + LineH(x+2,y+15,6,red,green,blue); + break; + case '9': + LineH(x+2,y,6,red,green,blue); + LineH(x+1,y+1,8,red,green,blue); + LineH(x,y+2,3,red,green,blue); + LineV(x,y+3,4,red,green,blue); + LineV(x+1,y+3,5,red,green,blue); + LineH(x+7,y+2,3,red,green,blue); + LineV(x+8,y+3,12,red,green,blue); + LineV(x+9,y+3,11,red,green,blue); + LineH(x+2,y+6,1,red,green,blue); + LineH(x+7,y+6,1,red,green,blue); + LineH(x+2,y+7,6,red,green,blue); + LineH(x+2,y+8,6,red,green,blue); + LineH(x,y+13,3,red,green,blue); + LineH(x+7,y+13,1,red,green,blue); + LineH(x+1,y+14,7,red,green,blue); + LineH(x+2,y+15,6,red,green,blue); + break; + case '.': + LineH(x,y+10,2,red,green,blue); + LineH(x,y+11,2,red,green,blue); + break; + case ':': + LineH(x,y+4,2,red,green,blue); + LineH(x,y+5,2,red,green,blue); + LineH(x,y+10,2,red,green,blue); + LineH(x,y+11,2,red,green,blue); + break; + case '>': + LineH(x+2,y+1,2,red,green,blue); + LineH(x+2,y+2,2,red,green,blue); + LineH(x+4,y+3,2,red,green,blue); + LineH(x+4,y+4,2,red,green,blue); + LineH(x+6,y+5,2,red,green,blue); + LineH(x+6,y+6,2,red,green,blue); + LineH(x+8,y+7,2,red,green,blue); + LineH(x+8,y+8,2,red,green,blue); + LineH(x+6,y+9,2,red,green,blue); + LineH(x+6,y+10,2,red,green,blue); + LineH(x+4,y+11,2,red,green,blue); + LineH(x+4,y+12,2,red,green,blue); + LineH(x+2,y+13,2,red,green,blue); + LineH(x+2,y+14,2,red,green,blue); + break; + case ' ': + for(uint8_t var= 0;var < 10;var++){ + LineV(x+var,y,16,0,0,0); + } + break; + case '-': + LineH(x+2,y+7,6,red,green,blue); + LineH(x+2,y+8,6,red,green,blue); + break; + } +} diff --git a/libraries/_NToolsFonts/char14x24.h b/libraries/_NToolsFonts/char14x24.h new file mode 100644 index 0000000..e672aa9 --- /dev/null +++ b/libraries/_NToolsFonts/char14x24.h @@ -0,0 +1,266 @@ +uint8_t Out14x24Char(char charater, uint8_t x, uint8_t y, uint8_t red,uint8_t green,uint8_t blue){ + switch (charater){ + case '0': + LineH(x+2,y,10,red,green,blue); + LineH(x+1,y+1,12,red,green,blue); + LineH(x,y+2,14,red,green,blue); + LineV(x,y+3,18,red,green,blue); + LineV(x+1,y+3,18,red,green,blue); + LineV(x+2,y+3,18,red,green,blue); + LineV(x+11,y+3,18,red,green,blue); + LineV(x+12,y+3,18,red,green,blue); + LineV(x+13,y+3,18,red,green,blue); + LineH(x,y+21,14,red,green,blue); + LineH(x+1,y+22,12,red,green,blue); + LineH(x+2,y+23,10,red,green,blue); + return 14; + break; + case '1': + LineV(x,y+6,4,red,green,blue); + LineV(x+1,y+5,4,red,green,blue); + LineV(x+2,y+4,4,red,green,blue); + LineV(x+3,y+3,4,red,green,blue); + LineV(x+4,y+2,4,red,green,blue); + LineV(x+5,y+1,4,red,green,blue); + LineV(x+6,y,4,red,green,blue); + LineV(x+7,y,24,red,green,blue); + LineV(x+8,y,24,red,green,blue); + LineV(x+9,y,24,red,green,blue); + return 10; + break; + case '2': + LineH(x+2,y,10,red,green,blue); + LineH(x+1,y+1,12,red,green,blue); + LineH(x,y+2,14,red,green,blue); + LineH(x,y+3,3,red,green,blue); + LineV(x+11,y+2,9,red,green,blue); + LineV(x+12,y+2,9,red,green,blue); + LineV(x+13,y+2,9,red,green,blue); + LineH(x+10,y+11,3,red,green,blue); + LineH(x+9,y+12,3,red,green,blue); + LineH(x+8,y+13,3,red,green,blue); + LineH(x+7,y+14,3,red,green,blue); + LineH(x+6,y+15,3,red,green,blue); + LineH(x+5,y+16,3,red,green,blue); + LineH(x+4,y+17,3,red,green,blue); + LineH(x+3,y+18,3,red,green,blue); + LineH(x+2,y+19,3,red,green,blue); + LineH(x+1,y+20,3,red,green,blue); + LineH(x,y+21,14,red,green,blue); + LineH(x,y+22,14,red,green,blue); + LineH(x,y+23,14,red,green,blue); + return 14; + break; + case '3': + LineH(x+2,y,10,red,green,blue); + LineH(x+1,y+1,12,red,green,blue); + LineH(x,y+2,14,red,green,blue); + LineH(x,y+3,3,red,green,blue); + LineV(x+11,y+3,18,red,green,blue); + LineV(x+12,y+3,18,red,green,blue); + LineV(x+13,y+3,8,red,green,blue); + LineV(x+13,y+13,8,red,green,blue); + + LineH(x+6,y+11,6,red,green,blue); + LineH(x+6,y+12,6,red,green,blue); + LineH(x,y+20,3,red,green,blue); + + LineH(x,y+21,14,red,green,blue); + LineH(x+1,y+22,12,red,green,blue); + LineH(x+2,y+23,10,red,green,blue); + return 14; + break; + case '4': + LineV(x,y,11,red,green,blue); + LineV(x+1,y,12,red,green,blue); + LineV(x+2,y,13,red,green,blue); + LineH(x+3,y+11,8,red,green,blue); + LineH(x+3,y+12,8,red,green,blue); + LineV(x+11,y,24,red,green,blue); + LineV(x+12,y,24,red,green,blue); + LineV(x+13,y,24,red,green,blue); + return 14; + break; + case '5': + LineH(x+1,y,13,red,green,blue); + LineH(x,y+1,14,red,green,blue); + LineH(x,y+2,13,red,green,blue); + + LineV(x,y+3,9,red,green,blue); + LineV(x+1,y+3,10,red,green,blue); + LineV(x+2,y+3,10,red,green,blue); + + LineH(x+3,y+11,9,red,green,blue); + LineH(x+3,y+12,10,red,green,blue); + + LineV(x+11,y+11,10,red,green,blue); + LineV(x+12,y+11,10,red,green,blue); + LineV(x+13,y+12,9,red,green,blue); + + LineH(x,y+20,3,red,green,blue); + LineH(x,y+21,14,red,green,blue); + LineH(x+1,y+22,12,red,green,blue); + LineH(x+2,y+23,10,red,green,blue); + return 14; + break; + case '6': + LineH(x+2,y,10,red,green,blue); + LineH(x+1,y+1,12,red,green,blue); + LineH(x,y+2,14,red,green,blue); + LineH(x+11,y+3,3,red,green,blue); + + LineV(x,y+3,18,red,green,blue); + LineV(x+1,y+3,18,red,green,blue); + LineV(x+2,y+3,18,red,green,blue); + + + LineH(x+3,y+11,8,red,green,blue); + LineH(x+3,y+12,8,red,green,blue); + + LineV(x+11,y+11,10,red,green,blue); + LineV(x+12,y+12,9,red,green,blue); + LineV(x+13,y+13,8,red,green,blue); + + LineH(x,y+21,14,red,green,blue); + LineH(x+1,y+22,12,red,green,blue); + LineH(x+2,y+23,10,red,green,blue); + return 14; + break; + case '7': + LineH(x+1,y,13,red,green,blue); + LineH(x,y+1,14,red,green,blue); + LineH(x,y+2,14,red,green,blue); + + LineH(x+11,y+3,3,red,green,blue); + LineH(x+11,y+4,3,red,green,blue); + LineH(x+11,y+5,3,red,green,blue); + LineH(x+10,y+6,3,red,green,blue); + LineH(x+10,y+7,3,red,green,blue); + LineH(x+10,y+8,3,red,green,blue); + LineH(x+9,y+9,3,red,green,blue); + LineH(x+9,y+10,3,red,green,blue); + LineH(x+9,y+11,3,red,green,blue); + LineH(x+8,y+12,3,red,green,blue); + LineH(x+8,y+13,3,red,green,blue); + LineH(x+8,y+14,3,red,green,blue); + LineH(x+7,y+15,3,red,green,blue); + LineH(x+7,y+16,3,red,green,blue); + LineH(x+7,y+17,3,red,green,blue); + LineH(x+6,y+18,3,red,green,blue); + LineH(x+6,y+19,3,red,green,blue); + LineH(x+6,y+20,3,red,green,blue); + LineH(x+5,y+21,3,red,green,blue); + LineH(x+5,y+22,3,red,green,blue); + LineH(x+5,y+23,3,red,green,blue); + return 14; + break; + case '8': + LineH(x+2,y,10,red,green,blue); + LineH(x+1,y+1,12,red,green,blue); + LineH(x,y+2,14,red,green,blue); + + LineV(x,y+3,8,red,green,blue); + LineV(x+1,y+3,8,red,green,blue); + LineV(x+2,y+3,8,red,green,blue); + + LineV(x,y+13,8,red,green,blue); + LineV(x+1,y+13,8,red,green,blue); + LineV(x+2,y+13,8,red,green,blue); + + LineV(x+11,y+3,8,red,green,blue); + LineV(x+12,y+3,8,red,green,blue); + LineV(x+13,y+3,8,red,green,blue); + + LineV(x+11,y+13,8,red,green,blue); + LineV(x+12,y+13,8,red,green,blue); + LineV(x+13,y+13,8,red,green,blue); + + LineH(x+1,y+11,12,red,green,blue); + LineH(x+1,y+12,12,red,green,blue); + + LineH(x,y+21,14,red,green,blue); + LineH(x+1,y+22,12,red,green,blue); + LineH(x+2,y+23,10,red,green,blue); + return 14; + break; + case '9': + LineH(x+2,y,10,red,green,blue); + LineH(x+1,y+1,12,red,green,blue); + LineH(x,y+2,14,red,green,blue); + + LineV(x,y+3,8,red,green,blue); + LineV(x+1,y+3,8,red,green,blue); + LineV(x+2,y+3,8,red,green,blue); + + LineV(x+11,y+3,18,red,green,blue); + LineV(x+12,y+3,18,red,green,blue); + LineV(x+13,y+3,18,red,green,blue); + + LineH(x+1,y+11,10,red,green,blue); + LineH(x+2,y+12,9,red,green,blue); + + LineH(x,y+21,14,red,green,blue); + LineH(x+1,y+22,12,red,green,blue); + LineH(x+2,y+23,10,red,green,blue); + return 14; + break; + case '.': + LineH(x,y+22,2,red,green,blue); + LineH(x,y+23,2,red,green,blue); + return 2; + break; + case ':': + //LineH(x,y+6,2,red,green,blue); + LineH(x,y+7,2,red,green,blue); + LineH(x,y+8,2,red,green,blue); + LineH(x,y+15,2,red,green,blue); + LineH(x,y+16,2,red,green,blue); + //LineH(x,y+17,2,red,green,blue); + return 2; + break; + case '>': + LineH(x,y+2,3,red,green,blue); + LineH(x,y+3,3,red,green,blue); + LineH(x,y+4,3,red,green,blue); + + LineH(x+3,y+5,3,red,green,blue); + LineH(x+3,y+6,3,red,green,blue); + LineH(x+3,y+7,3,red,green,blue); + + LineH(x+6,y+8,3,red,green,blue); + LineH(x+6,y+9,3,red,green,blue); + LineH(x+6,y+10,3,red,green,blue); + + LineH(x+9,y+11,3,red,green,blue); + LineH(x+9,y+12,3,red,green,blue); + LineH(x+9,y+13,3,red,green,blue); + + LineH(x+6,y+14,3,red,green,blue); + LineH(x+6,y+15,3,red,green,blue); + LineH(x+6,y+16,3,red,green,blue); + + LineH(x+3,y+17,3,red,green,blue); + LineH(x+3,y+18,3,red,green,blue); + LineH(x+3,y+19,3,red,green,blue); + + LineH(x,y+20,3,red,green,blue); + LineH(x,y+21,3,red,green,blue); + LineH(x,y+22,3,red,green,blue); + + return 12; + break; + case ' ': + for(uint8_t var= 0;var < 6;var++){ + LineV(x+var,y,24,0,0,0); + } + return 6; + break; + case '-': + LineH(x,y+11,6,red,green,blue); + LineH(x,y+12,6,red,green,blue); + LineH(x,y+13,6,red,green,blue); + return 6; + break; + } + return 0; +} diff --git a/libraries/_NToolsFonts/char16x24.h b/libraries/_NToolsFonts/char16x24.h new file mode 100644 index 0000000..0a0bd27 --- /dev/null +++ b/libraries/_NToolsFonts/char16x24.h @@ -0,0 +1,302 @@ +uint8_t Out16x24Char(char charater, uint8_t x, uint8_t y, uint8_t red,uint8_t green,uint8_t blue){ + switch (charater){ + case '0': + LineH(x+2,y,12,red,green,blue); + LineH(x+1,y+1,14,red,green,blue); + LineH(x,y+2,16,red,green,blue); + LineH(x,y+3,16,red,green,blue); + LineV(x,y+4,16,red,green,blue); + LineV(x+1,y+4,16,red,green,blue); + LineV(x+2,y+4,16,red,green,blue); + LineV(x+3,y+4,16,red,green,blue); + LineV(x+12,y+4,16,red,green,blue); + LineV(x+13,y+4,16,red,green,blue); + LineV(x+14,y+4,16,red,green,blue); + LineV(x+15,y+4,16,red,green,blue); + LineH(x,y+20,16,red,green,blue); + LineH(x,y+21,16,red,green,blue); + LineH(x+1,y+22,14,red,green,blue); + LineH(x+2,y+23,12,red,green,blue); + return 16; + break; + case '1': + LineV(x,y+6,5,red,green,blue); + LineV(x+1,y+5,5,red,green,blue); + LineV(x+2,y+4,5,red,green,blue); + LineV(x+3,y+3,5,red,green,blue); + LineV(x+4,y+2,5,red,green,blue); + LineV(x+5,y+1,5,red,green,blue); + LineV(x+6,y,24,red,green,blue); + LineV(x+7,y,24,red,green,blue); + LineV(x+8,y,24,red,green,blue); + LineV(x+9,y,24,red,green,blue); + return 10; + break; + case '2': + LineH(x+2,y,12,red,green,blue); + LineH(x+1,y+1,14,red,green,blue); + LineH(x,y+2,16,red,green,blue); + LineH(x,y+3,16,red,green,blue); + LineH(x,y+4,4,red,green,blue); + LineH(x,y+5,4,red,green,blue); + LineV(x+15,y+4,5,red,green,blue); + LineV(x+14,y+4,5,red,green,blue); + LineV(x+13,y+4,5,red,green,blue); + LineV(x+12,y+4,5,red,green,blue); + LineH(x+11,y+9,5,red,green,blue); + LineH(x+10,y+10,5,red,green,blue); + LineH(x+9,y+11,5,red,green,blue); + LineH(x+8,y+12,5,red,green,blue); + LineH(x+7,y+13,5,red,green,blue); + LineH(x+6,y+14,5,red,green,blue); + LineH(x+5,y+15,5,red,green,blue); + LineH(x+4,y+16,5,red,green,blue); + LineH(x+3,y+17,5,red,green,blue); + LineH(x+2,y+18,5,red,green,blue); + LineH(x+1,y+19,5,red,green,blue); + LineH(x,y+20,16,red,green,blue); + LineH(x,y+21,16,red,green,blue); + LineH(x,y+22,16,red,green,blue); + LineH(x,y+23,16,red,green,blue); + return 16; + break; + case '3': + LineH(x+2,y,12,red,green,blue); + LineH(x+1,y+1,14,red,green,blue); + LineH(x,y+2,16,red,green,blue); + LineH(x,y+3,16,red,green,blue); + LineH(x,y+4,4,red,green,blue); + LineH(x,y+5,4,red,green,blue); + LineV(x+12,y+4,16,red,green,blue); + LineV(x+13,y+4,16,red,green,blue); + LineV(x+14,y+4,16,red,green,blue); + LineV(x+15,y+4,6,red,green,blue); + LineV(x+15,y+14,6,red,green,blue); + LineH(x+6,y+10,6,red,green,blue); + LineH(x+6,y+11,6,red,green,blue); + LineH(x+6,y+12,6,red,green,blue); + LineH(x+6,y+13,6,red,green,blue); + LineH(x,y+18,4,red,green,blue); + LineH(x,y+19,4,red,green,blue); + LineH(x,y+20,16,red,green,blue); + LineH(x,y+21,16,red,green,blue); + LineH(x+1,y+22,14,red,green,blue); + LineH(x+2,y+23,12,red,green,blue); + return 16; + break; + case '4': + LineV(x,y,10,red,green,blue); + LineV(x+1,y,11,red,green,blue); + LineV(x+2,y,12,red,green,blue); + LineV(x+3,y,13,red,green,blue); + + LineH(x+4,y+10,8,red,green,blue); + LineH(x+4,y+11,8,red,green,blue); + LineH(x+4,y+12,8,red,green,blue); + LineH(x+4,y+13,8,red,green,blue); + + LineV(x+12,y,24,red,green,blue); + LineV(x+13,y,24,red,green,blue); + LineV(x+14,y,24,red,green,blue); + LineV(x+15,y,24,red,green,blue); + return 16; + break; + case '5': + LineH(x+1,y,15,red,green,blue); + LineH(x,y+1,16,red,green,blue); + LineH(x,y+2,16,red,green,blue); + LineH(x,y+3,15,red,green,blue); + LineV(x,y+4,8,red,green,blue); + LineV(x+1,y+4,9,red,green,blue); + LineV(x+2,y+4,10,red,green,blue); + LineV(x+3,y+4,10,red,green,blue); + LineH(x+4,y+10,10,red,green,blue); + LineH(x+4,y+11,11,red,green,blue); + LineH(x+4,y+12,12,red,green,blue); + LineH(x+4,y+13,12,red,green,blue); + LineV(x+12,y+14,6,red,green,blue); + LineV(x+13,y+14,7,red,green,blue); + LineV(x+14,y+14,8,red,green,blue); + LineV(x+15,y+14,8,red,green,blue); + LineH(x,y+18,4,red,green,blue); + LineH(x,y+19,4,red,green,blue); + LineH(x,y+20,16,red,green,blue); + LineH(x,y+21,16,red,green,blue); + LineH(x+1,y+22,14,red,green,blue); + LineH(x+2,y+23,12,red,green,blue); + return 16; + break; + case '6': + LineH(x+2,y,12,red,green,blue); + LineH(x+1,y+1,14,red,green,blue); + LineH(x,y+2,16,red,green,blue); + LineH(x,y+3,16,red,green,blue); + LineV(x,y+4,16,red,green,blue); + LineV(x+1,y+4,16,red,green,blue); + LineV(x+2,y+4,16,red,green,blue); + LineV(x+3,y+4,16,red,green,blue); + LineH(x+4,y+10,10,red,green,blue); + LineH(x+4,y+11,11,red,green,blue); + LineH(x+4,y+12,12,red,green,blue); + LineH(x+4,y+13,12,red,green,blue); + LineV(x+12,y+14,6,red,green,blue); + LineV(x+13,y+14,7,red,green,blue); + LineV(x+14,y+14,8,red,green,blue); + LineV(x+15,y+14,8,red,green,blue); + LineH(x,y+20,16,red,green,blue); + LineH(x,y+21,16,red,green,blue); + LineH(x+1,y+22,14,red,green,blue); + LineH(x+2,y+23,12,red,green,blue); + return 16; + break; + case '7': + LineH(x+1,y,15,red,green,blue); + LineH(x,y+1,16,red,green,blue); + LineH(x,y+2,16,red,green,blue); + LineH(x,y+3,16,red,green,blue); + + LineH(x+11,y+4,4,red,green,blue); + LineH(x+11,y+5,4,red,green,blue); + LineH(x+11,y+6,4,red,green,blue); + LineH(x+11,y+7,4,red,green,blue); + + LineH(x+10,y+8,4,red,green,blue); + LineH(x+10,y+9,4,red,green,blue); + LineH(x+10,y+10,4,red,green,blue); + LineH(x+10,y+11,4,red,green,blue); + + LineH(x+9,y+12,4,red,green,blue); + LineH(x+9,y+13,4,red,green,blue); + LineH(x+9,y+14,4,red,green,blue); + LineH(x+9,y+15,4,red,green,blue); + + LineH(x+8,y+16,4,red,green,blue); + LineH(x+8,y+17,4,red,green,blue); + LineH(x+8,y+18,4,red,green,blue); + LineH(x+8,y+19,4,red,green,blue); + + LineH(x+7,y+20,4,red,green,blue); + LineH(x+7,y+21,4,red,green,blue); + LineH(x+7,y+22,4,red,green,blue); + LineH(x+7,y+23,4,red,green,blue); + return 16; + break; + case '8': + LineH(x+2,y,12,red,green,blue); + LineH(x+1,y+1,14,red,green,blue); + LineH(x,y+2,16,red,green,blue); + LineH(x,y+3,16,red,green,blue); + + LineV(x,y+4,6,red,green,blue); + LineV(x,y+14,6,red,green,blue); + LineV(x+1,y+4,16,red,green,blue); + LineV(x+2,y+4,16,red,green,blue); + LineV(x+3,y+4,16,red,green,blue); + + LineH(x+4,y+10,8,red,green,blue); + LineH(x+4,y+11,8,red,green,blue); + LineH(x+4,y+12,8,red,green,blue); + LineH(x+4,y+13,8,red,green,blue); + + LineV(x+12,y+4,16,red,green,blue); + LineV(x+13,y+4,16,red,green,blue); + LineV(x+14,y+4,16,red,green,blue); + LineV(x+15,y+4,6,red,green,blue); + LineV(x+15,y+14,6,red,green,blue); + + LineH(x,y+20,16,red,green,blue); + LineH(x,y+21,16,red,green,blue); + LineH(x+1,y+22,14,red,green,blue); + LineH(x+2,y+23,12,red,green,blue); + return 16; + break; + case '9': + LineH(x+2,y,12,red,green,blue); + LineH(x+1,y+1,14,red,green,blue); + LineH(x,y+2,16,red,green,blue); + LineH(x,y+3,16,red,green,blue); + + LineV(x,y+4,8,red,green,blue); + LineV(x+1,y+4,9,red,green,blue); + LineV(x+2,y+4,10,red,green,blue); + LineV(x+3,y+4,10,red,green,blue); + + LineH(x+4,y+10,8,red,green,blue); + LineH(x+4,y+11,8,red,green,blue); + LineH(x+4,y+12,8,red,green,blue); + LineH(x+4,y+13,8,red,green,blue); + + LineV(x+12,y+4,16,red,green,blue); + LineV(x+13,y+4,16,red,green,blue); + LineV(x+14,y+4,16,red,green,blue); + LineV(x+15,y+4,16,red,green,blue); + + LineH(x,y+20,16,red,green,blue); + LineH(x,y+21,16,red,green,blue); + LineH(x+1,y+22,14,red,green,blue); + LineH(x+2,y+23,12,red,green,blue); + return 16; + break; + case '.': + LineH(x,y+20,4,red,green,blue); + LineH(x,y+21,4,red,green,blue); + LineH(x,y+22,4,red,green,blue); + LineH(x,y+23,4,red,green,blue); + return 4; + break; + case ':': + LineH(x,y+5,4,red,green,blue); + LineH(x,y+6,4,red,green,blue); + LineH(x,y+7,4,red,green,blue); + LineH(x,y+8,4,red,green,blue); + + LineH(x,y+15,4,red,green,blue); + LineH(x,y+16,4,red,green,blue); + LineH(x,y+17,4,red,green,blue); + LineH(x,y+18,4,red,green,blue); + return 4; + break; + case '>': + LineH(x,y+2,4,red,green,blue); + LineH(x,y+3,4,red,green,blue); + LineH(x,y+4,4,red,green,blue); + LineH(x,y+5,4,red,green,blue); + + LineH(x+4,y+6,4,red,green,blue); + LineH(x+4,y+7,4,red,green,blue); + LineH(x+4,y+8,4,red,green,blue); + LineH(x+4,y+9,4,red,green,blue); + + LineH(x+8,y+10,4,red,green,blue); + LineH(x+8,y+11,4,red,green,blue); + LineH(x+8,y+12,4,red,green,blue); + LineH(x+8,y+13,4,red,green,blue); + + LineH(x+4,y+14,4,red,green,blue); + LineH(x+4,y+15,4,red,green,blue); + LineH(x+4,y+16,4,red,green,blue); + LineH(x+4,y+17,4,red,green,blue); + + LineH(x,y+18,4,red,green,blue); + LineH(x,y+19,4,red,green,blue); + LineH(x,y+20,4,red,green,blue); + LineH(x,y+21,4,red,green,blue); + + return 12; + break; + case ' ': + for(uint8_t var= 0;var < 8;var++){ + LineV(x+var,y,24,0,0,0); + } + return 8; + break; + case '-': + LineH(x,y+10,6,red,green,blue); + LineH(x,y+11,6,red,green,blue); + LineH(x,y+12,6,red,green,blue); + LineH(x,y+13,6,red,green,blue); + return 6; + break; + } + return 0; +} diff --git a/libraries/_NToolsFonts/char16x24_light.h b/libraries/_NToolsFonts/char16x24_light.h new file mode 100644 index 0000000..4722ec5 --- /dev/null +++ b/libraries/_NToolsFonts/char16x24_light.h @@ -0,0 +1,267 @@ +uint8_t Out16x24Char_light(char charater, uint8_t x, uint8_t y, uint8_t red,uint8_t green,uint8_t blue){ + switch (charater){ + case '0': + LineH(x+2,y,12,red,green,blue); + LineH(x+1,y+1,14,red,green,blue); + LineH(x,y+2,16,red,green,blue); + LineH(x,y+3,3,red,green,blue); + LineH(x+13,y+3,3,red,green,blue); + LineV(x,y+4,16,red,green,blue); + LineV(x+1,y+4,16,red,green,blue); + LineV(x+2,y+4,16,red,green,blue); + LineV(x+13,y+4,16,red,green,blue); + LineV(x+14,y+4,16,red,green,blue); + LineV(x+15,y+4,16,red,green,blue); + LineH(x,y+20,3,red,green,blue); + LineH(x+13,y+20,3,red,green,blue); + LineH(x,y+21,16,red,green,blue); + LineH(x+1,y+22,14,red,green,blue); + LineH(x+2,y+23,12,red,green,blue); + return 16; + break; + case '1': + LineV(x,y+6,4,red,green,blue); + LineV(x+1,y+5,4,red,green,blue); + LineV(x+2,y+4,4,red,green,blue); + LineV(x+3,y+3,4,red,green,blue); + LineV(x+4,y+2,4,red,green,blue); + LineV(x+5,y+1,4,red,green,blue); + LineV(x+6,y,4,red,green,blue); + LineV(x+7,y,24,red,green,blue); + LineV(x+8,y,24,red,green,blue); + LineV(x+9,y,24,red,green,blue); + return 10; + break; + case '2': + LineH(x+2,y,12,red,green,blue); + LineH(x+1,y+1,14,red,green,blue); + LineH(x,y+2,16,red,green,blue); + LineH(x,y+3,3,red,green,blue); + LineH(x,y+4,3,red,green,blue); + LineV(x+15,y+3,5,red,green,blue); + LineV(x+14,y+3,5,red,green,blue); + LineV(x+13,y+3,5,red,green,blue); + LineH(x+12,y+8,4,red,green,blue); + LineH(x+11,y+9,4,red,green,blue); + LineH(x+10,y+10,4,red,green,blue); + LineH(x+9,y+11,4,red,green,blue); + LineH(x+8,y+12,4,red,green,blue); + LineH(x+7,y+13,4,red,green,blue); + LineH(x+6,y+14,4,red,green,blue); + LineH(x+5,y+15,4,red,green,blue); + LineH(x+4,y+16,4,red,green,blue); + LineH(x+3,y+17,4,red,green,blue); + LineH(x+2,y+18,4,red,green,blue); + LineH(x+1,y+19,4,red,green,blue); + LineH(x,y+20,4,red,green,blue); + LineH(x,y+21,16,red,green,blue); + LineH(x,y+22,16,red,green,blue); + LineH(x,y+23,16,red,green,blue); + return 16; + break; + case '3': + LineH(x+2,y,12,red,green,blue); + LineH(x+1,y+1,14,red,green,blue); + LineH(x,y+2,16,red,green,blue); + LineH(x,y+3,3,red,green,blue); + LineH(x+13,y+3,3,red,green,blue); + LineH(x,y+4,3,red,green,blue); + LineV(x+12,y+10,3,red,green,blue); + LineV(x+13,y+4,16,red,green,blue); + LineV(x+14,y+4,16,red,green,blue); + LineV(x+15,y+4,6,red,green,blue); + LineV(x+15,y+13,7,red,green,blue); + LineH(x+6,y+10,6,red,green,blue); + LineH(x+6,y+11,6,red,green,blue); + LineH(x+6,y+12,6,red,green,blue); + LineH(x,y+19,3,red,green,blue); + LineH(x,y+20,3,red,green,blue); + LineH(x+13,y+20,3,red,green,blue); + LineH(x,y+21,16,red,green,blue); + LineH(x+1,y+22,14,red,green,blue); + LineH(x+2,y+23,12,red,green,blue); + return 16; + break; + case '4': + LineV(x,y,10,red,green,blue); + LineV(x+1,y,11,red,green,blue); + LineV(x+2,y,12,red,green,blue); + + LineH(x+3,y+10,10,red,green,blue); + LineH(x+3,y+11,10,red,green,blue); + LineH(x+3,y+12,10,red,green,blue); + + LineV(x+13,y,24,red,green,blue); + LineV(x+14,y,24,red,green,blue); + LineV(x+15,y,24,red,green,blue); + return 16; + break; + case '5': + //ab hier noch machen + LineH(x+1,y,15,red,green,blue); + LineH(x,y+1,16,red,green,blue); + LineH(x,y+2,15,red,green,blue); + LineV(x,y+3,8,red,green,blue); + LineV(x+1,y+3,9,red,green,blue); + LineV(x+2,y+3,10,red,green,blue); + LineH(x+3,y+10,11,red,green,blue); + LineH(x+3,y+11,12,red,green,blue); + LineH(x+3,y+12,13,red,green,blue); + LineV(x+13,y+13,8,red,green,blue); + LineV(x+14,y+13,8,red,green,blue); + LineV(x+15,y+13,8,red,green,blue); + LineH(x,y+19,3,red,green,blue); + LineH(x,y+20,3,red,green,blue); + LineH(x,y+21,16,red,green,blue); + LineH(x+1,y+22,14,red,green,blue); + LineH(x+2,y+23,12,red,green,blue); + return 16; + break; + case '6': + LineH(x+2,y,12,red,green,blue); + LineH(x+1,y+1,14,red,green,blue); + LineH(x,y+2,16,red,green,blue); + LineV(x,y+3,18,red,green,blue); + LineV(x+1,y+3,18,red,green,blue); + LineV(x+2,y+3,18,red,green,blue); + LineH(x+3,y+10,11,red,green,blue); + LineH(x+3,y+11,12,red,green,blue); + LineH(x+3,y+12,13,red,green,blue); + LineV(x+13,y+13,8,red,green,blue); + LineV(x+14,y+13,8,red,green,blue); + LineV(x+15,y+13,8,red,green,blue); + LineH(x,y+21,16,red,green,blue); + LineH(x+1,y+22,14,red,green,blue); + LineH(x+2,y+23,12,red,green,blue); + return 16; + break; + case '7': + LineH(x+1,y,15,red,green,blue); + LineH(x,y+1,16,red,green,blue); + LineH(x,y+2,16,red,green,blue); + LineH(x+13,y+3,3,red,green,blue); + LineH(x+13,y+4,3,red,green,blue); + LineH(x+13,y+5,3,red,green,blue); + LineH(x+12,y+6,3,red,green,blue); + LineH(x+12,y+7,3,red,green,blue); + LineH(x+12,y+8,3,red,green,blue); + LineH(x+11,y+9,3,red,green,blue); + LineH(x+11,y+10,3,red,green,blue); + LineH(x+11,y+11,3,red,green,blue); + LineH(x+10,y+12,3,red,green,blue); + LineH(x+10,y+13,3,red,green,blue); + LineH(x+10,y+14,3,red,green,blue); + LineH(x+9,y+15,3,red,green,blue); + LineH(x+9,y+16,3,red,green,blue); + LineH(x+9,y+17,3,red,green,blue); + LineH(x+8,y+18,3,red,green,blue); + LineH(x+8,y+19,3,red,green,blue); + LineH(x+8,y+20,3,red,green,blue); + LineH(x+7,y+21,3,red,green,blue); + LineH(x+7,y+22,3,red,green,blue); + LineH(x+7,y+23,3,red,green,blue); + return 16; + break; + case '8': + LineH(x+2,y,12,red,green,blue); + LineH(x+1,y+1,14,red,green,blue); + LineH(x,y+2,16,red,green,blue); + + LineV(x,y+3,7,red,green,blue); + LineV(x,y+13,8,red,green,blue); + LineV(x+1,y+3,18,red,green,blue); + LineV(x+2,y+3,18,red,green,blue); + + LineH(x+3,y+10,10,red,green,blue); + LineH(x+3,y+11,10,red,green,blue); + LineH(x+3,y+12,10,red,green,blue); + + LineV(x+13,y+3,18,red,green,blue); + LineV(x+14,y+3,18,red,green,blue); + LineV(x+15,y+3,7,red,green,blue); + LineV(x+15,y+13,8,red,green,blue); + + LineH(x,y+21,16,red,green,blue); + LineH(x+1,y+22,14,red,green,blue); + LineH(x+2,y+23,12,red,green,blue); + return 16; + break; + case '9': + LineH(x+2,y,12,red,green,blue); + LineH(x+1,y+1,14,red,green,blue); + LineH(x,y+2,16,red,green,blue); + + LineV(x,y+3,8,red,green,blue); + LineV(x+1,y+3,9,red,green,blue); + LineV(x+2,y+3,10,red,green,blue); + + LineH(x+3,y+10,10,red,green,blue); + LineH(x+3,y+11,10,red,green,blue); + LineH(x+3,y+12,10,red,green,blue); + + LineV(x+13,y+3,18,red,green,blue); + LineV(x+14,y+3,18,red,green,blue); + LineV(x+15,y+3,18,red,green,blue); + + LineH(x,y+21,16,red,green,blue); + LineH(x+1,y+22,14,red,green,blue); + LineH(x+2,y+23,12,red,green,blue); + return 16; + break; + case '.': + LineH(x,y+21,3,red,green,blue); + LineH(x,y+22,3,red,green,blue); + LineH(x,y+23,3,red,green,blue); + return 3; + break; + case ':': + LineH(x,y+6,2,red,green,blue); + LineH(x,y+7,2,red,green,blue); + + LineH(x,y+16,2,red,green,blue); + LineH(x,y+17,2,red,green,blue); + return 2; + break; + case '>': + LineH(x,y+2,4,red,green,blue); + LineH(x,y+3,4,red,green,blue); + LineH(x,y+4,4,red,green,blue); + LineH(x,y+5,4,red,green,blue); + + LineH(x+4,y+6,4,red,green,blue); + LineH(x+4,y+7,4,red,green,blue); + LineH(x+4,y+8,4,red,green,blue); + LineH(x+4,y+9,4,red,green,blue); + + LineH(x+8,y+10,4,red,green,blue); + LineH(x+8,y+11,4,red,green,blue); + LineH(x+8,y+12,4,red,green,blue); + LineH(x+8,y+13,4,red,green,blue); + + LineH(x+4,y+14,4,red,green,blue); + LineH(x+4,y+15,4,red,green,blue); + LineH(x+4,y+16,4,red,green,blue); + LineH(x+4,y+17,4,red,green,blue); + + LineH(x,y+18,4,red,green,blue); + LineH(x,y+19,4,red,green,blue); + LineH(x,y+20,4,red,green,blue); + LineH(x,y+21,4,red,green,blue); + + return 12; + break; + case ' ': + for(uint8_t var= 0;var < 8;var++){ + LineV(x+var,y,24,0,0,0); + } + return 8; + break; + case '-': + LineH(x,y+10,6,red,green,blue); + LineH(x,y+11,6,red,green,blue); + LineH(x,y+12,6,red,green,blue); + return 6; + break; + } + return 0; +} diff --git a/libraries/_NToolsFonts/char3x5.h b/libraries/_NToolsFonts/char3x5.h new file mode 100644 index 0000000..01ac66f --- /dev/null +++ b/libraries/_NToolsFonts/char3x5.h @@ -0,0 +1,116 @@ +uint8_t Out3x5Char(char charater, uint8_t x, uint8_t y, uint8_t red,uint8_t green,uint8_t blue){ + switch (charater){ + case '0': + LineV(x,y,5,red,green,blue); + LineV(x+1,y,1,red,green,blue); + LineV(x+1,y+4,1,red,green,blue); + LineV(x+2,y,5,red,green,blue); + return 3; + break; + case '1': + LineV(x,y+2,1,red,green,blue); + LineV(x+1,y+1,1,red,green,blue); + LineV(x+2,y,5,red,green,blue); + return 3; + break; + case '2': + LineH(x,y,3,red,green,blue); + LineH(x+2,y+1,1,red,green,blue); + LineH(x+1,y+2,1,red,green,blue); + LineH(x,y+3,1,red,green,blue); + LineH(x,y+4,3,red,green,blue); + return 3; + break; + case '3': + LineH(x,y,3,red,green,blue); + LineH(x+2,y+1,1,red,green,blue); + LineH(x+1,y+2,2,red,green,blue); + LineH(x+2,y+3,1,red,green,blue); + LineH(x,y+4,3,red,green,blue); + return 3; + break; + case '4': + LineV(x,y,3,red,green,blue); + LineV(x+1,y+2,1,red,green,blue); + LineV(x+2,y,5,red,green,blue); + return 3; + break; + case '5': + LineH(x,y,3,red,green,blue); + LineH(x,y+1,1,red,green,blue); + LineH(x,y+2,3,red,green,blue); + LineH(x+2,y+3,1,red,green,blue); + LineH(x,y+4,3,red,green,blue); + return 3; + break; + case '6': + LineH(x,y,3,red,green,blue); + LineH(x,y+1,1,red,green,blue); + LineH(x,y+2,3,red,green,blue); + LineH(x,y+3,1,red,green,blue); + LineH(x+2,y+3,1,red,green,blue); + LineH(x,y+4,3,red,green,blue); + return 3; + break; + case '7': + LineH(x,y,3,red,green,blue); + LineH(x+2,y+1,1,red,green,blue); + LineV(x+1,y+2,3,red,green,blue); + return 3; + break; + case '8': + LineV(x,y,5,red,green,blue); + LineV(x+1,y,1,red,green,blue); + LineV(x+1,y+2,1,red,green,blue); + LineV(x+1,y+4,1,red,green,blue); + LineV(x+2,y,5,red,green,blue); + return 3; + break; + case '9': + LineV(x,y,3,red,green,blue); + LineV(x,y+4,1,red,green,blue); + LineV(x+1,y,1,red,green,blue); + LineV(x+1,y+2,1,red,green,blue); + LineV(x+1,y+4,1,red,green,blue); + LineV(x+2,y,5,red,green,blue); + return 3; + break; + case 'K': + LineV(x,y,5,red,green,blue); + LineV(x+2,y,2,red,green,blue); + LineV(x+1,y+2,1,red,green,blue); + LineV(x+2,y+3,2,red,green,blue); + return 3; + break; + case 'W': + LineV(x,y,5,red,green,blue); + LineV(x+1,y+3,2,red,green,blue); + LineV(x+2,y+2,2,red,green,blue); + LineV(x+3,y+3,2,red,green,blue); + LineV(x+4,y,5,red,green,blue); + return 5; + break; + case '.': + LineH(x,y+4,1,red,green,blue); + return 1; + break; + case ':': + LineH(x,y+1,1,red,green,blue); + LineH(x,y+3,1,red,green,blue); + return 1; + break; + case ' ': + LineV(x,y,5,0,0,0); + return 1; + break; + } + return 0; +} + +void show3x5(uint8_t x, uint8_t y, char text[] , uint8_t red, uint8_t green, uint8_t blue){ + uint8_t textlen = strlen(text); + for(uint8_t b=0;b': + LineH(x,y+3,5,red,green,blue); + LineH(x,y+4,5,red,green,blue); + LineH(x+2,y+1,1,red,green,blue); + LineH(x+2,y+6,1,red,green,blue); + LineH(x+3,y+2,1,red,green,blue); + LineH(x+3,y+5,1,red,green,blue); + + return 5; + break; + case '-': + LineH(x,y+3,3,red,green,blue); + LineH(x,y+4,3,red,green,blue); + return 3; + break; + case ' ': + LineV(x,y,8,0,0,0); + return 1; + break; + } + return 0; +} \ No newline at end of file diff --git a/libraries/_NToolsFonts/char6x8Lubalin.h b/libraries/_NToolsFonts/char6x8Lubalin.h new file mode 100644 index 0000000..9a908b1 --- /dev/null +++ b/libraries/_NToolsFonts/char6x8Lubalin.h @@ -0,0 +1,136 @@ +uint8_t Out6x8Char(char charater, uint8_t x, uint8_t y, uint8_t red,uint8_t green,uint8_t blue){ + switch (charater){ + case '0': + LineH(x+1,y,4,red,green,blue); + LineH(x,y+1,6,red,green,blue); + LineV(x,y+1,6,red,green,blue); + LineV(x+1,y+1,6,red,green,blue); + LineV(x+4,y+1,6,red,green,blue); + LineV(x+5,y+1,6,red,green,blue); + LineH(x,y+6,6,red,green,blue); + LineH(x+1,y+7,4,red,green,blue); + return 6; + break; + case '1': + LineV(x,y,2,red,green,blue); + LineV(x,y+6,2,red,green,blue); + LineV(x+1,y,8,red,green,blue); + LineV(x+2,y,8,red,green,blue); + LineV(x+3,y+6,2,red,green,blue); + return 4; + break; + case '2': + LineH(x+1,y,4,red,green,blue); + LineH(x,y+1,6,red,green,blue); + LineH(x+4,y+2,2,red,green,blue); + LineH(x+3,y+3,2,red,green,blue); + LineH(x+2,y+4,2,red,green,blue); + LineH(x+1,y+5,2,red,green,blue); + LineH(x,y+6,6,red,green,blue); + LineH(x,y+7,6,red,green,blue); + LineH(x+5,y+5,1,red,green,blue); + return 6; + break; + case '3': + LineH(x+1,y,4,red,green,blue); + LineH(x,y+1,6,red,green,blue); + LineH(x+4,y+2,2,red,green,blue); + LineH(x+2,y+3,3,red,green,blue); + LineH(x+2,y+4,3,red,green,blue); + LineH(x+4,y+5,2,red,green,blue); + LineH(x,y+6,6,red,green,blue); + LineH(x+1,y+7,4,red,green,blue); + return 6; + break; + case '4': + LineH(x,y,2,red,green,blue); + LineH(x+3,y,2,red,green,blue); + LineH(x,y+1,2,red,green,blue); + LineH(x+3,y+1,2,red,green,blue); + LineH(x,y+2,2,red,green,blue); + LineH(x+3,y+2,2,red,green,blue); + LineH(x,y+3,6,red,green,blue); + LineH(x,y+4,6,red,green,blue); + LineH(x+3,y+5,2,red,green,blue); + LineH(x+2,y+6,4,red,green,blue); + LineH(x+2,y+7,4,red,green,blue); + return 6; + break; + case '5': + LineH(x,y,6,red,green,blue); + LineH(x,y+1,6,red,green,blue); + LineH(x,y+2,2,red,green,blue); + LineH(x,y+3,5,red,green,blue); + LineH(x,y+4,6,red,green,blue); + LineH(x+4,y+5,2,red,green,blue); + LineH(x,y+6,6,red,green,blue); + LineH(x+1,y+7,4,red,green,blue); + return 6; + break; + case '6': + LineH(x+1,y,4,red,green,blue); + LineH(x,y+1,6,red,green,blue); + LineH(x,y+2,2,red,green,blue); + LineH(x,y+3,5,red,green,blue); + LineH(x,y+4,6,red,green,blue); + LineH(x,y+5,2,red,green,blue); + LineH(x+4,y+5,2,red,green,blue); + LineH(x,y+6,6,red,green,blue); + LineH(x+1,y+7,4,red,green,blue); + return 6; + break; + case '7': + LineH(x,y,6,red,green,blue); + LineH(x,y+1,6,red,green,blue); + LineH(x+4,y+2,2,red,green,blue); + LineH(x+3,y+3,2,red,green,blue); + LineH(x+2,y+4,2,red,green,blue); + LineH(x+2,y+5,2,red,green,blue); + LineH(x+2,y+6,2,red,green,blue); + LineH(x+2,y+7,2,red,green,blue); + return 6; + break; + case '8': + LineH(x+1,y,4,red,green,blue); + LineH(x,y+1,6,red,green,blue); + LineH(x,y+2,2,red,green,blue); + LineH(x+4,y+2,2,red,green,blue); + LineH(x+1,y+3,4,red,green,blue); + LineH(x,y+4,6,red,green,blue); + LineH(x,y+5,2,red,green,blue); + LineH(x+4,y+5,2,red,green,blue); + LineH(x,y+6,6,red,green,blue); + LineH(x+1,y+7,4,red,green,blue); + return 6; + break; + case '9': + LineH(x+1,y,4,red,green,blue); + LineH(x,y+1,6,red,green,blue); + LineH(x,y+2,2,red,green,blue); + LineH(x+4,y+2,2,red,green,blue); + LineH(x,y+3,6,red,green,blue); + LineH(x+1,y+4,5,red,green,blue); + LineH(x+4,y+5,2,red,green,blue); + LineH(x,y+6,6,red,green,blue); + LineH(x+1,y+7,4,red,green,blue); + return 6; + break; + case '.': + LineH(x,y+6,2,red,green,blue); + LineH(x,y+7,2,red,green,blue); + return 2; + break; + case ':': + LineH(x,y+2,2,red,green,blue); + LineH(x,y+3,2,red,green,blue); + LineH(x,y+5,2,red,green,blue); + LineH(x,y+6,2,red,green,blue); + + return 2; + break; + case ' ': + LineV(x,y,8,0,0,0); + return 1; + break; + } +} \ No newline at end of file diff --git a/libraries/_NToolsFonts/flama8p.h b/libraries/_NToolsFonts/flama8p.h new file mode 100644 index 0000000..45b6787 --- /dev/null +++ b/libraries/_NToolsFonts/flama8p.h @@ -0,0 +1,171 @@ +const uint8_t Flama_Regular8pt7bBitmaps[] PROGMEM = { + 0x00, 0xFE, 0x60, 0x99, 0x90, 0x24, 0x48, 0x97, 0xF4, 0x49, 0x3F, 0xA4, + 0x48, 0x90, 0x08, 0x79, 0x1A, 0x07, 0x07, 0x81, 0xA1, 0x42, 0x78, 0x20, + 0x60, 0xA4, 0x49, 0x32, 0x48, 0x94, 0x1B, 0x60, 0xA4, 0x49, 0x32, 0x48, + 0x94, 0x18, 0x1E, 0x04, 0x20, 0x84, 0x19, 0x81, 0xE0, 0x78, 0x33, 0xA6, + 0x3C, 0xC3, 0x9C, 0x70, 0xF3, 0x00, 0xE0, 0x29, 0x29, 0x24, 0x92, 0x24, + 0x88, 0x89, 0x22, 0x49, 0x24, 0xA4, 0xA0, 0x25, 0x5C, 0xAD, 0x80, 0x10, + 0x20, 0x47, 0xF1, 0x02, 0x04, 0x00, 0xF0, 0xF0, 0xC0, 0x08, 0x44, 0x21, + 0x10, 0x84, 0x42, 0x11, 0x80, 0x3D, 0x8E, 0x0C, 0x18, 0x30, 0x60, 0xC1, + 0x83, 0x8D, 0xF0, 0x71, 0xA0, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10, 0x23, + 0xF8, 0x7A, 0x18, 0x41, 0x04, 0x21, 0x8C, 0x21, 0x0F, 0xC0, 0x79, 0x1A, + 0x10, 0x20, 0xC7, 0x01, 0x81, 0x83, 0x8D, 0xE0, 0x0C, 0x0C, 0x14, 0x34, + 0x24, 0x44, 0xC4, 0xFF, 0x04, 0x04, 0x04, 0xFF, 0x02, 0x04, 0x0F, 0xD8, + 0xC0, 0x81, 0x83, 0x89, 0xE0, 0x3D, 0x8E, 0x0C, 0x0B, 0xD8, 0xE0, 0xC1, + 0x83, 0x8D, 0xF0, 0xFE, 0x0C, 0x10, 0x60, 0x83, 0x04, 0x18, 0x20, 0xC1, + 0x00, 0x7D, 0x8E, 0x0C, 0x1C, 0x6F, 0xB1, 0xC1, 0x83, 0x8D, 0xF0, 0x7D, + 0x8E, 0x0C, 0x18, 0x38, 0xDE, 0x81, 0x83, 0x8D, 0xE0, 0xC6, 0xC7, 0x80, + 0x06, 0x33, 0x86, 0x03, 0x80, 0xC0, 0xFE, 0x00, 0x07, 0xF0, 0xC0, 0x60, + 0x38, 0x33, 0x98, 0x00, 0x7B, 0x38, 0x41, 0x08, 0x42, 0x08, 0x00, 0x82, + 0x00, 0x0F, 0x83, 0x06, 0x60, 0x34, 0x71, 0x89, 0x19, 0x11, 0x91, 0x39, + 0x32, 0x8D, 0xC4, 0x00, 0x20, 0x41, 0xF8, 0x0C, 0x03, 0x00, 0xE0, 0x68, + 0x13, 0x0C, 0xC3, 0x10, 0xFE, 0x61, 0x90, 0x24, 0x0C, 0xFC, 0x86, 0x82, + 0x82, 0x86, 0xFC, 0x83, 0x81, 0x81, 0x83, 0xFC, 0x3C, 0x43, 0x81, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x81, 0x43, 0x3C, 0xFC, 0x82, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x82, 0xFC, 0xFF, 0x02, 0x04, 0x08, 0x1F, 0xA0, + 0x40, 0x81, 0x03, 0xF8, 0xFE, 0x08, 0x20, 0x83, 0xE8, 0x20, 0x82, 0x08, + 0x00, 0x3C, 0x43, 0x81, 0x80, 0x80, 0x8F, 0x81, 0x81, 0x81, 0x42, 0x3C, + 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFC, + 0x41, 0x04, 0x10, 0x41, 0x04, 0x10, 0x4F, 0xC0, 0x02, 0x04, 0x08, 0x10, + 0x20, 0x40, 0xC1, 0x83, 0x89, 0xE0, 0x86, 0x84, 0x88, 0x98, 0xB0, 0xF0, + 0xD8, 0x8C, 0x8C, 0x86, 0x83, 0x82, 0x08, 0x20, 0x82, 0x08, 0x20, 0x82, + 0x0F, 0xC0, 0xC0, 0xF0, 0x3E, 0x1E, 0x85, 0xB3, 0x64, 0x99, 0xE6, 0x71, + 0x8C, 0x60, 0x18, 0x04, 0x81, 0xC1, 0xE1, 0xB1, 0xB1, 0x99, 0x8D, 0x8D, + 0x87, 0x83, 0x81, 0x3C, 0x42, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x42, 0x3C, 0xFD, 0x0E, 0x0C, 0x18, 0x30, 0xBE, 0x40, 0x81, 0x02, 0x00, + 0x3C, 0x21, 0x20, 0x50, 0x28, 0x14, 0x0A, 0x05, 0x02, 0x8D, 0x23, 0x8F, + 0xC0, 0x00, 0xFD, 0x0E, 0x0C, 0x18, 0x30, 0xFF, 0x44, 0x8D, 0x0E, 0x08, + 0x3E, 0x63, 0x40, 0x40, 0x78, 0x1E, 0x03, 0x01, 0xC1, 0x62, 0x3C, 0xFF, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x42, 0x3C, 0xC1, 0xA0, 0xD8, + 0x4C, 0x62, 0x31, 0x90, 0xD8, 0x2C, 0x1C, 0x0E, 0x03, 0x00, 0xC3, 0x0D, + 0x0C, 0x26, 0x30, 0x99, 0xE6, 0x24, 0x98, 0x92, 0x43, 0x49, 0x0F, 0x3C, + 0x18, 0x60, 0x61, 0x81, 0x86, 0x00, 0x41, 0x31, 0x8D, 0x82, 0xC1, 0xC0, + 0xC0, 0x70, 0x6C, 0x22, 0x31, 0xB0, 0x60, 0x41, 0x31, 0x88, 0x86, 0xC1, + 0x40, 0xE0, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0xFE, 0x0C, 0x30, 0x41, + 0x82, 0x0C, 0x30, 0x41, 0x83, 0xF8, 0xF2, 0x49, 0x24, 0x92, 0x49, 0x38, + 0x82, 0x10, 0x82, 0x10, 0x82, 0x10, 0x82, 0x10, 0xE4, 0x92, 0x49, 0x24, + 0x92, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xC9, 0x80, 0x39, 0x10, 0x5F, 0x86, 0x18, + 0xDF, 0x82, 0x08, 0x2E, 0xC6, 0x18, 0x61, 0x87, 0x3F, 0x80, 0x7B, 0x38, + 0x60, 0x82, 0x1C, 0xDE, 0x04, 0x10, 0x5F, 0xCE, 0x18, 0x61, 0x86, 0x37, + 0x40, 0x7B, 0x18, 0x7F, 0x82, 0x0C, 0x5E, 0x32, 0x2F, 0x22, 0x22, 0x22, + 0x20, 0x7F, 0x38, 0x61, 0x86, 0x1C, 0xDD, 0x06, 0x37, 0x80, 0x82, 0x08, + 0x2E, 0xC6, 0x18, 0x61, 0x86, 0x18, 0x40, 0x9F, 0xE0, 0x20, 0x12, 0x49, + 0x24, 0x93, 0x80, 0x82, 0x08, 0x23, 0x9A, 0xCF, 0x34, 0x9A, 0x28, 0xC0, + 0x92, 0x49, 0x24, 0x93, 0x80, 0xB9, 0xD8, 0xC6, 0x10, 0xC2, 0x18, 0x43, + 0x08, 0x61, 0x0C, 0x21, 0xBB, 0x18, 0x61, 0x86, 0x18, 0x61, 0x7B, 0x38, + 0x61, 0x86, 0x1C, 0xDE, 0xBB, 0x18, 0x61, 0x86, 0x1C, 0xFE, 0x82, 0x08, + 0x00, 0x7F, 0x38, 0x61, 0x86, 0x18, 0xDD, 0x04, 0x10, 0x40, 0xBC, 0x88, + 0x88, 0x88, 0x7A, 0x08, 0x3C, 0x1C, 0x18, 0x7E, 0x21, 0x09, 0xF2, 0x10, + 0x84, 0x21, 0x0E, 0x86, 0x18, 0x61, 0x86, 0x1C, 0xDD, 0xC2, 0x8D, 0x91, + 0x22, 0xC7, 0x06, 0x0C, 0xC6, 0x34, 0x62, 0x67, 0x26, 0xD6, 0x29, 0x62, + 0x94, 0x38, 0xC1, 0x0C, 0x46, 0xC8, 0xF0, 0xC1, 0x87, 0x99, 0x23, 0x87, + 0x89, 0x12, 0x66, 0x85, 0x0C, 0x18, 0x30, 0x43, 0x80, 0xFC, 0x31, 0x8C, + 0x31, 0x8C, 0x3F, 0x74, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x70, 0xFF, + 0xF0, 0xE2, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xE0, 0xFF, 0xE0, 0x18, + 0x06, 0x01, 0x80, 0x60, 0x18, 0x06, 0x01, 0x80, 0x60, 0x1F, 0xFC }; + +const GFXglyph Flama_Regular8pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 4, 0, 0 }, // 0x20 ' ' + { 1, 1, 11, 5, 2, -10 }, // 0x21 '!' + { 3, 4, 3, 6, 1, -10 }, // 0x22 '"' + { 5, 7, 10, 9, 1, -9 }, // 0x23 '#' + { 14, 7, 11, 8, 0, -10 }, // 0x24 '$' + { 24, 10, 11, 12, 1, -10 }, // 0x25 '%' + { 38, 11, 11, 12, 1, -10 }, // 0x26 '&' + { 54, 1, 3, 3, 1, -10 }, // 0x27 ''' + { 55, 3, 15, 5, 2, -11 }, // 0x28 '(' + { 61, 3, 15, 5, 0, -11 }, // 0x29 ')' + { 67, 5, 5, 7, 1, -10 }, // 0x2A '*' + { 71, 7, 7, 9, 1, -7 }, // 0x2B '+' + { 78, 1, 4, 3, 1, -1 }, // 0x2C ',' + { 79, 4, 1, 6, 1, -4 }, // 0x2D '-' + { 80, 1, 2, 3, 1, -1 }, // 0x2E '.' + { 81, 5, 12, 5, 0, -10 }, // 0x2F '/' + { 89, 7, 11, 9, 1, -10 }, // 0x30 '0' + { 99, 7, 11, 9, 1, -10 }, // 0x31 '1' + { 109, 6, 11, 8, 1, -10 }, // 0x32 '2' + { 118, 7, 11, 9, 1, -10 }, // 0x33 '3' + { 128, 8, 11, 10, 1, -10 }, // 0x34 '4' + { 139, 7, 11, 9, 1, -10 }, // 0x35 '5' + { 149, 7, 11, 9, 1, -10 }, // 0x36 '6' + { 159, 7, 11, 9, 1, -10 }, // 0x37 '7' + { 169, 7, 11, 9, 1, -10 }, // 0x38 '8' + { 179, 7, 11, 9, 1, -10 }, // 0x39 '9' + { 189, 1, 7, 3, 1, -6 }, // 0x3A ':' + { 190, 1, 9, 3, 1, -6 }, // 0x3B ';' + { 192, 7, 6, 9, 1, -7 }, // 0x3C '<' + { 198, 7, 4, 9, 1, -6 }, // 0x3D '=' + { 202, 7, 6, 9, 1, -7 }, // 0x3E '>' + { 208, 6, 11, 8, 1, -10 }, // 0x3F '?' + { 217, 12, 12, 14, 1, -10 }, // 0x40 '@' + { 235, 10, 11, 10, 0, -10 }, // 0x41 'A' + { 249, 8, 11, 10, 1, -10 }, // 0x42 'B' + { 260, 8, 11, 10, 1, -10 }, // 0x43 'C' + { 271, 8, 11, 10, 1, -10 }, // 0x44 'D' + { 282, 7, 11, 9, 1, -10 }, // 0x45 'E' + { 292, 6, 11, 8, 1, -10 }, // 0x46 'F' + { 301, 8, 11, 10, 1, -10 }, // 0x47 'G' + { 312, 8, 11, 10, 1, -10 }, // 0x48 'H' + { 323, 6, 11, 8, 1, -10 }, // 0x49 'I' + { 332, 7, 11, 9, 1, -10 }, // 0x4A 'J' + { 342, 8, 11, 9, 1, -10 }, // 0x4B 'K' + { 353, 6, 11, 8, 1, -10 }, // 0x4C 'L' + { 362, 10, 11, 12, 1, -10 }, // 0x4D 'M' + { 376, 8, 11, 10, 1, -10 }, // 0x4E 'N' + { 387, 8, 11, 10, 1, -10 }, // 0x4F 'O' + { 398, 7, 11, 9, 1, -10 }, // 0x50 'P' + { 408, 9, 12, 10, 1, -10 }, // 0x51 'Q' + { 422, 7, 11, 9, 1, -10 }, // 0x52 'R' + { 432, 8, 11, 9, 0, -10 }, // 0x53 'S' + { 443, 8, 11, 10, 1, -10 }, // 0x54 'T' + { 454, 8, 11, 10, 1, -10 }, // 0x55 'U' + { 465, 9, 11, 9, 0, -10 }, // 0x56 'V' + { 478, 14, 11, 14, 0, -10 }, // 0x57 'W' + { 498, 9, 11, 9, 0, -10 }, // 0x58 'X' + { 511, 9, 11, 9, 0, -10 }, // 0x59 'Y' + { 524, 7, 11, 9, 1, -10 }, // 0x5A 'Z' + { 534, 3, 15, 6, 2, -11 }, // 0x5B '[' + { 540, 5, 12, 5, 0, -10 }, // 0x5C '\' + { 548, 3, 15, 5, 0, -11 }, // 0x5D ']' + { 554, 10, 11, 12, 1, -10 }, // 0x5E '^' + { 568, 8, 1, 8, 0, 2 }, // 0x5F '_' + { 569, 3, 3, 5, 1, -11 }, // 0x60 '`' + { 571, 6, 8, 8, 1, -7 }, // 0x61 'a' + { 577, 6, 11, 8, 1, -10 }, // 0x62 'b' + { 586, 6, 8, 8, 1, -7 }, // 0x63 'c' + { 592, 6, 11, 8, 1, -10 }, // 0x64 'd' + { 601, 6, 8, 8, 1, -7 }, // 0x65 'e' + { 607, 4, 11, 6, 1, -10 }, // 0x66 'f' + { 613, 6, 11, 8, 1, -7 }, // 0x67 'g' + { 622, 6, 11, 8, 1, -10 }, // 0x68 'h' + { 631, 1, 11, 3, 1, -10 }, // 0x69 'i' + { 633, 3, 14, 3, -1, -10 }, // 0x6A 'j' + { 639, 6, 11, 8, 1, -10 }, // 0x6B 'k' + { 648, 3, 11, 4, 1, -10 }, // 0x6C 'l' + { 653, 11, 8, 13, 1, -7 }, // 0x6D 'm' + { 664, 6, 8, 8, 1, -7 }, // 0x6E 'n' + { 670, 6, 8, 8, 1, -7 }, // 0x6F 'o' + { 676, 6, 11, 8, 1, -7 }, // 0x70 'p' + { 685, 6, 11, 8, 1, -7 }, // 0x71 'q' + { 694, 4, 8, 6, 1, -7 }, // 0x72 'r' + { 698, 6, 8, 8, 1, -7 }, // 0x73 's' + { 704, 5, 11, 7, 1, -10 }, // 0x74 't' + { 711, 6, 8, 8, 1, -7 }, // 0x75 'u' + { 717, 7, 8, 8, 0, -7 }, // 0x76 'v' + { 724, 12, 8, 12, 0, -7 }, // 0x77 'w' + { 736, 7, 8, 8, 0, -7 }, // 0x78 'x' + { 743, 7, 11, 8, 1, -7 }, // 0x79 'y' + { 753, 6, 8, 8, 1, -7 }, // 0x7A 'z' + { 759, 4, 15, 6, 1, -11 }, // 0x7B '{' + { 767, 1, 12, 5, 2, -10 }, // 0x7C '|' + { 769, 4, 15, 5, 0, -11 }, // 0x7D '}' + { 777, 10, 11, 12, 1, -10 } }; // 0x7E '~' + +const GFXfont Flama_Regular8pt7b PROGMEM = { + (uint8_t *)Flama_Regular8pt7bBitmaps, + (GFXglyph *)Flama_Regular8pt7bGlyphs, + 0x20, 0x7E, 18 }; + +// Approx. 1463 bytes diff --git a/libraries/_NToolsFonts/teko4P.h b/libraries/_NToolsFonts/teko4P.h new file mode 100644 index 0000000..5ac0656 --- /dev/null +++ b/libraries/_NToolsFonts/teko4P.h @@ -0,0 +1,120 @@ +const uint8_t teko4pt7bBitmaps[] PROGMEM = { + 0x00, 0xE8, 0xF0, 0x5F, 0x6E, 0xA0, 0x5A, 0xE3, 0xD0, 0xD7, 0x3E, 0x75, + 0x80, 0x6A, 0x4A, 0xF0, 0xC0, 0x6A, 0xA4, 0x95, 0x58, 0x70, 0x5D, 0x00, + 0xC0, 0xC0, 0x80, 0x29, 0x29, 0x00, 0xF6, 0xDE, 0xF8, 0xF5, 0xC0, 0xF7, + 0xC0, 0x4A, 0x72, 0xF3, 0xDE, 0xF7, 0xDE, 0xD6, 0x80, 0xF5, 0x5E, 0xF7, + 0xDE, 0x90, 0x98, 0x39, 0x80, 0xFC, 0xC7, 0x00, 0xD4, 0x40, 0xE9, 0xFB, + 0xCE, 0x4A, 0xFA, 0xF7, 0xDE, 0xF6, 0x5E, 0xF6, 0xDE, 0xD3, 0x4E, 0xF3, + 0x48, 0xF6, 0xDE, 0xB7, 0xDA, 0xF8, 0x57, 0xC0, 0xBB, 0x6A, 0xAA, 0xC0, + 0x9F, 0xFB, 0x90, 0xBF, 0xDA, 0xF6, 0xDE, 0xF7, 0xC8, 0xF6, 0xDE, 0x40, + 0xF7, 0xDA, 0xD7, 0x1E, 0xD5, 0x40, 0xB6, 0xDE, 0xB6, 0xE4, 0xAD, 0x7C, + 0xE5, 0x00, 0xB9, 0x6A, 0xB5, 0x24, 0xD6, 0xC0, 0xEA, 0xAC, 0x89, 0x22, + 0x40, 0xD5, 0x5C, 0x6E, 0x80, 0xF0, 0x80, 0xFF, 0x9A, 0xDC, 0xD6, 0x70, + 0x7F, 0xC0, 0xD7, 0x70, 0xFA, 0x80, 0xFF, 0xC0, 0x9A, 0xDA, 0xF8, 0xFC, + 0x97, 0x6A, 0xF8, 0xFB, 0xBB, 0xD6, 0xD0, 0xF6, 0xF0, 0xD6, 0xE8, 0xFF, + 0x40, 0xEA, 0xE7, 0xEB, 0xB6, 0xF0, 0xFD, 0xBB, 0xF7, 0xA9, 0x50, 0xB7, + 0x2C, 0xDB, 0x56, 0x54, 0xFE, 0x95, 0x58, 0xF0 }; + +const GFXglyph teko4pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 1, 0, 0 }, // 0x20 ' ' + { 1, 1, 5, 2, 0, -4 }, // 0x21 '!' + { 2, 2, 2, 2, 0, -4 }, // 0x22 '"' + { 3, 4, 5, 4, 0, -4 }, // 0x23 '#' + { 6, 3, 7, 3, 0, -5 }, // 0x24 '$' + { 9, 5, 5, 5, 0, -4 }, // 0x25 '%' + { 13, 4, 5, 4, 0, -4 }, // 0x26 '&' + { 16, 1, 2, 1, 0, -4 }, // 0x27 ''' + { 17, 2, 7, 2, 0, -5 }, // 0x28 '(' + { 19, 2, 7, 2, 0, -5 }, // 0x29 ')' + { 21, 2, 2, 3, 0, -4 }, // 0x2A '*' + { 22, 3, 3, 3, 0, -3 }, // 0x2B '+' + { 24, 1, 2, 1, 0, 0 }, // 0x2C ',' + { 25, 2, 1, 2, 0, -2 }, // 0x2D '-' + { 26, 1, 1, 1, 0, 0 }, // 0x2E '.' + { 27, 3, 6, 3, 0, -4 }, // 0x2F '/' + { 30, 3, 5, 3, 0, -4 }, // 0x30 '0' + { 32, 1, 5, 2, 0, -4 }, // 0x31 '1' + { 33, 2, 5, 3, 0, -4 }, // 0x32 '2' + { 35, 2, 5, 3, 0, -4 }, // 0x33 '3' + { 37, 3, 5, 3, 0, -4 }, // 0x34 '4' + { 39, 3, 5, 3, 0, -4 }, // 0x35 '5' + { 41, 3, 5, 3, 0, -4 }, // 0x36 '6' + { 43, 2, 5, 2, 0, -4 }, // 0x37 '7' + { 45, 3, 5, 3, 0, -4 }, // 0x38 '8' + { 47, 3, 5, 3, 0, -4 }, // 0x39 '9' + { 49, 1, 4, 1, 0, -3 }, // 0x3A ':' + { 50, 1, 5, 1, 0, -3 }, // 0x3B ';' + { 51, 3, 3, 3, 0, -3 }, // 0x3C '<' + { 53, 3, 2, 3, 0, -2 }, // 0x3D '=' + { 54, 3, 3, 3, 0, -3 }, // 0x3E '>' + { 56, 2, 5, 3, 0, -4 }, // 0x3F '?' + { 58, 4, 6, 5, 1, -4 }, // 0x40 '@' + { 61, 3, 5, 3, 0, -4 }, // 0x41 'A' + { 63, 3, 5, 3, 0, -4 }, // 0x42 'B' + { 65, 3, 5, 3, 0, -4 }, // 0x43 'C' + { 67, 3, 5, 3, 0, -4 }, // 0x44 'D' + { 69, 3, 5, 3, 0, -4 }, // 0x45 'E' + { 71, 3, 5, 3, 0, -4 }, // 0x46 'F' + { 73, 3, 5, 3, 0, -4 }, // 0x47 'G' + { 75, 3, 5, 3, 0, -4 }, // 0x48 'H' + { 77, 1, 5, 2, 0, -4 }, // 0x49 'I' + { 78, 2, 5, 3, 0, -4 }, // 0x4A 'J' + { 80, 3, 5, 3, 0, -4 }, // 0x4B 'K' + { 82, 2, 5, 2, 0, -4 }, // 0x4C 'L' + { 84, 4, 5, 4, 0, -4 }, // 0x4D 'M' + { 87, 3, 5, 3, 0, -4 }, // 0x4E 'N' + { 89, 3, 5, 3, 0, -4 }, // 0x4F 'O' + { 91, 3, 5, 3, 0, -4 }, // 0x50 'P' + { 93, 3, 6, 3, 0, -4 }, // 0x51 'Q' + { 96, 3, 5, 3, 0, -4 }, // 0x52 'R' + { 98, 3, 5, 3, 0, -4 }, // 0x53 'S' + { 100, 2, 5, 2, 0, -4 }, // 0x54 'T' + { 102, 3, 5, 3, 0, -4 }, // 0x55 'U' + { 104, 3, 5, 3, 0, -4 }, // 0x56 'V' + { 106, 5, 5, 5, 0, -4 }, // 0x57 'W' + { 110, 3, 5, 3, 0, -4 }, // 0x58 'X' + { 112, 3, 5, 3, 0, -4 }, // 0x59 'Y' + { 114, 2, 5, 2, 0, -4 }, // 0x5A 'Z' + { 116, 2, 7, 2, 0, -5 }, // 0x5B '[' + { 118, 3, 6, 3, 0, -4 }, // 0x5C '\' + { 121, 2, 7, 2, 0, -5 }, // 0x5D ']' + { 123, 3, 3, 4, 0, -4 }, // 0x5E '^' + { 125, 4, 1, 4, 0, 1 }, // 0x5F '_' + { 126, 1, 1, 3, 1, -4 }, // 0x60 '`' + { 127, 2, 4, 3, 0, -3 }, // 0x61 'a' + { 128, 3, 5, 3, 0, -4 }, // 0x62 'b' + { 130, 3, 4, 3, 0, -3 }, // 0x63 'c' + { 132, 2, 5, 3, 0, -4 }, // 0x64 'd' + { 134, 3, 4, 3, 0, -3 }, // 0x65 'e' + { 136, 2, 5, 2, 0, -4 }, // 0x66 'f' + { 138, 2, 5, 3, 0, -3 }, // 0x67 'g' + { 140, 3, 5, 3, 0, -4 }, // 0x68 'h' + { 142, 1, 5, 1, 0, -4 }, // 0x69 'i' + { 143, 1, 6, 1, 0, -4 }, // 0x6A 'j' + { 144, 3, 5, 3, 0, -4 }, // 0x6B 'k' + { 146, 1, 5, 1, 0, -4 }, // 0x6C 'l' + { 147, 4, 4, 4, 0, -3 }, // 0x6D 'm' + { 149, 3, 4, 3, 0, -3 }, // 0x6E 'n' + { 151, 3, 4, 3, 0, -3 }, // 0x6F 'o' + { 153, 3, 5, 3, 0, -3 }, // 0x70 'p' + { 155, 2, 5, 3, 0, -3 }, // 0x71 'q' + { 157, 2, 4, 2, 0, -3 }, // 0x72 'r' + { 158, 2, 4, 3, 0, -3 }, // 0x73 's' + { 159, 2, 4, 2, 0, -3 }, // 0x74 't' + { 160, 3, 4, 3, 0, -3 }, // 0x75 'u' + { 162, 2, 4, 2, 0, -3 }, // 0x76 'v' + { 163, 4, 4, 4, 0, -3 }, // 0x77 'w' + { 165, 3, 4, 3, 0, -3 }, // 0x78 'x' + { 167, 3, 5, 3, 0, -3 }, // 0x79 'y' + { 169, 2, 4, 2, 0, -3 }, // 0x7A 'z' + { 170, 2, 7, 2, 0, -5 }, // 0x7B '{' + { 172, 1, 7, 2, 0, -5 }, // 0x7C '|' + { 173, 2, 7, 2, 0, -5 }, // 0x7D '}' + { 175, 4, 1, 4, 0, -2 } }; // 0x7E '~' + +const GFXfont teko4pt7b PROGMEM = { + (uint8_t *)teko4pt7bBitmaps, + (GFXglyph *)teko4pt7bGlyphs, + 0x20, 0x7E, 11 }; + +// Approx. 848 bytes diff --git a/libraries/_NToolsFonts/teko6P.h b/libraries/_NToolsFonts/teko6P.h new file mode 100644 index 0000000..36bbe53 --- /dev/null +++ b/libraries/_NToolsFonts/teko6P.h @@ -0,0 +1,134 @@ +const uint8_t teko6pt7bBitmaps[] PROGMEM = { + 0x00, 0xFA, 0xB4, 0x52, 0xBE, 0xAF, 0xA9, 0x40, 0x23, 0xA3, 0x07, 0x06, + 0x2E, 0x20, 0x00, 0xE5, 0x52, 0xA7, 0xF1, 0xA5, 0x4B, 0x80, 0x71, 0x45, + 0x18, 0xFA, 0x47, 0xC0, 0xC0, 0x29, 0x29, 0x22, 0x48, 0x80, 0x89, 0x22, + 0x4A, 0x4A, 0x00, 0x96, 0x66, 0x90, 0x21, 0x3E, 0x42, 0x00, 0xD4, 0x00, + 0xC0, 0xF0, 0x11, 0x22, 0x24, 0x44, 0x90, 0xF9, 0x99, 0x99, 0xF0, 0xD5, + 0x54, 0x00, 0xF1, 0x17, 0x88, 0xF0, 0xF9, 0x17, 0x19, 0xF0, 0x99, 0x9F, + 0x11, 0x10, 0xF8, 0x8E, 0x11, 0xE0, 0xF8, 0x8F, 0x99, 0xF0, 0xE4, 0xA4, + 0x90, 0x00, 0xF9, 0x9F, 0x99, 0xF0, 0xF9, 0x9F, 0x11, 0xF0, 0xF0, 0xF0, + 0xF0, 0x35, 0x12, 0x44, 0x21, 0x78, 0x1E, 0x00, 0x88, 0x95, 0x00, 0xF9, + 0x13, 0x20, 0x20, 0xFF, 0x06, 0xED, 0x5A, 0xB7, 0xE0, 0x7C, 0xF9, 0x9F, + 0x99, 0x90, 0xE9, 0x9E, 0x99, 0xE0, 0xF9, 0x88, 0x89, 0xF0, 0xE9, 0x99, + 0x99, 0xE0, 0xF8, 0x8E, 0x88, 0xF0, 0xF8, 0x8E, 0x88, 0x80, 0xF9, 0x8F, + 0x99, 0xF0, 0x99, 0x9F, 0x99, 0x90, 0xFE, 0x24, 0x93, 0x78, 0x99, 0xAC, + 0xA9, 0x90, 0x92, 0x49, 0x38, 0x00, 0x8E, 0xEB, 0x18, 0xC6, 0x20, 0x9D, + 0xB9, 0x99, 0x90, 0xF9, 0x99, 0x99, 0xF0, 0xF6, 0xF9, 0x20, 0xF9, 0x99, + 0x99, 0xF1, 0xE9, 0x9F, 0xA9, 0x90, 0xF9, 0x8F, 0x19, 0xF0, 0xE9, 0x24, + 0x90, 0x00, 0x99, 0x99, 0x99, 0xF0, 0x99, 0x99, 0x66, 0x60, 0x8C, 0x63, + 0x1A, 0xD7, 0x60, 0x8A, 0x88, 0x42, 0x2A, 0x20, 0x8A, 0x88, 0x42, 0x10, + 0x80, 0xF1, 0x24, 0x48, 0xF0, 0xEA, 0xAA, 0xAC, 0x42, 0x10, 0x42, 0x10, + 0x42, 0x10, 0x00, 0xD5, 0x55, 0x5C, 0x66, 0x99, 0xFC, 0x88, 0x80, 0x07, + 0x99, 0x97, 0x88, 0x8F, 0x99, 0x9F, 0x06, 0x98, 0x96, 0x11, 0x17, 0x99, + 0x97, 0x06, 0x9F, 0x86, 0x6B, 0xA4, 0x92, 0x07, 0x99, 0x97, 0x16, 0x92, + 0x6B, 0x6D, 0x10, 0x55, 0x10, 0x55, 0x60, 0x92, 0xFD, 0xBD, 0xFF, 0x06, + 0xEB, 0x5A, 0xD4, 0x00, 0x1A, 0xDB, 0x40, 0x06, 0x99, 0x96, 0x1A, 0xDB, + 0xA4, 0x07, 0x99, 0x97, 0x11, 0x3A, 0xA0, 0x1E, 0x33, 0xC0, 0x5D, 0x24, + 0x90, 0x00, 0x09, 0x99, 0x97, 0x0A, 0xAA, 0xA4, 0x02, 0x28, 0xAA, 0xF9, + 0x40, 0x09, 0x66, 0x69, 0x09, 0x99, 0x66, 0x24, 0x1C, 0xA9, 0xC0, 0x69, + 0x25, 0x92, 0x49, 0x80, 0xFF, 0xC0, 0xC9, 0x24, 0xD2, 0x4B, 0x00, 0x5A +}; + +const GFXglyph teko6pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 2, 1, 0 }, // 0x20 ' ' + { 1, 1, 7, 2, 1, -6 }, // 0x21 '!' + { 2, 3, 2, 4, 1, -6 }, // 0x22 '"' + { 3, 5, 7, 6, 1, -6 }, // 0x23 '#' + { 8, 5, 9, 6, 1, -7 }, // 0x24 '$' + { 15, 7, 7, 8, 1, -6 }, // 0x25 '%' + { 22, 6, 7, 7, 1, -6 }, // 0x26 '&' + { 28, 1, 2, 2, 1, -6 }, // 0x27 ''' + { 29, 3, 11, 4, 1, -8 }, // 0x28 '(' + { 34, 3, 11, 4, 1, -8 }, // 0x29 ')' + { 39, 4, 5, 5, 1, -5 }, // 0x2A '*' + { 42, 5, 5, 6, 1, -5 }, // 0x2B '+' + { 46, 2, 3, 3, 1, 0 }, // 0x2C ',' + { 48, 2, 1, 3, 1, -3 }, // 0x2D '-' + { 49, 2, 2, 3, 1, -1 }, // 0x2E '.' + { 50, 4, 9, 5, 1, -7 }, // 0x2F '/' + { 55, 4, 7, 5, 1, -6 }, // 0x30 '0' + { 59, 2, 7, 3, 1, -6 }, // 0x31 '1' + { 62, 4, 7, 5, 1, -6 }, // 0x32 '2' + { 66, 4, 7, 5, 1, -6 }, // 0x33 '3' + { 70, 4, 7, 5, 1, -6 }, // 0x34 '4' + { 74, 4, 7, 5, 1, -6 }, // 0x35 '5' + { 78, 4, 7, 5, 1, -6 }, // 0x36 '6' + { 82, 3, 7, 4, 1, -6 }, // 0x37 '7' + { 86, 4, 7, 5, 1, -6 }, // 0x38 '8' + { 90, 4, 7, 5, 1, -6 }, // 0x39 '9' + { 94, 2, 6, 3, 1, -5 }, // 0x3A ':' + { 96, 2, 8, 3, 1, -5 }, // 0x3B ';' + { 98, 4, 6, 4, 0, -5 }, // 0x3C '<' + { 101, 5, 3, 5, 0, -4 }, // 0x3D '=' + { 104, 3, 6, 4, 1, -5 }, // 0x3E '>' + { 107, 4, 7, 5, 1, -6 }, // 0x3F '?' + { 111, 7, 8, 8, 1, -6 }, // 0x40 '@' + { 118, 4, 7, 5, 1, -6 }, // 0x41 'A' + { 122, 4, 7, 5, 1, -6 }, // 0x42 'B' + { 126, 4, 7, 5, 1, -6 }, // 0x43 'C' + { 130, 4, 7, 5, 1, -6 }, // 0x44 'D' + { 134, 4, 7, 5, 1, -6 }, // 0x45 'E' + { 138, 4, 7, 5, 1, -6 }, // 0x46 'F' + { 142, 4, 7, 5, 1, -6 }, // 0x47 'G' + { 146, 4, 7, 5, 1, -6 }, // 0x48 'H' + { 150, 1, 7, 2, 1, -6 }, // 0x49 'I' + { 151, 3, 7, 4, 1, -6 }, // 0x4A 'J' + { 154, 4, 7, 5, 1, -6 }, // 0x4B 'K' + { 158, 3, 7, 4, 1, -6 }, // 0x4C 'L' + { 162, 5, 7, 6, 1, -6 }, // 0x4D 'M' + { 167, 4, 7, 5, 1, -6 }, // 0x4E 'N' + { 171, 4, 7, 5, 1, -6 }, // 0x4F 'O' + { 175, 3, 7, 4, 1, -6 }, // 0x50 'P' + { 178, 4, 8, 5, 1, -6 }, // 0x51 'Q' + { 182, 4, 7, 5, 1, -6 }, // 0x52 'R' + { 186, 4, 7, 5, 1, -6 }, // 0x53 'S' + { 190, 3, 7, 4, 1, -6 }, // 0x54 'T' + { 194, 4, 7, 5, 1, -6 }, // 0x55 'U' + { 198, 4, 7, 5, 1, -6 }, // 0x56 'V' + { 202, 5, 7, 6, 1, -6 }, // 0x57 'W' + { 207, 5, 7, 6, 1, -6 }, // 0x58 'X' + { 212, 5, 7, 6, 1, -6 }, // 0x59 'Y' + { 217, 4, 7, 5, 1, -6 }, // 0x5A 'Z' + { 221, 2, 11, 3, 1, -8 }, // 0x5B '[' + { 224, 5, 9, 4, 0, -7 }, // 0x5C '\' + { 231, 2, 11, 4, 1, -8 }, // 0x5D ']' + { 234, 4, 4, 5, 1, -7 }, // 0x5E '^' + { 236, 6, 1, 6, 0, 1 }, // 0x5F '_' + { 237, 3, 3, 3, 0, -7 }, // 0x60 '`' + { 239, 4, 6, 5, 1, -5 }, // 0x61 'a' + { 242, 4, 8, 5, 1, -7 }, // 0x62 'b' + { 246, 4, 6, 5, 1, -5 }, // 0x63 'c' + { 249, 4, 8, 5, 1, -7 }, // 0x64 'd' + { 253, 4, 6, 5, 1, -5 }, // 0x65 'e' + { 256, 3, 8, 4, 1, -7 }, // 0x66 'f' + { 259, 4, 8, 5, 1, -5 }, // 0x67 'g' + { 263, 3, 8, 4, 1, -7 }, // 0x68 'h' + { 266, 2, 8, 2, 0, -7 }, // 0x69 'i' + { 268, 2, 10, 3, 1, -7 }, // 0x6A 'j' + { 271, 3, 8, 4, 1, -7 }, // 0x6B 'k' + { 274, 1, 8, 2, 1, -7 }, // 0x6C 'l' + { 275, 5, 6, 6, 1, -5 }, // 0x6D 'm' + { 280, 3, 6, 4, 1, -5 }, // 0x6E 'n' + { 283, 4, 6, 5, 1, -5 }, // 0x6F 'o' + { 286, 3, 8, 4, 1, -5 }, // 0x70 'p' + { 289, 4, 8, 5, 1, -5 }, // 0x71 'q' + { 293, 2, 6, 3, 1, -5 }, // 0x72 'r' + { 295, 3, 6, 4, 1, -5 }, // 0x73 's' + { 298, 3, 7, 4, 1, -6 }, // 0x74 't' + { 302, 4, 6, 5, 1, -5 }, // 0x75 'u' + { 305, 4, 6, 4, 1, -5 }, // 0x76 'v' + { 308, 6, 6, 6, 1, -5 }, // 0x77 'w' + { 313, 4, 6, 5, 1, -5 }, // 0x78 'x' + { 316, 4, 8, 5, 1, -5 }, // 0x79 'y' + { 320, 3, 6, 4, 1, -5 }, // 0x7A 'z' + { 323, 3, 11, 4, 1, -8 }, // 0x7B '{' + { 328, 1, 10, 2, 1, -8 }, // 0x7C '|' + { 330, 3, 11, 4, 1, -8 }, // 0x7D '}' + { 335, 4, 2, 5, 1, -3 } // 0x7E '~' +}; + +const GFXfont teko6pt7b PROGMEM = { + (uint8_t *)teko6pt7bBitmaps, + (GFXglyph *)teko6pt7bGlyphs, 0x20, 0x7E, 17 }; + +// Approx. 975 bytes diff --git a/libraries/_NToolsFonts/teko8P.h b/libraries/_NToolsFonts/teko8P.h new file mode 100644 index 0000000..a0ecd6f --- /dev/null +++ b/libraries/_NToolsFonts/teko8P.h @@ -0,0 +1,148 @@ +const uint8_t teko8pt7bBitmaps[] PROGMEM = { + 0x00, 0xFE, 0xC0, 0xB6, 0xD0, 0x12, 0x6C, 0x93, 0xF2, 0x44, 0xBF, 0xB6, + 0x48, 0x90, 0x6F, 0x99, 0x8E, 0x71, 0x99, 0xF6, 0x71, 0x34, 0x8D, 0x23, + 0x50, 0xD4, 0x0A, 0xF0, 0xAC, 0x4B, 0x12, 0xCC, 0xE0, 0xF1, 0x22, 0x44, + 0x87, 0x0C, 0x2D, 0x4E, 0x8D, 0xF8, 0x08, 0xF0, 0x7B, 0x49, 0x24, 0x92, + 0x4C, 0xC8, 0xCC, 0x92, 0x49, 0x24, 0x97, 0xA0, 0x27, 0xDC, 0xA5, 0x00, + 0x30, 0xC3, 0x3F, 0x30, 0xC0, 0xFE, 0xE0, 0xF0, 0x0C, 0x21, 0x84, 0x10, + 0xC2, 0x08, 0x61, 0x04, 0x30, 0x80, 0xF9, 0x99, 0x99, 0x99, 0x9F, 0xED, + 0xB6, 0xDB, 0x6C, 0x76, 0xF6, 0x31, 0x18, 0x8C, 0x47, 0xC0, 0x76, 0xF6, + 0x33, 0x9C, 0x7B, 0xDB, 0xC0, 0x10, 0xC2, 0x08, 0x41, 0x6D, 0xBF, 0x18, + 0x60, 0xF8, 0x88, 0xF1, 0x19, 0x9F, 0xF9, 0x98, 0xF9, 0x99, 0x9F, 0xF1, + 0x13, 0x22, 0x66, 0x4C, 0xF9, 0x99, 0x9F, 0x99, 0x9F, 0xF9, 0x99, 0x9F, + 0x19, 0x9F, 0xF0, 0x0F, 0xF0, 0x0F, 0xE0, 0x04, 0x7F, 0x38, 0x1C, 0x10, + 0xFC, 0x00, 0x3F, 0x83, 0xC1, 0xC7, 0xF2, 0x00, 0x76, 0xF6, 0x31, 0x98, + 0x80, 0x21, 0x00, 0xFF, 0xE0, 0x77, 0xBA, 0xDD, 0x6E, 0xB7, 0x5B, 0xBF, + 0xC0, 0x7F, 0x00, 0x30, 0xC3, 0x1E, 0x59, 0x24, 0x9E, 0xCF, 0x30, 0xF4, + 0xE7, 0x3F, 0xFE, 0x73, 0x9F, 0x80, 0xF9, 0x98, 0x88, 0x89, 0x9F, 0xF4, + 0xE7, 0x39, 0xCE, 0x73, 0x9F, 0x80, 0xF8, 0x88, 0xFF, 0x88, 0x8F, 0xF8, + 0x88, 0x8F, 0x88, 0x88, 0xF9, 0x98, 0x8B, 0x99, 0x9F, 0x9C, 0xE7, 0x39, + 0xFE, 0x73, 0x9C, 0xC0, 0xFF, 0xC0, 0x11, 0x11, 0x11, 0x1D, 0xDF, 0x9C, + 0xAD, 0x4A, 0x72, 0x96, 0x94, 0xC0, 0x88, 0x88, 0x88, 0x88, 0x8F, 0x87, + 0x3C, 0xF3, 0xEE, 0xDB, 0x6D, 0x86, 0x10, 0x9E, 0xF7, 0xBB, 0xDE, 0xF7, + 0x9C, 0xC0, 0xF9, 0x99, 0x99, 0x99, 0x9F, 0xF4, 0xA7, 0x39, 0xFA, 0x10, + 0x84, 0x00, 0xF4, 0xA5, 0x29, 0x4A, 0x52, 0x97, 0x8E, 0xF4, 0xA7, 0x39, + 0xFA, 0xD2, 0x94, 0xC0, 0xF9, 0x98, 0xE7, 0x19, 0x9F, 0xF9, 0x08, 0x42, + 0x10, 0x84, 0x21, 0x00, 0x99, 0x99, 0x99, 0x99, 0x9F, 0xCF, 0x2C, 0x92, + 0x49, 0x67, 0x1C, 0x30, 0xC0, 0xCC, 0xE6, 0x53, 0x2B, 0x95, 0x5A, 0xAD, + 0x54, 0xEE, 0x73, 0x19, 0x80, 0xCD, 0x27, 0x8C, 0x30, 0xC3, 0x16, 0x4B, + 0x30, 0xCF, 0x24, 0x96, 0x70, 0xC3, 0x0C, 0x30, 0xC0, 0xF8, 0xC4, 0x62, + 0x11, 0x88, 0xC7, 0xC0, 0xF2, 0x49, 0x24, 0x92, 0x49, 0xF8, 0xC1, 0x06, + 0x08, 0x20, 0xC1, 0x04, 0x18, 0x20, 0x83, 0x04, 0xED, 0xB6, 0xDB, 0x6D, + 0xB7, 0xF8, 0x30, 0xC7, 0x16, 0xCB, 0x30, 0xFE, 0xCC, 0xDF, 0x99, 0x99, + 0x9F, 0x88, 0xEF, 0x99, 0x99, 0x9F, 0xEF, 0x98, 0x88, 0x9F, 0x11, 0xDB, + 0x99, 0x99, 0x9F, 0xE9, 0x99, 0xF8, 0x9F, 0x6B, 0xF4, 0x92, 0x48, 0xDF, + 0x99, 0x99, 0xBD, 0x1F, 0x88, 0xEF, 0x99, 0x99, 0x99, 0xDF, 0xE0, 0x51, + 0x55, 0x55, 0xC0, 0x84, 0x27, 0x2B, 0x53, 0x94, 0xB4, 0xC0, 0xFF, 0xC0, + 0xED, 0xFE, 0x4C, 0x99, 0x32, 0x64, 0xC9, 0xEF, 0x99, 0x99, 0x99, 0xF9, + 0x99, 0x99, 0x9F, 0xEF, 0x99, 0x99, 0x9F, 0x88, 0xDF, 0x99, 0x99, 0x9F, + 0x11, 0xBE, 0x49, 0x24, 0xEB, 0x88, 0xF3, 0xBE, 0x5F, 0xA4, 0x92, 0x60, + 0x99, 0x99, 0x99, 0x9F, 0x9E, 0xF6, 0xA5, 0x29, 0x4E, 0x99, 0xD9, 0xD9, + 0x5D, 0x57, 0x56, 0x76, 0x66, 0xCA, 0xDC, 0x63, 0x39, 0x79, 0xCE, 0x56, + 0xB5, 0x39, 0xC6, 0x33, 0x00, 0xF1, 0x32, 0x64, 0xCF, 0x32, 0x22, 0x22, + 0x6E, 0x22, 0x22, 0x23, 0x30, 0xFF, 0xFC, 0xE6, 0x66, 0x66, 0x23, 0x66, + 0x66, 0x6E, 0xC0, 0xE6, 0xD8, 0xC0 }; + +const GFXglyph teko8pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 2, 0, 0 }, // 0x20 ' ' + { 1, 1, 10, 3, 1, -9 }, // 0x21 '!' + { 3, 3, 4, 5, 1, -9 }, // 0x22 '"' + { 5, 7, 10, 8, 0, -9 }, // 0x23 '#' + { 14, 4, 12, 6, 1, -10 }, // 0x24 '$' + { 20, 10, 10, 10, 0, -9 }, // 0x25 '%' + { 33, 7, 11, 7, 1, -9 }, // 0x26 '&' + { 43, 1, 4, 3, 1, -9 }, // 0x27 ''' + { 44, 3, 15, 4, 1, -11 }, // 0x28 '(' + { 50, 3, 15, 4, 0, -11 }, // 0x29 ')' + { 56, 5, 5, 5, 0, -9 }, // 0x2A '*' + { 60, 6, 6, 6, 0, -7 }, // 0x2B '+' + { 65, 2, 4, 3, 0, -1 }, // 0x2C ',' + { 66, 3, 1, 5, 1, -4 }, // 0x2D '-' + { 67, 2, 2, 3, 0, -1 }, // 0x2E '.' + { 68, 6, 13, 6, 0, -10 }, // 0x2F '/' + { 78, 4, 10, 6, 1, -9 }, // 0x30 '0' + { 83, 3, 10, 4, 0, -9 }, // 0x31 '1' + { 87, 5, 10, 5, 0, -9 }, // 0x32 '2' + { 94, 5, 10, 6, 0, -9 }, // 0x33 '3' + { 101, 6, 10, 6, 0, -9 }, // 0x34 '4' + { 109, 4, 10, 6, 1, -9 }, // 0x35 '5' + { 114, 4, 10, 6, 1, -9 }, // 0x36 '6' + { 119, 4, 10, 5, 0, -9 }, // 0x37 '7' + { 124, 4, 10, 6, 1, -9 }, // 0x38 '8' + { 129, 4, 10, 6, 1, -9 }, // 0x39 '9' + { 134, 2, 8, 3, 0, -7 }, // 0x3A ':' + { 136, 2, 10, 3, 0, -7 }, // 0x3B ';' + { 139, 6, 6, 7, 0, -7 }, // 0x3C '<' + { 144, 6, 4, 7, 0, -6 }, // 0x3D '=' + { 147, 6, 6, 7, 0, -7 }, // 0x3E '>' + { 152, 5, 10, 5, 0, -9 }, // 0x3F '?' + { 159, 9, 10, 11, 1, -8 }, // 0x40 '@' + { 171, 6, 10, 6, 0, -9 }, // 0x41 'A' + { 179, 5, 10, 6, 1, -9 }, // 0x42 'B' + { 186, 4, 10, 6, 1, -9 }, // 0x43 'C' + { 191, 5, 10, 6, 1, -9 }, // 0x44 'D' + { 198, 4, 10, 5, 1, -9 }, // 0x45 'E' + { 203, 4, 10, 5, 1, -9 }, // 0x46 'F' + { 208, 4, 10, 6, 1, -9 }, // 0x47 'G' + { 213, 5, 10, 7, 1, -9 }, // 0x48 'H' + { 220, 1, 10, 3, 1, -9 }, // 0x49 'I' + { 222, 4, 10, 5, 0, -9 }, // 0x4A 'J' + { 227, 5, 10, 6, 1, -9 }, // 0x4B 'K' + { 234, 4, 10, 5, 1, -9 }, // 0x4C 'L' + { 239, 6, 10, 8, 1, -9 }, // 0x4D 'M' + { 247, 5, 10, 6, 1, -9 }, // 0x4E 'N' + { 254, 4, 10, 6, 1, -9 }, // 0x4F 'O' + { 259, 5, 10, 6, 1, -9 }, // 0x50 'P' + { 266, 5, 11, 6, 1, -9 }, // 0x51 'Q' + { 273, 5, 10, 6, 1, -9 }, // 0x52 'R' + { 280, 4, 10, 6, 1, -9 }, // 0x53 'S' + { 285, 5, 10, 5, 0, -9 }, // 0x54 'T' + { 292, 4, 10, 6, 1, -9 }, // 0x55 'U' + { 297, 6, 10, 6, 0, -9 }, // 0x56 'V' + { 305, 9, 10, 10, 0, -9 }, // 0x57 'W' + { 317, 6, 10, 6, 0, -9 }, // 0x58 'X' + { 325, 6, 10, 6, 0, -9 }, // 0x59 'Y' + { 333, 5, 10, 5, 0, -9 }, // 0x5A 'Z' + { 340, 3, 15, 5, 1, -11 }, // 0x5B '[' + { 346, 6, 13, 6, 0, -10 }, // 0x5C '\' + { 356, 3, 15, 5, 1, -11 }, // 0x5D ']' + { 362, 6, 6, 8, 1, -10 }, // 0x5E '^' + { 367, 7, 1, 7, 0, 2 }, // 0x5F '_' + { 368, 3, 2, 7, 2, -9 }, // 0x60 '`' + { 369, 4, 8, 6, 1, -7 }, // 0x61 'a' + { 373, 4, 10, 6, 1, -9 }, // 0x62 'b' + { 378, 4, 8, 6, 1, -7 }, // 0x63 'c' + { 382, 4, 10, 6, 1, -9 }, // 0x64 'd' + { 387, 4, 8, 6, 1, -7 }, // 0x65 'e' + { 391, 3, 10, 3, 0, -9 }, // 0x66 'f' + { 395, 4, 10, 6, 1, -7 }, // 0x67 'g' + { 400, 4, 10, 6, 1, -9 }, // 0x68 'h' + { 405, 1, 11, 3, 1, -10 }, // 0x69 'i' + { 407, 2, 13, 3, 0, -10 }, // 0x6A 'j' + { 411, 5, 10, 6, 1, -9 }, // 0x6B 'k' + { 418, 1, 10, 3, 1, -9 }, // 0x6C 'l' + { 420, 7, 8, 9, 1, -7 }, // 0x6D 'm' + { 427, 4, 8, 6, 1, -7 }, // 0x6E 'n' + { 431, 4, 8, 6, 1, -7 }, // 0x6F 'o' + { 435, 4, 10, 6, 1, -7 }, // 0x70 'p' + { 440, 4, 10, 6, 1, -7 }, // 0x71 'q' + { 445, 3, 8, 4, 1, -7 }, // 0x72 'r' + { 448, 4, 8, 5, 1, -7 }, // 0x73 's' + { 452, 3, 9, 3, 0, -8 }, // 0x74 't' + { 456, 4, 8, 6, 1, -7 }, // 0x75 'u' + { 460, 5, 8, 5, 0, -7 }, // 0x76 'v' + { 465, 8, 8, 9, 0, -7 }, // 0x77 'w' + { 473, 5, 8, 5, 0, -7 }, // 0x78 'x' + { 478, 5, 10, 5, 0, -7 }, // 0x79 'y' + { 485, 4, 8, 5, 0, -7 }, // 0x7A 'z' + { 489, 4, 15, 4, 0, -11 }, // 0x7B '{' + { 497, 1, 14, 3, 1, -11 }, // 0x7C '|' + { 499, 4, 15, 4, 0, -11 }, // 0x7D '}' + { 507, 6, 3, 8, 1, -5 } }; // 0x7E '~' + +const GFXfont teko8pt7b PROGMEM = { + (uint8_t *)teko8pt7bBitmaps, + (GFXglyph *)teko8pt7bGlyphs, + 0x20, 0x7E, 22 }; + +// Approx. 1182 bytes diff --git a/libraries/_NToolsFonts/thw12p.h b/libraries/_NToolsFonts/thw12p.h new file mode 100644 index 0000000..005e488 --- /dev/null +++ b/libraries/_NToolsFonts/thw12p.h @@ -0,0 +1,337 @@ +const uint8_t LubalinGraphBold12pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xF0, 0xF3, + 0xFC, 0xFF, 0x3F, 0xCF, 0xF3, 0xFC, 0xFF, 0x3F, 0xCF, 0xF3, 0xC0, 0x0C, + 0x60, 0x63, 0x03, 0x18, 0x18, 0xC0, 0x8C, 0x04, 0x63, 0xFF, 0xFF, 0xFF, + 0x18, 0xC0, 0xC6, 0x06, 0x31, 0xFF, 0xEF, 0xFF, 0x08, 0xC0, 0xC6, 0x06, + 0x30, 0x31, 0x81, 0x8C, 0x08, 0xC0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, + 0x01, 0xFF, 0x3F, 0xF9, 0xFF, 0xDF, 0xFE, 0xF8, 0xF7, 0xC7, 0xBF, 0x01, + 0xFE, 0x07, 0xFC, 0x1F, 0xF0, 0x3F, 0xC0, 0x7F, 0x00, 0xFF, 0x87, 0xFE, + 0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFB, 0xDF, 0x00, 0xE0, 0x07, 0x00, 0x38, + 0x01, 0xC0, 0x3C, 0x0E, 0x0F, 0xC3, 0x83, 0xFC, 0x70, 0x73, 0x9E, 0x0E, + 0x73, 0x81, 0xCE, 0x70, 0x39, 0xDC, 0x07, 0x3B, 0x80, 0xFF, 0xF0, 0x0F, + 0xDC, 0xF0, 0xF7, 0xBF, 0x00, 0xEF, 0xF0, 0x1D, 0xCE, 0x07, 0x39, 0xC0, + 0xE7, 0x38, 0x3C, 0xE7, 0x07, 0x1F, 0xE0, 0xE1, 0xF8, 0x38, 0x1E, 0x00, + 0x07, 0x80, 0x0F, 0xF0, 0x07, 0xF8, 0x07, 0xFE, 0x03, 0xCF, 0x01, 0xE7, + 0x80, 0xFF, 0xC0, 0x3F, 0xC0, 0x1F, 0xC7, 0x8F, 0xE7, 0xCF, 0xFB, 0xEF, + 0x7F, 0xFF, 0x1F, 0xE7, 0x87, 0xF3, 0xE3, 0xF9, 0xFF, 0xFE, 0x7F, 0xFF, + 0x9F, 0xF7, 0x87, 0xE1, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x01, 0x81, + 0xC3, 0xE3, 0xF3, 0xF9, 0xFD, 0xF8, 0xF8, 0xFC, 0x7C, 0x3E, 0x1F, 0x0F, + 0x87, 0xC3, 0xE1, 0xF0, 0xFC, 0x7E, 0x1F, 0x8F, 0xE3, 0xF8, 0xFC, 0x3E, + 0x0F, 0x03, 0x80, 0x40, 0xC0, 0x70, 0x3E, 0x1F, 0x8F, 0xC7, 0xF1, 0xFC, + 0x7E, 0x1F, 0x07, 0xC3, 0xE1, 0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x1F, 0x8F, + 0x8F, 0xCF, 0xCF, 0xE7, 0xE3, 0xE1, 0xE0, 0xC0, 0x40, 0x00, 0x04, 0x7E, + 0x3C, 0xFF, 0xFF, 0x3C, 0x7E, 0x24, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, + 0x06, 0x00, 0x60, 0xFF, 0xFF, 0xFF, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, + 0x06, 0x00, 0xFF, 0xFF, 0x33, 0xFE, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0x00, + 0x1C, 0x00, 0x38, 0x00, 0xF0, 0x01, 0xC0, 0x03, 0x80, 0x0E, 0x00, 0x1C, + 0x00, 0x70, 0x00, 0xE0, 0x03, 0xC0, 0x07, 0x00, 0x0E, 0x00, 0x38, 0x00, + 0x70, 0x01, 0xE0, 0x03, 0x80, 0x0F, 0x00, 0x1C, 0x00, 0x38, 0x00, 0xE0, + 0x01, 0xC0, 0x07, 0x80, 0x0E, 0x00, 0x1C, 0x00, 0x70, 0x00, 0xE0, 0x03, + 0xC0, 0x07, 0x00, 0x00, 0x0F, 0xC0, 0x7F, 0x83, 0xFF, 0x1F, 0xFE, 0xFE, + 0x7F, 0xF0, 0xFF, 0xC3, 0xFF, 0x0F, 0xFC, 0x3F, 0xF0, 0xFF, 0xC3, 0xFF, + 0x0F, 0xFC, 0x3F, 0xF0, 0xFF, 0xE7, 0xDF, 0xFE, 0x3F, 0xF8, 0x7F, 0xC0, + 0xFC, 0x00, 0xFE, 0x7F, 0x3F, 0x9F, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, + 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0xFF, 0x7F, 0xBF, 0xDF, 0xE0, + 0x0F, 0x81, 0xFF, 0x1F, 0xFD, 0xFF, 0xEF, 0x8F, 0xF8, 0x3C, 0x01, 0xE0, + 0x1F, 0x01, 0xF8, 0x1F, 0x81, 0xF8, 0x1F, 0x81, 0xF8, 0x1F, 0xBD, 0xF9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x07, 0xC0, 0x7F, 0x83, 0xFF, + 0x1F, 0xFE, 0x7C, 0xF9, 0xE1, 0xE0, 0x0F, 0x80, 0xFC, 0x03, 0xE0, 0x0F, + 0xE0, 0x3F, 0x80, 0x3F, 0x00, 0x7F, 0xE1, 0xFF, 0x8F, 0xFF, 0xFF, 0x7F, + 0xF8, 0xFF, 0xC0, 0xFC, 0x00, 0x01, 0xF8, 0x01, 0xF8, 0x03, 0xF8, 0x07, + 0xF8, 0x0F, 0xF8, 0x0F, 0xF8, 0x1F, 0xF8, 0x3F, 0x78, 0x7E, 0x78, 0x7C, + 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x78, 0x01, + 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x3F, 0xF0, 0xFF, 0xC3, 0xFF, + 0x1F, 0xFC, 0x7C, 0x01, 0xE0, 0x07, 0xBC, 0x1F, 0xFC, 0x7F, 0xFB, 0xFF, + 0xEF, 0x8F, 0xCC, 0x1F, 0x00, 0x7C, 0x01, 0xFF, 0x8F, 0xFF, 0xFE, 0x7F, + 0xF8, 0xFF, 0x80, 0xFC, 0x00, 0x03, 0xE0, 0x1F, 0x00, 0xFC, 0x03, 0xE0, + 0x1F, 0x80, 0xFC, 0x03, 0xFC, 0x1F, 0xFC, 0x7F, 0xFB, 0xFF, 0xEF, 0xC7, + 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0xC7, 0xDF, 0xFE, 0x7F, 0xF0, 0x7F, + 0x80, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF8, + 0xFB, 0xC7, 0xC0, 0x7E, 0x03, 0xE0, 0x1F, 0x01, 0xF0, 0x0F, 0x80, 0xF8, + 0x07, 0xC0, 0x7C, 0x03, 0xE0, 0x3F, 0x01, 0xF0, 0x0F, 0x80, 0x07, 0xC0, + 0x7F, 0x83, 0xFF, 0x1F, 0xFE, 0x7C, 0xF9, 0xE1, 0xE7, 0x8F, 0x8F, 0xFC, + 0x3F, 0xE0, 0xFF, 0xE7, 0xFF, 0xBE, 0x7F, 0xF0, 0xFF, 0xC3, 0xFF, 0x9F, + 0xFF, 0xFE, 0x7F, 0xF8, 0xFF, 0xC0, 0xFC, 0x00, 0x07, 0xC0, 0x7F, 0x83, + 0xFF, 0x1F, 0xFE, 0xF8, 0xFF, 0xC1, 0xFF, 0x07, 0xFC, 0x1F, 0xF0, 0x7F, + 0xE3, 0xF7, 0xFF, 0x9F, 0xFE, 0x3F, 0xF0, 0x3F, 0xC0, 0x3E, 0x01, 0xF0, + 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x00, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF0, + 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF3, 0x3F, 0xE0, 0x00, 0x18, 0x03, 0xC0, + 0x7C, 0x1F, 0x03, 0xE0, 0x7C, 0x03, 0x80, 0x1E, 0x00, 0x7E, 0x00, 0x7C, + 0x00, 0xF8, 0x00, 0xF0, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0xFC, 0x40, 0x01, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x01, + 0xF0, 0x01, 0xF0, 0x01, 0xC0, 0x0F, 0x01, 0xF8, 0x1F, 0x03, 0xF0, 0x3E, + 0x00, 0x60, 0x00, 0x0F, 0x03, 0xFC, 0x7F, 0xE7, 0xFE, 0xF9, 0xFF, 0x0F, + 0x00, 0xF0, 0x0F, 0x01, 0xF0, 0x3E, 0x07, 0xE0, 0xFC, 0x0F, 0x80, 0xF0, + 0x00, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0x03, 0xF0, 0x06, 0x06, + 0x04, 0x00, 0x84, 0x00, 0x24, 0x00, 0x12, 0x1E, 0xC6, 0x19, 0x63, 0x18, + 0x61, 0x9C, 0x30, 0xCC, 0x18, 0x66, 0x1C, 0x53, 0x0C, 0x24, 0x8E, 0x22, + 0x3B, 0x30, 0x80, 0xE4, 0x20, 0x04, 0x0C, 0x0C, 0x01, 0xF8, 0x00, 0x0F, + 0xF0, 0x01, 0xFE, 0x00, 0x3F, 0xE0, 0x07, 0xFC, 0x00, 0x3F, 0x80, 0x0F, + 0xF8, 0x01, 0xEF, 0x00, 0x3D, 0xF0, 0x0F, 0xBE, 0x01, 0xE3, 0xC0, 0x7F, + 0xFC, 0x0F, 0xFF, 0x81, 0xFF, 0xF8, 0x7F, 0xFF, 0x0F, 0x83, 0xE7, 0xF8, + 0xFF, 0xFF, 0x1F, 0xFF, 0xE3, 0xFF, 0xFC, 0x7F, 0x80, 0xFF, 0xF8, 0xFF, + 0xFC, 0xFF, 0xFE, 0xFF, 0xFE, 0x3E, 0x1E, 0x3E, 0x1E, 0x3E, 0x3E, 0x3F, + 0xFC, 0x3F, 0xF8, 0x3F, 0xFC, 0x3F, 0xFE, 0x3E, 0x3E, 0x3E, 0x1E, 0x3E, + 0x1F, 0x3E, 0x3F, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFC, 0xFF, 0xF0, 0x03, + 0xF3, 0xC1, 0xFF, 0x78, 0x7F, 0xFF, 0x1F, 0xFF, 0xE7, 0xFB, 0xFC, 0xF8, + 0x1F, 0xBE, 0x01, 0xF7, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, + 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x7E, 0xF8, 0x0F, 0x9F, 0x83, 0xF1, 0xFF, + 0xFC, 0x1F, 0xFF, 0x01, 0xFF, 0xC0, 0x0F, 0xE0, 0x00, 0xFF, 0xF8, 0x3F, + 0xFF, 0x8F, 0xFF, 0xF3, 0xFF, 0xFE, 0x3E, 0x1F, 0x8F, 0x83, 0xF3, 0xE0, + 0x7C, 0xF8, 0x1F, 0x3E, 0x03, 0xCF, 0x80, 0xF3, 0xE0, 0x3C, 0xF8, 0x1F, + 0x3E, 0x07, 0xCF, 0x81, 0xF3, 0xE1, 0xFB, 0xFF, 0xFE, 0xFF, 0xFF, 0x3F, + 0xFF, 0x8F, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, + 0x3C, 0xF8, 0xF3, 0xE0, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, + 0x80, 0x3E, 0x3C, 0xF8, 0xF3, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0x3C, 0xF8, + 0xF3, 0xE3, 0xCF, 0x80, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3E, + 0x00, 0xF8, 0x03, 0xE0, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x00, + 0x01, 0xF9, 0xE0, 0xFF, 0xFC, 0x7F, 0xFF, 0x9F, 0xFF, 0xF7, 0xF0, 0xFE, + 0xF8, 0x0F, 0xFF, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x7F, 0xFF, 0x0F, 0xFF, + 0xE1, 0xFF, 0xFE, 0x3F, 0xFF, 0xC0, 0x7E, 0xFE, 0x1F, 0xDF, 0xFF, 0xF9, + 0xFF, 0xFF, 0x1F, 0xFF, 0xE1, 0xFF, 0xFC, 0x0F, 0xE7, 0x80, 0xFF, 0x3F, + 0xFF, 0xE7, 0xFF, 0xFC, 0xFF, 0xFF, 0x9F, 0xF3, 0xC0, 0xF8, 0x78, 0x1F, + 0x0F, 0x03, 0xE1, 0xFF, 0xFC, 0x3F, 0xFF, 0x87, 0xFF, 0xF0, 0xFF, 0xFE, + 0x1E, 0x07, 0xC3, 0xC0, 0xF8, 0x78, 0x1F, 0x0F, 0x03, 0xE7, 0xF9, 0xFF, + 0xFF, 0x3F, 0xFF, 0xE7, 0xFF, 0xFC, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0xFF, + 0xFF, 0xFF, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x00, 0xF0, + 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, + 0x00, 0xF3, 0xE3, 0xCF, 0x8F, 0x3F, 0xFC, 0xFF, 0xE1, 0xFF, 0x01, 0xF8, + 0x00, 0xFF, 0x7F, 0xFF, 0xDF, 0xFF, 0xF7, 0xFF, 0xFD, 0xFF, 0x3E, 0x3F, + 0x0F, 0x9F, 0x83, 0xEF, 0xC0, 0xFF, 0xE0, 0x3F, 0xF0, 0x0F, 0xF8, 0x03, + 0xFF, 0x00, 0xFF, 0xE0, 0x3E, 0xFC, 0x0F, 0x9F, 0x83, 0xE3, 0xF3, 0xFD, + 0xFF, 0xFF, 0x7F, 0xFF, 0xDF, 0xFF, 0xF7, 0xFC, 0xFF, 0x03, 0xFC, 0x0F, + 0xF0, 0x3F, 0xC0, 0x3E, 0x00, 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x00, + 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x3C, 0xF8, 0xF3, 0xE3, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0x01, 0xFF, 0xFF, 0x81, 0xFF, + 0xFF, 0x81, 0xFF, 0xFF, 0x83, 0xFF, 0x3F, 0xC3, 0xFC, 0x3F, 0xC3, 0xFC, + 0x3F, 0xC7, 0xFC, 0x3F, 0xE7, 0xFC, 0x3F, 0xE7, 0xFC, 0x3D, 0xEF, 0xBC, + 0x3D, 0xFF, 0xBC, 0x3D, 0xFF, 0x3C, 0x3C, 0xFF, 0x3C, 0x3C, 0xFF, 0x3C, + 0x3C, 0x7E, 0x3C, 0xFF, 0x7E, 0xFF, 0xFF, 0x7E, 0xFF, 0xFF, 0x3C, 0xFF, + 0xFF, 0x3C, 0xFF, 0xFC, 0x1F, 0xFF, 0xE1, 0xFF, 0xFF, 0x1F, 0xFF, 0xF1, + 0xFF, 0x3F, 0x87, 0xC3, 0xFC, 0x7C, 0x3F, 0xC7, 0xC3, 0xFE, 0x7C, 0x3F, + 0xF7, 0xC3, 0xFF, 0xFC, 0x3D, 0xFF, 0xC3, 0xCF, 0xFC, 0x3C, 0x7F, 0xC3, + 0xC7, 0xFC, 0x3C, 0x3F, 0xCF, 0xF1, 0xFC, 0xFF, 0x0F, 0xCF, 0xF0, 0xFC, + 0xFF, 0x07, 0xC0, 0x03, 0xF8, 0x01, 0xFF, 0xC0, 0x7F, 0xFC, 0x1F, 0xFF, + 0xC7, 0xFF, 0xFC, 0xFC, 0x1F, 0xBF, 0x01, 0xFF, 0xC0, 0x1F, 0xF8, 0x03, + 0xFF, 0x00, 0x7F, 0xE0, 0x0F, 0xFC, 0x01, 0xFF, 0x80, 0x3E, 0xF8, 0x0F, + 0x9F, 0x87, 0xF1, 0xFF, 0xFC, 0x1F, 0xFF, 0x01, 0xFF, 0xC0, 0x0F, 0xE0, + 0x00, 0xFF, 0xE1, 0xFF, 0xF3, 0xFF, 0xF7, 0xFF, 0xE3, 0xE3, 0xE7, 0xC3, + 0xCF, 0x87, 0x9F, 0x0F, 0x3E, 0x3E, 0x7F, 0xF8, 0xFF, 0xF1, 0xFF, 0xC3, + 0xFE, 0x07, 0xC0, 0x0F, 0x80, 0x7F, 0x80, 0xFF, 0x01, 0xFE, 0x03, 0xFC, + 0x00, 0x01, 0xF8, 0x00, 0x0F, 0xFC, 0x00, 0x7F, 0xFC, 0x01, 0xFF, 0xFC, + 0x03, 0xF0, 0xFC, 0x0F, 0x80, 0xFC, 0x1F, 0x00, 0xF8, 0x7C, 0x00, 0xF0, + 0xFF, 0xC1, 0xF1, 0xFF, 0xE3, 0xE3, 0xFF, 0xE7, 0x87, 0xFF, 0xFF, 0x0F, + 0xC7, 0xFE, 0x0F, 0xC3, 0xFC, 0x1F, 0xC7, 0xF7, 0x9F, 0xFF, 0xFF, 0x3F, + 0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x1F, 0xF9, 0xF8, 0x0F, 0xC0, 0x00, 0xFF, + 0xF0, 0xFF, 0xF8, 0xFF, 0xFC, 0xFF, 0xFE, 0x3C, 0x3E, 0x3C, 0x1F, 0x3C, + 0x1F, 0x3C, 0x1F, 0x3C, 0x3F, 0x3F, 0xFE, 0x3F, 0xFE, 0x3F, 0xFC, 0x3F, + 0xF0, 0x3F, 0xF8, 0x3E, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x3F, 0xFF, + 0x1F, 0x1E, 0xF1, 0xFF, 0x9F, 0xFD, 0xFF, 0xEF, 0x9F, 0x78, 0x7B, 0xC0, + 0x1F, 0xC0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC, 0x07, 0xF0, 0x0F, 0xF8, 0x7F, + 0xE7, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0x3D, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xCF, 0xF3, 0xCF, 0xF3, 0xC0, 0x03, 0xC0, + 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, + 0x03, 0xC0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x9F, + 0xFF, 0xE7, 0xFF, 0xF9, 0xFF, 0xFE, 0x7F, 0x3C, 0x0F, 0x0F, 0x03, 0xC3, + 0xC0, 0xF0, 0xF0, 0x3C, 0x3C, 0x0F, 0x0F, 0x03, 0xC3, 0xC0, 0xF0, 0xF0, + 0x3C, 0x3C, 0x0F, 0x0F, 0x83, 0xC3, 0xF1, 0xF0, 0xFF, 0xF8, 0x1F, 0xFE, + 0x03, 0xFE, 0x00, 0x3F, 0x00, 0xFF, 0x3F, 0xFF, 0xCF, 0xFF, 0xF3, 0xFF, + 0xFC, 0xFF, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1, 0xE0, 0xF8, 0xF8, 0x1F, + 0x3E, 0x07, 0xCF, 0x01, 0xF7, 0xC0, 0x3F, 0xF0, 0x0F, 0xF8, 0x03, 0xFE, + 0x00, 0x7F, 0x80, 0x1F, 0xC0, 0x07, 0xF0, 0x00, 0xFC, 0x00, 0x3E, 0x00, + 0xFF, 0x1E, 0x7F, 0xFF, 0xCF, 0x9F, 0xFF, 0xF3, 0xE7, 0xFF, 0xFC, 0xFD, + 0xFF, 0x3C, 0x7F, 0x1F, 0x0F, 0x9F, 0xC7, 0x83, 0xE7, 0xF9, 0xE0, 0xF9, + 0xFE, 0xF8, 0x1E, 0xFF, 0xBE, 0x07, 0xFF, 0xEF, 0x01, 0xFF, 0x7F, 0xC0, + 0x7F, 0xCF, 0xF0, 0x0F, 0xF3, 0xFC, 0x03, 0xF8, 0xFE, 0x00, 0xFE, 0x3F, + 0x80, 0x1F, 0x87, 0xE0, 0x07, 0xE1, 0xF8, 0x01, 0xF0, 0x7C, 0x00, 0x7C, + 0x0F, 0x00, 0xFF, 0x3F, 0xFF, 0xE7, 0xFF, 0xFC, 0xFF, 0xFF, 0x9F, 0xF1, + 0xE1, 0xF8, 0x3E, 0x7E, 0x03, 0xFF, 0x80, 0x3F, 0xE0, 0x03, 0xF8, 0x00, + 0x3F, 0x00, 0x0F, 0xE0, 0x03, 0xFE, 0x00, 0xFF, 0xE0, 0x3E, 0x7E, 0x0F, + 0x87, 0xE7, 0xF9, 0xFF, 0xFF, 0x3F, 0xFF, 0xE7, 0xFF, 0xFC, 0xFF, 0x80, + 0xFE, 0x7F, 0xFF, 0x3F, 0xFF, 0x9F, 0xFF, 0xCF, 0xF3, 0xE1, 0xE0, 0xF9, + 0xF0, 0x7C, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x03, 0xF8, 0x01, 0xFC, 0x00, + 0x7C, 0x00, 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x1F, 0xE0, 0x0F, 0xF0, + 0x07, 0xF8, 0x03, 0xFC, 0x00, 0x7F, 0xFD, 0xFF, 0xF7, 0xFF, 0xDF, 0xFF, + 0x78, 0xFD, 0xE7, 0xE0, 0x3F, 0x00, 0xF8, 0x07, 0xE0, 0x3F, 0x01, 0xF8, + 0x07, 0xC0, 0x3F, 0x01, 0xF8, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, + 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xFF, 0xFF, 0xFF, 0xC0, 0xE0, + 0x18, 0x07, 0x00, 0xC0, 0x30, 0x0E, 0x01, 0x80, 0x70, 0x0C, 0x03, 0x00, + 0xE0, 0x18, 0x06, 0x00, 0xC0, 0x30, 0x0E, 0x01, 0x80, 0x60, 0x0C, 0xFF, + 0xFF, 0xFF, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC7, + 0x8F, 0x1E, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, 0x3C, 0x1F, 0x1F, 0x8E, 0xEF, + 0x77, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0xE3, 0xF7, 0xFF, 0xE7, 0xC1, + 0x80, 0x07, 0xDF, 0x8F, 0xFF, 0xCF, 0xFF, 0xEF, 0xFF, 0xF7, 0xC7, 0xE7, + 0x81, 0xF3, 0xC0, 0x79, 0xE0, 0x3C, 0xF0, 0x1E, 0x7E, 0x3F, 0x1F, 0xFF, + 0xE7, 0xFF, 0xF1, 0xFF, 0xF8, 0x3E, 0xFC, 0xF8, 0x00, 0x7C, 0x00, 0x3E, + 0x00, 0x1F, 0x00, 0x07, 0x80, 0x03, 0xDF, 0x81, 0xFF, 0xF0, 0xFF, 0xFC, + 0x7F, 0xFF, 0x3F, 0x0F, 0x9F, 0x03, 0xEF, 0x00, 0xF7, 0x80, 0x7B, 0xE0, + 0x3D, 0xF8, 0x7F, 0xFF, 0xFE, 0xFF, 0xFE, 0x7F, 0xFE, 0x3F, 0x3E, 0x00, + 0x0F, 0xBC, 0x7F, 0xF9, 0xFF, 0xF3, 0xFF, 0xEF, 0x87, 0xDE, 0x00, 0x3C, + 0x00, 0x78, 0x00, 0xF0, 0x00, 0xF0, 0xFD, 0xFF, 0xF1, 0xFF, 0xC1, 0xFF, + 0x00, 0xF8, 0x00, 0x00, 0x7E, 0x00, 0x3F, 0x00, 0x1F, 0x80, 0x0F, 0xC0, + 0x01, 0xE0, 0x3F, 0xF0, 0x7F, 0xF8, 0x7F, 0xFC, 0x7F, 0xFE, 0x7E, 0x3F, + 0x3E, 0x07, 0x9E, 0x03, 0xCF, 0x01, 0xE7, 0x81, 0xF3, 0xE1, 0xF8, 0xFF, + 0xFF, 0x3F, 0xFF, 0x8F, 0xFF, 0xC1, 0xF7, 0xE0, 0x07, 0xC0, 0x3F, 0xE0, + 0xFF, 0xE3, 0xFF, 0xEF, 0x83, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x01, 0xFF, 0xF1, 0xFF, 0xC1, 0xFF, 0x00, 0xF8, 0x00, 0x0F, + 0x1F, 0x1F, 0x3F, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0x7C, 0x7C, 0x7C, 0x7C, + 0x7C, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xDF, 0x1F, 0xFF, 0x3F, 0xFF, + 0x7F, 0xFF, 0xFC, 0x7E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF8, 0x1E, + 0xFC, 0x7E, 0x7F, 0xFE, 0x3F, 0xFE, 0x1F, 0xFE, 0x0F, 0xDE, 0x00, 0x3E, + 0x7F, 0xFC, 0x7F, 0xFC, 0x3F, 0xF8, 0x0F, 0xE0, 0xFC, 0x00, 0xFC, 0x00, + 0xFC, 0x00, 0xFC, 0x00, 0x3C, 0x00, 0x3D, 0xF0, 0x3F, 0xF8, 0x3F, 0xFC, + 0x3F, 0xFE, 0x3E, 0x3E, 0x3C, 0x1E, 0x3C, 0x1E, 0x3C, 0x1E, 0x3C, 0x1E, + 0x3C, 0x1E, 0xFF, 0x1F, 0xFF, 0x1F, 0xFF, 0x1F, 0xFF, 0x1F, 0x3C, 0x3C, + 0x3C, 0x3C, 0x00, 0xFC, 0xFC, 0xFC, 0xFC, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0x3C, 0xF3, 0xCF, 0x03, 0xFF, 0xFF, 0xFC, + 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, 0xFF, 0xFF, 0xB8, 0xFC, + 0x01, 0xF8, 0x03, 0xF0, 0x07, 0xE0, 0x03, 0xC0, 0x07, 0xBF, 0xCF, 0x7F, + 0x9E, 0xFF, 0x3D, 0xFE, 0x79, 0xF0, 0xF7, 0xC1, 0xFF, 0x03, 0xFE, 0x07, + 0xFE, 0x0F, 0x7E, 0x7E, 0x7F, 0xFC, 0x7F, 0xF8, 0xFF, 0xF0, 0xF8, 0xFD, + 0xFB, 0xF7, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC7, 0x8F, + 0x7F, 0xFF, 0xFF, 0xF8, 0xFF, 0xE1, 0xF0, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, + 0xFC, 0xFF, 0xFF, 0xFE, 0x3E, 0x7E, 0x3E, 0x3C, 0x3C, 0x1E, 0x3C, 0x3C, + 0x1E, 0x3C, 0x3C, 0x1E, 0x3C, 0x3C, 0x1E, 0x3C, 0x3C, 0x1E, 0xFE, 0x3F, + 0x1F, 0xFE, 0x3F, 0x1F, 0xFE, 0x3F, 0x1F, 0xFE, 0x3F, 0x1F, 0xFD, 0xF0, + 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFE, 0x3E, 0x3E, 0x3C, 0x1E, 0x3C, 0x1E, + 0x3C, 0x1E, 0x3C, 0x1E, 0x3C, 0x1E, 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x1F, + 0xFE, 0x1F, 0x07, 0xC0, 0x3F, 0xE0, 0xFF, 0xE3, 0xFF, 0xEF, 0xC7, 0xDF, + 0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x3F, 0xF8, 0xFD, 0xFF, 0xF1, 0xFF, + 0xC1, 0xFF, 0x00, 0xF8, 0x00, 0xFD, 0xF8, 0x7F, 0xFE, 0x3F, 0xFF, 0x9F, + 0xFF, 0xE3, 0xF1, 0xF9, 0xE0, 0x7C, 0xF0, 0x1E, 0x78, 0x0F, 0x3C, 0x07, + 0x9F, 0x8F, 0xCF, 0xFF, 0xC7, 0xFF, 0xC3, 0xFF, 0xC1, 0xE7, 0xC3, 0xF8, + 0x01, 0xFC, 0x00, 0xFE, 0x00, 0x7F, 0x00, 0x00, 0x0F, 0xDF, 0x1F, 0xFF, + 0x3F, 0xFF, 0x7F, 0xFF, 0xFC, 0x7E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, + 0xF0, 0x1E, 0xFC, 0x7E, 0x7F, 0xFE, 0x3F, 0xFE, 0x1F, 0xFE, 0x0F, 0xDE, + 0x00, 0x1E, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0xFB, 0xFF, + 0xFF, 0xFF, 0xFF, 0x7E, 0x1F, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x0F, 0xC3, + 0xF0, 0xFC, 0x3F, 0x00, 0x3F, 0xE7, 0xFE, 0xFF, 0xEF, 0xFE, 0xF8, 0x0F, + 0x80, 0x7F, 0x81, 0xFE, 0x03, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, + 0x7C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0x3C, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3F, 0x3F, 0x3F, 0x3F, 0xF8, 0xFC, 0xF8, 0xFC, + 0xF8, 0xFC, 0xF8, 0xFC, 0x78, 0x3C, 0x78, 0x3C, 0x78, 0x3C, 0x78, 0x3C, + 0x78, 0x3C, 0x7C, 0x7C, 0x7F, 0xFF, 0x3F, 0xFF, 0x1F, 0xFF, 0x0F, 0xBF, + 0xFE, 0xFF, 0xFD, 0xFF, 0xFB, 0xFF, 0xF7, 0xF7, 0xC7, 0x87, 0x9F, 0x0F, + 0xBC, 0x0F, 0x78, 0x1E, 0xF0, 0x3F, 0xC0, 0x3F, 0x80, 0x7E, 0x00, 0xFC, + 0x00, 0xF8, 0x00, 0xFE, 0x71, 0xFF, 0xFB, 0xE7, 0xFF, 0xEF, 0x9F, 0xFF, + 0xBE, 0x7F, 0x79, 0xFC, 0xF0, 0xF7, 0xF7, 0xC3, 0xDF, 0xDE, 0x0F, 0x77, + 0xF8, 0x3F, 0xDF, 0xE0, 0x7F, 0x7F, 0x01, 0xF8, 0xFC, 0x07, 0xE3, 0xF0, + 0x0F, 0x0F, 0x80, 0x3C, 0x1E, 0x00, 0xFE, 0x7F, 0xFC, 0xFF, 0xF9, 0xFF, + 0xFF, 0xF3, 0xFF, 0x83, 0xFE, 0x03, 0xF8, 0x07, 0xF0, 0x1F, 0xF8, 0x7F, + 0xFB, 0xFB, 0xFF, 0xE3, 0xFF, 0xC7, 0xFF, 0x8F, 0xC0, 0xFE, 0x7F, 0xFC, + 0xFF, 0xF9, 0xFF, 0xF3, 0xF3, 0xC7, 0xC7, 0xDF, 0x07, 0xBE, 0x0F, 0x78, + 0x1F, 0xF0, 0x1F, 0xE0, 0x3F, 0x80, 0x3F, 0x00, 0x7C, 0x00, 0xF8, 0x01, + 0xF0, 0x07, 0xF0, 0x0F, 0xE0, 0x1F, 0xC0, 0x3F, 0x80, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF3, 0xE0, 0x7C, 0x0F, 0x81, 0xF0, 0x3E, 0x07, 0xCF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0x70, 0xE1, 0xC3, 0x87, 0x0E, + 0x1C, 0x38, 0x63, 0x81, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC1, + 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x70, 0x70, 0xE1, 0xC3, 0x87, + 0x0E, 0x1C, 0x38, 0x70, 0x38, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, + 0xC6, 0x00, 0x71, 0x7F, 0x9F, 0xE0, 0xE0 }; + +const GFXglyph LubalinGraphBold12pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 6, 0, 0 }, // 0x20 ' ' + { 1, 4, 19, 6, 1, -18 }, // 0x21 '!' + { 11, 10, 9, 12, 0, -18 }, // 0x22 '"' + { 23, 13, 19, 15, 0, -18 }, // 0x23 '#' + { 54, 13, 27, 15, 0, -22 }, // 0x24 '$' + { 98, 19, 19, 22, 1, -18 }, // 0x25 '%' + { 144, 17, 19, 19, 0, -18 }, // 0x26 '&' + { 185, 4, 9, 6, 0, -18 }, // 0x27 ''' + { 190, 9, 26, 11, 0, -18 }, // 0x28 '(' + { 220, 9, 26, 11, 1, -18 }, // 0x29 ')' + { 250, 8, 8, 10, 1, -18 }, // 0x2A '*' + { 258, 12, 13, 15, 1, -12 }, // 0x2B '+' + { 278, 4, 8, 6, 1, -3 }, // 0x2C ',' + { 282, 6, 3, 7, 0, -9 }, // 0x2D '-' + { 285, 4, 4, 6, 1, -3 }, // 0x2E '.' + { 287, 15, 28, 14, -1, -20 }, // 0x2F '/' + { 340, 14, 19, 16, 0, -18 }, // 0x30 '0' + { 374, 9, 19, 10, 1, -18 }, // 0x31 '1' + { 396, 13, 19, 15, 1, -18 }, // 0x32 '2' + { 427, 14, 19, 16, 1, -18 }, // 0x33 '3' + { 461, 16, 19, 17, 0, -18 }, // 0x34 '4' + { 499, 14, 19, 16, 0, -18 }, // 0x35 '5' + { 533, 14, 19, 16, 1, -18 }, // 0x36 '6' + { 567, 13, 19, 15, 1, -18 }, // 0x37 '7' + { 598, 14, 19, 16, 1, -18 }, // 0x38 '8' + { 632, 14, 19, 16, 1, -18 }, // 0x39 '9' + { 666, 4, 11, 6, 0, -10 }, // 0x3A ':' + { 672, 4, 15, 6, 1, -10 }, // 0x3B ';' + { 680, 13, 13, 15, 0, -13 }, // 0x3C '<' + { 702, 13, 6, 15, 1, -9 }, // 0x3D '=' + { 712, 14, 13, 15, -1, -13 }, // 0x3E '>' + { 735, 12, 19, 15, 1, -18 }, // 0x3F '?' + { 764, 17, 18, 19, 1, -17 }, // 0x40 '@' + { 803, 19, 19, 22, 1, -18 }, // 0x41 'A' + { 849, 16, 19, 17, 0, -18 }, // 0x42 'B' + { 887, 19, 19, 21, 1, -18 }, // 0x43 'C' + { 933, 18, 19, 20, 1, -18 }, // 0x44 'D' + { 976, 14, 19, 16, 0, -18 }, // 0x45 'E' + { 1010, 14, 19, 16, 0, -18 }, // 0x46 'F' + { 1044, 19, 19, 21, 0, -18 }, // 0x47 'G' + { 1090, 19, 19, 21, 0, -18 }, // 0x48 'H' + { 1136, 8, 19, 10, 0, -18 }, // 0x49 'I' + { 1155, 14, 19, 16, 1, -18 }, // 0x4A 'J' + { 1189, 18, 19, 20, 1, -18 }, // 0x4B 'K' + { 1232, 14, 19, 16, 0, -18 }, // 0x4C 'L' + { 1266, 24, 19, 26, 0, -18 }, // 0x4D 'M' + { 1323, 20, 19, 22, 0, -18 }, // 0x4E 'N' + { 1371, 19, 19, 21, 1, -18 }, // 0x4F 'O' + { 1417, 15, 19, 17, 1, -18 }, // 0x50 'P' + { 1453, 23, 20, 25, 1, -18 }, // 0x51 'Q' + { 1511, 16, 19, 18, 1, -18 }, // 0x52 'R' + { 1549, 13, 19, 15, 0, -18 }, // 0x53 'S' + { 1580, 16, 19, 18, 0, -18 }, // 0x54 'T' + { 1618, 18, 19, 19, 0, -18 }, // 0x55 'U' + { 1661, 18, 19, 20, 0, -18 }, // 0x56 'V' + { 1704, 26, 19, 28, 1, -18 }, // 0x57 'W' + { 1766, 19, 19, 21, 1, -18 }, // 0x58 'X' + { 1812, 17, 19, 19, 0, -18 }, // 0x59 'Y' + { 1853, 14, 19, 16, 0, -18 }, // 0x5A 'Z' + { 1887, 7, 22, 9, 0, -18 }, // 0x5B '[' + { 1907, 10, 19, 12, 1, -18 }, // 0x5C '\' + { 1931, 7, 22, 9, 0, -18 }, // 0x5D ']' + { 1951, 9, 6, 10, 1, -20 }, // 0x5E '^' + { 1958, 16, 2, 17, 0, 2 }, // 0x5F '_' + { 1962, 7, 7, 9, 1, -21 }, // 0x60 '`' + { 1969, 17, 14, 19, 0, -13 }, // 0x61 'a' + { 1999, 17, 19, 18, 0, -18 }, // 0x62 'b' + { 2040, 15, 14, 16, 0, -13 }, // 0x63 'c' + { 2067, 17, 19, 19, 1, -18 }, // 0x64 'd' + { 2108, 15, 14, 17, 0, -13 }, // 0x65 'e' + { 2135, 8, 19, 9, 0, -18 }, // 0x66 'f' + { 2154, 16, 19, 18, 0, -13 }, // 0x67 'g' + { 2192, 16, 19, 18, 1, -18 }, // 0x68 'h' + { 2230, 8, 19, 9, 1, -18 }, // 0x69 'i' + { 2249, 6, 24, 8, 0, -18 }, // 0x6A 'j' + { 2267, 15, 19, 17, 1, -18 }, // 0x6B 'k' + { 2303, 7, 19, 9, 1, -18 }, // 0x6C 'l' + { 2320, 24, 14, 27, 0, -13 }, // 0x6D 'm' + { 2362, 16, 14, 18, 1, -13 }, // 0x6E 'n' + { 2390, 15, 14, 17, 0, -13 }, // 0x6F 'o' + { 2417, 17, 18, 19, 0, -13 }, // 0x70 'p' + { 2456, 16, 19, 19, 1, -13 }, // 0x71 'q' + { 2494, 10, 14, 11, 0, -13 }, // 0x72 'r' + { 2512, 12, 14, 14, 1, -13 }, // 0x73 's' + { 2533, 8, 19, 10, 0, -18 }, // 0x74 't' + { 2552, 16, 14, 18, 0, -13 }, // 0x75 'u' + { 2580, 15, 14, 17, 1, -13 }, // 0x76 'v' + { 2607, 22, 14, 24, 1, -13 }, // 0x77 'w' + { 2646, 15, 14, 17, 1, -13 }, // 0x78 'x' + { 2673, 15, 19, 17, 0, -13 }, // 0x79 'y' + { 2709, 12, 14, 14, 1, -13 }, // 0x7A 'z' + { 2730, 7, 21, 9, 0, -18 }, // 0x7B '{' + { 2749, 2, 21, 4, 0, -18 }, // 0x7C '|' + { 2755, 7, 21, 9, 0, -18 }, // 0x7D '}' + { 2774, 9, 4, 11, 0, -18 } }; // 0x7E '~' + +const GFXfont LubalinGraphBold12pt7b PROGMEM = { + (uint8_t *)LubalinGraphBold12pt7bBitmaps, + (GFXglyph *)LubalinGraphBold12pt7bGlyphs, + 0x20, 0x7E, 34 }; + +// Approx. 3451 bytes diff --git a/libraries/_NToolsFonts/thw6p.h b/libraries/_NToolsFonts/thw6p.h new file mode 100644 index 0000000..83d09ee --- /dev/null +++ b/libraries/_NToolsFonts/thw6p.h @@ -0,0 +1,165 @@ +const uint8_t LubalinGraphBold6pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xF3, 0xC0, 0xDE, 0xF7, 0xB0, 0x0C, 0x99, 0x33, 0xFF, 0xFF, + 0xE6, 0x4C, 0x98, 0x30, 0x61, 0xF7, 0xEC, 0x1E, 0x1F, 0x06, 0xCF, 0xFB, + 0xE1, 0x83, 0x00, 0x62, 0x7B, 0x3D, 0x1F, 0xE6, 0xF8, 0x7C, 0x7E, 0x2F, + 0x33, 0x00, 0x38, 0x3E, 0x1B, 0x05, 0x77, 0xFE, 0xFB, 0x3D, 0xFF, 0x7B, + 0x00, 0xFF, 0x19, 0xDE, 0xEE, 0x73, 0x8C, 0x71, 0xC6, 0x10, 0xC7, 0x1C, + 0x73, 0x8C, 0xE7, 0x77, 0xB9, 0x00, 0x2F, 0xF6, 0xC0, 0x18, 0x18, 0xFF, + 0xFF, 0x18, 0x18, 0xFF, 0xFC, 0xF0, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, + 0x18, 0x10, 0x30, 0x30, 0x60, 0x60, 0x40, 0x38, 0xFB, 0x9F, 0x3E, 0x7C, + 0xF9, 0xBF, 0x38, 0xEE, 0x66, 0x66, 0x6F, 0xF0, 0x3D, 0xFF, 0x18, 0x31, + 0xC7, 0x1D, 0xFF, 0xFE, 0x3C, 0xFD, 0x98, 0xE1, 0xE1, 0xFB, 0xFF, 0x3C, + 0x1C, 0x3C, 0x3C, 0x6C, 0xFF, 0xFF, 0x0C, 0x1E, 0x1E, 0x7E, 0x7E, 0x60, + 0x7C, 0x7E, 0x67, 0x06, 0x7E, 0x3C, 0x1C, 0x18, 0x3C, 0x7E, 0x63, 0xE3, + 0x63, 0x7E, 0x3C, 0xFF, 0xFF, 0x38, 0x61, 0xC3, 0x0E, 0x18, 0x70, 0x79, + 0xFB, 0x37, 0xCF, 0xD9, 0xF3, 0xFF, 0x78, 0x3C, 0x7E, 0xC6, 0xC7, 0xFE, + 0x7E, 0x1C, 0x1C, 0x38, 0xF0, 0xF0, 0xF0, 0xFF, 0x06, 0x3D, 0xF7, 0xC3, + 0xE0, 0xC0, 0xFF, 0xFF, 0xF8, 0xC1, 0xE0, 0xF1, 0xFF, 0x9C, 0x00, 0x7B, + 0xFC, 0xC3, 0x18, 0xC0, 0x0C, 0x30, 0x3C, 0x42, 0x99, 0xB5, 0xB7, 0xBE, + 0x61, 0x3E, 0x3C, 0x0F, 0x01, 0x60, 0xD8, 0x3F, 0x1F, 0xC6, 0x3B, 0xDF, + 0xF7, 0xC0, 0xFC, 0xFE, 0x66, 0x7C, 0x7E, 0x67, 0x67, 0xFE, 0xFE, 0x1F, + 0xCF, 0xF7, 0xFD, 0x87, 0xE0, 0x18, 0x07, 0x1C, 0xFE, 0x1F, 0x00, 0xFE, + 0x3F, 0xE7, 0x39, 0xC7, 0x71, 0xDC, 0x77, 0x1B, 0xFE, 0xFE, 0x00, 0xFF, + 0xFD, 0x9B, 0xE7, 0xCC, 0xD9, 0xFF, 0xFE, 0xFF, 0xFD, 0x9B, 0x37, 0x8F, + 0x18, 0x78, 0xF0, 0x1F, 0xBF, 0xF8, 0xF8, 0x0C, 0xFE, 0x7F, 0x8E, 0xFF, + 0x3D, 0x80, 0xFB, 0xFE, 0xF7, 0x19, 0xFE, 0x7F, 0x9C, 0x67, 0x1B, 0xEF, + 0xFB, 0xC0, 0xFF, 0xDC, 0xE7, 0x39, 0xDF, 0xF8, 0x1E, 0x3C, 0x38, 0x70, + 0xE1, 0xFB, 0xBE, 0x38, 0xF7, 0xFB, 0xD9, 0xCD, 0xC7, 0xC3, 0xE1, 0xBD, + 0xEF, 0xF7, 0x80, 0xF1, 0xE1, 0x83, 0x06, 0x0C, 0x19, 0xFF, 0xFE, 0xF0, + 0xFF, 0x9F, 0x79, 0xE7, 0x9E, 0x7F, 0x66, 0xF6, 0x6F, 0x6F, 0x6F, 0xF6, + 0xF0, 0xE3, 0xFC, 0xF7, 0x99, 0xF6, 0x7D, 0x9B, 0xE6, 0x7B, 0xCE, 0xF3, + 0x80, 0x1E, 0x0F, 0xE7, 0x1F, 0x87, 0xE0, 0xF8, 0x77, 0x1C, 0xFE, 0x1E, + 0x00, 0xFE, 0xFF, 0x73, 0x73, 0x7F, 0x7E, 0x60, 0xF0, 0xF0, 0x1E, 0x0F, + 0xF1, 0x8E, 0x70, 0xEF, 0xDD, 0xFF, 0x39, 0xDB, 0xFF, 0x7E, 0xE3, 0x80, + 0xFE, 0x7F, 0x9C, 0xCE, 0x67, 0xF3, 0xF1, 0xF9, 0xEF, 0xF3, 0x80, 0x7F, + 0xFC, 0xF8, 0x78, 0x7C, 0xFF, 0xF8, 0xFF, 0xFF, 0xDB, 0x18, 0x18, 0x18, + 0x18, 0x3C, 0x3C, 0xF7, 0xFB, 0xD8, 0xCC, 0x66, 0x33, 0x19, 0x8C, 0xFE, + 0x3C, 0x00, 0xF7, 0xFB, 0xDC, 0xC6, 0x63, 0xF1, 0xF0, 0x78, 0x3C, 0x1C, + 0x00, 0xFB, 0x7F, 0xFB, 0xDD, 0xEC, 0x6F, 0x63, 0x7F, 0x1E, 0xF0, 0x73, + 0x83, 0x9C, 0x1C, 0xE0, 0xF7, 0xFB, 0xCF, 0xC3, 0xC1, 0xC1, 0xF1, 0xDD, + 0xEF, 0xF7, 0x80, 0xF7, 0xFB, 0xD9, 0x87, 0xC3, 0xC0, 0xE0, 0x60, 0x78, + 0x3C, 0x00, 0xFF, 0xFF, 0x30, 0xE3, 0x8E, 0x19, 0xFF, 0xFE, 0xFF, 0xCC, + 0xCC, 0xCC, 0xFF, 0x83, 0x04, 0x18, 0x60, 0xC3, 0x06, 0x18, 0xFF, 0x33, + 0x33, 0x33, 0xFF, 0x73, 0xC0, 0xFF, 0x67, 0x3F, 0x7F, 0xC7, 0xC3, 0xE7, + 0x7F, 0x3B, 0xE0, 0xE0, 0x7C, 0x7E, 0x63, 0x63, 0x63, 0xFE, 0xFC, 0x3E, + 0xFF, 0x06, 0x0C, 0x6F, 0xCF, 0x00, 0x07, 0x03, 0x8E, 0xCF, 0xEE, 0x76, + 0x1B, 0x1C, 0xFF, 0x3B, 0x80, 0x3C, 0x7E, 0xFF, 0xFF, 0xC0, 0x7E, 0x3C, + 0x37, 0xFF, 0x66, 0x6F, 0xF0, 0x3F, 0x7F, 0xC6, 0xC6, 0xC6, 0x7E, 0x3E, + 0xE6, 0x7C, 0x38, 0xE0, 0xE0, 0x7C, 0x7E, 0x66, 0x66, 0x66, 0xF7, 0xF7, + 0x66, 0xEE, 0x66, 0x6F, 0xF0, 0x6F, 0xF6, 0xDB, 0x7F, 0x00, 0xE0, 0xE0, + 0x6E, 0x6E, 0x7C, 0x78, 0x7C, 0xEF, 0xE7, 0xEE, 0x66, 0x66, 0x6F, 0xF0, + 0xFD, 0xCF, 0xFE, 0x66, 0x66, 0x66, 0x66, 0x6F, 0x77, 0xF7, 0x70, 0xFC, + 0xFE, 0x66, 0x66, 0x66, 0xF7, 0xF7, 0x3C, 0x7E, 0xE3, 0xC3, 0xC7, 0x7E, + 0x3C, 0xFC, 0xFE, 0x63, 0x63, 0x63, 0x7E, 0x7C, 0xF0, 0xF0, 0x3F, 0xBF, + 0xF8, 0xD8, 0x6C, 0x73, 0xF8, 0xEC, 0x0F, 0x07, 0x80, 0xFF, 0xD8, 0xC6, + 0x7B, 0xC0, 0x7F, 0xFC, 0x1E, 0x0F, 0xFF, 0x80, 0x66, 0xFF, 0x66, 0x67, + 0x70, 0xEE, 0xEE, 0x66, 0x66, 0x66, 0x7F, 0x3F, 0xEF, 0xDD, 0x9B, 0xE3, + 0xC7, 0x0E, 0x00, 0xF6, 0xFF, 0xDD, 0xBB, 0x3F, 0xE3, 0xBC, 0x77, 0x0E, + 0x60, 0xF7, 0xF7, 0x7C, 0x38, 0x7E, 0xF7, 0xF7, 0xEF, 0xEF, 0x66, 0x7C, + 0x3C, 0x38, 0x18, 0x38, 0x38, 0xFF, 0xF1, 0x8C, 0x6F, 0xFF, 0xC0, 0x66, + 0x66, 0x66, 0x66, 0x66, 0xFF, 0xFF, 0xF0, 0x66, 0x66, 0x62, 0x66, 0x66, + 0x80, 0xB3, 0xD8 }; + +const GFXglyph LubalinGraphBold6pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 3, 0, 0 }, // 0x20 ' ' + { 1, 2, 9, 3, 0, -8 }, // 0x21 '!' + { 4, 5, 4, 6, 0, -8 }, // 0x22 '"' + { 7, 7, 9, 8, 0, -8 }, // 0x23 '#' + { 15, 7, 13, 7, 0, -10 }, // 0x24 '$' + { 27, 9, 9, 11, 0, -8 }, // 0x25 '%' + { 38, 9, 9, 9, 0, -8 }, // 0x26 '&' + { 49, 2, 4, 3, 0, -8 }, // 0x27 ''' + { 50, 5, 12, 6, 0, -8 }, // 0x28 '(' + { 58, 5, 12, 5, 0, -8 }, // 0x29 ')' + { 66, 4, 5, 5, 0, -9 }, // 0x2A '*' + { 69, 8, 6, 7, 0, -5 }, // 0x2B '+' + { 75, 2, 4, 3, 0, -1 }, // 0x2C ',' + { 76, 3, 2, 4, 0, -4 }, // 0x2D '-' + { 77, 2, 2, 3, 0, -1 }, // 0x2E '.' + { 78, 8, 13, 7, 0, -9 }, // 0x2F '/' + { 91, 7, 9, 8, 0, -8 }, // 0x30 '0' + { 99, 4, 9, 5, 0, -8 }, // 0x31 '1' + { 104, 7, 9, 7, 0, -8 }, // 0x32 '2' + { 112, 7, 9, 8, 0, -8 }, // 0x33 '3' + { 120, 8, 9, 9, 0, -8 }, // 0x34 '4' + { 129, 8, 9, 8, 0, -8 }, // 0x35 '5' + { 138, 8, 9, 8, 0, -8 }, // 0x36 '6' + { 147, 7, 9, 7, 0, -8 }, // 0x37 '7' + { 155, 7, 9, 8, 0, -8 }, // 0x38 '8' + { 163, 8, 9, 8, 0, -8 }, // 0x39 '9' + { 172, 2, 6, 3, 0, -5 }, // 0x3A ':' + { 174, 2, 8, 3, 0, -5 }, // 0x3B ';' + { 176, 7, 6, 7, 0, -6 }, // 0x3C '<' + { 182, 7, 3, 7, 0, -4 }, // 0x3D '=' + { 185, 7, 6, 7, 0, -6 }, // 0x3E '>' + { 191, 6, 9, 7, 0, -8 }, // 0x3F '?' + { 198, 8, 8, 9, 0, -7 }, // 0x40 '@' + { 206, 10, 9, 11, 0, -8 }, // 0x41 'A' + { 218, 8, 9, 9, 0, -8 }, // 0x42 'B' + { 227, 10, 9, 11, 0, -8 }, // 0x43 'C' + { 239, 10, 9, 10, 0, -8 }, // 0x44 'D' + { 251, 7, 9, 8, 0, -8 }, // 0x45 'E' + { 259, 7, 9, 8, 0, -8 }, // 0x46 'F' + { 267, 9, 9, 10, 0, -8 }, // 0x47 'G' + { 278, 10, 9, 10, 0, -8 }, // 0x48 'H' + { 290, 5, 9, 5, 0, -8 }, // 0x49 'I' + { 296, 7, 9, 8, 0, -8 }, // 0x4A 'J' + { 304, 9, 9, 10, 0, -8 }, // 0x4B 'K' + { 315, 7, 9, 8, 0, -8 }, // 0x4C 'L' + { 323, 12, 9, 13, 0, -8 }, // 0x4D 'M' + { 337, 10, 9, 11, 0, -8 }, // 0x4E 'N' + { 349, 10, 9, 11, 0, -8 }, // 0x4F 'O' + { 361, 8, 9, 9, 0, -8 }, // 0x50 'P' + { 370, 11, 10, 12, 0, -8 }, // 0x51 'Q' + { 384, 9, 9, 9, 0, -8 }, // 0x52 'R' + { 395, 6, 9, 7, 0, -8 }, // 0x53 'S' + { 402, 8, 9, 9, 0, -8 }, // 0x54 'T' + { 411, 9, 9, 10, 0, -8 }, // 0x55 'U' + { 422, 9, 9, 10, 0, -8 }, // 0x56 'V' + { 433, 13, 9, 14, 0, -8 }, // 0x57 'W' + { 448, 9, 9, 10, 0, -8 }, // 0x58 'X' + { 459, 9, 9, 9, 0, -8 }, // 0x59 'Y' + { 470, 7, 9, 8, 0, -8 }, // 0x5A 'Z' + { 478, 4, 10, 5, 0, -8 }, // 0x5B '[' + { 483, 6, 9, 6, 0, -8 }, // 0x5C '\' + { 490, 4, 10, 5, 0, -8 }, // 0x5D ']' + { 495, 5, 2, 5, 0, -9 }, // 0x5E '^' + { 497, 8, 1, 8, 0, 1 }, // 0x5F '_' + { 498, 4, 2, 5, 0, -9 }, // 0x60 '`' + { 499, 8, 7, 9, 0, -6 }, // 0x61 'a' + { 506, 8, 9, 9, 0, -8 }, // 0x62 'b' + { 515, 7, 7, 8, 0, -6 }, // 0x63 'c' + { 522, 9, 9, 9, 0, -8 }, // 0x64 'd' + { 533, 8, 7, 8, 0, -6 }, // 0x65 'e' + { 540, 4, 9, 5, 0, -8 }, // 0x66 'f' + { 545, 8, 10, 9, 0, -6 }, // 0x67 'g' + { 555, 8, 9, 9, 0, -8 }, // 0x68 'h' + { 564, 4, 9, 5, 0, -8 }, // 0x69 'i' + { 569, 3, 11, 4, 0, -8 }, // 0x6A 'j' + { 574, 8, 9, 9, 0, -8 }, // 0x6B 'k' + { 583, 4, 9, 5, 0, -8 }, // 0x6C 'l' + { 588, 12, 7, 13, 0, -6 }, // 0x6D 'm' + { 599, 8, 7, 9, 0, -6 }, // 0x6E 'n' + { 606, 8, 7, 8, 0, -6 }, // 0x6F 'o' + { 613, 8, 9, 9, 0, -6 }, // 0x70 'p' + { 622, 9, 9, 9, 0, -6 }, // 0x71 'q' + { 633, 5, 7, 6, 0, -6 }, // 0x72 'r' + { 638, 6, 7, 7, 0, -6 }, // 0x73 's' + { 644, 4, 9, 5, 0, -8 }, // 0x74 't' + { 649, 8, 7, 9, 0, -6 }, // 0x75 'u' + { 656, 7, 7, 8, 0, -6 }, // 0x76 'v' + { 663, 11, 7, 12, 0, -6 }, // 0x77 'w' + { 673, 8, 7, 9, 0, -6 }, // 0x78 'x' + { 680, 8, 9, 9, 0, -6 }, // 0x79 'y' + { 689, 6, 7, 7, 0, -6 }, // 0x7A 'z' + { 695, 4, 10, 4, 0, -8 }, // 0x7B '{' + { 700, 2, 10, 2, 0, -8 }, // 0x7C '|' + { 703, 4, 11, 4, 0, -8 }, // 0x7D '}' + { 709, 5, 3, 6, 0, -9 } }; // 0x7E '~' + +const GFXfont LubalinGraphBold6pt7b PROGMEM = { + (uint8_t *)LubalinGraphBold6pt7bBitmaps, + (GFXglyph *)LubalinGraphBold6pt7bGlyphs, + 0x20, 0x7E, 17 }; + +// Approx. 1383 bytes diff --git a/libraries/_NToolsFonts/thw8p.h b/libraries/_NToolsFonts/thw8p.h new file mode 100644 index 0000000..2f9da60 --- /dev/null +++ b/libraries/_NToolsFonts/thw8p.h @@ -0,0 +1,215 @@ +const uint8_t LubalinGraphBold8pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0xFF, 0xE3, 0xFE, 0xEF, 0xDF, 0xBF, 0x7E, 0xFD, 0xC0, + 0x09, 0x04, 0x82, 0x41, 0x21, 0x23, 0xFC, 0x48, 0x24, 0xFF, 0x89, 0x04, + 0x84, 0x82, 0x40, 0x1C, 0x0E, 0x07, 0xCF, 0xEF, 0xF7, 0x3B, 0x81, 0xF0, + 0x7E, 0x0F, 0x81, 0xFC, 0xFF, 0xFF, 0xFB, 0xFC, 0x38, 0x1C, 0x0E, 0x00, + 0x70, 0xC7, 0xCC, 0x36, 0x61, 0xB3, 0x0D, 0xB0, 0x6D, 0xBB, 0xFB, 0xEE, + 0xDB, 0x0E, 0xD8, 0x66, 0xC3, 0x36, 0x31, 0xF1, 0x87, 0x00, 0x1C, 0x03, + 0xF0, 0x7F, 0x07, 0x70, 0x77, 0x03, 0xEF, 0x7E, 0xFF, 0xFF, 0xE7, 0xCE, + 0x3C, 0xFF, 0xE7, 0xFE, 0x3E, 0x40, 0xFF, 0xFF, 0xC0, 0x06, 0x1C, 0x79, + 0xE7, 0x8E, 0x1C, 0x78, 0xF0, 0xE1, 0xC3, 0xC3, 0xC7, 0xC7, 0x87, 0x02, + 0x83, 0x8F, 0x3C, 0x78, 0xE3, 0xCF, 0x3C, 0xF3, 0xDE, 0xFB, 0xCE, 0x30, + 0x00, 0x1B, 0xBE, 0xED, 0x08, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18, 0x18, + 0x18, 0x18, 0xFF, 0xBF, 0x80, 0x3F, 0xF0, 0xFF, 0x80, 0x00, 0xC0, 0x60, + 0x18, 0x0E, 0x03, 0x00, 0xC0, 0x60, 0x18, 0x0C, 0x03, 0x01, 0xC0, 0x60, + 0x38, 0x0C, 0x03, 0x01, 0x80, 0x60, 0x38, 0x00, 0x3E, 0x3F, 0xBF, 0xDC, + 0x7E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xFF, 0xEF, 0xE1, 0xE0, 0xFB, + 0xEF, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xE7, 0xDF, 0x7C, 0x3E, 0x3F, 0xBF, + 0xFC, 0x7E, 0x38, 0x3C, 0x3C, 0x3C, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xF8, + 0x1E, 0x1F, 0x9F, 0xEE, 0x70, 0x38, 0x78, 0x3C, 0x1F, 0x03, 0xF1, 0xFF, + 0xEF, 0xE3, 0xE0, 0x0F, 0x03, 0xC1, 0xF0, 0xFC, 0x37, 0x1D, 0xCF, 0xFF, + 0xFF, 0xFF, 0xC1, 0xC0, 0xF8, 0x3E, 0x0F, 0x80, 0x3F, 0x8F, 0xE3, 0xF8, + 0xC0, 0x7F, 0x1F, 0xE7, 0xFD, 0xCF, 0x31, 0xC0, 0xF7, 0xFD, 0xFE, 0x1E, + 0x00, 0x1E, 0x0E, 0x0F, 0x0F, 0x07, 0xE7, 0xFB, 0xFF, 0xC7, 0xE3, 0xF1, + 0xFF, 0xCF, 0xE3, 0xC0, 0xFF, 0xFF, 0xFF, 0xE7, 0xEF, 0x0E, 0x1E, 0x1C, + 0x1C, 0x38, 0x38, 0x78, 0x70, 0x1E, 0x1F, 0x9F, 0xEE, 0x77, 0x3B, 0xF8, + 0xFC, 0xFF, 0xE3, 0xF1, 0xFF, 0xEF, 0xE3, 0xE0, 0x3E, 0x3F, 0xBF, 0xFC, + 0x7E, 0x3F, 0x1F, 0xFE, 0xFE, 0x3F, 0x07, 0x07, 0x87, 0x87, 0x80, 0xFF, + 0x81, 0xFF, 0xFF, 0x81, 0xFF, 0x7F, 0x00, 0x00, 0x81, 0x83, 0x06, 0x0C, + 0x06, 0x00, 0xC0, 0x1C, 0x01, 0x80, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x40, + 0x18, 0x07, 0x00, 0xC0, 0x18, 0x0C, 0x1C, 0x70, 0xC0, 0x00, 0x3E, 0x3F, + 0xBF, 0xFC, 0x7E, 0x38, 0x3C, 0x3C, 0x3C, 0x1C, 0x00, 0x07, 0x03, 0x81, + 0xC0, 0x1F, 0x06, 0x11, 0x01, 0x60, 0xD8, 0xF3, 0x22, 0x68, 0x4D, 0x1A, + 0x66, 0x4B, 0x74, 0xC3, 0x0F, 0x80, 0x1F, 0x00, 0xF8, 0x07, 0xE0, 0x1F, + 0x01, 0xF8, 0x0E, 0xE0, 0x67, 0x07, 0xFC, 0x3F, 0xE3, 0xFF, 0x3F, 0x3F, + 0xF9, 0xFF, 0xCF, 0x80, 0xFF, 0xBF, 0xFF, 0xFD, 0xE7, 0x79, 0xDF, 0xE7, + 0xF9, 0xFF, 0x78, 0xDE, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x1F, 0x73, 0xFF, + 0x7F, 0xFF, 0xFF, 0xF9, 0xFE, 0x07, 0xE0, 0x0E, 0x00, 0xE0, 0x0F, 0x0F, + 0x7F, 0xF3, 0xFE, 0x1F, 0x80, 0xFF, 0x8F, 0xFC, 0xFF, 0xE7, 0x1E, 0x70, + 0xF7, 0x07, 0x70, 0x77, 0x07, 0x70, 0xF7, 0x0E, 0xFF, 0xEF, 0xFC, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, 0xFD, 0xE7, 0x78, 0x1F, 0x87, 0xE1, 0xF8, 0x78, + 0x1E, 0x7F, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFD, 0xE7, 0x79, + 0xDE, 0x07, 0xE1, 0xF8, 0x7E, 0x1E, 0x0F, 0xC3, 0xF0, 0xFC, 0x00, 0x0F, + 0x71, 0xFF, 0x9F, 0xFC, 0xFF, 0xEF, 0x0F, 0x70, 0x03, 0x9F, 0xFC, 0xFF, + 0xE7, 0xFB, 0x87, 0xDF, 0xFE, 0x7F, 0xF0, 0xFB, 0x80, 0xFE, 0xFF, 0xF7, + 0xFF, 0xBE, 0x70, 0xE3, 0x87, 0x1F, 0xF8, 0xFF, 0xC7, 0xFE, 0x38, 0x71, + 0xC3, 0xBF, 0xBF, 0xFD, 0xFF, 0xEF, 0x80, 0xFF, 0xFF, 0xCE, 0x38, 0xE3, + 0x8E, 0x38, 0xEF, 0xFF, 0xFC, 0x1F, 0x8F, 0xC7, 0xE0, 0xE0, 0x70, 0x38, + 0x1C, 0x0E, 0x07, 0x73, 0xBF, 0xDF, 0xC7, 0xC0, 0xFD, 0xFF, 0xDF, 0xFD, + 0xF7, 0x3E, 0x77, 0x87, 0xF0, 0x7F, 0x07, 0x78, 0x73, 0xC7, 0x1E, 0xFD, + 0xFF, 0xDF, 0xFD, 0xF0, 0xFC, 0x3F, 0x0F, 0xC1, 0xE0, 0x78, 0x1E, 0x07, + 0x81, 0xE0, 0x79, 0xDE, 0x7F, 0xFF, 0xFF, 0xFF, 0xC0, 0xF8, 0x3F, 0xFC, + 0x3F, 0xFC, 0x3F, 0x7C, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x76, 0xEE, 0x77, + 0xEE, 0x77, 0xEE, 0x73, 0xCE, 0xFB, 0xDF, 0xFB, 0xDF, 0xF9, 0x9F, 0xF0, + 0xFF, 0xC7, 0xFF, 0x3E, 0xF8, 0xE7, 0xE7, 0x3F, 0xB9, 0xFD, 0xCE, 0xFE, + 0x73, 0xF3, 0x9F, 0xBE, 0x7D, 0xF1, 0xEF, 0x87, 0x00, 0x1F, 0x83, 0xFC, + 0x7F, 0xEF, 0xFF, 0xF0, 0xFE, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7F, 0x0F, + 0x7F, 0xE3, 0xFC, 0x1F, 0x00, 0xFF, 0x3F, 0xEF, 0xFD, 0xC7, 0x71, 0xDC, + 0x77, 0xFD, 0xFE, 0x7F, 0x1E, 0x0F, 0xC3, 0xF0, 0xFC, 0x00, 0x0F, 0x80, + 0x7F, 0xC0, 0xFF, 0xC3, 0xFF, 0x8F, 0x8F, 0x9E, 0x0F, 0x3F, 0x8E, 0x7F, + 0xDC, 0xFF, 0xF1, 0xE3, 0xDD, 0xFF, 0xF9, 0xFF, 0xF3, 0xFD, 0xE1, 0xE0, + 0x00, 0xFF, 0x3F, 0xEF, 0xFD, 0xC7, 0x71, 0xDC, 0x77, 0xFD, 0xFE, 0x7F, + 0x1F, 0xEF, 0xFF, 0xEF, 0xF9, 0xC0, 0x37, 0x3F, 0xBF, 0xDC, 0xEE, 0x07, + 0xC1, 0xFC, 0x3F, 0x07, 0xF3, 0xFF, 0xFF, 0xEE, 0xE0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xB7, 0xED, 0xC3, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x03, 0xF0, 0xFC, + 0x3F, 0x00, 0xFB, 0xFF, 0x7F, 0xEF, 0xB8, 0xE7, 0x1C, 0xE3, 0x9C, 0x73, + 0x8E, 0x71, 0xCF, 0x39, 0xFF, 0x1F, 0xC1, 0xF0, 0xFD, 0xFF, 0xEF, 0xFF, + 0x7E, 0x71, 0xC3, 0x8E, 0x1E, 0xF0, 0x77, 0x03, 0xB8, 0x1F, 0xC0, 0x7C, + 0x03, 0xE0, 0x1F, 0x00, 0x70, 0x00, 0xF9, 0xDF, 0xFD, 0xEF, 0xFE, 0xF7, + 0xEE, 0x79, 0xC7, 0x3E, 0xE3, 0xBF, 0x70, 0xFF, 0xB8, 0x7E, 0xF8, 0x3F, + 0x7C, 0x1F, 0x3E, 0x07, 0x9F, 0x03, 0xC7, 0x01, 0xC3, 0x80, 0xFD, 0xFF, + 0xEF, 0xFF, 0x7E, 0x79, 0xC1, 0xFC, 0x07, 0xC0, 0x3C, 0x03, 0xF0, 0x1F, + 0xC1, 0xCF, 0x3F, 0x7F, 0xFB, 0xFF, 0xDF, 0x80, 0xFB, 0xFF, 0x7F, 0xEF, + 0xB8, 0xE3, 0xB8, 0x37, 0x07, 0xC0, 0x78, 0x0E, 0x01, 0xC0, 0x7C, 0x0F, + 0x81, 0xF0, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xF0, 0x70, 0x70, 0x78, 0x7B, + 0xB9, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xCE, 0x73, 0x9C, 0xE7, 0x39, + 0xCF, 0xFF, 0xE0, 0xC0, 0xC1, 0x83, 0x03, 0x06, 0x06, 0x0C, 0x18, 0x18, + 0x30, 0x30, 0x60, 0xFF, 0xFF, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, + 0xFF, 0xFF, 0xC0, 0x73, 0xED, 0x80, 0xFF, 0xE0, 0x61, 0xE7, 0x86, 0x1F, + 0xEF, 0xFD, 0xFF, 0xF9, 0xEE, 0x1D, 0xC3, 0xBC, 0xF3, 0xFF, 0x7F, 0xE3, + 0xBC, 0xF0, 0x1E, 0x03, 0xC0, 0x3B, 0x87, 0xFC, 0xFF, 0x9E, 0x7B, 0x87, + 0x70, 0xEF, 0x3F, 0xFF, 0x7F, 0xEF, 0x70, 0x1C, 0x1F, 0xF7, 0xFF, 0xC7, + 0xE0, 0x38, 0x0F, 0x01, 0xFF, 0x3F, 0x87, 0x80, 0x03, 0xC0, 0x78, 0x0F, + 0x0E, 0xE7, 0xFC, 0xFF, 0xBC, 0xF7, 0x0E, 0xE1, 0xDE, 0x79, 0xFF, 0xBF, + 0xF1, 0xDE, 0x1E, 0x1F, 0xE7, 0xFB, 0xFF, 0xFF, 0xFF, 0xFE, 0x01, 0xFE, + 0x7F, 0x87, 0x80, 0x3B, 0xDF, 0xFF, 0xFD, 0xCE, 0x73, 0xBF, 0xFF, 0x80, + 0x1D, 0xEF, 0xFD, 0xFF, 0xF9, 0xEE, 0x1D, 0xC3, 0xBC, 0xF3, 0xFE, 0x7F, + 0xC3, 0xF9, 0xC7, 0x3F, 0xE3, 0xF8, 0x3C, 0x00, 0xF0, 0x1E, 0x03, 0xC0, + 0x3B, 0x87, 0xF8, 0xFF, 0x9C, 0x73, 0x8E, 0x71, 0xCE, 0x3B, 0xE7, 0xFC, + 0xFF, 0x9E, 0x73, 0x9D, 0xEF, 0x79, 0xCE, 0x73, 0xBF, 0xFF, 0x80, 0x77, + 0x7F, 0xFF, 0x77, 0x77, 0x77, 0x7F, 0xFE, 0xF0, 0x3C, 0x0F, 0x01, 0xDF, + 0x77, 0xDD, 0xF7, 0x71, 0xF8, 0x7E, 0x1F, 0xCF, 0x7F, 0xCF, 0xF1, 0xC0, + 0xF7, 0xBC, 0xE7, 0x39, 0xCE, 0x73, 0xBF, 0xFF, 0x80, 0xFF, 0x1C, 0x7F, + 0xDF, 0x3F, 0xFF, 0xCE, 0x38, 0xE7, 0x1C, 0x73, 0x8E, 0x39, 0xC7, 0x1D, + 0xF3, 0xCF, 0xF9, 0xE7, 0xFC, 0xF3, 0xC0, 0xF7, 0x9F, 0xF3, 0xFF, 0x38, + 0xE7, 0x1C, 0xE3, 0x9C, 0x77, 0xCF, 0xF9, 0xFF, 0x3C, 0x1E, 0x1F, 0xE7, + 0xFB, 0xCF, 0xE1, 0xF8, 0x7F, 0x3D, 0xFE, 0x7F, 0x87, 0x80, 0xF7, 0x1F, + 0xFB, 0xFF, 0x3C, 0xF7, 0x0E, 0xE1, 0xDE, 0x7B, 0xFE, 0x7F, 0xCE, 0xF3, + 0xE0, 0x7C, 0x0F, 0x80, 0x1D, 0xEF, 0xFD, 0xFF, 0xF9, 0xEE, 0x1D, 0xC3, + 0xBC, 0xF3, 0xFE, 0x7F, 0xC7, 0xB8, 0x0F, 0x81, 0xF0, 0x3E, 0xFF, 0xFF, + 0xDE, 0x71, 0xC7, 0x3E, 0xFB, 0xE0, 0x78, 0xFF, 0xFF, 0xE0, 0x78, 0x1E, + 0xEF, 0xFF, 0xFF, 0xEE, 0x73, 0x9D, 0xFF, 0xFD, 0xCE, 0x73, 0x9E, 0xF7, + 0x80, 0xF3, 0xDE, 0x7B, 0xCF, 0x38, 0xE7, 0x1C, 0xE3, 0x9C, 0x73, 0xFF, + 0x3F, 0xE3, 0xFC, 0xF7, 0xFD, 0xFF, 0x7D, 0xCE, 0x73, 0x0F, 0xC3, 0xF0, + 0xF8, 0x1E, 0x07, 0x00, 0xF7, 0x3F, 0xDC, 0xFF, 0x7B, 0xD9, 0xEE, 0x7F, + 0xB9, 0xFF, 0xC7, 0xDF, 0x0F, 0x7C, 0x38, 0xE0, 0xE3, 0x80, 0xF3, 0xFC, + 0xFF, 0x3C, 0xFE, 0x1F, 0x07, 0xC7, 0xFB, 0xCF, 0xF3, 0xFC, 0xF0, 0xFB, + 0xFE, 0xFF, 0xBD, 0xCE, 0x37, 0x8F, 0xC1, 0xF0, 0x78, 0x1E, 0x07, 0x03, + 0xE0, 0xF8, 0x3E, 0x00, 0xFF, 0xFF, 0xFF, 0xEE, 0x1C, 0x38, 0x77, 0xFF, + 0xFF, 0xFF, 0x11, 0x8C, 0x63, 0x18, 0xD8, 0x31, 0x8C, 0x63, 0x18, 0x40, + 0xFF, 0xFE, 0x43, 0x18, 0xC6, 0x31, 0x83, 0x63, 0x18, 0xC6, 0x31, 0x00, + 0x7C, 0xF8, 0xC0 }; + +const GFXglyph LubalinGraphBold8pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 4, 0, 0 }, // 0x20 ' ' + { 1, 3, 13, 4, 0, -12 }, // 0x21 '!' + { 6, 7, 6, 8, 0, -12 }, // 0x22 '"' + { 12, 9, 13, 10, 0, -12 }, // 0x23 '#' + { 27, 9, 18, 10, 0, -14 }, // 0x24 '$' + { 48, 13, 13, 15, 1, -12 }, // 0x25 '%' + { 70, 12, 13, 13, 0, -12 }, // 0x26 '&' + { 90, 3, 6, 4, 0, -12 }, // 0x27 ''' + { 93, 7, 17, 7, 0, -12 }, // 0x28 '(' + { 108, 6, 17, 7, 0, -12 }, // 0x29 ')' + { 121, 5, 6, 6, 0, -12 }, // 0x2A '*' + { 125, 8, 9, 10, 0, -8 }, // 0x2B '+' + { 134, 3, 6, 4, 0, -2 }, // 0x2C ',' + { 137, 4, 3, 5, 0, -6 }, // 0x2D '-' + { 139, 3, 3, 4, 0, -2 }, // 0x2E '.' + { 141, 10, 18, 9, -1, -13 }, // 0x2F '/' + { 164, 9, 13, 10, 0, -12 }, // 0x30 '0' + { 179, 6, 13, 7, 0, -12 }, // 0x31 '1' + { 189, 9, 13, 10, 0, -12 }, // 0x32 '2' + { 204, 9, 13, 11, 0, -12 }, // 0x33 '3' + { 219, 10, 13, 12, 0, -12 }, // 0x34 '4' + { 236, 10, 13, 11, 0, -12 }, // 0x35 '5' + { 253, 9, 13, 11, 0, -12 }, // 0x36 '6' + { 268, 8, 13, 10, 0, -12 }, // 0x37 '7' + { 281, 9, 13, 10, 0, -12 }, // 0x38 '8' + { 296, 9, 13, 11, 0, -12 }, // 0x39 '9' + { 311, 3, 8, 4, 0, -7 }, // 0x3A ':' + { 314, 3, 11, 4, 0, -7 }, // 0x3B ';' + { 319, 9, 9, 10, 0, -9 }, // 0x3C '<' + { 330, 8, 5, 10, 0, -6 }, // 0x3D '=' + { 335, 9, 9, 10, -1, -9 }, // 0x3E '>' + { 346, 9, 13, 10, 0, -12 }, // 0x3F '?' + { 361, 11, 12, 12, 0, -11 }, // 0x40 '@' + { 378, 13, 13, 14, 0, -12 }, // 0x41 'A' + { 400, 10, 13, 12, 0, -12 }, // 0x42 'B' + { 417, 12, 13, 14, 0, -12 }, // 0x43 'C' + { 437, 12, 13, 14, 0, -12 }, // 0x44 'D' + { 457, 10, 13, 11, 0, -12 }, // 0x45 'E' + { 474, 10, 13, 11, 0, -12 }, // 0x46 'F' + { 491, 13, 13, 14, 0, -12 }, // 0x47 'G' + { 513, 13, 13, 14, 0, -12 }, // 0x48 'H' + { 535, 6, 13, 7, 0, -12 }, // 0x49 'I' + { 545, 9, 13, 11, 0, -12 }, // 0x4A 'J' + { 560, 12, 13, 14, 0, -12 }, // 0x4B 'K' + { 580, 10, 13, 11, 0, -12 }, // 0x4C 'L' + { 597, 16, 13, 17, 0, -12 }, // 0x4D 'M' + { 623, 13, 13, 14, 0, -12 }, // 0x4E 'N' + { 645, 12, 13, 14, 0, -12 }, // 0x4F 'O' + { 665, 10, 13, 11, 0, -12 }, // 0x50 'P' + { 682, 15, 14, 16, 0, -12 }, // 0x51 'Q' + { 709, 10, 13, 12, 0, -12 }, // 0x52 'R' + { 726, 9, 13, 10, 0, -12 }, // 0x53 'S' + { 741, 10, 13, 12, 0, -12 }, // 0x54 'T' + { 758, 11, 13, 13, 0, -12 }, // 0x55 'U' + { 776, 13, 13, 13, 0, -12 }, // 0x56 'V' + { 798, 17, 13, 19, 0, -12 }, // 0x57 'W' + { 826, 13, 13, 14, 0, -12 }, // 0x58 'X' + { 848, 11, 13, 13, 0, -12 }, // 0x59 'Y' + { 866, 9, 13, 11, 0, -12 }, // 0x5A 'Z' + { 881, 5, 15, 6, 0, -12 }, // 0x5B '[' + { 891, 7, 13, 8, 0, -12 }, // 0x5C '\' + { 903, 6, 15, 6, 0, -12 }, // 0x5D ']' + { 915, 6, 3, 7, 0, -13 }, // 0x5E '^' + { 918, 11, 1, 11, 0, 2 }, // 0x5F '_' + { 920, 6, 4, 6, -1, -14 }, // 0x60 '`' + { 923, 11, 10, 12, 0, -9 }, // 0x61 'a' + { 937, 11, 13, 12, 0, -12 }, // 0x62 'b' + { 955, 10, 10, 11, 0, -9 }, // 0x63 'c' + { 968, 11, 13, 13, 0, -12 }, // 0x64 'd' + { 986, 10, 10, 11, 0, -9 }, // 0x65 'e' + { 999, 5, 13, 6, 0, -12 }, // 0x66 'f' + { 1008, 11, 14, 12, 0, -9 }, // 0x67 'g' + { 1028, 11, 13, 12, 0, -12 }, // 0x68 'h' + { 1046, 5, 13, 6, 0, -12 }, // 0x69 'i' + { 1055, 4, 16, 5, 0, -12 }, // 0x6A 'j' + { 1063, 10, 13, 11, 0, -12 }, // 0x6B 'k' + { 1080, 5, 13, 6, 0, -12 }, // 0x6C 'l' + { 1089, 17, 10, 18, 0, -9 }, // 0x6D 'm' + { 1111, 11, 10, 12, 0, -9 }, // 0x6E 'n' + { 1125, 10, 10, 11, 0, -9 }, // 0x6F 'o' + { 1138, 11, 13, 13, 0, -9 }, // 0x70 'p' + { 1156, 11, 13, 12, 0, -9 }, // 0x71 'q' + { 1174, 6, 10, 8, 0, -9 }, // 0x72 'r' + { 1182, 8, 10, 9, 0, -9 }, // 0x73 's' + { 1192, 5, 13, 7, 0, -12 }, // 0x74 't' + { 1201, 11, 10, 12, 0, -9 }, // 0x75 'u' + { 1215, 10, 10, 11, 0, -9 }, // 0x76 'v' + { 1228, 14, 10, 16, 0, -9 }, // 0x77 'w' + { 1246, 10, 10, 12, 0, -9 }, // 0x78 'x' + { 1259, 10, 13, 11, 0, -9 }, // 0x79 'y' + { 1276, 8, 10, 9, 0, -9 }, // 0x7A 'z' + { 1286, 5, 15, 6, 0, -12 }, // 0x7B '{' + { 1296, 1, 15, 2, 0, -12 }, // 0x7C '|' + { 1298, 5, 15, 6, 0, -12 }, // 0x7D '}' + { 1308, 7, 3, 7, 0, -12 } }; // 0x7E '~' + +const GFXfont LubalinGraphBold8pt7b PROGMEM = { + (uint8_t *)LubalinGraphBold8pt7bBitmaps, + (GFXglyph *)LubalinGraphBold8pt7bGlyphs, + 0x20, 0x7E, 23 }; + +// Approx. 1983 bytes diff --git a/libraries/_NToolsFonts/tthcent8p.h b/libraries/_NToolsFonts/tthcent8p.h new file mode 100644 index 0000000..b19aa0f --- /dev/null +++ b/libraries/_NToolsFonts/tthcent8p.h @@ -0,0 +1,172 @@ +const uint8_t TTHCENT8pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFC, 0xF0, 0xDE, 0xF7, 0xB0, 0x1B, 0x06, 0xC7, 0xB9, 0xFE, + 0x00, 0x00, 0x0F, 0x7B, 0x9E, 0x66, 0x19, 0x00, 0x30, 0xFB, 0xF7, 0x8F, + 0xC7, 0xCD, 0xFF, 0x7C, 0x60, 0x72, 0x3F, 0xCD, 0xE3, 0xF8, 0x7C, 0x03, + 0xE1, 0xFC, 0x7B, 0x3E, 0xCD, 0xF0, 0x38, 0x7C, 0x3F, 0x8C, 0x63, 0x80, + 0x31, 0xBF, 0x6C, 0x7B, 0x0E, 0xFF, 0xCF, 0x30, 0xFF, 0x36, 0x6C, 0xCC, + 0xCC, 0xC6, 0x63, 0xCE, 0x67, 0x33, 0x33, 0x76, 0xEC, 0x18, 0x18, 0xDB, + 0xFF, 0x3E, 0x7E, 0xFF, 0x18, 0x18, 0x30, 0xCF, 0xFF, 0x30, 0xFF, 0xF8, + 0xF0, 0x08, 0x71, 0x86, 0x30, 0xC7, 0x18, 0x63, 0x0C, 0x30, 0x3C, 0x7E, + 0xE7, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C, 0x7F, 0xB6, 0xDB, 0x6C, + 0x7C, 0xFC, 0x18, 0x31, 0xCF, 0x18, 0x60, 0xFF, 0xFC, 0x78, 0xF9, 0x30, + 0xE3, 0xC3, 0xC1, 0x83, 0xFE, 0xF0, 0x00, 0x02, 0x06, 0x0E, 0x1E, 0x3E, + 0x7F, 0xFF, 0x06, 0x06, 0xFF, 0xFF, 0x07, 0xEF, 0xE0, 0xC1, 0x87, 0xFD, + 0xF0, 0x18, 0x71, 0x87, 0xEF, 0xF8, 0xF1, 0xE3, 0x7C, 0x70, 0xFE, 0xFE, + 0x0C, 0x1C, 0x18, 0x18, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x7E, 0x66, 0x66, + 0x7E, 0xFF, 0xC3, 0xC3, 0x7E, 0x3C, 0x38, 0xFB, 0x1E, 0x3C, 0x7F, 0xDF, + 0x86, 0x38, 0x60, 0xF0, 0x3C, 0xF0, 0x3F, 0xC0, 0x0C, 0x73, 0xBC, 0x70, + 0x70, 0xC0, 0xFF, 0xC1, 0xFF, 0x80, 0xC3, 0x87, 0x87, 0x39, 0xCE, 0x20, + 0x7D, 0xFC, 0x18, 0x30, 0xE3, 0x0C, 0x08, 0x30, 0x60, 0x3E, 0x3F, 0xBB, + 0xFB, 0xFD, 0xFE, 0xFF, 0xBE, 0xF6, 0x38, 0x00, 0x1C, 0x0E, 0x0F, 0x86, + 0xC3, 0x63, 0x19, 0xFC, 0xFE, 0xC1, 0xE0, 0xC0, 0xFC, 0xFE, 0xC6, 0xC6, + 0xFE, 0xFF, 0xC3, 0xC3, 0xFF, 0xFE, 0x1E, 0x3F, 0xD8, 0x78, 0x0C, 0x06, + 0x03, 0x00, 0xC2, 0x7F, 0x8F, 0x00, 0xFC, 0x7F, 0xB0, 0xD8, 0x3C, 0x1E, + 0x0F, 0x07, 0x86, 0xFF, 0x7E, 0x00, 0xFF, 0xFF, 0x06, 0x0F, 0x9F, 0x30, + 0x60, 0xFF, 0xFC, 0xFF, 0xFF, 0x06, 0x0F, 0x9F, 0x30, 0x60, 0xC1, 0x80, + 0x1E, 0x1F, 0xE6, 0x1B, 0x00, 0xC0, 0x31, 0xFC, 0x7D, 0x87, 0x7F, 0x87, + 0xC0, 0xC1, 0xE0, 0xF0, 0x78, 0x3F, 0xFF, 0xFF, 0x07, 0x83, 0xC1, 0xE0, + 0xC0, 0xFF, 0xFF, 0xF0, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC7, 0xFB, 0xC0, + 0xC6, 0xC6, 0xCC, 0xDC, 0xFC, 0xFC, 0xEE, 0xE6, 0xC3, 0xC3, 0xC1, 0x83, + 0x06, 0x0C, 0x18, 0x30, 0x60, 0xFF, 0xFC, 0x80, 0x60, 0x1C, 0x0F, 0x87, + 0xE3, 0xFC, 0xFD, 0xFF, 0x7B, 0xCC, 0xF0, 0x30, 0x81, 0xE0, 0xF8, 0x7F, + 0x3F, 0xDE, 0x7F, 0x1F, 0x87, 0xC1, 0xE0, 0x40, 0x1E, 0x1F, 0xE6, 0x1B, + 0x03, 0xC0, 0xF0, 0x3C, 0x0D, 0x86, 0x7F, 0x87, 0x80, 0xFE, 0xFE, 0xC3, + 0xC3, 0xC3, 0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 0x1E, 0x1F, 0xE6, 0x1B, 0x03, + 0xC0, 0xF0, 0x3C, 0x0D, 0x86, 0x7F, 0x87, 0xF0, 0x0C, 0xFE, 0xFF, 0xC3, + 0xC3, 0xC3, 0xFE, 0xDC, 0xCE, 0xC7, 0xC3, 0x7E, 0xFE, 0xC0, 0xE0, 0x7C, + 0x0F, 0x03, 0x03, 0xFE, 0x7C, 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0xC7, + 0x7F, 0x1F, 0x00, 0xC1, 0xE0, 0xF8, 0xCC, 0x66, 0x31, 0xB0, 0xD8, 0x7C, + 0x1C, 0x0E, 0x00, 0xC1, 0x83, 0xC1, 0x87, 0xE3, 0x86, 0x63, 0xC6, 0x63, + 0xCE, 0x36, 0xCC, 0x36, 0x6C, 0x36, 0x78, 0x1C, 0x78, 0x1C, 0x38, 0xC2, + 0xC7, 0x6E, 0x7C, 0x38, 0x38, 0x7C, 0x6E, 0xE6, 0xC2, 0xC1, 0x61, 0xD9, + 0xCE, 0xC3, 0xC1, 0xE0, 0x60, 0x30, 0x18, 0x0C, 0x00, 0xFF, 0x7F, 0x81, + 0x81, 0x81, 0xC0, 0xC0, 0xE0, 0x60, 0x7F, 0xFF, 0xC0, 0xFF, 0xF1, 0x8C, + 0x63, 0x18, 0xC6, 0x3F, 0xF0, 0xC3, 0x06, 0x18, 0x60, 0xC3, 0x06, 0x18, + 0x70, 0xC3, 0xFF, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xFF, 0xF0, 0x10, 0x70, + 0xF3, 0x6E, 0x78, 0xC0, 0xFF, 0xBF, 0xE0, 0xDD, 0x00, 0x1C, 0x3D, 0xDF, + 0xFC, 0x78, 0xFF, 0xBF, 0xC1, 0x83, 0xE7, 0xEC, 0xF8, 0xF1, 0xE3, 0xFD, + 0xF0, 0x3C, 0xFB, 0x86, 0x0C, 0x1C, 0x1F, 0x9E, 0x06, 0x0C, 0xFB, 0xFE, + 0x78, 0xF1, 0xE3, 0x7E, 0x7C, 0x3C, 0x7E, 0xC6, 0xFF, 0xFF, 0xE0, 0x78, + 0x38, 0x3B, 0xD9, 0xF6, 0x31, 0x8C, 0x63, 0x00, 0x3C, 0xFF, 0x1E, 0x3C, + 0x78, 0xDF, 0x9F, 0x0E, 0x38, 0x60, 0xC3, 0x0F, 0xBF, 0xCF, 0x3C, 0xF3, + 0xCF, 0x30, 0xF3, 0xFF, 0xF0, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3E, 0xC0, + 0xC1, 0x83, 0x06, 0xCF, 0x9F, 0x3F, 0x66, 0xC7, 0x8C, 0xFF, 0xFF, 0xF0, + 0xFF, 0xEF, 0xFF, 0xC6, 0x3C, 0x63, 0xC6, 0x3C, 0x63, 0xC6, 0x3C, 0x63, + 0xFD, 0xFF, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0x3C, 0x7E, 0xE7, 0xC3, 0xC3, + 0xE7, 0x7E, 0x3C, 0xF9, 0xFB, 0x3E, 0x3C, 0x79, 0xFF, 0x7C, 0xC1, 0x83, + 0x00, 0x3E, 0xFF, 0x9E, 0x3C, 0x7C, 0xDF, 0x9F, 0x06, 0x0C, 0x18, 0xFF, + 0xF9, 0x8C, 0x63, 0x18, 0x7D, 0xFB, 0x07, 0xC3, 0xE0, 0xFF, 0xBE, 0x63, + 0xFE, 0xC6, 0x31, 0x8F, 0x38, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xFF, 0xBF, + 0xC7, 0x8F, 0x1B, 0x66, 0xCD, 0x8E, 0x1C, 0xC2, 0x16, 0x31, 0xB1, 0xCC, + 0xDE, 0x66, 0xF6, 0x36, 0xF0, 0xE7, 0x87, 0x18, 0xCF, 0x37, 0x9E, 0x79, + 0xEE, 0xF3, 0xC3, 0xC3, 0xE6, 0x66, 0x66, 0x3C, 0x3C, 0x38, 0x18, 0x18, + 0x10, 0x7F, 0x7E, 0x0C, 0x1C, 0x18, 0x30, 0x7F, 0xFF, 0x1E, 0x7C, 0xC1, + 0x83, 0x1C, 0x38, 0x18, 0x30, 0x60, 0xF8, 0xF0, 0x00, 0xF1, 0xF0, 0x60, + 0xC1, 0x81, 0xC3, 0x8C, 0x18, 0x33, 0xE7, 0x80, 0x71, 0xFE, 0xF3, 0xD8, + 0xE0 +}; + +const GFXglyph TTHCENT8pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 5, 0, 0 }, // 0x20 ' ' + { 1, 2, 10, 4, 1, -9 }, // 0x21 '!' + { 4, 5, 4, 7, 1, -9 }, // 0x22 '"' + { 7, 10, 10, 11, 0, -9 }, // 0x23 '#' + { 20, 7, 10, 8, 1, -10 }, // 0x24 '$' + { 29, 10, 11, 11, 0, -9 }, // 0x25 '%' + { 43, 10, 10, 11, 0, -9 }, // 0x26 '&' + { 56, 2, 4, 5, 1, -9 }, // 0x27 ''' + { 57, 4, 12, 5, 0, -9 }, // 0x28 '(' + { 63, 4, 12, 6, 1, -9 }, // 0x29 ')' + { 69, 8, 9, 11, 1, -10 }, // 0x2A '*' + { 78, 6, 5, 8, 1, -7 }, // 0x2B '+' + { 82, 2, 4, 5, 1, -1 }, // 0x2C ',' + { 83, 5, 1, 6, 0, -5 }, // 0x2D '-' + { 84, 2, 2, 4, 1, -1 }, // 0x2E '.' + { 85, 6, 12, 6, 0, -10 }, // 0x2F '/' + { 94, 8, 10, 10, 0, -9 }, // 0x30 '0' + { 104, 3, 10, 5, 1, -9 }, // 0x31 '1' + { 108, 7, 10, 9, 0, -9 }, // 0x32 '2' + { 117, 7, 10, 9, 1, -9 }, // 0x33 '3' + { 126, 8, 10, 10, 1, -9 }, // 0x34 '4' + { 136, 7, 10, 9, 1, -9 }, // 0x35 '5' + { 145, 7, 10, 9, 1, -9 }, // 0x36 '6' + { 154, 8, 10, 8, 0, -9 }, // 0x37 '7' + { 164, 8, 10, 9, 0, -9 }, // 0x38 '8' + { 174, 7, 10, 9, 1, -9 }, // 0x39 '9' + { 183, 2, 7, 4, 1, -6 }, // 0x3A ':' + { 185, 2, 9, 4, 1, -6 }, // 0x3B ';' + { 188, 6, 7, 8, 1, -8 }, // 0x3C '<' + { 194, 5, 5, 8, 1, -7 }, // 0x3D '=' + { 198, 6, 8, 8, 0, -8 }, // 0x3E '>' + { 204, 7, 10, 8, 0, -9 }, // 0x3F '?' + { 213, 9, 9, 10, 0, -8 }, // 0x40 '@' + { 224, 9, 10, 11, 1, -9 }, // 0x41 'A' + { 236, 8, 10, 10, 1, -9 }, // 0x42 'B' + { 246, 9, 10, 10, 0, -9 }, // 0x43 'C' + { 258, 9, 10, 11, 1, -9 }, // 0x44 'D' + { 270, 7, 10, 8, 0, -9 }, // 0x45 'E' + { 279, 7, 10, 8, 1, -9 }, // 0x46 'F' + { 288, 10, 10, 11, 0, -9 }, // 0x47 'G' + { 301, 9, 10, 11, 1, -9 }, // 0x48 'H' + { 313, 2, 10, 4, 1, -9 }, // 0x49 'I' + { 316, 6, 10, 8, 1, -9 }, // 0x4A 'J' + { 324, 8, 10, 10, 1, -9 }, // 0x4B 'K' + { 334, 7, 10, 8, 1, -9 }, // 0x4C 'L' + { 343, 10, 10, 12, 1, -9 }, // 0x4D 'M' + { 356, 9, 10, 11, 1, -9 }, // 0x4E 'N' + { 368, 10, 10, 11, 0, -9 }, // 0x4F 'O' + { 381, 8, 10, 10, 1, -9 }, // 0x50 'P' + { 391, 10, 11, 12, 0, -9 }, // 0x51 'Q' + { 405, 8, 10, 10, 1, -9 }, // 0x52 'R' + { 415, 8, 10, 9, 0, -9 }, // 0x53 'S' + { 425, 8, 10, 10, 0, -9 }, // 0x54 'T' + { 435, 9, 10, 10, 1, -9 }, // 0x55 'U' + { 447, 9, 10, 10, 1, -9 }, // 0x56 'V' + { 459, 16, 10, 17, 1, -9 }, // 0x57 'W' + { 479, 8, 10, 9, 0, -9 }, // 0x58 'X' + { 489, 9, 10, 10, 1, -9 }, // 0x59 'Y' + { 501, 9, 10, 10, 0, -9 }, // 0x5A 'Z' + { 513, 5, 12, 6, 1, -9 }, // 0x5B '[' + { 521, 6, 12, 7, 0, -9 }, // 0x5C '\' + { 530, 5, 12, 6, 0, -9 }, // 0x5D ']' + { 538, 7, 6, 9, 1, -10 }, // 0x5E '^' + { 544, 10, 2, 11, 1, 1 }, // 0x5F '_' + { 547, 3, 3, 5, 1, -10 }, // 0x60 '`' + { 549, 7, 8, 9, 1, -7 }, // 0x61 'a' + { 556, 7, 10, 8, 0, -9 }, // 0x62 'b' + { 565, 7, 8, 8, 0, -7 }, // 0x63 'c' + { 572, 7, 10, 8, 0, -9 }, // 0x64 'd' + { 581, 8, 8, 9, 1, -7 }, // 0x65 'e' + { 589, 5, 10, 6, 0, -9 }, // 0x66 'f' + { 596, 7, 11, 9, 1, -7 }, // 0x67 'g' + { 606, 6, 10, 8, 1, -9 }, // 0x68 'h' + { 614, 2, 10, 4, 1, -9 }, // 0x69 'i' + { 617, 4, 13, 5, 0, -9 }, // 0x6A 'j' + { 624, 7, 10, 8, 0, -9 }, // 0x6B 'k' + { 633, 2, 10, 4, 1, -9 }, // 0x6C 'l' + { 636, 12, 8, 15, 1, -7 }, // 0x6D 'm' + { 648, 7, 8, 9, 1, -7 }, // 0x6E 'n' + { 655, 8, 8, 10, 0, -7 }, // 0x6F 'o' + { 663, 7, 11, 8, 0, -7 }, // 0x70 'p' + { 673, 7, 11, 9, 1, -7 }, // 0x71 'q' + { 683, 5, 8, 7, 1, -7 }, // 0x72 'r' + { 688, 7, 8, 8, 1, -7 }, // 0x73 's' + { 695, 5, 9, 7, 0, -8 }, // 0x74 't' + { 701, 7, 8, 9, 1, -7 }, // 0x75 'u' + { 708, 7, 8, 9, 0, -7 }, // 0x76 'v' + { 715, 13, 8, 14, 0, -7 }, // 0x77 'w' + { 728, 6, 8, 9, 1, -7 }, // 0x78 'x' + { 734, 8, 11, 9, 0, -7 }, // 0x79 'y' + { 745, 8, 8, 9, 0, -7 }, // 0x7A 'z' + { 753, 7, 12, 8, 0, -9 }, // 0x7B '{' + { 764, 1, 1, 5, 0, 0 }, // 0x7C '|' + { 765, 7, 12, 8, 0, -9 }, // 0x7D '}' + { 776, 9, 4, 11, 1, -6 } // 0x7E '~' +}; + +const GFXfont TTHCENT8pt7b PROGMEM = { + (uint8_t *)TTHCENT8pt7bBitmaps, + (GFXglyph *)TTHCENT8pt7bGlyphs, 0x20, 0x7E, 16 }; + +// Approx. 1453 bytes diff --git a/libraries/_NToolsFonts/urwdin10p.h b/libraries/_NToolsFonts/urwdin10p.h new file mode 100644 index 0000000..c61b7bc --- /dev/null +++ b/libraries/_NToolsFonts/urwdin10p.h @@ -0,0 +1,205 @@ +const uint8_t URWDIN_Regular10pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0xF0, 0xF0, 0xDE, 0xF7, 0xBD, 0x80, 0x09, 0x02, 0x41, + 0x90, 0x64, 0x7F, 0xC4, 0xC1, 0x33, 0xFF, 0x32, 0x0C, 0x83, 0x20, 0x88, + 0x18, 0x0C, 0x1F, 0x9C, 0x6C, 0x06, 0x03, 0x80, 0xF0, 0x3F, 0x03, 0xC0, + 0x60, 0x30, 0x1E, 0x19, 0xF8, 0x30, 0x18, 0x0C, 0x00, 0x78, 0xC0, 0xCC, + 0xC0, 0xCC, 0xC0, 0xCC, 0x80, 0xCD, 0x80, 0xCD, 0x80, 0xCD, 0xBE, 0x7B, + 0x63, 0x03, 0x63, 0x03, 0x63, 0x02, 0x63, 0x06, 0x63, 0x06, 0x63, 0x06, + 0x3E, 0x1E, 0x03, 0x18, 0x31, 0x83, 0x18, 0x3B, 0x81, 0xF0, 0x0E, 0x01, + 0xC0, 0x76, 0x2E, 0x36, 0xC1, 0xCC, 0x0C, 0xE3, 0x47, 0xC6, 0xFF, 0xC0, + 0x11, 0x8C, 0xC6, 0x73, 0x18, 0xC6, 0x31, 0x8C, 0x31, 0x8C, 0x30, 0x80, + 0x43, 0x18, 0x63, 0x08, 0x63, 0x18, 0xC6, 0x31, 0x98, 0xC6, 0x62, 0x00, + 0x0C, 0x03, 0x04, 0xC9, 0xFE, 0x0C, 0x07, 0x83, 0x30, 0x84, 0x0C, 0x06, + 0x03, 0x01, 0x8F, 0xF8, 0x60, 0x30, 0x18, 0x0C, 0x00, 0x69, 0x6C, 0xFC, + 0xF0, 0x0C, 0x30, 0x86, 0x18, 0x43, 0x0C, 0x21, 0x86, 0x10, 0xC3, 0x00, + 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, + 0x66, 0x3C, 0x3F, 0xE6, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x3C, + 0x46, 0xC3, 0x03, 0x03, 0x07, 0x06, 0x0E, 0x1C, 0x18, 0x30, 0x60, 0x60, + 0xFF, 0x3C, 0x66, 0xC3, 0x03, 0x03, 0x06, 0x3C, 0x06, 0x03, 0x03, 0x03, + 0xC3, 0xC6, 0x3C, 0x08, 0x0C, 0x06, 0x02, 0x03, 0x01, 0x01, 0x98, 0xCC, + 0x46, 0x63, 0x3F, 0xE0, 0xC0, 0x60, 0x30, 0x7F, 0x40, 0x40, 0x40, 0xC0, + 0xFC, 0xC6, 0x03, 0x03, 0x03, 0x03, 0x83, 0xC6, 0x7C, 0x0C, 0x18, 0x18, + 0x30, 0x30, 0x7C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, 0xFE, + 0x0C, 0x10, 0x20, 0xC1, 0x02, 0x0C, 0x18, 0x20, 0xC1, 0x82, 0x0C, 0x00, + 0x3C, 0xE7, 0xC3, 0xC3, 0xC3, 0xE6, 0x7C, 0xE6, 0xC3, 0xC3, 0xC3, 0xC3, + 0x66, 0x3C, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x06, 0x0C, + 0x0C, 0x18, 0x18, 0x30, 0xF0, 0x00, 0xF0, 0x6C, 0x00, 0x00, 0x6F, 0x6C, + 0x00, 0x03, 0x0E, 0x38, 0xE0, 0xE0, 0x38, 0x0E, 0x03, 0xFF, 0x80, 0x00, + 0x1F, 0xF0, 0x00, 0xC0, 0x70, 0x1C, 0x07, 0x07, 0x1C, 0x70, 0xC0, 0x3C, + 0xC6, 0xC3, 0x83, 0x03, 0x07, 0x0E, 0x1C, 0x18, 0x18, 0x00, 0x00, 0x18, + 0x18, 0x07, 0xE0, 0x38, 0x30, 0xC0, 0x33, 0x00, 0x26, 0x3D, 0x38, 0xC4, + 0x71, 0x88, 0xE6, 0x11, 0xCC, 0x23, 0x98, 0xCF, 0x33, 0x96, 0x39, 0xC6, + 0x00, 0x0E, 0x00, 0x0E, 0x06, 0x07, 0xF8, 0x06, 0x00, 0x60, 0x0F, 0x00, + 0xB0, 0x19, 0x01, 0x98, 0x11, 0x83, 0x08, 0x30, 0xC2, 0x0C, 0x7F, 0xC6, + 0x06, 0x40, 0x6C, 0x03, 0xFE, 0x30, 0xCC, 0x1B, 0x06, 0xC1, 0xB0, 0xCF, + 0xE3, 0x06, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC1, 0xBF, 0xC0, 0x3E, 0x30, + 0xB0, 0x78, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x36, + 0x19, 0xF0, 0xFE, 0x30, 0xEC, 0x1B, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, + 0xC0, 0xF0, 0x3C, 0x0F, 0x06, 0xC3, 0xBF, 0x80, 0xFF, 0xE0, 0x30, 0x18, + 0x0C, 0x06, 0x03, 0xFD, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFC, + 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, + 0xC0, 0xC0, 0x3F, 0x18, 0x6C, 0x1B, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x1F, + 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0x61, 0x8F, 0xC0, 0xC1, 0xE0, 0xF0, 0x78, + 0x3C, 0x1E, 0x0F, 0xFF, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0C, + 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x46, 0x7C, 0xC0, 0xF0, 0x6C, 0x33, 0x18, 0xCC, + 0x33, 0x0D, 0xC3, 0xD8, 0xE6, 0x30, 0xCC, 0x33, 0x06, 0xC0, 0xF0, 0x30, + 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, + 0x18, 0x0C, 0x07, 0xFC, 0xC0, 0x3E, 0x07, 0xE0, 0x7F, 0x0F, 0xD0, 0xBD, + 0x0B, 0xD9, 0xBC, 0x93, 0xCF, 0x3C, 0x63, 0xC6, 0x3C, 0x03, 0xC0, 0x3C, + 0x03, 0xC0, 0xF8, 0x3E, 0x0F, 0xC3, 0xD0, 0xF6, 0x3C, 0x8F, 0x13, 0xC6, + 0xF0, 0xBC, 0x3F, 0x07, 0xC1, 0xF0, 0x30, 0x3F, 0x18, 0x6C, 0x1F, 0x03, + 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x87, 0x61, 0x8F, + 0x80, 0xFE, 0x61, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x0D, 0xFC, 0xC0, 0x60, + 0x30, 0x18, 0x0C, 0x06, 0x00, 0x3F, 0x0C, 0x33, 0x07, 0x60, 0x6C, 0x0D, + 0x81, 0xB0, 0x36, 0x06, 0xC0, 0xD8, 0x1B, 0x1B, 0x71, 0xE6, 0x1C, 0x7E, + 0xC0, 0xFE, 0x61, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x0D, 0xFC, 0xC4, 0x63, + 0x30, 0x98, 0x6C, 0x36, 0x0C, 0x3E, 0x31, 0xB0, 0x18, 0x0C, 0x07, 0x01, + 0xF0, 0x3E, 0x03, 0x80, 0xC0, 0x60, 0x3C, 0x33, 0xF0, 0xFF, 0xC3, 0x00, + 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, + 0x0C, 0x03, 0x00, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, + 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0x61, 0x8F, 0xC0, 0xC0, 0x68, 0x09, + 0x83, 0x30, 0x62, 0x08, 0x61, 0x0C, 0x60, 0x88, 0x19, 0x03, 0x60, 0x28, + 0x07, 0x00, 0xE0, 0x08, 0x00, 0x81, 0x02, 0xC1, 0x82, 0xC3, 0x86, 0xC2, + 0x86, 0x42, 0x84, 0x46, 0xC4, 0x66, 0x4C, 0x64, 0x4C, 0x24, 0x48, 0x2C, + 0x68, 0x38, 0x28, 0x38, 0x38, 0x18, 0x30, 0x18, 0x10, 0x60, 0xC4, 0x18, + 0xC6, 0x0C, 0x81, 0xB0, 0x1C, 0x03, 0x80, 0x70, 0x0A, 0x03, 0x60, 0xC6, + 0x18, 0xC6, 0x0C, 0x80, 0x80, 0xC0, 0xF0, 0x36, 0x19, 0x86, 0x33, 0x0C, + 0xC1, 0xE0, 0x78, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xFF, + 0x01, 0x81, 0x80, 0xC0, 0xC0, 0x60, 0x60, 0x20, 0x30, 0x10, 0x18, 0x08, + 0x0C, 0x07, 0xFC, 0xFC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xF0, + 0xC3, 0x04, 0x18, 0x60, 0x83, 0x0C, 0x10, 0x61, 0x82, 0x0C, 0x30, 0xF3, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xF0, 0x08, 0x0C, 0x07, 0x06, + 0xC6, 0x22, 0x1B, 0x06, 0xFF, 0xC0, 0xC9, 0x80, 0x3E, 0x63, 0x03, 0x03, + 0x7F, 0xC3, 0xC3, 0xC3, 0xC3, 0x7F, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0xE6, + 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE6, 0xFE, 0x3E, 0x62, 0xC0, 0xC0, + 0xC0, 0xC0, 0xC0, 0xC0, 0x62, 0x3E, 0x03, 0x03, 0x03, 0x03, 0x7F, 0x67, + 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x7F, 0x3C, 0x66, 0xC3, 0xC3, + 0xFF, 0xC0, 0xC0, 0xC0, 0x62, 0x3E, 0x3B, 0x18, 0xCF, 0xB1, 0x8C, 0x63, + 0x18, 0xC6, 0x30, 0x7F, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, + 0x7F, 0x03, 0x03, 0x46, 0x7C, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0xE7, 0xC3, + 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xF0, 0xFF, 0xFF, 0xF0, 0x18, + 0xC0, 0x01, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x3F, 0x80, 0xC0, + 0x60, 0x30, 0x18, 0x0C, 0x36, 0x33, 0x31, 0x90, 0xD8, 0x7E, 0x39, 0x18, + 0xCC, 0x36, 0x18, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xC7, 0xFC, 0xFB, + 0x9E, 0x7C, 0x30, 0xF0, 0xC3, 0xC3, 0x0F, 0x0C, 0x3C, 0x30, 0xF0, 0xC3, + 0xC3, 0x0F, 0x0C, 0x30, 0xFE, 0xE7, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, + 0xC3, 0xC3, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, + 0xFE, 0xE6, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE6, 0xFE, 0xC0, 0xC0, + 0xC0, 0xC0, 0x7F, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x7F, + 0x03, 0x03, 0x03, 0x03, 0xFF, 0x8C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x00, + 0x79, 0x8B, 0x06, 0x0F, 0xC7, 0xC1, 0x83, 0x86, 0xF8, 0x63, 0x19, 0xF6, + 0x31, 0x8C, 0x63, 0x18, 0xC3, 0x80, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, + 0xC3, 0xC3, 0xE7, 0x7F, 0x83, 0xC3, 0xC2, 0x46, 0x64, 0x64, 0x2C, 0x38, + 0x18, 0x18, 0x82, 0x0E, 0x18, 0xD1, 0xC6, 0x8A, 0x26, 0x59, 0x36, 0x58, + 0xA2, 0x85, 0x1C, 0x38, 0x60, 0x82, 0x00, 0x61, 0x11, 0x8D, 0x83, 0x81, + 0xC0, 0xE0, 0x50, 0x6C, 0x63, 0x21, 0x80, 0xC1, 0xA0, 0x98, 0xC4, 0x62, + 0x21, 0xB0, 0x58, 0x38, 0x1C, 0x06, 0x02, 0x03, 0x01, 0x03, 0x80, 0xFE, + 0x0C, 0x30, 0xC1, 0x86, 0x08, 0x30, 0xC1, 0xFC, 0x1C, 0xC3, 0x0C, 0x30, + 0xC3, 0x30, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x1C, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0xE0, 0xC3, 0x0C, 0x30, 0xC3, 0x03, 0x30, 0xC3, 0x0C, 0x30, + 0xC3, 0x0C, 0xE0, 0x70, 0xE4, 0xA1, 0xC0 }; + +const GFXglyph URWDIN_Regular10pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 4, 0, 0 }, // 0x20 ' ' + { 1, 2, 14, 6, 2, -13 }, // 0x21 '!' + { 5, 5, 5, 9, 2, -13 }, // 0x22 '"' + { 9, 10, 12, 11, 0, -12 }, // 0x23 '#' + { 24, 9, 18, 11, 1, -14 }, // 0x24 '$' + { 45, 16, 14, 18, 1, -13 }, // 0x25 '%' + { 73, 12, 14, 16, 2, -13 }, // 0x26 '&' + { 94, 2, 5, 6, 2, -13 }, // 0x27 ''' + { 96, 5, 18, 9, 3, -15 }, // 0x28 '(' + { 108, 5, 18, 9, 1, -15 }, // 0x29 ')' + { 120, 10, 8, 12, 1, -14 }, // 0x2A '*' + { 130, 9, 9, 11, 1, -10 }, // 0x2B '+' + { 141, 3, 5, 6, 1, 0 }, // 0x2C ',' + { 143, 6, 1, 10, 2, -7 }, // 0x2D '-' + { 144, 2, 2, 6, 2, -1 }, // 0x2E '.' + { 145, 6, 14, 8, 1, -13 }, // 0x2F '/' + { 156, 8, 14, 11, 1, -13 }, // 0x30 '0' + { 170, 5, 14, 11, 2, -13 }, // 0x31 '1' + { 179, 8, 14, 11, 1, -13 }, // 0x32 '2' + { 193, 8, 14, 11, 1, -13 }, // 0x33 '3' + { 207, 9, 14, 11, 1, -13 }, // 0x34 '4' + { 223, 8, 14, 11, 2, -13 }, // 0x35 '5' + { 237, 8, 14, 11, 1, -13 }, // 0x36 '6' + { 251, 7, 14, 11, 2, -13 }, // 0x37 '7' + { 264, 8, 14, 11, 1, -13 }, // 0x38 '8' + { 278, 8, 14, 11, 1, -13 }, // 0x39 '9' + { 292, 2, 10, 6, 2, -9 }, // 0x3A ':' + { 295, 3, 13, 6, 1, -9 }, // 0x3B ';' + { 300, 8, 9, 11, 1, -11 }, // 0x3C '<' + { 309, 9, 4, 11, 1, -8 }, // 0x3D '=' + { 314, 8, 9, 11, 2, -11 }, // 0x3E '>' + { 323, 8, 14, 11, 2, -13 }, // 0x3F '?' + { 337, 15, 16, 17, 1, -13 }, // 0x40 '@' + { 367, 12, 14, 12, 0, -13 }, // 0x41 'A' + { 388, 10, 14, 13, 2, -13 }, // 0x42 'B' + { 406, 9, 14, 13, 2, -13 }, // 0x43 'C' + { 422, 10, 14, 14, 2, -13 }, // 0x44 'D' + { 440, 9, 14, 12, 2, -13 }, // 0x45 'E' + { 456, 8, 14, 11, 2, -13 }, // 0x46 'F' + { 470, 10, 14, 13, 2, -13 }, // 0x47 'G' + { 488, 9, 14, 13, 2, -13 }, // 0x48 'H' + { 504, 2, 14, 6, 2, -13 }, // 0x49 'I' + { 508, 8, 14, 10, 0, -13 }, // 0x4A 'J' + { 522, 10, 14, 12, 2, -13 }, // 0x4B 'K' + { 540, 9, 14, 11, 2, -13 }, // 0x4C 'L' + { 556, 12, 14, 16, 2, -13 }, // 0x4D 'M' + { 577, 10, 14, 14, 2, -13 }, // 0x4E 'N' + { 595, 10, 14, 14, 2, -13 }, // 0x4F 'O' + { 613, 9, 14, 12, 2, -13 }, // 0x50 'P' + { 629, 11, 14, 14, 2, -13 }, // 0x51 'Q' + { 649, 9, 14, 12, 2, -13 }, // 0x52 'R' + { 665, 9, 14, 11, 1, -13 }, // 0x53 'S' + { 681, 10, 14, 12, 1, -13 }, // 0x54 'T' + { 699, 10, 14, 14, 2, -13 }, // 0x55 'U' + { 717, 11, 14, 11, 0, -13 }, // 0x56 'V' + { 737, 16, 14, 17, 1, -13 }, // 0x57 'W' + { 765, 11, 14, 11, 0, -13 }, // 0x58 'X' + { 785, 10, 14, 10, 0, -13 }, // 0x59 'Y' + { 803, 9, 14, 11, 1, -13 }, // 0x5A 'Z' + { 819, 4, 17, 9, 3, -14 }, // 0x5B '[' + { 828, 6, 14, 8, 1, -13 }, // 0x5C '\' + { 839, 4, 17, 9, 2, -14 }, // 0x5D ']' + { 848, 9, 7, 11, 1, -13 }, // 0x5E '^' + { 856, 10, 1, 10, 0, 3 }, // 0x5F '_' + { 858, 3, 3, 10, 3, -13 }, // 0x60 '`' + { 860, 8, 10, 11, 1, -9 }, // 0x61 'a' + { 870, 8, 14, 11, 2, -13 }, // 0x62 'b' + { 884, 8, 10, 9, 1, -9 }, // 0x63 'c' + { 894, 8, 14, 11, 1, -13 }, // 0x64 'd' + { 908, 8, 10, 10, 1, -9 }, // 0x65 'e' + { 918, 5, 14, 7, 1, -13 }, // 0x66 'f' + { 927, 8, 14, 11, 1, -9 }, // 0x67 'g' + { 941, 8, 14, 12, 2, -13 }, // 0x68 'h' + { 955, 2, 14, 6, 2, -13 }, // 0x69 'i' + { 959, 5, 18, 6, -1, -13 }, // 0x6A 'j' + { 971, 9, 14, 11, 2, -13 }, // 0x6B 'k' + { 987, 4, 14, 6, 2, -13 }, // 0x6C 'l' + { 994, 14, 10, 18, 2, -9 }, // 0x6D 'm' + { 1012, 8, 10, 12, 2, -9 }, // 0x6E 'n' + { 1022, 8, 10, 10, 1, -9 }, // 0x6F 'o' + { 1032, 8, 14, 11, 2, -9 }, // 0x70 'p' + { 1046, 8, 14, 11, 1, -9 }, // 0x71 'q' + { 1060, 6, 10, 8, 2, -9 }, // 0x72 'r' + { 1068, 7, 10, 9, 1, -9 }, // 0x73 's' + { 1077, 5, 13, 7, 1, -12 }, // 0x74 't' + { 1086, 8, 10, 12, 2, -9 }, // 0x75 'u' + { 1096, 8, 10, 10, 1, -9 }, // 0x76 'v' + { 1106, 13, 10, 15, 1, -9 }, // 0x77 'w' + { 1123, 9, 10, 9, 0, -9 }, // 0x78 'x' + { 1135, 9, 14, 10, 0, -9 }, // 0x79 'y' + { 1151, 7, 10, 9, 1, -9 }, // 0x7A 'z' + { 1160, 6, 17, 8, 1, -14 }, // 0x7B '{' + { 1173, 2, 18, 12, 5, -15 }, // 0x7C '|' + { 1178, 6, 17, 8, 1, -14 }, // 0x7D '}' + { 1191, 9, 3, 11, 1, -8 } }; // 0x7E '~' + +const GFXfont URWDIN_Regular10pt7b PROGMEM = { + (uint8_t *)URWDIN_Regular10pt7bBitmaps, + (GFXglyph *)URWDIN_Regular10pt7bGlyphs, + 0x20, 0x7E, 24 }; + +// Approx. 1867 bytes