|
1 | 1 | #include "main.h" |
2 | 2 |
|
3 | 3 | void setup() { |
| 4 | + #ifndef DISABLE_USB_SERIAL |
4 | 5 | Serial.begin(115200); |
5 | 6 | delay(100); |
| 7 | + #endif |
6 | 8 | writeSerial("=== FIRMWARE INFO ==="); |
7 | 9 | writeSerial("Firmware Version: " + String(getFirmwareMajor()) + "." + String(getFirmwareMinor())); |
8 | 10 | const char* shaCStr = SHA_STRING; |
@@ -612,6 +614,13 @@ void full_config_init(){ |
612 | 614 | if (loadGlobalConfig()) { |
613 | 615 | writeSerial("Global configuration loaded successfully"); |
614 | 616 | printConfigSummary(); |
| 617 | + #ifdef TARGET_NRF |
| 618 | + if (globalConfig.loaded && (globalConfig.system_config.device_flags & DEVICE_FLAG_XIAOINIT)) { |
| 619 | + writeSerial("Device flag DEVICE_FLAG_XIAOINIT is set, calling xiaoinit()..."); |
| 620 | + xiaoinit(); |
| 621 | + writeSerial("xiaoinit() completed"); |
| 622 | + } |
| 623 | + #endif |
615 | 624 | } else { |
616 | 625 | writeSerial("Global configuration load failed or no config found"); |
617 | 626 | } |
@@ -755,8 +764,134 @@ void pwrmgm(bool onoff){ |
755 | 764 | } |
756 | 765 |
|
757 | 766 | void writeSerial(String message, bool newLine){ |
| 767 | + #ifndef DISABLE_USB_SERIAL |
758 | 768 | if (newLine == true) Serial.println(message); |
759 | 769 | else Serial.print(message); |
| 770 | + #endif |
| 771 | + // When USB is disabled, writeSerial does nothing (no-op) to save power |
| 772 | +} |
| 773 | + |
| 774 | +void xiaoinit(){ |
| 775 | + powerDownExternalFlash(20,24,21,25,22,23); |
| 776 | + pinMode(31, INPUT); |
| 777 | + pinMode(14, INPUT); |
| 778 | + pinMode(13, OUTPUT); //that actually does something |
| 779 | + digitalWrite(13, LOW); |
| 780 | + pinMode(17, INPUT); |
| 781 | + //buttons |
| 782 | + pinMode(15, INPUT); |
| 783 | + pinMode(3, INPUT); |
| 784 | + pinMode(28, INPUT); |
| 785 | +} |
| 786 | + |
| 787 | +bool powerDownExternalFlash(uint8_t mosiPin, uint8_t misoPin, uint8_t sckPin, uint8_t csPin, uint8_t wpPin, uint8_t holdPin) { |
| 788 | + #ifdef TARGET_NRF |
| 789 | + // Software SPI transfer function (bit-banging) |
| 790 | + auto spiTransfer = [&](uint8_t data) -> uint8_t { |
| 791 | + uint8_t result = 0; |
| 792 | + for (int i = 7; i >= 0; i--) { |
| 793 | + // Set MOSI to current bit |
| 794 | + digitalWrite(mosiPin, (data >> i) & 1); |
| 795 | + // Clock low |
| 796 | + digitalWrite(sckPin, LOW); |
| 797 | + delayMicroseconds(1); |
| 798 | + // Read MISO |
| 799 | + result |= (digitalRead(misoPin) << i); |
| 800 | + // Clock high |
| 801 | + digitalWrite(sckPin, HIGH); |
| 802 | + delayMicroseconds(1); |
| 803 | + } |
| 804 | + return result; |
| 805 | + }; |
| 806 | + writeSerial("=== External Flash Power-Down ==="); |
| 807 | + writeSerial("Pin configuration: MOSI=" + String(mosiPin) + " MISO=" + String(misoPin) + " SCK=" + String(sckPin) + " CS=" + String(csPin) + " WP=" + String(wpPin) + " HOLD=" + String(holdPin)); |
| 808 | + writeSerial("Configuring SPI pins..."); |
| 809 | + pinMode(mosiPin, OUTPUT); |
| 810 | + pinMode(misoPin, INPUT); |
| 811 | + pinMode(sckPin, OUTPUT); |
| 812 | + pinMode(csPin, OUTPUT); |
| 813 | + pinMode(wpPin, OUTPUT); |
| 814 | + pinMode(holdPin, OUTPUT); |
| 815 | + writeSerial("SPI pins configured"); |
| 816 | + digitalWrite(sckPin, HIGH); // Clock idle high (SPI mode 0) |
| 817 | + digitalWrite(csPin, HIGH); // CS inactive |
| 818 | + digitalWrite(wpPin, HIGH); // WP disabled (active-low) |
| 819 | + digitalWrite(holdPin, HIGH); // HOLD disabled (active-low) |
| 820 | + writeSerial("Control pins set: CS=HIGH, WP=HIGH (disabled), HOLD=HIGH (disabled), SCK=HIGH (idle)"); |
| 821 | + delay(1); |
| 822 | + writeSerial("Attempting to wake flash from deep power-down (command 0xAB)..."); |
| 823 | + digitalWrite(csPin, LOW); |
| 824 | + spiTransfer(0xAB); |
| 825 | + digitalWrite(csPin, HIGH); |
| 826 | + delay(10); // Wait for flash to wake up (typically 3-35us, using 10ms for safety) |
| 827 | + writeSerial("Wake-up command sent, waiting 10ms..."); |
| 828 | + // Read JEDEC ID before power-down (for verification) |
| 829 | + writeSerial("Reading JEDEC ID before power-down..."); |
| 830 | + digitalWrite(csPin, LOW); |
| 831 | + spiTransfer(0x9F); // JEDEC ID command |
| 832 | + uint8_t jedecId[3]; |
| 833 | + for (int i = 0; i < 3; i++) { |
| 834 | + jedecId[i] = spiTransfer(0x00); |
| 835 | + } |
| 836 | + digitalWrite(csPin, HIGH); |
| 837 | + String jedecIdStr = "0x"; |
| 838 | + for (int i = 0; i < 3; i++) { |
| 839 | + if (jedecId[i] < 16) jedecIdStr += "0"; |
| 840 | + jedecIdStr += String(jedecId[i], HEX); |
| 841 | + } |
| 842 | + jedecIdStr.toUpperCase(); |
| 843 | + writeSerial("JEDEC ID before: " + jedecIdStr + " (Manufacturer=0x" + String(jedecId[0], HEX) + ", MemoryType=0x" + String(jedecId[1], HEX) + ", Capacity=0x" + String(jedecId[2], HEX) + ")"); |
| 844 | + bool flashResponding = false; |
| 845 | + for (int i = 0; i < 3; i++) { |
| 846 | + if (jedecId[i] != 0xFF) { |
| 847 | + flashResponding = true; |
| 848 | + break; |
| 849 | + } |
| 850 | + } |
| 851 | + delay(1); |
| 852 | + writeSerial("Sending deep power-down command (0xB9)..."); |
| 853 | + digitalWrite(csPin, LOW); |
| 854 | + spiTransfer(0xB9); |
| 855 | + digitalWrite(csPin, HIGH); |
| 856 | + if(false){ |
| 857 | + writeSerial("Deep power-down command sent, waiting 10ms..."); |
| 858 | + delay(10); // Wait for command to complete |
| 859 | + writeSerial("Reading JEDEC ID after power-down command..."); |
| 860 | + digitalWrite(csPin, LOW); |
| 861 | + spiTransfer(0x9F); |
| 862 | + uint8_t jedecIdAfter[3]; |
| 863 | + for (int i = 0; i < 3; i++) { |
| 864 | + jedecIdAfter[i] = spiTransfer(0x00); |
| 865 | + } |
| 866 | + digitalWrite(csPin, HIGH); |
| 867 | + String jedecIdAfterStr = "0x"; |
| 868 | + for (int i = 0; i < 3; i++) { |
| 869 | + if (jedecIdAfter[i] < 16) jedecIdAfterStr += "0"; |
| 870 | + jedecIdAfterStr += String(jedecIdAfter[i], HEX); |
| 871 | + } |
| 872 | + jedecIdAfterStr.toUpperCase(); |
| 873 | + writeSerial("JEDEC ID after: " + jedecIdAfterStr + " (byte[0]=0x" + String(jedecIdAfter[0], HEX) + ", byte[1]=0x" + String(jedecIdAfter[1], HEX) + ", byte[2]=0x" + String(jedecIdAfter[2], HEX) + ")"); |
| 874 | + bool inPowerDown = true; |
| 875 | + String mismatchBytes = ""; |
| 876 | + for (int i = 0; i < 3; i++) { |
| 877 | + if (jedecIdAfter[i] != 0xFF) { |
| 878 | + inPowerDown = false; |
| 879 | + if (mismatchBytes.length() > 0) mismatchBytes += ", "; |
| 880 | + mismatchBytes += "byte[" + String(i) + "]=0x" + String(jedecIdAfter[i], HEX) + " (expected 0xFF)"; |
| 881 | + } |
| 882 | + } |
| 883 | + } |
| 884 | + digitalWrite(csPin, HIGH); |
| 885 | + pinMode(wpPin, INPUT); |
| 886 | + pinMode(holdPin, INPUT); |
| 887 | + pinMode(mosiPin, INPUT); |
| 888 | + pinMode(misoPin, INPUT); |
| 889 | + pinMode(sckPin, INPUT); |
| 890 | + #else |
| 891 | + writeSerial("External flash power-down not implemented for ESP32"); |
| 892 | + return false; |
| 893 | + #endif |
| 894 | + return false; |
760 | 895 | } |
761 | 896 |
|
762 | 897 | int mapEpd(int id){ |
@@ -844,9 +979,11 @@ void initDisplay(){ |
844 | 979 | bbepSendCMDSequence(&bbep, bbep.pInitFull); |
845 | 980 | String chipId = getChipIdHex(); |
846 | 981 | String infoText = "openepaperlink.org\nName: OEPL" + chipId + "\nFW: " + String(getFirmwareMajor()) + "." + String(getFirmwareMinor()) + "\nEpaper driver by\nLarry Bank\ngithub.com/bitbank2"; |
847 | | - writeTextAndFill(infoText.c_str()); |
| 982 | + if (globalConfig.displays[0].transmission_modes & TRANSMISSION_MODE_CLEAR_ON_BOOT) writeTextAndFill(""); |
| 983 | + else writeTextAndFill(infoText.c_str()); |
848 | 984 | bbepRefresh(&bbep, REFRESH_FULL); |
849 | 985 | waitforrefresh(60); |
| 986 | + pwrmgm(false); |
850 | 987 | } |
851 | 988 | else{ |
852 | 989 | writeSerial("No display found"); |
@@ -1476,6 +1613,10 @@ void printConfigSummary(){ |
1476 | 1613 | writeSerial("IC Type: 0x" + String(globalConfig.system_config.ic_type, HEX)); |
1477 | 1614 | writeSerial("Communication Modes: 0x" + String(globalConfig.system_config.communication_modes, HEX)); |
1478 | 1615 | writeSerial("Device Flags: 0x" + String(globalConfig.system_config.device_flags, HEX)); |
| 1616 | + writeSerial(" PWR_PIN flag: " + String((globalConfig.system_config.device_flags & DEVICE_FLAG_PWR_PIN) ? "enabled" : "disabled")); |
| 1617 | + #ifdef TARGET_NRF |
| 1618 | + writeSerial(" XIAOINIT flag: " + String((globalConfig.system_config.device_flags & DEVICE_FLAG_XIAOINIT) ? "enabled" : "disabled")); |
| 1619 | + #endif |
1479 | 1620 | writeSerial("Power Pin: " + String(globalConfig.system_config.pwr_pin)); |
1480 | 1621 | writeSerial(""); |
1481 | 1622 | // Manufacturer Data |
@@ -1519,6 +1660,11 @@ void printConfigSummary(){ |
1519 | 1660 | writeSerial(" Partial Update: " + String(globalConfig.displays[i].partial_update_support ? "Yes" : "No")); |
1520 | 1661 | writeSerial(" Color Scheme: 0x" + String(globalConfig.displays[i].color_scheme, HEX)); |
1521 | 1662 | writeSerial(" Transmission Modes: 0x" + String(globalConfig.displays[i].transmission_modes, HEX)); |
| 1663 | + writeSerial(" RAW: " + String((globalConfig.displays[i].transmission_modes & TRANSMISSION_MODE_RAW) ? "enabled" : "disabled")); |
| 1664 | + writeSerial(" ZIP: " + String((globalConfig.displays[i].transmission_modes & TRANSMISSION_MODE_ZIP) ? "enabled" : "disabled")); |
| 1665 | + writeSerial(" G5: " + String((globalConfig.displays[i].transmission_modes & TRANSMISSION_MODE_G5) ? "enabled" : "disabled")); |
| 1666 | + writeSerial(" DIRECT_WRITE: " + String((globalConfig.displays[i].transmission_modes & TRANSMISSION_MODE_DIRECT_WRITE) ? "enabled" : "disabled")); |
| 1667 | + writeSerial(" CLEAR_ON_BOOT: " + String((globalConfig.displays[i].transmission_modes & TRANSMISSION_MODE_CLEAR_ON_BOOT) ? "enabled" : "disabled")); |
1522 | 1668 | writeSerial(""); |
1523 | 1669 | } |
1524 | 1670 | // LEDs |
@@ -1699,6 +1845,8 @@ void handleDirectWriteStart(uint8_t* data, uint16_t len) { |
1699 | 1845 | writeSerial("Expected total bytes: " + String(directWriteTotalBytes) + (directWriteBitplanes ? " per plane" : "")); |
1700 | 1846 | directWriteActive = true; |
1701 | 1847 | directWriteBytesWritten = 0; |
| 1848 | + pwrmgm(true); |
| 1849 | + bbepInitIO(&bbep, globalConfig.displays[0].dc_pin, globalConfig.displays[0].reset_pin, globalConfig.displays[0].busy_pin, globalConfig.displays[0].cs_pin, globalConfig.displays[0].data_pin, globalConfig.displays[0].clk_pin, 8000000); |
1702 | 1850 | bbepWakeUp(&bbep); |
1703 | 1851 | bbepSendCMDSequence(&bbep, bbep.pInitFull);// important for some displays |
1704 | 1852 | bbepSetAddrWindow(&bbep, 0, 0, globalConfig.displays[0].pixel_width, globalConfig.displays[0].pixel_height); |
@@ -2231,6 +2379,7 @@ void handleDirectWriteEnd() { |
2231 | 2379 | } |
2232 | 2380 | bbepRefresh(&bbep, REFRESH_FULL); |
2233 | 2381 | waitforrefresh(60); |
| 2382 | + pwrmgm(false); |
2234 | 2383 | directWriteActive = false; |
2235 | 2384 | directWriteCompressed = false; |
2236 | 2385 | directWriteBytesWritten = 0; |
|
0 commit comments