diff --git a/examples/Example_Fast_Temperature/Example_Fast_Temperature.ino b/examples/Example_Fast_Temperature/Example_Fast_Temperature.ino index 4937286..a9efea5 100644 --- a/examples/Example_Fast_Temperature/Example_Fast_Temperature.ino +++ b/examples/Example_Fast_Temperature/Example_Fast_Temperature.ino @@ -34,8 +34,8 @@ // Define structures and classes // Define variables and constants -Screen_EPD_EXT3_Fast myScreen(eScreen_EPD_271_PS_09, boardRaspberryPiPico_RP2040); -// Screen_EPD_EXT3_Fast myScreen(eScreen_EPD_271_KS_09, boardRaspberryPiPico_RP2040); +Screen_EPD_EXT3_Fast myScreen(eScreen_EPD_271_PS_09_Fast, boardRaspberryPiPico_RP2040); +// Screen_EPD_EXT3_Fast myScreen(eScreen_EPD_271_PS_09_Wide, boardRaspberryPiPico_RP2040); // Prototypes diff --git a/library.properties b/library.properties index babfb26..068da8f 100755 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=PDLS_EXT3_Basic_Fast -version=8.0.1 +version=8.0.3 author=Rei Vilo for Pervasive Displays maintainer=Rei Vilo sentence=Library for Pervasive Displays iTC monochrome screens with embedded fast update and EXT3-1 board diff --git a/src/Screen_EPD_EXT3.cpp b/src/Screen_EPD_EXT3.cpp index afc0c56..52f4f4b 100755 --- a/src/Screen_EPD_EXT3.cpp +++ b/src/Screen_EPD_EXT3.cpp @@ -10,6 +10,7 @@ // // Copyright (c) Rei Vilo, 2010-2024 // Licence Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) +// For exclusive use with Pervasive Displays screens // Portions (c) Pervasive Displays, 2010-2024 // // Release 509: Added eScreen_EPD_EXT3_271_Fast @@ -30,148 +31,448 @@ // Release 703: Added support for eScreen_EPD_EXT3_152_0J_Wide xE2152KS0Jx // Release 800: Read OTP memory // Release 801: Improved OTP implementation +// Release 802: Added support for 343-KS-0B xE2343PS0Bx +// Release 802: Added references to application notes +// Release 802: Refactored CoG functions +// Release 803: Added types for string and frame-buffer // // Library header #include "Screen_EPD_EXT3.h" -#define DEBUG_OTP 1 - // // === COG section // /// @cond +/// @see +/// * ApplicationNote_smallSize_fast-update_v02_20220907 +/// * ApplicationNote_Small_Size_wide-Temperature_EPD_v03_20231031_B +/// * ApplicationNote_Small_Size_wide-Temperature_EPD_v01_20231225_A +/// * ApplicationNote_EPD343_Mono(E2343PS0Bx)_240320a +/// * ApplicationNote_for_5.8inch_fast-update_EPDE2581PS0B1_20230206b +/// * ApplicationNote_152_Size_wide-Temperature_EPD_v01_20231225_A +// -void Screen_EPD_EXT3_Fast::COG_reset() +// +// --- Medium screens with K or P film +// +void Screen_EPD_EXT3_Fast::COG_MediumKP_reset() { // Application note § 2. Power on COG driver - switch (u_codeSize) + b_reset(5, 2, 4, 20, 5); // Medium +} + +void Screen_EPD_EXT3_Fast::COG_MediumKP_getDataOTP() +{ + // Read OTP + uint8_t ui8 = 0; + uint16_t _readBytes = 0; + u_flagOTP = false; + + COG_MediumKP_reset(); + if (b_family == FAMILY_LARGE) { - case SIZE_565: // 5.65" - case SIZE_581: // 5.81" - case SIZE_741: // 7.41" + digitalWrite(b_pin.panelCSS, HIGH); // Unselect slave panel + } + + // Read OTP + switch (u_codeDriver) + { + case DRIVER_B: + + _readBytes = 128; - b_reset(200, 20, 200, 50, 5); // medium + digitalWrite(b_pin.panelDC, LOW); // Command + digitalWrite(b_pin.panelCS, LOW); // Select + hV_HAL_SPI3_write(0xb9); + delay(5); break; - case SIZE_969: // 9.69" - case SIZE_1198: // 11.98" + default: + + mySerial.println(); + mySerial.println(formatString("hV * OTP failed for screen %i-%cS-0%c", u_codeSize, u_codeFilm, u_codeDriver)); + while (0x01); + break; + } + + digitalWrite(b_pin.panelDC, HIGH); // Data + ui8 = hV_HAL_SPI3_read(); // Dummy + // hV_HAL_log(LEVEL_DEBUG, "Dummy read 0x%02x", ui8); + + // Populate COG_data + for (uint16_t index = 0; index < _readBytes; index += 1) + { + COG_data[index] = hV_HAL_SPI3_read(); // Read OTP + } + + // End of OTP reading + digitalWrite(b_pin.panelCS, HIGH); // Unselect - b_reset(200, 20, 200, 200, 5); // large + // Check + uint8_t _chipId; + switch (u_eScreen_EPD) + { + case eScreen_EPD_343_PS_0B: + case eScreen_EPD_343_PS_0B_Touch: + case eScreen_EPD_581_PS_0B: + + _chipId = 0x10; + u_flagOTP = (COG_data[0x00] == _chipId); + break; + + case eScreen_EPD_581_KS_0B: + + _chipId = 0x16; + u_flagOTP = (COG_data[0x00] == _chipId); break; default: - b_reset(5, 5, 10, 5, 5); // small + _chipId = 0x00; + u_flagOTP = false; break; - } // u_codeSize + } + + if (u_flagOTP == true) + { + mySerial.println("hV . OTP check passed"); + } + else + { + mySerial.println(); + mySerial.println(formatString("hV * OTP check failed - First byte 0x%02x, expected 0x%04x", COG_data[0x00], _chipId)); + while (0x01); + } } -void Screen_EPD_EXT3_Fast::COG_initial(uint8_t updateMode) +void Screen_EPD_EXT3_Fast::COG_MediumKP_initial(uint8_t updateMode) { - // Application note § 4. Input initial command - if ((u_eScreen_EPD == eScreen_EPD_150_KS_0J) or (u_eScreen_EPD == eScreen_EPD_152_KS_0J)) + uint8_t workDCTL[2]; + workDCTL[0] = COG_data[0x10]; // DCTL + workDCTL[1] = 0x00; + b_sendIndexData(0x01, workDCTL, 2); +} + +void Screen_EPD_EXT3_Fast::COG_MediumKP_sendImageData(uint8_t updateMode) +{ + // Application note § 3.2 Input image to the EPD + FRAMEBUFFER_TYPE nextBuffer = s_newImage; + FRAMEBUFFER_TYPE previousBuffer = s_newImage + u_pageColourSize; + + // Send image data + b_sendIndexData(0x13, &COG_data[0x15], 6); // DUW + b_sendIndexData(0x90, &COG_data[0x0c], 4); // DRFW + + // Next frame + b_sendIndexData(0x12, &COG_data[0x12], 3); // RAM_RW + b_sendIndexData(0x10, nextBuffer, u_pageColourSize); // Next frame + + switch (updateMode) { - // Soft reset - b_sendCommand8(0x12); - digitalWrite(b_pin.panelDC, LOW); // Select - b_waitBusy(LOW); // 150 and 152 specific + case UPDATE_GLOBAL: - // Work settings - b_sendCommandData8(0x1a, u_temperature); + // Previous frame = dummy + b_sendIndexData(0x12, &COG_data[0x12], 3); // RAM_RW + b_sendIndexFixed(0x11, 0x00, u_pageColourSize); // Previous frame = dummy - if (updateMode == UPDATE_GLOBAL) - { - b_sendCommandData8(0x22, 0xd7); - } - else if (updateMode == UPDATE_FAST) - { - b_sendCommandData8(0x3c, 0xc0); - b_sendCommandData8(0x22, 0xdf); - } + break; + + case UPDATE_FAST: + + // Previous frame + b_sendIndexData(0x12, &COG_data[0x12], 3); // RAM_RW + b_sendIndexData(0x11, previousBuffer, u_pageColourSize); // Next frame + break; + + default: + break; } - else + + // Copy next frame to previous frame + memcpy(previousBuffer, nextBuffer, u_pageColourSize); // Copy displayed next to previous +} + +void Screen_EPD_EXT3_Fast::COG_MediumKP_update(uint8_t updateMode) +{ + // Initial COG + // Application note § 3.1 Initial flow chart + b_sendCommandData8(0x05, 0x7d); + delay(50); + b_sendCommandData8(0x05, 0x00); + delay(1); + b_sendCommandData8(0xd8, COG_data[0x1c]); // MS_SYNC + b_sendCommandData8(0xd6, COG_data[0x1d]); // BVSS + + b_sendCommandData8(0xa7, 0x10); + delay(2); + b_sendCommandData8(0xa7, 0x00); + delay(10); + + b_sendCommandData8(0x44, 0x00); + b_sendCommandData8(0x45, 0x80); + + b_sendCommandData8(0xa7, 0x10); + delay(2); + b_sendCommandData8(0xa7, 0x00); + delay(10); + + uint8_t indexTemperature; + switch (u_eScreen_EPD) { - // Work settings - uint8_t indexE5_work; // Temperature - uint8_t index00_work[2]; // PSR + case eScreen_EPD_343_PS_0B: + case eScreen_EPD_343_PS_0B_Touch: - // FILM_P and FILM_K already checked - if (updateMode != UPDATE_GLOBAL) // Specific settings for fast update - { - indexE5_work = u_temperature | 0x40; // temperature | 0x40 - index00_work[0] = COG_initialData[0] | 0x10; // PSR0 | 0x10 - index00_work[1] = COG_initialData[1] | 0x02; // PSR1 | 0x02 - } - else // Common settings - { - indexE5_work = u_temperature; // Temperature - index00_work[0] = COG_initialData[0]; // PSR0 - index00_work[1] = COG_initialData[1]; // PSR1 - } // u_codeExtra updateMode + switch (updateMode) + { + case UPDATE_FAST: - // New algorithm - b_sendCommandData8(0x00, 0x0e); // Soft-reset - b_waitBusy(); + indexTemperature = (u_temperature < 22) ? 0xc9 : 0xca; + break; - b_sendCommandData8(0xe5, indexE5_work); // Input Temperature - b_sendCommandData8(0xe0, 0x02); // Activate Temperature + case UPDATE_GLOBAL: - if (u_codeSize == SIZE_290) // No PSR - { - b_sendCommandData8(0x4d, 0x55); - b_sendCommandData8(0xe9, 0x02); - } - else - { - b_sendIndexData(0x00, index00_work, 2); // PSR - } + indexTemperature = 2 * u_temperature + 0x50; // Temperature 0x82@25C + // indexTemperature = (u_temperature > 50) ? 0xb4 : indexTemperature; + indexTemperature = checkRange(indexTemperature, (uint8_t)0x50, (uint8_t)0xb4); + break; + + default: + + break; + } + + case eScreen_EPD_581_PS_0B: - // Specific settings for fast update, all screens - // if (((u_codeFilm == FILM_P) or (u_codeFilm == FILM_K)) and (updateMode != UPDATE_GLOBAL)) - // FILM_P and FILM_K already checked - if (updateMode != UPDATE_GLOBAL) + switch (updateMode) + { + case UPDATE_FAST: + + indexTemperature = (u_temperature + 0x28) + 0x80; + break; + + case UPDATE_GLOBAL: + + indexTemperature = u_temperature + 0x28; // Temperature 0x41@25C + // indexTemperature = (u_temperature > 50) ? 0x5a : indexTemperature; + // indexTemperature = (u_temperature < 0) ? 0x28 : indexTemperature; + indexTemperature = checkRange(indexTemperature, (uint8_t)0x28, (uint8_t)0x5a); + break; + + default: + + break; + } + break; + + case eScreen_EPD_581_KS_0B: + + switch (updateMode) + { + case UPDATE_FAST: + + indexTemperature = (u_temperature + 0x28) + 0x80; + // indexTemperature = (u_temperature > 50) ? 0xda : indexTemperature; + // indexTemperature = (u_temperature < 0) ? 0xa8 : indexTemperature; + indexTemperature = checkRange(indexTemperature, (uint8_t)0xa8, (uint8_t)0xda); + break; + + case UPDATE_GLOBAL: + + indexTemperature = u_temperature + 0x28; // Temperature 0x41@25C + // indexTemperature = (u_temperature > 60) ? 0x64 : indexTemperature; + // indexTemperature = (u_temperature < -15) ? 0x19 : indexTemperature; + indexTemperature = checkRange(indexTemperature, (uint8_t)0x19, (uint8_t)0x64); + break; + + default: + + break; + } + break; + + default: + + break; + } + + b_sendCommandData8(0x44, 0x06); + b_sendCommandData8(0x45, indexTemperature); + + b_sendCommandData8(0xa7, 0x10); + delay(2); + b_sendCommandData8(0xa7, 0x00); + delay(10); + + b_sendCommandData8(0x60, COG_data[0x0b]); // TCON + b_sendCommandData8(0x61, COG_data[0x1b]); // STV_DIR + // No DCTL here + b_sendCommandData8(0x02, COG_data[0x11]); // VCOM + switch (u_eScreen_EPD) + { + case eScreen_EPD_581_KS_0B: + + b_sendCommandData8(0x03, COG_data[0x1f]); // VCOM_CTRL + break; + + default: + + break; + } + + // DC/DC Soft-start + // Application note § 3.3 DC/DC soft-start + // DRIVER_B = 0x28, DRIVER_8 = 0x20 + uint8_t offsetFrame = 0x28; + + // Filter for register 0x09 + uint8_t _filter09 = 0xff; + + switch (u_eScreen_EPD) + { + case eScreen_EPD_343_PS_0B: + case eScreen_EPD_343_PS_0B_Touch: + + _filter09 = 0xfb; + break; + + default: + + _filter09 = 0xff; + break; + } + + for (uint8_t stage = 0; stage < 4; stage += 1) + { + uint8_t offset = offsetFrame + 0x08 * stage; + uint8_t FORMAT = COG_data[offset] & 0x80; + uint8_t REPEAT = COG_data[offset] & 0x7f; + + if (FORMAT > 0) // Format 1 { - b_sendCommandData8(0x50, 0x07); // Vcom and data interval setting + uint8_t PHL_PHH[2]; + PHL_PHH[0] = COG_data[offset + 1]; // PHL_INI + PHL_PHH[1] = COG_data[offset + 2]; // PHH_INI + uint8_t PHL_VAR = COG_data[offset + 3]; + uint8_t PHH_VAR = COG_data[offset + 4]; + uint8_t BST_SW_a = COG_data[offset + 5] & _filter09; + uint8_t BST_SW_b = COG_data[offset + 6] & _filter09; + uint8_t DELAY_SCALE = COG_data[offset + 7] & 0x80; + uint16_t DELAY_VALUE = COG_data[offset + 7] & 0x7f; + + for (uint8_t i = 0; i < REPEAT; i += 1) + { + b_sendCommandData8(0x09, BST_SW_a); + PHL_PHH[0] += PHL_VAR; // PHL + PHL_PHH[1] += PHH_VAR; // PHH + b_sendIndexData(0x51, PHL_PHH, 2); + b_sendCommandData8(0x09, BST_SW_b); + + if (DELAY_SCALE > 0) + { + delay(DELAY_VALUE); // ms + } + else + { + delayMicroseconds(10 * DELAY_VALUE); //10 us + } + } } - - // Additional settings for fast update, 154 213 266 and 370 screens (s_flag50) - // if (((u_codeFilm == FILM_P) or (u_codeFilm == FILM_K)) and (updateMode != UPDATE_GLOBAL) and s_flag50) - // FILM_P and FILM_K already checked - if ((updateMode != UPDATE_GLOBAL) and s_flag50) + else // Format 2 { - b_sendCommandData8(0x50, 0x27); // Vcom and data interval setting + uint8_t BST_SW_a = COG_data[offset + 1] & _filter09; + uint8_t BST_SW_b = COG_data[offset + 2] & _filter09; + uint8_t DELAY_a_SCALE = COG_data[offset + 3] & 0x80; + uint16_t DELAY_a_VALUE = COG_data[offset + 3] & 0x7f; + uint8_t DELAY_b_SCALE = COG_data[offset + 4] & 0x80; + uint16_t DELAY_b_VALUE = COG_data[offset + 4] & 0x7f; + + for (uint8_t i = 0; i < REPEAT; i += 1) + { + b_sendCommandData8(0x09, BST_SW_a); + + if (DELAY_a_SCALE > 0) + { + delay(DELAY_a_VALUE); // ms + } + else + { + delayMicroseconds(10 * DELAY_a_VALUE); // 10 us + } + + b_sendCommandData8(0x09, BST_SW_b); + + if (DELAY_b_SCALE > 0) + { + delay(DELAY_b_VALUE); // ms + } + else + { + delayMicroseconds(10 * DELAY_b_VALUE); // 10 us + } + } } } + + // Display Refresh Start + // Application note § 4 Send updating command + b_waitBusy(); + b_sendCommandData8(0x15, 0x3c); } -void Screen_EPD_EXT3_Fast::COG_getDataOTP() +void Screen_EPD_EXT3_Fast::COG_MediumKP_powerOff() { -#if defined(ARDUINO_FEATHER_ESP32) + // Application note § 5. Turn-off DC/DC - hV_HAL_SPI3_define(SCK, MOSI) // SCK SDA + // DC-DC off + b_waitBusy(); -#elif defined(ARDUINO_XIAO_ESP32C3) - - // Board Xiao ESP32-C3 crashes if pins are not specified. - hV_HAL_SPI3_define(8, 9) // SCK SDA - -#elif defined(ARDUINO_NANO_ESP32) + switch (u_eScreen_EPD) + { + case eScreen_EPD_343_PS_0B: + case eScreen_EPD_343_PS_0B_Touch: + case eScreen_EPD_581_PS_0B: + + b_sendCommandData8(0x09, 0x7b); + b_sendCommandData8(0x05, 0x5d); + b_sendCommandData8(0x09, 0x7a); + delay(15); + b_sendCommandData8(0x09, 0x00); + break; - // Board Arduino Nano ESP32 arduino_nano_nora v2.0.11 - hV_HAL_SPI3_define(SCK, MOSI) // SCK SDA + case eScreen_EPD_581_KS_0B: -#elif defined(ARDUINO_ARCH_ESP32) + b_sendCommandData8(0x09, 0x7f); + b_sendCommandData8(0x05, 0x3d); + b_sendCommandData8(0x09, 0x7e); + delay(60); + b_sendCommandData8(0x09, 0x00); + break; - // void begin(int8_t sck=-1, int8_t miso=-1, int8_t mosi=-1, int8_t ss=-1); - // Board ESP32-Pico-DevKitM-2 crashes if pins are not specified. - hV_HAL_SPI3_define(14, 12) // SCK SDA + default: -#else + break; + } +} +// +// --- End of Medium screens with K or P film +// - hV_HAL_SPI3_define(SCK, MOSI); // SCK SDA +// +// --- Small screens with K or P film +// +void Screen_EPD_EXT3_Fast::COG_SmallKP_reset() +{ + // Application note § 2. Power on COG driver + b_reset(5, 5, 10, 5, 5); // small +} -#endif // ARDUINO +void Screen_EPD_EXT3_Fast::COG_SmallKP_getDataOTP() +{ + // Read OTP + uint8_t ui8 = 0; + uint16_t _readBytes = 0; + u_flagOTP = false; // Application note § 3. Read OTP memory // Register 0x50 flag @@ -202,20 +503,31 @@ void Screen_EPD_EXT3_Fast::COG_getDataOTP() } // Screens with no OTP - if ((u_eScreen_EPD == eScreen_EPD_290_KS_0F) or (u_eScreen_EPD == eScreen_EPD_150_KS_0J) or (u_eScreen_EPD == eScreen_EPD_152_KS_0J)) + switch (u_eScreen_EPD) { - u_flagOTP = true; - return; // No PSR + case eScreen_EPD_150_KS_0J: + case eScreen_EPD_152_KS_0J: + case eScreen_EPD_290_KS_0F: + + u_flagOTP = true; + mySerial.println("hV . OTP check passed - embedded PSR"); + return; // No PSR + break; + + default: + + break; } // GPIO - COG_reset(); // Although not mentioned, reset to ensure stable state + COG_SmallKP_reset(); // Although not mentioned, reset to ensure stable state // Read OTP - uint8_t ui8 = 0; + _readBytes = 2; + ui8 = 0; + uint16_t offsetA5 = 0x0000; uint16_t offsetPSR = 0x0000; - uint16_t u_readBytes = 2; digitalWrite(b_pin.panelDC, LOW); // Command digitalWrite(b_pin.panelCS, LOW); // Select @@ -227,7 +539,7 @@ void Screen_EPD_EXT3_Fast::COG_getDataOTP() digitalWrite(b_pin.panelCS, LOW); // Select ui8 = hV_HAL_SPI3_read(); // Dummy digitalWrite(b_pin.panelCS, HIGH); // Unselect - // hV_HAL_log(LEVEL_DEBUG, "Dummy read 0x%02x", ui8); + // mySerial.println, "hV . Dummy read 0x%02x", ui8); digitalWrite(b_pin.panelCS, LOW); // Select ui8 = hV_HAL_SPI3_read(); // First byte to be checked @@ -247,27 +559,20 @@ void Screen_EPD_EXT3_Fast::COG_getDataOTP() if (bank > 0) { - COG_initialData[0] = 0xcf; - COG_initialData[1] = 0x82; + COG_data[0] = 0xcf; + COG_data[1] = 0x82; return; } break; case eScreen_EPD_271_PS_09: + // case eScreen_EPD_271_KS_09_Touch: case eScreen_EPD_271_PS_09_Touch: - // case eScreen_EPD_287_KS_09: case eScreen_EPD_287_PS_09: offsetPSR = 0x004b; offsetA5 = 0x0000; - if (bank > 0) - { - mySerial.println(); - mySerial.println(formatString("hV * OTP check failed - Bank %i, first 0x%02x, expected 0x%02x", bank, ui8, 0xa5)); - mySerial.flush(); - while (true); - } break; case eScreen_EPD_154_KS_0C: @@ -275,6 +580,7 @@ void Screen_EPD_EXT3_Fast::COG_getDataOTP() case eScreen_EPD_266_KS_0C: case eScreen_EPD_266_PS_0C: case eScreen_EPD_271_KS_0C: // 2.71(A) + case eScreen_EPD_350_KS_0C: case eScreen_EPD_370_KS_0C: case eScreen_EPD_370_PS_0C: case eScreen_EPD_370_PS_0C_Touch: @@ -331,7 +637,22 @@ void Screen_EPD_EXT3_Fast::COG_getDataOTP() } } - mySerial.println(formatString("hV . OTP check passed - Bank %i, first 0x%02x as expected", bank, ui8)); + switch (u_eScreen_EPD) + { + case eScreen_EPD_271_KS_09: + case eScreen_EPD_271_PS_09: + case eScreen_EPD_271_PS_09_Touch: + // case eScreen_EPD_287_KS_09: + case eScreen_EPD_287_PS_09: + + mySerial.println(formatString("hV . OTP check passed - Bank %i, first 0x%02x %s", bank, ui8, (bank == 0) ? "as expected" : "not checked")); + break; + + default: + + mySerial.println(formatString("hV . OTP check passed - Bank %i, first 0x%02x as expected", bank, ui8)); + break; + } // Ignore bytes 1..offsetPSR for (uint16_t index = offsetA5 + 1; index < offsetPSR; index += 1) @@ -341,110 +662,178 @@ void Screen_EPD_EXT3_Fast::COG_getDataOTP() digitalWrite(b_pin.panelCS, HIGH); // Unselect } - // Populate COG_initialData - for (uint16_t index = 0; index < u_readBytes; index += 1) + // Populate COG_data + for (uint16_t index = 0; index < _readBytes; index += 1) { digitalWrite(b_pin.panelCS, LOW); // Select ui8 = hV_HAL_SPI3_read(); // Read OTP - COG_initialData[index] = ui8; + COG_data[index] = ui8; digitalWrite(b_pin.panelCS, HIGH); // Unselect } u_flagOTP = true; +} - // Debug COG_initialData -#if (DEBUG_OTP == 1) - uint8_t debugIndex = u_readBytes; - - mySerial.print(formatString("const uint8_t COG_initialData[%i] =", debugIndex)); - mySerial.println(); - mySerial.print("{"); - for (uint16_t index = 0; index < debugIndex; index += 1) +void Screen_EPD_EXT3_Fast::COG_SmallKP_initial(uint8_t updateMode) +{ + // Application note § 4. Input initial command + switch (u_eScreen_EPD) { - if ((index % 8) == 0) - { - mySerial.println(); - mySerial.print(" "); - } + case eScreen_EPD_150_KS_0J: + case eScreen_EPD_152_KS_0J: - mySerial.print(formatString("0x%02x", COG_initialData[index])); - mySerial.print(formatString("%s ", (index + 1 < debugIndex ? "," : " "))); // no comma on last value + // Soft reset + b_sendCommand8(0x12); + digitalWrite(b_pin.panelDC, LOW); + b_waitBusy(LOW); // 150 and 152 specific - if (((index + 1) % 8) == 0) - { - mySerial.print(formatString(" // 0x%04x..%04x", index - 7, index)); - } - } - mySerial.println(); + // Work settings + b_sendCommandData8(0x1a, u_temperature); - mySerial.print(formatString("} // %i", debugIndex)); - mySerial.println(); -#endif // DEBUG_OTP + if (updateMode == UPDATE_GLOBAL) + { + b_sendCommandData8(0x22, 0xd7); + } + else if (updateMode == UPDATE_FAST) + { + b_sendCommandData8(0x3c, 0xc0); + b_sendCommandData8(0x22, 0xdf); + } + break; + + default: + + // Work settings + uint8_t indexTemperature; // Temperature + uint8_t index00_work[2]; // PSR + + // FILM_P and FILM_K already checked + if (updateMode != UPDATE_GLOBAL) // Specific settings for fast update + { + indexTemperature = u_temperature | 0x40; // temperature | 0x40 + index00_work[0] = COG_data[0] | 0x10; // PSR0 | 0x10 + index00_work[1] = COG_data[1] | 0x02; // PSR1 | 0x02 + } + else // Common settings + { + indexTemperature = u_temperature; // Temperature + index00_work[0] = COG_data[0]; // PSR0 + index00_work[1] = COG_data[1]; // PSR1 + } // u_codeExtra updateMode + + // New algorithm + b_sendCommandData8(0x00, 0x0e); // Soft-reset + b_waitBusy(); + + b_sendCommandData8(0xe5, indexTemperature); // Input Temperature + b_sendCommandData8(0xe0, 0x02); // Activate Temperature + + if (u_codeSize == SIZE_290) // No PSR + { + b_sendCommandData8(0x4d, 0x55); + b_sendCommandData8(0xe9, 0x02); + } + else + { + b_sendIndexData(0x00, index00_work, 2); // PSR + } + + // Specific settings for fast update, all screens + // FILM_P and FILM_K already checked + if (updateMode != UPDATE_GLOBAL) + { + b_sendCommandData8(0x50, 0x07); // Vcom and data interval setting + } + break; + } } -void Screen_EPD_EXT3_Fast::COG_sendImageDataFast() +void Screen_EPD_EXT3_Fast::COG_SmallKP_sendImageData(uint8_t updateMode) { // Application note § 5. Input image to the EPD - uint8_t * nextBuffer = u_newImage; - uint8_t * previousBuffer = u_newImage + u_pageColourSize; + FRAMEBUFFER_TYPE nextBuffer = s_newImage; + FRAMEBUFFER_TYPE previousBuffer = s_newImage + u_pageColourSize; - if ((u_eScreen_EPD == eScreen_EPD_150_KS_0J) or (u_eScreen_EPD == eScreen_EPD_152_KS_0J)) - { - b_sendIndexData(0x24, previousBuffer, u_frameSize); // Previous frame - b_sendIndexData(0x26, nextBuffer, u_frameSize); // Next frame - } - else + // Send image data + // case UPDATE_FAST: + switch (u_eScreen_EPD) { - b_sendIndexData(0x10, previousBuffer, u_frameSize); // Previous frame - b_sendIndexData(0x13, nextBuffer, u_frameSize); // Next frame - } - memcpy(previousBuffer, nextBuffer, u_frameSize); // Copy displayed next to previous + case eScreen_EPD_150_KS_0J: + case eScreen_EPD_152_KS_0J: + + b_sendIndexData(0x24, previousBuffer, u_pageColourSize); // Next frame, blackBuffer + b_sendIndexData(0x26, nextBuffer, u_pageColourSize); // Previous frame, 0x00 + break; + + default: + // Additional settings for fast update, 154 213 266 370 and 437 screens (s_flag50) + if (s_flag50) + { + b_sendCommandData8(0x50, 0x27); // Vcom and data interval setting + } + + b_sendIndexData(0x10, previousBuffer, u_pageColourSize); // First frame, blackBuffer + b_sendIndexData(0x13, nextBuffer, u_pageColourSize); // Second frame, 0x00 + + // Additional settings for fast update, 154 213 266 370 and 437 screens (s_flag50) + if (s_flag50) + { + b_sendCommandData8(0x50, 0x07); // Vcom and data interval setting + } + break; + } // u_eScreen_EPD + + // Copy next frame to previous frame + memcpy(previousBuffer, nextBuffer, u_pageColourSize); // Copy displayed next to previous } -void Screen_EPD_EXT3_Fast::COG_update(uint8_t updateMode) +void Screen_EPD_EXT3_Fast::COG_SmallKP_update(uint8_t updateMode) { // Application note § 6. Send updating command - if ((u_eScreen_EPD == eScreen_EPD_150_KS_0J) or (u_eScreen_EPD == eScreen_EPD_152_KS_0J)) - { - b_waitBusy(LOW); // 152 specific - b_sendCommand8(0x20); // Display Refresh - digitalWrite(b_pin.panelCS, HIGH); // CS# = 1 - b_waitBusy(LOW); // 152 specific - } - else + switch (u_eScreen_EPD) { - // Specific settings for fast update, 154 213 266 and 370 screens (s_flag50) - // FILM_P and FILM_K already checked - if ((updateMode != UPDATE_GLOBAL) and s_flag50) + case eScreen_EPD_150_KS_0J: + case eScreen_EPD_152_KS_0J: - { - b_sendCommandData8(0x50, 0x07); // Vcom and data interval setting - } + b_waitBusy(LOW); // 152 specific + b_sendCommand8(0x20); // Display Refresh + digitalWrite(b_pin.panelCS, HIGH); // CS# = 1 + b_waitBusy(LOW); // 152 specific + break; + + default: - b_sendCommand8(0x04); // Power on - digitalWrite(b_pin.panelCS, HIGH); // CS# = 1 - b_waitBusy(); + b_waitBusy(); - b_sendCommand8(0x12); // Display Refresh - digitalWrite(b_pin.panelCS, HIGH); // CS# = 1 - b_waitBusy(); + b_sendCommand8(0x04); // Power on + b_waitBusy(); + + b_sendCommand8(0x12); // Display Refresh + b_waitBusy(); + break; } } -void Screen_EPD_EXT3_Fast::COG_powerOff() +void Screen_EPD_EXT3_Fast::COG_SmallKP_powerOff() { // Application note § 7. Turn-off DC/DC - if ((u_eScreen_EPD == eScreen_EPD_150_KS_0J) or (u_eScreen_EPD == eScreen_EPD_152_KS_0J)) - { - // Empty - } - else + switch (u_eScreen_EPD) { - b_sendCommand8(0x02); // Turn off DC/DC - digitalWrite(b_pin.panelCS, HIGH); // CS# = 1 - b_waitBusy(); + case eScreen_EPD_150_KS_0J: + case eScreen_EPD_152_KS_0J: + + break; + + default: + + b_sendCommand8(0x02); // Turn off DC/DC + b_waitBusy(); + break; } } +// +// --- End of Small screens with K or P film +// /// @endcond // // === End of COG section @@ -457,12 +846,13 @@ Screen_EPD_EXT3_Fast::Screen_EPD_EXT3_Fast(eScreen_EPD_t eScreen_EPD_EXT3, pins_ { u_eScreen_EPD = eScreen_EPD_EXT3; b_pin = board; - u_newImage = 0; // nullptr - COG_initialData[0] = 0; + s_newImage = 0; // nullptr + COG_data[0] = 0; } void Screen_EPD_EXT3_Fast::begin() { + // u_eScreen_EPD = eScreen_EPD_EXT3; u_codeSize = SCREEN_SIZE(u_eScreen_EPD); u_codeFilm = SCREEN_FILM(u_eScreen_EPD); u_codeDriver = SCREEN_DRIVER(u_eScreen_EPD); @@ -472,22 +862,29 @@ void Screen_EPD_EXT3_Fast::begin() // Checks switch (u_codeFilm) { - case FILM_P: // BWR, fast update - case FILM_K: // BWR, fast update and wide temperature + case FILM_P: // BW, fast update + case FILM_K: // BW, fast update and wide temperature break; default: - mySerial.println(); - mySerial.println(formatString("hV * Screen %i-%cS-0%c with no fast update", u_codeSize, u_codeFilm, u_codeDriver)); - while (0x01); + debugVariant(FILM_P); break; } + // Check panelCSS for large screens + if (((u_codeSize == SIZE_969) or (u_codeSize == SIZE_1198)) and (b_pin.panelCSS == NOT_CONNECTED)) + { + mySerial.println(); + mySerial.println("hV * Required pin panelCSS is NOT_CONNECTED"); + while (0x01); + } + // Configure board switch (u_codeSize) { + case SIZE_343: // 3.43" case SIZE_581: // 5.81" case SIZE_741: // 7.41" @@ -558,6 +955,18 @@ void Screen_EPD_EXT3_Fast::begin() v_screenSizeH = 168; // horizontal = small size break; + case SIZE_343: // 3.43" and 3.43"-Touch + + v_screenSizeV = 392; // vertical = wide size + v_screenSizeH = 456; // horizontal = small size + break; + + case SIZE_350: // 3.50" + + v_screenSizeV = 384; // vertical = wide size + v_screenSizeH = 168; // horizontal = small size + break; + case SIZE_370: // 3.70" and 3.70"-Touch v_screenSizeV = 416; // vertical = wide size @@ -576,7 +985,7 @@ void Screen_EPD_EXT3_Fast::begin() v_screenSizeH = 176; // horizontal = small size break; - // Those screens are not available with embedded fast update + // Those screens are not available with embedded fast update or wide temperature // case SIZE_565: // 5.65" // // v_screenSizeV = 600; // v = wide size @@ -630,43 +1039,27 @@ void Screen_EPD_EXT3_Fast::begin() // Actually for 1 colour; BWR requires 2 pages. u_pageColourSize = (uint32_t)u_bufferSizeV * (uint32_t)u_bufferSizeH; - // u_frameSize = u_pageColourSize, except for 9.69 and 11.98 - // 9.69 and 11.98 combine two half-screens, hence two frames with adjusted size - switch (u_codeSize) - { - case SIZE_969: // 9.69" - case SIZE_1198: // 11.98" - - u_frameSize = u_pageColourSize / 2; - break; - - default: - - u_frameSize = u_pageColourSize; - break; - } // u_codeSize - #if defined(BOARD_HAS_PSRAM) // ESP32 PSRAM specific case - if (u_newImage == 0) + if (s_newImage == 0) { static uint8_t * _newFrameBuffer; _newFrameBuffer = (uint8_t *) ps_malloc(u_pageColourSize * u_bufferDepth); - u_newImage = (uint8_t *) _newFrameBuffer; + s_newImage = (uint8_t *) _newFrameBuffer; } #else // default case - if (u_newImage == 0) + if (s_newImage == 0) { static uint8_t * _newFrameBuffer; _newFrameBuffer = new uint8_t[u_pageColourSize * u_bufferDepth]; - u_newImage = (uint8_t *) _newFrameBuffer; + s_newImage = (uint8_t *) _newFrameBuffer; } #endif // ESP32 BOARD_HAS_PSRAM - memset(u_newImage, 0x00, u_pageColourSize * u_bufferDepth); + memset(s_newImage, 0x00, u_pageColourSize * u_bufferDepth); // Turn SPI on, initialise GPIOs and set GPIO levels // Reset panel and get tables @@ -674,6 +1067,7 @@ void Screen_EPD_EXT3_Fast::begin() // Fonts hV_Screen_Buffer::begin(); // Standard + if (f_fontMax() > 0) { f_selectFont(0); @@ -687,9 +1081,12 @@ void Screen_EPD_EXT3_Fast::begin() u_invert = false; setTemperatureC(25); // 25 Celsius = 77 Fahrenheit + + // Turn SPI off and pull GPIOs low + suspend(); } -String Screen_EPD_EXT3_Fast::WhoAmI() +STRING_TYPE Screen_EPD_EXT3_Fast::WhoAmI() { char work[64] = {0}; u_WhoAmI(work); @@ -697,41 +1094,136 @@ String Screen_EPD_EXT3_Fast::WhoAmI() return formatString("iTC %i.%02i\"%s", v_screenDiagonal / 100, v_screenDiagonal % 100, work); } +void Screen_EPD_EXT3_Fast::suspend() +{ + // Suspend GPIO + b_suspend(); + + // Suspend SPI + hV_HAL_SPI_end(); +} + void Screen_EPD_EXT3_Fast::resume() { + // Resume GPIO b_resume(); // Check type and get tables if (u_flagOTP == false) { hV_HAL_SPI3_begin(); // Define 3-wire SPI pins - COG_getDataOTP(); // 3-wire SPI read OTP memory + s_getDataOTP(); // 3-wire SPI read OTP memory } // Reset - COG_reset(); + s_reset(); // Check after reset - if ((u_eScreen_EPD == eScreen_EPD_150_KS_0J) or (u_eScreen_EPD == eScreen_EPD_152_KS_0J)) + switch (u_eScreen_EPD) { - if (digitalRead(b_pin.panelBusy) == HIGH) - { - mySerial.println(); - mySerial.println("hV * Incorrect type for 1.52-Wide"); - while(0x01); - } + case eScreen_EPD_150_KS_0J: + case eScreen_EPD_152_KS_0J: + + if (digitalRead(b_pin.panelBusy) == HIGH) + { + mySerial.println(); + mySerial.println("hV * Incorrect type for 1.52-Wide"); + while (0x01); + } + break; + + default: + + break; } - // Start SPI and Wire - if ((u_eScreen_EPD == eScreen_EPD_150_KS_0J) or (u_eScreen_EPD == eScreen_EPD_152_KS_0J)) + // Start SPI + switch (u_eScreen_EPD) { - hV_HAL_SPI_begin(16000000); // 1.52" tested with 4, 8, 16 and 32 MHz + case eScreen_EPD_150_KS_0J: + case eScreen_EPD_152_KS_0J: + + hV_HAL_SPI_begin(16000000); // 1.52" tested with 4, 8, 16 and 32 MHz + break; + + default: + + hV_HAL_SPI_begin(); // Standard 8 MHz + break; } - else +} + +void Screen_EPD_EXT3_Fast::s_reset() +{ + switch (b_family) { - hV_HAL_SPI_begin(); // Standard 8 MHz + case FAMILY_MEDIUM: + + COG_MediumKP_reset(); + break; + + case FAMILY_SMALL: + + COG_SmallKP_reset(); + break; + + default: + + break; + } +} + +void Screen_EPD_EXT3_Fast::s_getDataOTP() +{ + uint16_t _readBytes = 0; + switch (b_family) + { + case FAMILY_MEDIUM: + + COG_MediumKP_getDataOTP(); + break; + + case FAMILY_SMALL: + + COG_SmallKP_getDataOTP(); + break; + + default: + + break; + } +} + +void Screen_EPD_EXT3_Fast::s_flush(uint8_t updateMode) +{ + // Turn SPI on, initialise GPIOs and set GPIO levels + resume(); + + switch (b_family) + { + case FAMILY_MEDIUM: + + COG_MediumKP_initial(updateMode); // Initialise + COG_MediumKP_sendImageData(updateMode); // Send image data + COG_MediumKP_update(updateMode); // Update + COG_MediumKP_powerOff(); // Power off + break; + + case FAMILY_SMALL: + + COG_SmallKP_initial(updateMode); // Initialise + COG_SmallKP_sendImageData(updateMode); // Send image data + COG_SmallKP_update(updateMode); // Update + COG_SmallKP_powerOff(); // Power off + break; + + default: + + break; } - // hV_HAL_Wire_begin(); + + // Turn SPI off and pull GPIOs low + suspend(); } uint8_t Screen_EPD_EXT3_Fast::flushMode(uint8_t updateMode) @@ -743,7 +1235,7 @@ uint8_t Screen_EPD_EXT3_Fast::flushMode(uint8_t updateMode) case UPDATE_FAST: case UPDATE_GLOBAL: - s_flushFast(); + s_flush(UPDATE_FAST); break; default: @@ -761,20 +1253,6 @@ void Screen_EPD_EXT3_Fast::flush() flushMode(UPDATE_FAST); } -void Screen_EPD_EXT3_Fast::s_flushFast() -{ - // Configure - COG_initial(UPDATE_FAST); - - // Send image data - COG_sendImageDataFast(); - - // Update - COG_update(UPDATE_FAST); - - COG_powerOff(); -} - void Screen_EPD_EXT3_Fast::clear(uint16_t colour) { if (colour == myColours.grey) @@ -785,19 +1263,19 @@ void Screen_EPD_EXT3_Fast::clear(uint16_t colour) uint8_t pattern = (i % 2) ? 0b10101010 : 0b01010101; for (uint16_t j = 0; j < u_bufferSizeH; j++) { - u_newImage[i * u_bufferSizeH + j] = pattern; + s_newImage[i * u_bufferSizeH + j] = pattern; } } } else if ((colour == myColours.white) xor u_invert) { // physical black 0-0 - memset(u_newImage, 0x00, u_pageColourSize); + memset(s_newImage, 0x00, u_pageColourSize); } else { // physical white 1-0 - memset(u_newImage, 0xff, u_pageColourSize); + memset(s_newImage, 0xff, u_pageColourSize); } } @@ -843,12 +1321,12 @@ void Screen_EPD_EXT3_Fast::s_setPoint(uint16_t x1, uint16_t y1, uint16_t colour) if ((colour == myColours.white) xor u_invert) { // physical black 0-0 - bitClear(u_newImage[z1], b1); + bitClear(s_newImage[z1], b1); } else if ((colour == myColours.black) xor u_invert) { // physical white 1-0 - bitSet(u_newImage[z1], b1); + bitSet(s_newImage[z1], b1); } } @@ -954,7 +1432,7 @@ uint16_t Screen_EPD_EXT3_Fast::s_getPoint(uint16_t x1, uint16_t y1) uint32_t z1 = s_getZ(x1, y1); uint16_t b1 = s_getB(x1, y1); - _value = bitRead(u_newImage[z1], b1); + _value = bitRead(s_newImage[z1], b1); _value <<= 4; _value &= 0b11110000; diff --git a/src/Screen_EPD_EXT3.h b/src/Screen_EPD_EXT3.h index f6df998..5544e3b 100755 --- a/src/Screen_EPD_EXT3.h +++ b/src/Screen_EPD_EXT3.h @@ -26,8 +26,8 @@ /// * 4.37 reference xE2437PS0Cx /// /// @author Rei Vilo -/// @date 21 Mar 2024 -/// @version 801 +/// @date 21 May 2024 +/// @version 803 /// /// @copyright (c) Rei Vilo, 2010-2024 /// @copyright All rights reserved @@ -73,8 +73,8 @@ #error Required hV_HAL_PERIPHERALS_RELEASE 801 #endif // hV_HAL_PERIPHERALS_RELEASE -#if (hV_CONFIGURATION_RELEASE < 801) -#error Required hV_CONFIGURATION_RELEASE 801 +#if (hV_CONFIGURATION_RELEASE < 803) +#error Required hV_CONFIGURATION_RELEASE 803 #endif // hV_CONFIGURATION_RELEASE #if (hV_SCREEN_BUFFER_RELEASE < 801) @@ -89,20 +89,13 @@ /// /// @brief Library release number /// -#define SCREEN_EPD_EXT3_RELEASE 801 +#define SCREEN_EPD_EXT3_RELEASE 803 /// /// @brief Library variant /// #define SCREEN_EPD_EXT3_VARIANT "Basic-Fast" -// Other libraries -#include "hV_Screen_Buffer.h" - -#if (hV_SCREEN_BUFFER_RELEASE < 801) -#error Required hV_SCREEN_BUFFER_RELEASE 801 -#endif // hV_SCREEN_BUFFER_RELEASE - /// /// @name Constants for features /// @{ @@ -141,6 +134,12 @@ class Screen_EPD_EXT3_Fast final : public hV_Screen_Buffer, public hV_Utilities_ /// void begin(); + /// + /// @brief Suspend + /// @details Turn SPI off and set all GPIOs low + /// + void suspend(); + /// /// @brief Resume after suspend() /// @details Turn SPI on and set all GPIOs levels @@ -151,7 +150,7 @@ class Screen_EPD_EXT3_Fast final : public hV_Screen_Buffer, public hV_Utilities_ /// @brief Who Am I /// @return Who Am I string /// - String WhoAmI(); + virtual STRING_TYPE WhoAmI(); /// /// @brief Clear the screen @@ -220,12 +219,28 @@ class Screen_EPD_EXT3_Fast final : public hV_Screen_Buffer, public hV_Utilities_ /// uint16_t s_getPoint(uint16_t x1, uint16_t y1); + /// + /// @brief Reset the screen + /// + void s_reset(); + + /// + /// @brief Get data from OTP + /// + void s_getDataOTP(); + + /// + /// @brief Update the screen + /// @param updateMode update mode, default = UPDATE_FAST, otherwise UPDATE_GLOBAL + /// + void s_flush(uint8_t updateMode = UPDATE_FAST); + // Position /// /// @brief Convert /// @param x1 x-axis coordinate /// @param y1 y-axis coordinate - /// @return index for u_newImage[] + /// @return index for s_newImage[] /// uint32_t s_getZ(uint16_t x1, uint16_t y1); @@ -233,7 +248,7 @@ class Screen_EPD_EXT3_Fast final : public hV_Screen_Buffer, public hV_Utilities_ /// @brief Convert /// @param x1 x-axis coordinate /// @param y1 y-axis coordinate - /// @return bit for u_newImage[] + /// @return bit for s_newImage[] /// uint16_t s_getB(uint16_t x1, uint16_t y1); @@ -246,17 +261,21 @@ class Screen_EPD_EXT3_Fast final : public hV_Screen_Buffer, public hV_Utilities_ // // * Other functions specific to the screen - uint8_t COG_initialData[128]; // OTP - - void COG_reset(); - void COG_initial(uint8_t updateMode); - void COG_getDataOTP(); - void COG_sendImageDataFast(); - void COG_update(uint8_t updateMode); - void COG_powerOff(); - - // * Flush - void s_flushFast(); + uint8_t COG_data[128]; // OTP + + void COG_MediumKP_reset(); + void COG_MediumKP_getDataOTP(); + void COG_MediumKP_initial(uint8_t updateMode); + void COG_MediumKP_sendImageData(uint8_t updateMode); + void COG_MediumKP_update(uint8_t updateMode); + void COG_MediumKP_powerOff(); + + void COG_SmallKP_reset(); + void COG_SmallKP_getDataOTP(); + void COG_SmallKP_initial(uint8_t updateMode); + void COG_SmallKP_sendImageData(uint8_t updateMode); + void COG_SmallKP_update(uint8_t updateMode); + void COG_SmallKP_powerOff(); bool s_flag50; // Register 0x50 diff --git a/src/hV_Board.cpp b/src/hV_Board.cpp index a416744..658d1a5 100755 --- a/src/hV_Board.cpp +++ b/src/hV_Board.cpp @@ -32,14 +32,14 @@ void hV_Board::b_begin(pins_t board, uint8_t family, uint16_t delayCS) void hV_Board::b_reset(uint32_t ms1, uint32_t ms2, uint32_t ms3, uint32_t ms4, uint32_t ms5) { - delay(ms1); // delay 5ms - digitalWrite(b_pin.panelReset, HIGH); // RES# = 1 - delay(ms2); // delay 5ms - digitalWrite(b_pin.panelReset, LOW); + delay(ms1); // Wait for power stabilisation + digitalWrite(b_pin.panelReset, HIGH); // RESET = HIGH + delay(ms2); + digitalWrite(b_pin.panelReset, LOW); // RESET = LOW delay(ms3); - digitalWrite(b_pin.panelReset, HIGH); + digitalWrite(b_pin.panelReset, HIGH); // RESET = HIGH delay(ms4); - digitalWrite(b_pin.panelCS, HIGH); // CS# = 1 + digitalWrite(b_pin.panelCS, HIGH); // CS = HIGH, unselect delay(ms5); } @@ -54,7 +54,11 @@ void hV_Board::b_waitBusy(bool state) void hV_Board::b_suspend() { - // Not implemented + // Optional power circuit + if (b_pin.panelPower != NOT_CONNECTED) // generic + { + digitalWrite(b_pin.panelPower, LOW); + } } void hV_Board::b_resume() @@ -115,7 +119,7 @@ void hV_Board::b_sendIndexFixed(uint8_t index, uint8_t data, uint32_t size) delayMicroseconds(b_delayCS); SPI.transfer(index); - delayMicroseconds(b_delayCS); + delayMicroseconds(b_delayCS); digitalWrite(b_pin.panelDC, HIGH); // DC High = Data diff --git a/src/hV_Board.h b/src/hV_Board.h index 75c8683..0a89267 100755 --- a/src/hV_Board.h +++ b/src/hV_Board.h @@ -164,12 +164,6 @@ class hV_Board /// void b_sendCommandDataSelect8(uint8_t command, uint8_t data, uint8_t select = PANEL_CS_BOTH); - /// @brief Select one half of large screens - /// @param select default = PANEL_CS_BOTH, otherwise PANEL_CS_MASTER or PANEL_CS_SLAVE - /// @note Valid only for 9.69 and 11.98" screens - /// - void b_select(uint8_t select = PANEL_CS_BOTH); - /// /// @brief Suspend /// @@ -184,6 +178,13 @@ class hV_Board uint16_t b_delayCS = 50; // ms uint8_t b_family; + private: + /// @brief Select one half of large screens + /// @param select default = PANEL_CS_BOTH, otherwise PANEL_CS_MASTER or PANEL_CS_SLAVE + /// @note Valid only for 9.69 and 11.98" screens + /// + void b_select(uint8_t select = PANEL_CS_BOTH); + /// @endcond }; diff --git a/src/hV_Common.h b/src/hV_Common.h index 8115a41..edc199e 100755 --- a/src/hV_Common.h +++ b/src/hV_Common.h @@ -6,8 +6,8 @@ /// @n Based on highView technology /// /// @author Rei Vilo -/// @date 21 Mar 2024 -/// @version 801 +/// @date 21 May 2024 +/// @version 803 /// /// @copyright (c) Rei Vilo, 2010-2024 /// @copyright All rights reserved @@ -36,7 +36,7 @@ /// /// @brief Library release number /// -#define hV_COMMON_RELEASE 801 +#define hV_COMMON_RELEASE 803 // SDK #include "hV_HAL_Peripherals.h" diff --git a/src/hV_Configuration.h b/src/hV_Configuration.h index 13f5837..b9d7ecf 100755 --- a/src/hV_Configuration.h +++ b/src/hV_Configuration.h @@ -19,8 +19,8 @@ /// * 11. Set storage mode, not implemented /// /// @author Rei Vilo -/// @date 21 Mar 2024 -/// @version 801 +/// @date 21 May 2024 +/// @version 803 /// /// @copyright (c) Rei Vilo, 2010-2024 /// @copyright All rights reserved @@ -65,8 +65,8 @@ #error Required hV_LIST_CONSTANTS_RELEASE 801 #endif // hV_LIST_CONSTANTS_RELEASE -#if (hV_LIST_OPTIONS_RELEASE < 801) -#error Required hV_LIST_OPTIONS_RELEASE 801 +#if (hV_LIST_OPTIONS_RELEASE < 803) +#error Required hV_LIST_OPTIONS_RELEASE 803 #endif // hV_LIST_OPTIONS_RELEASE #if (hV_LIST_BOARDS_RELEASE < 801) @@ -81,7 +81,7 @@ /// /// @brief Release /// -#define hV_CONFIGURATION_RELEASE 801 +#define hV_CONFIGURATION_RELEASE 803 /// /// @name 1- List of supported Pervasive Displays screens @@ -107,5 +107,18 @@ /// @see hV_List_Options.h /// +/// +/// @brief Type for framebuffer +/// @details Based on SRAM_MODE selection +/// +#define FRAMEBUFFER_TYPE uint8_t * + +/// +/// @brief Type for string +/// @details Based on STRING_MODE selection +/// +#define STRING_TYPE String +#define STRING_CONST_TYPE String + #endif // hV_CONFIGURATION_RELEASE diff --git a/src/hV_Documentation.h b/src/hV_Documentation.h index 40af983..2b0fc88 100755 --- a/src/hV_Documentation.h +++ b/src/hV_Documentation.h @@ -41,8 +41,8 @@ /// Additionally, the **[Wiki](https://docs.pervasivedisplays.com/)** provides a gradual introduction to the e-paper technology and how to use it. /// /// @author Rei Vilo -/// @date 21 Mar 2024 -/// @version 801 +/// @date 21 May 2024 +/// @version 803 /// /// @copyright (c) Rei Vilo, 2010-2024 /// @copyright All rights reserved diff --git a/src/hV_Font_Terminal.cpp b/src/hV_Font_Terminal.cpp index b214a9d..4a521a0 100755 --- a/src/hV_Font_Terminal.cpp +++ b/src/hV_Font_Terminal.cpp @@ -19,21 +19,27 @@ // * Commercial edition: for professionals or organisations, commercial usage // All rights reserved // +// Release 803: Added types for string and frame-buffer +// -#include "hV_Font_Terminal.h" +// Configuration +#include "hV_Configuration.h" // The Arduino IDE does not allow to select the libraries, hence this condition. #if (FONT_MODE == USE_FONT_TERMINAL) +// Font structure +#include "hV_Font_Terminal.h" + // Code // Font functions -//hV_Font_Terminal::hV_Font_Terminal() +// hV_Font_Terminal::hV_Font_Terminal() void hV_Font_Terminal::f_begin() { - f_fontSize = 0; - f_fontNumber = MAX_FONT_SIZE; - f_fontSolid = true; - f_fontSpaceX = 1; + f_fontSize = 0; + f_fontNumber = MAX_FONT_SIZE; + f_fontSolid = true; + f_fontSpaceX = 1; // Take first font f_selectFont(0); @@ -141,21 +147,33 @@ uint16_t hV_Font_Terminal::f_characterSizeY() return f_font.height; } -uint16_t hV_Font_Terminal::f_stringSizeX(String text) +uint16_t hV_Font_Terminal::f_stringSizeX(STRING_CONST_TYPE text) { - return (uint16_t) text.length() * f_font.maxWidth; + uint16_t textWidth = 0; + uint8_t textLength = 0; + + textLength = text.length(); + + textWidth = (f_font.maxWidth + f_fontSpaceX) * textLength; + + return textWidth; } -uint8_t hV_Font_Terminal::f_stringLengthToFitX(String text, uint16_t pixels) +uint8_t hV_Font_Terminal::f_stringLengthToFitX(STRING_CONST_TYPE text, uint16_t pixels) { uint8_t index = 0; + uint16_t textWidth = 0; + uint8_t textLength = 0; + + textLength = text.length(); // Monospaced font index = pixels / f_font.maxWidth - 1; - if (index > text.length()) + if (index > textLength) { - index = text.length(); + index = textLength; } + return index; } diff --git a/src/hV_Font_Terminal.h b/src/hV_Font_Terminal.h index 1e047e9..6e2a0ac 100755 --- a/src/hV_Font_Terminal.h +++ b/src/hV_Font_Terminal.h @@ -6,8 +6,8 @@ /// @n Based on highView technology /// /// @author Rei Vilo -/// @date 21 Mar 2024 -/// @version 801 +/// @date 21 May 2024 +/// @version 803 /// /// @copyright (c) Rei Vilo, 2010-2024 /// @copyright All rights reserved @@ -41,6 +41,14 @@ // Configuration #include "hV_Configuration.h" +// Utilities +#include "hV_Utilities_Common.h" + +// Checks +#if (hV_CONFIGURATION_RELEASE < 803) +#error Required hV_CONFIGURATION_RELEASE 803 +#endif // hV_CONFIGURATION_RELEASE + // The Arduino IDE does not allow to select the libraries, hence this condition. #if (FONT_MODE == USE_FONT_TERMINAL) @@ -87,6 +95,13 @@ enum fontNumber_e /// class hV_Font_Terminal { + // public: + // /// + // /// @brief Constructor + // /// + // hV_Font_Terminal(); + + /// @cond protected: /// /// @brief Initialisation @@ -157,7 +172,7 @@ class hV_Font_Terminal /// @return horizontal size of the string for current font, in pixels /// @n @b More: @ref Fonts /// - uint16_t f_stringSizeX(String text); + uint16_t f_stringSizeX(STRING_CONST_TYPE text); /// /// @brief Number of characters to fit a size, x-axis @@ -166,7 +181,7 @@ class hV_Font_Terminal /// @return number of characters to be displayed inside the pixels /// @n @b More: @ref Fonts /// - uint8_t f_stringLengthToFitX(String text, uint16_t pixels); + uint8_t f_stringLengthToFitX(STRING_CONST_TYPE text, uint16_t pixels); /// /// @brief Number of fonts @@ -188,7 +203,6 @@ class hV_Font_Terminal /// uint8_t f_getFontMaxWidth(); - protected: /// /// @brief Get definition for line of character /// @param character character 32~255 @@ -206,7 +220,7 @@ class hV_Font_Terminal uint8_t f_fontSize; ///< actual font selected uint8_t f_fontSpaceX; ///< pixels between two characters, horizontal axis uint8_t f_fontSpaceY; ///< pixels between two characters, vertical axis - bool f_fontSolid; ///< + bool f_fontSolid; ///< opaque print /// @} }; /// @endcond @@ -214,3 +228,4 @@ class hV_Font_Terminal #endif // USE_FONT_TERMINAL #endif // hV_FONT_TERMINAL_RELEASE + diff --git a/src/hV_HAL_Peripherals.cpp b/src/hV_HAL_Peripherals.cpp index 491fefc..38f624a 100644 --- a/src/hV_HAL_Peripherals.cpp +++ b/src/hV_HAL_Peripherals.cpp @@ -21,9 +21,15 @@ // // Release 800: Added 3-wire SPI // Release 801: Added SPI configuration +// Release 803: Improved stability +// +// Library header #include "hV_HAL_Peripherals.h" +// +// === General section +// #if defined(ENERGIA) /// /// @brief Proxy for SPISettings @@ -63,6 +69,9 @@ void hV_HAL_begin() { // Empty } +// +// === End of General section +// // // === SPI section @@ -100,6 +109,11 @@ void hV_HAL_SPI_begin(uint32_t speed) #endif // ENERGIA } + +void hV_HAL_SPI_end() +{ + SPI.end(); +} // // === End of SPI section // diff --git a/src/hV_HAL_Peripherals.h b/src/hV_HAL_Peripherals.h index eb36732..e234ceb 100755 --- a/src/hV_HAL_Peripherals.h +++ b/src/hV_HAL_Peripherals.h @@ -6,8 +6,8 @@ /// @n Based on highView technology /// /// @author Rei Vilo -/// @date 21 Mar 2024 -/// @version 801 +/// @date 21 May 2024 +/// @version 803 /// /// @copyright (c) Rei Vilo, 2010-2024 /// @copyright All rights reserved @@ -36,7 +36,7 @@ /// /// @brief Release /// -#define hV_HAL_PERIPHERALS_RELEASE 801 +#define hV_HAL_PERIPHERALS_RELEASE 803 /// /// @brief SDK library @@ -75,6 +75,11 @@ void hV_HAL_begin(); /// void hV_HAL_SPI_begin(uint32_t speed = 8000000); +/// +/// @brief End SPI +/// +void hV_HAL_SPI_end(); + /// /// @name 3-wire SPI bus /// @warning @@ -88,7 +93,7 @@ void hV_HAL_SPI_begin(uint32_t speed = 8000000); #define SCK 7 #define MOSI 15 -#endif // ENERGIA +#endif // ENERGIA /// /// @brief Configure 3-wire SPI @@ -100,6 +105,7 @@ void hV_HAL_SPI3_begin(); /// @brief Set the 3-wire SPI pins /// @param pinClock clock, default = SCK /// @param pinData combined data, default = MOSI +/// @note For manual configuration only /// void hV_HAL_SPI3_define(uint8_t pinClock = SCK, uint8_t pinData = MOSI); @@ -119,6 +125,8 @@ uint8_t hV_HAL_SPI3_read(); /// void hV_HAL_SPI3_write(uint8_t value); +/// @} + /// /// @name Wire bus /// diff --git a/src/hV_List_Boards.h b/src/hV_List_Boards.h index 9a1988f..99e8229 100755 --- a/src/hV_List_Boards.h +++ b/src/hV_List_Boards.h @@ -7,6 +7,10 @@ /// /// @n Content /// * 2- List of pre-configured boards +/// * 2.1 Recommended boards +/// * 2.2 Other boards +/// * 2.3 Deprecated boards +/// /// /// @author Rei Vilo /// @date 21 Mar 2024 @@ -42,7 +46,7 @@ /// /// @brief Release /// -#define hV_LIST_BOARDS_RELEASE 801 +#define hV_LIST_BOARDS_RELEASE 803 /// /// @brief Not connected pin @@ -76,9 +80,30 @@ struct pins_t }; /// -/// @name Recommended boards +/// @name 2.1 Recommended boards /// @{ +/// +/// @brief Arduino Nano Matter with Silicon Labs MGM240P, tested +/// @note Numbers refer to pins +/// @note Recommended board +/// +const pins_t boardArduinoNanoMatter = +{ + .panelBusy = 10, ///< EXT3 and EXT3-1 pin 3 Red -> D10 + .panelDC = 9, ///< EXT3 and EXT3-1 pin 4 Orange -> D9 + .panelReset = 8, ///< EXT3 and EXT3-1 pin 5 Yellow -> D8 + .flashCS = 7, ///< EXT3 and EXT3-1 pin 8 Violet -> D7 + .panelCS = 6, ///< EXT3 and EXT3-1 pin 9 Grey -> D6 + .panelCSS = NOT_CONNECTED, ///< EXT3 and EXT3-1 pin 12 Grey2 + .flashCSS = NOT_CONNECTED, ///< EXT3 pin 20 or EXT3-1 pin 11 Black2 + .touchInt = NOT_CONNECTED, ///< EXT3-Touch pin 3 Red + .touchReset = NOT_CONNECTED, ///< EXT3-Touch pin 4 Orange + .panelPower = 2, ///< Optional power circuit -> D2 + .cardCS = NOT_CONNECTED, ///< Separate SD-card board + .cardDetect = NOT_CONNECTED, ///< Separate SD-card board +}; + /// /// @brief Raspberry Pi Pico and Pico W with default RP2040 configuration, tested /// @note Numbers refer to GPIOs, not pins @@ -87,13 +112,9 @@ struct pins_t /// const pins_t boardRaspberryPiPico_RP2040 = { - ///< EXT3 and EXT3-1 pin 1 Black -> +3.3V - ///< EXT3 and EXT3-1 pin 2 Brown -> SPI SCK GP18 .panelBusy = 13, ///< EXT3 and EXT3-1 pin 3 Red -> GP13 .panelDC = 12, ///< EXT3 and EXT3-1 pin 4 Orange -> GP12 .panelReset = 11, ///< EXT3 and EXT3-1 pin 5 Yellow -> GP11 - ///< EXT3 and EXT3-1 pin 6 Green -> SPI MISO or NC GP16 - ///< EXT3 and EXT3-1 pin 7 Blue -> SPI MOSI or SDIO GP19 .flashCS = 10, ///< EXT3 and EXT3-1 pin 8 Violet -> GP10 .panelCS = 17, ///< EXT3 and EXT3-1 pin 9 Grey -> GP17 .panelCSS = 14, ///< EXT3 and EXT3-1 pin 12 Grey2 -> GP14 @@ -133,20 +154,13 @@ const pins_t boardFeatherNRF52840 = /// const pins_t boardESP32DevKitC = { - ///< EXT3 and EXT3-1 pin 1 Black -> +3.3V - ///< EXT3 and EXT3-1 pin 2 Brown -> SPI SCK GPIO14 .panelBusy = 27, ///< EXT3 and EXT3-1 pin 3 Red -> GPIO27 .panelDC = 26, ///< EXT3 and EXT3-1 pin 4 Orange -> GPIO26 .panelReset = 25, ///< EXT3 and EXT3-1 pin 5 Yellow -> GPIO25 - ///< EXT3 and EXT3-1 pin 6 Green -> SPI MISO GPIO12 - ///< EXT3 and EXT3-1 pin 7 Blue -> SPI MOSI GPIO13 .flashCS = 33, ///< EXT3 and EXT3-1 pin 8 Violet -> GPIO33 .panelCS = 32, ///< EXT3 and EXT3-1 pin 9 Grey -> GPIO32 .panelCSS = 4, ///< EXT3 and EXT3-1 pin 12 Grey2 -> GPIO4 .flashCSS = 0, ///< EXT3 pin 20 or EXT3-1 pin 11 Black2 -> GPIO0 - ///< EXT3 and EXT3-1 pin 10 White -> GROUND - ///< EXT3-Touch pin 1 Brown -> I2C SDA GPIO21 - ///< EXT3-Touch pin 2 Black -> I2C SCL GPIO22 .touchInt = NOT_CONNECTED, ///< EXT3-Touch pin 3 Red -> GPIO10 .touchReset = NOT_CONNECTED, ///< EXT3-Touch pin 4 Orange -> GPIO9 .panelPower = NOT_CONNECTED, ///< Optional power circuit @@ -157,88 +171,9 @@ const pins_t boardESP32DevKitC = /// @} /// -/// @name Other boards +/// @name 2.2 Other boards /// @{ -/// -/// @brief Texas Instruments LaunchPad MSP430 and MSP432 LaunchPad configuration, tested -/// -const pins_t boardLaunchPad = -{ - .panelBusy = 11, ///< EXT3 and EXT3-1 pin 3 Red -> 11 - .panelDC = 12, ///< EXT3 and EXT3-1 pin 4 Orange -> 12 - .panelReset = 13, ///< EXT3 and EXT3-1 pin 5 Yellow -> 13 - .flashCS = 18, ///< EXT3 and EXT3-1 pin 8 Violet -> 18 - .panelCS = 19, ///< EXT3 and EXT3-1 pin 9 Grey -> 19 - .panelCSS = 39, ///< EXT3 and EXT3-1 pin 12 Grey2 -> 39 - .flashCSS = 38, ///< EXT3 pin 20 or EXT3-1 pin 11 Black2 -> 38 - .touchInt = NOT_CONNECTED, ///< EXT3-Touch pin 3 Red -> 8 - .touchReset = NOT_CONNECTED, ///< EXT3-Touch pin 4 Orange -> 6 - .panelPower = NOT_CONNECTED, ///< Optional power circuit -> 2 - .cardCS = NOT_CONNECTED, ///< Separate SD-card board -> 5 - .cardDetect = NOT_CONNECTED, ///< Separate SD-card board -}; - -/// -/// @brief Texas Instruments LaunchPad MSP430FR5994 LaunchPad with SD-card configuration, tested -/// -const pins_t boardMSP430FR5994 = -{ - .panelBusy = 11, ///< EXT3 and EXT3-1 pin 3 Red - .panelDC = 12, ///< EXT3 and EXT3-1 pin 4 Orange - .panelReset = 13, ///< EXT3 and EXT3-1 pin 5 Yellow - .flashCS = 18, ///< EXT3 and EXT3-1 pin 8 Violet - .panelCS = 19, ///< EXT3 and EXT3-1 pin 9 Grey - .panelCSS = 39, ///< EXT3 and EXT3-1 pin 12 Grey2 - .flashCSS = 38, ///< EXT3 pin 20 or EXT3-1 pin 11 Black2 - .touchInt = NOT_CONNECTED, ///< EXT3-Touch pin 3 Red - .touchReset = NOT_CONNECTED, ///< EXT3-Touch pin 4 Orange - .panelPower = NOT_CONNECTED, ///< Optional power circuit - .cardCS = 47, ///< Included SD-card - .cardDetect = 51 ///< Included SD-card -}; - -/// -/// @brief Texas Instruments LaunchPad CC1352 configuration, tested -/// -const pins_t boardCC1352 = -{ - .panelBusy = 5, ///< EXT3 and EXT3-1 pin 3 Red - .panelDC = 6, ///< EXT3 and EXT3-1 pin 4 Orange - .panelReset = 19, ///< EXT3 and EXT3-1 pin 5 Yellow - .flashCS = 24, ///< EXT3 and EXT3-1 pin 8 Violet - .panelCS = 26, ///< EXT3 and EXT3-1 pin 9 Grey - .panelCSS = 37, ///< EXT3 and EXT3-1 pin 12 Grey2 -> 37 - .flashCSS = 27, ///< EXT3 pin 20 or EXT3-1 pin 11 Black2 -> 27 - .touchInt = NOT_CONNECTED, ///< EXT3-Touch pin 3 Red - .touchReset = NOT_CONNECTED, ///< EXT3-Touch pin 4 Orange - .panelPower = NOT_CONNECTED, ///< Optional power circuit - .cardCS = NOT_CONNECTED, ///< Separate SD-card board - .cardDetect = NOT_CONNECTED, ///< Separate SD-card board -}; - -/// -/// @brief Raspberry Pi Zero, 2B, 3B, 4B configuration with RasPiArduino, tested -/// @warning Not recommended -/// @deprecated Use boardRaspberryPiZeroB_MRAA instead (7.0.0) -/// @see https://github.com/me-no-dev/RasPiArduino -/// -const pins_t boardRaspberryPiZeroB_RasPiArduino = -{ - .panelBusy = 7, ///< EXT3 and EXT3-1 pin 3 Red -> GPIO7 pin 26 - .panelDC = 8, ///< EXT3 and EXT3-1 pin 4 Orange -> GPIO8 pin 24 - .panelReset = 25, ///< EXT3 and EXT3-1 pin 5 Yellow -> GPIO25 pin 22 - .flashCS = 22, ///< EXT3 and EXT3-1 pin 8 Violet -> GPIO22 pin 15 - .panelCS = 27, ///< EXT3 and EXT3-1 pin 9 Grey -> GPIO27 pin 13 - .panelCSS = 23, ///< EXT3 and EXT3-1 pin 12 Grey2 -> GPIO23 pin 16 - .flashCSS = 24, ///< EXT3 pin 20 or EXT3-1 pin 11 Black2 -> GPIO24 pin 18 - .touchInt = NOT_CONNECTED, ///< EXT3-Touch pin 3 Red - .touchReset = NOT_CONNECTED, ///< EXT3-Touch pin 4 Orange - .panelPower = NOT_CONNECTED, ///< Optional power circuit - .cardCS = NOT_CONNECTED, ///< Separate SD-card board - .cardDetect = NOT_CONNECTED, ///< Separate SD-card board -}; - /// /// @brief Raspberry Pi Pico Arduino Mbed-OS configuration, not recommended, tested /// @warning Not recommended @@ -350,11 +285,6 @@ const pins_t boardParticlePhoton = .cardDetect = NOT_CONNECTED, ///< Separate SD-card board }; -/// -/// @brief RedBear Duo configuration, tested -/// -const pins_t boardRedBearDuo = boardParticlePhoton; - /// /// @brief Espressif ESP32-Pico-v4 /// @note Numbers refer to GPIOs not pins @@ -432,9 +362,6 @@ const pins_t boardSiLabsBG24Explorer = .panelCS = 0x11, ///< EXT3 and EXT3-1 pin 9 Grey -> PB01 .panelCSS = NOT_CONNECTED, ///< EXT3 and EXT3-1 pin 12 Grey2 -> P.0. .flashCSS = NOT_CONNECTED, ///< EXT3 pin 20 or EXT3-1 pin 11 Black2 -> P.0. - ///< EXT3 and EXT3-1 pin 10 White -> GROUND - // .i2cSDA = 0x15, ///< EXT3-Touch pin 1 Brown -> I2C SDA PB05 - // .i2cSCL = 0x14, ///< EXT3-Touch pin 2 Black -> I2C SCL PB04 .touchInt = NOT_CONNECTED, ///< EXT3-Touch pin 3 Red -> PD05 .touchReset = NOT_CONNECTED, ///< EXT3-Touch pin 4 Orange -> PD04 .panelPower = NOT_CONNECTED, ///< Optional power circuit @@ -442,6 +369,26 @@ const pins_t boardSiLabsBG24Explorer = .cardDetect = NOT_CONNECTED, ///< Separate SD-card board }; +/// +/// @brief STMicroelectronics Nucleo32 L431KC, tested +/// @warning D7/D8 shared with OSC32_IN/OSC32_OUT +/// +const pins_t boardNucleo32L431KC = +{ + .panelBusy = 4, ///< EXT3 and EXT3-1 pin 3 Red + .panelDC = 5, ///< EXT3 and EXT3-1 pin 4 Orange + .panelReset = 6, ///< EXT3 and EXT3-1 pin 5 Yellow + .flashCS = 9, ///< EXT3 and EXT3-1 pin 8 Violet + .panelCS = 10, ///< EXT3 and EXT3-1 pin 9 Grey + .panelCSS = NOT_CONNECTED, ///< EXT3 and EXT3-1 pin 12 Grey2 + .flashCSS = NOT_CONNECTED, ///< EXT3 pin 20 or EXT3-1 pin 11 Black2 + .touchInt = NOT_CONNECTED, ///< EXT3-Touch pin 3 Red + .touchReset = NOT_CONNECTED, ///< EXT3-Touch pin 4 Orange + .panelPower = NOT_CONNECTED, ///< Optional power circuit + .cardCS = NOT_CONNECTED, ///< Separate SD-card board + .cardDetect = NOT_CONNECTED, ///< Separate SD-card board +}; + /// /// @brief Teensy 3.x configuration, tested /// @@ -463,5 +410,69 @@ const pins_t boardTeensy3x = /// @} +/// +/// @name 2.3 Deprecated boards +/// @{ + +/// +/// @brief Texas Instruments LaunchPad MSP430 and MSP432 configuration, tested +/// @deprecated Texas Instruments LaunchPad boards are deprecated (8.0.3) +/// +const pins_t boardLaunchPad = +{ + .panelBusy = 11, ///< EXT3 and EXT3-1 pin 3 Red -> 11 + .panelDC = 12, ///< EXT3 and EXT3-1 pin 4 Orange -> 12 + .panelReset = 13, ///< EXT3 and EXT3-1 pin 5 Yellow -> 13 + .flashCS = 18, ///< EXT3 and EXT3-1 pin 8 Violet -> 18 + .panelCS = 19, ///< EXT3 and EXT3-1 pin 9 Grey -> 19 + .panelCSS = 39, ///< EXT3 and EXT3-1 pin 12 Grey2 -> 39 + .flashCSS = 38, ///< EXT3 pin 20 or EXT3-1 pin 11 Black2 -> 38 + .touchInt = NOT_CONNECTED, ///< EXT3-Touch pin 3 Red -> 8 + .touchReset = NOT_CONNECTED, ///< EXT3-Touch pin 4 Orange -> 6 + .panelPower = NOT_CONNECTED, ///< Optional power circuit -> 2 + .cardCS = NOT_CONNECTED, ///< Separate SD-card board -> 5 + .cardDetect = NOT_CONNECTED, ///< Separate SD-card board +}; + +/// +/// @brief Texas Instruments LaunchPad MSP430FR5994 LaunchPad with SD-card configuration, tested +/// +const pins_t boardMSP430FR5994 = +{ + .panelBusy = 11, ///< EXT3 and EXT3-1 pin 3 Red + .panelDC = 12, ///< EXT3 and EXT3-1 pin 4 Orange + .panelReset = 13, ///< EXT3 and EXT3-1 pin 5 Yellow + .flashCS = 18, ///< EXT3 and EXT3-1 pin 8 Violet + .panelCS = 19, ///< EXT3 and EXT3-1 pin 9 Grey + .panelCSS = 39, ///< EXT3 and EXT3-1 pin 12 Grey2 + .flashCSS = 38, ///< EXT3 pin 20 or EXT3-1 pin 11 Black2 + .touchInt = NOT_CONNECTED, ///< EXT3-Touch pin 3 Red + .touchReset = NOT_CONNECTED, ///< EXT3-Touch pin 4 Orange + .panelPower = NOT_CONNECTED, ///< Optional power circuit + .cardCS = 47, ///< Included SD-card + .cardDetect = 51 ///< Included SD-card +}; + +/// +/// @brief Texas Instruments LaunchPad CC1352 configuration, tested +/// +const pins_t boardCC1352 = +{ + .panelBusy = 5, ///< EXT3 and EXT3-1 pin 3 Red + .panelDC = 6, ///< EXT3 and EXT3-1 pin 4 Orange + .panelReset = 19, ///< EXT3 and EXT3-1 pin 5 Yellow + .flashCS = 24, ///< EXT3 and EXT3-1 pin 8 Violet + .panelCS = 26, ///< EXT3 and EXT3-1 pin 9 Grey + .panelCSS = 37, ///< EXT3 and EXT3-1 pin 12 Grey2 -> 37 + .flashCSS = 27, ///< EXT3 pin 20 or EXT3-1 pin 11 Black2 -> 27 + .touchInt = NOT_CONNECTED, ///< EXT3-Touch pin 3 Red + .touchReset = NOT_CONNECTED, ///< EXT3-Touch pin 4 Orange + .panelPower = NOT_CONNECTED, ///< Optional power circuit + .cardCS = NOT_CONNECTED, ///< Separate SD-card board + .cardDetect = NOT_CONNECTED, ///< Separate SD-card board +}; + +/// @} + #endif // hV_LIST_BOARDS_RELEASE diff --git a/src/hV_List_Options.h b/src/hV_List_Options.h index 128eab3..2a7ad8f 100755 --- a/src/hV_List_Options.h +++ b/src/hV_List_Options.h @@ -15,10 +15,11 @@ /// * 9. Set GPIO expander mode, not implemented /// * 10. String object for basic edition /// * 11. Set storage mode, not implemented +/// * 12. Set debug options /// /// @author Rei Vilo -/// @date 21 Mar 2024 -/// @version 801 +/// @date 21 May 2024 +/// @version 803 /// /// @copyright (c) Rei Vilo, 2010-2024 /// @copyright All rights reserved @@ -47,7 +48,7 @@ /// /// @brief Release /// -#define hV_LIST_OPTIONS_RELEASE 801 +#define hV_LIST_OPTIONS_RELEASE 803 /// /// @name 1- List of supported Pervasive Displays screens @@ -183,3 +184,10 @@ #endif // hV_LIST_OPTIONS_RELEASE +/// +/// @brief 12- Debug options +/// * Basic edition: none +/// * Evaluation edition: all +/// * Commercial edition: option +/// + diff --git a/src/hV_List_Screens.h b/src/hV_List_Screens.h index e47896b..455611c 100755 --- a/src/hV_List_Screens.h +++ b/src/hV_List_Screens.h @@ -10,8 +10,8 @@ /// * 1- List of supported Pervasive Displays screens /// /// @author Rei Vilo -/// @date 21 Mar 2024 -/// @version 801 +/// @date 21 May 2024 +/// @version 803 /// /// @copyright (c) Rei Vilo, 2010-2024 /// @copyright All rights reserved @@ -43,7 +43,7 @@ /// /// @brief Release /// -#define hV_LIST_SCREENS_RELEASE 801 +#define hV_LIST_SCREENS_RELEASE 803 /// @deprecated Screen name format (8.0.0) /// * Name format eScreen_EPD_EXT3___ is deprecated (8.0.0). @@ -171,6 +171,17 @@ #define eScreen_EPD_266_HS_09 SCREEN(SIZE_266, FILM_H, DRIVER_9) ///< reference xE2266HS09x /// @} +/// +/// @name Legacy monochrome screens +/// @note Global update mode +/// @{ +/// +#define eScreen_EPD_581_CS_08 SCREEN(SIZE_581, FILM_C, DRIVER_8) ///< reference xE2581CS08x, previous type +#define eScreen_EPD_741_CS_08 SCREEN(SIZE_741, FILM_C, DRIVER_8) ///< reference xE2741CS08x, previous type +#define eScreen_EPD_969_CS_08 SCREEN(SIZE_969, FILM_C, DRIVER_8) ///< reference xE2969CS08x, previous type +#define eScreen_EPD_B98_CS_08 SCREEN(SIZE_1198, FILM_C, DRIVER_8) ///< reference xE2B98CS08x, previous type +/// @} + /// /// @name Colour black-white-red "Spectra" screens /// @note Global update mode @@ -250,11 +261,13 @@ #define eScreen_EPD_266_PS_0C SCREEN(SIZE_266, FILM_P, DRIVER_C) ///< reference xE2266PS0Cx #define eScreen_EPD_271_PS_09 SCREEN(SIZE_271, FILM_P, DRIVER_9) ///< reference xE2271PS09x #define eScreen_EPD_287_PS_09 SCREEN(SIZE_287, FILM_P, DRIVER_9) ///< reference xE2287PS09x +/// @todo eScreen_EPD_343_PS_0B not tested +#define eScreen_EPD_343_PS_0B SCREEN(SIZE_343, FILM_P, DRIVER_B) ///< reference xE2343PS0Bx #define eScreen_EPD_370_PS_0C SCREEN(SIZE_370, FILM_P, DRIVER_C) ///< reference xE2370PS0Cx #define eScreen_EPD_417_PS_0D SCREEN(SIZE_417, FILM_P, DRIVER_D) ///< reference xE2417PS0Dx #define eScreen_EPD_437_PS_0C SCREEN(SIZE_437, FILM_P, DRIVER_C) ///< reference xE2437PS0Cx -// /// @todo eScreen_EPD_581_PS_0B not tested -// #define eScreen_EPD_581_PS_0B SCREEN(SIZE_581, FILM_P, DRIVER_B) ///< reference xE2581PS0Bx, not tested +/// @todo eScreen_EPD_581_PS_0B not tested +#define eScreen_EPD_581_PS_0B SCREEN(SIZE_581, FILM_P, DRIVER_B) ///< reference xE2581PS0Bx, not tested // /// @todo eScreen_EPD_741_PS_0B not tested // #define eScreen_EPD_741_PS_0B SCREEN(SIZE_741, FILM_P, DRIVER_B) ///< reference xE2741PS0Bx, not tested // /// @todo eScreen_EPD_969_PS_0B not tested @@ -277,12 +290,14 @@ #define eScreen_EPD_271_KS_09 SCREEN(SIZE_271, FILM_K, DRIVER_9) ///< reference xE2271KS09x #define eScreen_EPD_271_KS_0C SCREEN(SIZE_271, FILM_K, DRIVER_C) ///< reference xE2271KS0Cx #define eScreen_EPD_290_KS_0F SCREEN(SIZE_290, FILM_K, DRIVER_F) ///< reference xE2290KS0Fx +/// @todo eScreen_EPD_350_KS_0C not tested +#define eScreen_EPD_350_KS_0C SCREEN(SIZE_350, FILM_K, DRIVER_C) ///< reference xE2350KS0Cx) #define eScreen_EPD_370_KS_0C SCREEN(SIZE_370, FILM_K, DRIVER_C) ///< reference xE2370KS0Cx #define eScreen_EPD_417_KS_0D SCREEN(SIZE_417, FILM_K, DRIVER_D) ///< reference xE2417KS0Dx /// @todo eScreen_EPD_437_KS_0C not tested #define eScreen_EPD_437_KS_0C SCREEN(SIZE_437, FILM_K, DRIVER_C) ///< reference xE2437KS0Cx, not tested -// /// @todo eScreen_EPD_581_KS_0B not tested -// #define eScreen_EPD_581_KS_0B SCREEN(SIZE_581, FILM_K, DRIVER_B) ///< reference xE2581KS0Bx, not tested +/// @todo eScreen_EPD_581_KS_0B not tested +#define eScreen_EPD_581_KS_0B SCREEN(SIZE_581, FILM_K, DRIVER_B) ///< reference xE2581KS0Bx, not tested // /// @todo eScreen_EPD_741_KS_0B not tested // #define eScreen_EPD_741_KS_0B SCREEN(SIZE_741, FILM_K, DRIVER_B) ///< reference xE2741KS0Bx, not tested // /// @todo eScreen_EPD_969_KS_0B not tested diff --git a/src/hV_List_Screens_Legacy.h b/src/hV_List_Screens_Legacy.h index f32d2a1..dfd5e4b 100644 --- a/src/hV_List_Screens_Legacy.h +++ b/src/hV_List_Screens_Legacy.h @@ -135,7 +135,7 @@ // #define eScreen_EPD_EXT3_581_0B_Fast eScreen_EPD_581_PS_0B ///< reference xE2581PS0Bx, not tested // /// @todo eScreen_EPD_EXT3_741_0B_Fast not tested // #define eScreen_EPD_EXT3_741_0B_Fast eScreen_EPD_741_PS_0B ///< reference xE2741PS0Bx, not tested -// /// @todo eScreen_EPD_EXT3_969_0B_Fast not tested +/// @todo eScreen_EPD_EXT3_969_0B_Fast not tested // #define eScreen_EPD_EXT3_969_0B_Fast eScreen_EPD_969_PS_0B ///< reference xE2969PS0Bx, not tested // /// @todo eScreen_EPD_EXT3_B98_0B_Fast not tested // #define eScreen_EPD_EXT3_B98_0B_Fast eScreen_EPD_B98_PS_0B ///< reference xE2B98PS0Bx, not tested diff --git a/src/hV_Screen_Buffer.h b/src/hV_Screen_Buffer.h index 74595b5..5196a19 100755 --- a/src/hV_Screen_Buffer.h +++ b/src/hV_Screen_Buffer.h @@ -406,7 +406,7 @@ class hV_Screen_Buffer : protected hV_Font_Terminal /// uint8_t s_getCharacter(uint8_t character, uint8_t index); - uint8_t * u_newImage; + uint8_t * s_newImage; // Variables provided by hV_Screen_Virtual bool v_penSolid, v_flagRead, v_flagStorage, v_flagEnergy; diff --git a/src/hV_Utilities_Common.cpp b/src/hV_Utilities_Common.cpp index d4c734c..6772942 100755 --- a/src/hV_Utilities_Common.cpp +++ b/src/hV_Utilities_Common.cpp @@ -3,7 +3,8 @@ // Library C++ code // ---------------------------------- // -// Project highView Library Suite +// Project Pervasive Displays Library Suite +// Based on highView technology // // Created by Rei Vilo, 01 Jun 2013 // @@ -14,6 +15,7 @@ // See hV_Utilities_Common.h for references // // Release 700: Refactored screen and board functions +// Release 803: Added types for string and frame-buffer // // Library header @@ -32,17 +34,19 @@ char bufferOut[128]; // Code // Utilities -String formatString(const char * format, ...) + +STRING_TYPE formatString(const char * format, ...) { memset(&bufferOut, 0x00, sizeof(bufferOut)); va_list args; va_start(args, format); vsnprintf(bufferOut, 127, format, args); va_end(args); + return String(bufferOut); } -String trimString(String text) +STRING_TYPE trimString(STRING_TYPE text) { String work = ""; bool flag = true; @@ -153,45 +157,7 @@ int32_t sin32x100(int32_t degreesX100) return cos32x100(degreesX100 + 27000); } -void convertPolar2Rectangle(uint16_t centerX, uint16_t centerY, uint16_t angle, uint16_t radius, uint16_t & rectangularX, uint16_t & rectangularY) -{ - rectangularX = (uint16_t)(centerX + radius * sin32x100(angle * 100) / 100); - rectangularY = (uint16_t)(centerY - radius * cos32x100(angle * 100) / 100); -} - -void convertRectangle2Polar(uint16_t centerX, uint16_t centerY, uint16_t rectangularX, uint16_t rectangularY, uint16_t & angle, uint16_t & radius) -{ - float fX = (float)rectangularX - centerX; - float fY = (float)rectangularY - centerY; - float fZ = sqrt(fX * fX + fY * fY); - fX /= fZ; - fY /= fZ; - - if ((fY == 0) and (fX > 0)) - { - angle = 90; - } - else if ((fY == 0) and (fX < 0)) - { - angle = 270; - } - else - { - float fAngle = -atan(fX / fY); - fAngle *= 360 / 2 / PI; - - if (fY > 0) - { - fAngle += 180; - } - if ((fX < 0) and (fY < 0)) - { - fAngle += 360; - } - angle = (uint16_t)fAngle; - } -} -String utf2iso(String s) +STRING_TYPE utf2iso(STRING_TYPE s) { uint8_t c; diff --git a/src/hV_Utilities_Common.h b/src/hV_Utilities_Common.h index e3277ce..bb9e03e 100755 --- a/src/hV_Utilities_Common.h +++ b/src/hV_Utilities_Common.h @@ -6,8 +6,8 @@ /// @n Based on highView technology /// /// @author Rei Vilo -/// @date 21 Mar 2024 -/// @version 801 +/// @date 21 May 2024 +/// @version 803 /// /// @copyright (c) Rei Vilo, 2010-2024 /// @copyright All rights reserved @@ -35,11 +35,14 @@ // SDK #include "hV_HAL_Peripherals.h" +// Configuration +#include "hV_Configuration.h" + #ifndef hV_UTILITIES_RELEASE /// /// @brief Library release number /// -#define hV_UTILITIES_RELEASE 801 +#define hV_UTILITIES_RELEASE 803 #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) @@ -85,31 +88,6 @@ int32_t cos32x100(int32_t degreesX100); /// int32_t sin32x100(int32_t degreesX100); -/* -/// -/// @brief Convert polar to rectangle coordinates -/// @param[in] centerX circle center, x coordinate -/// @param[in] centerY circle center, y coordinate -/// @param[in] angle angle, degrees 0..360° -/// @param[in] radius radius, pixels -/// @param[out] rectangularX x rectangular coordinate -/// @param[out] rectangularY y rectangular coordinate -/// @note This function uses floats. -/// -void convertPolar2Rectangle(uint16_t centerX, uint16_t centerY, uint16_t angle, uint16_t radius, uint16_t & rectangularX, uint16_t & rectangularY); - -/// @brief Convert rectangle to polar coordinates -/// @param[in] centerX circle center, x coordinate -/// @param[in] centerY circle center, y coordinate -/// @param[in] rectangularX x rectangular coordinate -/// @param[in] rectangularY y rectangular coordinate -/// @param[out] angle angle in degrees 0..360° -/// @param[out] radius radius in pixels -/// @note This function uses floats. -/// -void convertRectangle2Polar(uint16_t centerX, uint16_t centerY, uint16_t rectangularX, uint16_t rectangularY, uint16_t & angle, uint16_t & radius); -*/ - /// /// @brief UTF-8 to ISO-8859-1 Converter /// @param s UTF-8 string, input @@ -119,7 +97,7 @@ void convertRectangle2Polar(uint16_t centerX, uint16_t centerY, uint16_t rectang /// (Mountain View, CA: The Unicode Consortium, 2012. ISBN 978-1-936213-07-8) /// http://www.unicode.org/versions/Unicode6.2.0/ /// -String utf2iso(String s); +STRING_TYPE utf2iso(STRING_TYPE s); /// /// @brief Format string @@ -129,7 +107,7 @@ String utf2iso(String s); /// @return string with values formatted /// @see http://www.cplusplus.com/reference/cstdio/printf/?kw=printf for codes /// -String formatString(const char * format, ...); +STRING_TYPE formatString(const char * format, ...); /// /// @brief Remove leading and ending characters @@ -137,7 +115,7 @@ String formatString(const char * format, ...); /// @return trimmed text /// @note Removed characters are LF CR TAB SPACE ' /// -String trimString(String text); +STRING_TYPE trimString(STRING_TYPE text); /// @} diff --git a/src/hV_Utilities_PDLS.cpp b/src/hV_Utilities_PDLS.cpp index 1b77d4b..335e5ee 100755 --- a/src/hV_Utilities_PDLS.cpp +++ b/src/hV_Utilities_PDLS.cpp @@ -6,13 +6,14 @@ // Project Pervasive Displays Library Suite // Based on highView technology // -// Created by Rei Vilo, 16 Aug 2023 +// Created by Rei Vilo, 21 Mar 2024 // // Copyright (c) Rei Vilo, 2010-2024 // Licence All rights reserved // // Release 800: Read OTP memory // Release 801: Added number of colours +// Release 803: Added types for string and frame-buffer // // Library header @@ -45,14 +46,23 @@ void hV_Utilities_PDLS::u_WhoAmI(char * answer) strcat(answer, "-Wide"); break; + case FILM_H: // Film H, Freezer + + strcat(answer, "-Freezer"); + break; + case FILM_J: // Film J, BWR, "Spectra" case FILM_E: // Film E, BWR, deprecated case FILM_F: // Film F, BWR, deprecated - case FILM_G: // Film G, BWY, deprecated strcat(answer, "-BWR"); break; + case FILM_G: // Film G, BWY, deprecated + + strcat(answer, "-BWY"); + break; + case FILM_Q: // Film Q, BWRY, "Spectra 4" strcat(answer, "-BWRY"); @@ -140,21 +150,13 @@ uint8_t hV_Utilities_PDLS::screenColours() default: - result = 0; // error + result = 0; // Error break; } return result; } -String hV_Utilities_PDLS::screenNumber() -{ - char work[64] = {0}; - u_screenNumber(work); - - return formatString("Number %s", work); -} - void hV_Utilities_PDLS::u_screenNumber(char * answer) { memcpy(answer, 0x00, strlen(answer)); @@ -180,6 +182,14 @@ void hV_Utilities_PDLS::u_screenNumber(char * answer) } } +STRING_TYPE hV_Utilities_PDLS::screenNumber() +{ + char work[64] = {0}; + u_screenNumber(work); + + return formatString("Number %s", work); +} + // // === Temperature section // @@ -286,3 +296,47 @@ uint8_t hV_Utilities_PDLS::checkTemperatureMode(uint8_t updateMode) return updateMode; } +void hV_Utilities_PDLS::debugVariant(uint8_t contextFilm) +{ + mySerial.println(); + + switch (contextFilm) + { + case FILM_P: // BW, fast update + case FILM_K: // BW, fast update and wide temperature + + mySerial.println(formatString("hV * Screen %i-%cS-0%c with no fast update", u_codeSize, u_codeFilm, u_codeDriver)); + break; + + case FILM_Q: // BWRY + + mySerial.println(formatString("hV * Screen %i-%cS-0%c is not black-white-red-yellow", u_codeSize, u_codeFilm, u_codeDriver)); + break; + + default: + + mySerial.println(formatString("hV * Screen %i-%cS-0%c is not supported", u_codeSize, u_codeFilm, u_codeDriver)); + break; + } // u_codeFilm + + switch (u_codeFilm) + { + case FILM_P: // BW, fast update + case FILM_K: // BW, fast update and wide temperature + + mySerial.println(formatString("hV * Use PDLS_EXT3_%s_%s instead", "Basic", "Fast")); + break; + + case FILM_Q: // BWRY + + mySerial.println(formatString("hV * Use PDLS_EXT3_%s_%s instead", "Basic", "BWRY")); + break; + + default: + + mySerial.println(formatString("hV * Use PDLS_EXT3_%s_%s instead", "Basic", "Global")); + break; + } // u_codeFilm + + while (0x01); +} diff --git a/src/hV_Utilities_PDLS.h b/src/hV_Utilities_PDLS.h index 94db69f..2339878 100755 --- a/src/hV_Utilities_PDLS.h +++ b/src/hV_Utilities_PDLS.h @@ -8,8 +8,8 @@ /// * Edition: Advanced /// /// @author Rei Vilo -/// @date 21 Mar 2024 -/// @version 801 +/// @date 21 May 2024 +/// @version 803 /// /// @copyright (c) Rei Vilo, 2010-2024 /// @copyright All rights reserved @@ -51,8 +51,8 @@ #error Required hV_HAL_PERIPHERALS_RELEASE 801 #endif // hV_HAL_PERIPHERALS_RELEASE -#if (hV_CONFIGURATION_RELEASE < 801) -#error Required hV_CONFIGURATION_RELEASE 801 +#if (hV_CONFIGURATION_RELEASE < 803) +#error Required hV_CONFIGURATION_RELEASE 803 #endif // hV_CONFIGURATION_RELEASE #if (hV_BOARD_RELEASE < 801) @@ -63,7 +63,7 @@ /// /// @brief Library release number /// -#define hV_UTILITIES_PDLS_RELEASE 801 +#define hV_UTILITIES_PDLS_RELEASE 803 // Objects // @@ -123,7 +123,14 @@ class hV_Utilities_PDLS : public hV_Board /// @brief Screen number /// @return Screen number as string /// - virtual String screenNumber(); + virtual STRING_TYPE screenNumber(); + + /// + /// @brief Recommend variant for film + /// @param uint8_t Context film + /// @note exit() called after + /// + void debugVariant(uint8_t contextFilm); /// @cond protected: @@ -154,7 +161,7 @@ class hV_Utilities_PDLS : public hV_Board uint8_t u_codeDriver; uint8_t u_codeExtra; uint16_t u_bufferSizeV, u_bufferSizeH, u_bufferDepth; - uint32_t u_pageColourSize, u_frameSize; + uint32_t u_pageColourSize; bool u_invert = false; bool u_flagOTP = false;