diff --git a/Compatible_models/Stellar-M3N@_Back.jpg b/Compatible_models/Stellar-M3N@_Back.jpg new file mode 100644 index 0000000..596d6a3 Binary files /dev/null and b/Compatible_models/Stellar-M3N@_Back.jpg differ diff --git a/Compatible_models/Stellar-M3N@_Front.jpg b/Compatible_models/Stellar-M3N@_Front.jpg new file mode 100644 index 0000000..12afdc6 Binary files /dev/null and b/Compatible_models/Stellar-M3N@_Front.jpg differ diff --git a/Compatible_models/Stellar-MFN@_Back.jpg b/Compatible_models/Stellar-MFN@_Back.jpg new file mode 100644 index 0000000..236c690 Binary files /dev/null and b/Compatible_models/Stellar-MFN@_Back.jpg differ diff --git a/Compatible_models/Stellar-MFN@_Front.jpg b/Compatible_models/Stellar-MFN@_Front.jpg new file mode 100644 index 0000000..eec076c Binary files /dev/null and b/Compatible_models/Stellar-MFN@_Front.jpg differ diff --git a/Compatible_models/Stellar-MN@_Back.jpg b/Compatible_models/Stellar-MN@_Back.jpg new file mode 100644 index 0000000..be63f80 Binary files /dev/null and b/Compatible_models/Stellar-MN@_Back.jpg differ diff --git a/Compatible_models/Stellar-MN@_Front.jpg b/Compatible_models/Stellar-MN@_Front.jpg new file mode 100644 index 0000000..70e10bc Binary files /dev/null and b/Compatible_models/Stellar-MN@_Front.jpg differ diff --git a/Compatible_models/Stellar-S3TN@_Back.jpg b/Compatible_models/Stellar-S3TN@_Back.jpg new file mode 100644 index 0000000..1bb16c6 Binary files /dev/null and b/Compatible_models/Stellar-S3TN@_Back.jpg differ diff --git a/Compatible_models/Stellar-S3TN@_Front.jpg b/Compatible_models/Stellar-S3TN@_Front.jpg new file mode 100644 index 0000000..914595b Binary files /dev/null and b/Compatible_models/Stellar-S3TN@_Front.jpg differ diff --git a/Firmware/ATC_Paper.bin b/Firmware/ATC_Paper.bin index 3060809..522c0c3 100644 Binary files a/Firmware/ATC_Paper.bin and b/Firmware/ATC_Paper.bin differ diff --git a/Firmware/src/cmd_parser.c b/Firmware/src/cmd_parser.c index fa43117..82fbe45 100644 --- a/Firmware/src/cmd_parser.c +++ b/Firmware/src/cmd_parser.c @@ -62,4 +62,7 @@ void cmd_parser(void * p){ }else if(inData == 0xDF){// Save current settings in flash save_settings_to_flash(); } + else if(inData == 0xE0){// force set an EPD model, if it wasnt detect automatically correct + set_EPD_model(req->dat[1]); + } } diff --git a/Firmware/src/epd.c b/Firmware/src/epd.c index 89fe1f6..200ecfa 100755 --- a/Firmware/src/epd.c +++ b/Firmware/src/epd.c @@ -3,8 +3,10 @@ #include "main.h" #include "epd.h" #include "epd_spi.h" -#include "epd_bw.h" -#include "epd_bwr.h" +#include "epd_bw_213.h" +#include "epd_bwr_213.h" +#include "epd_bw_213_ice.h" +#include "epd_bwr_154.h" #include "drivers.h" #include "stack/ble/ble.h" @@ -18,11 +20,11 @@ extern const uint8_t ucMirror[]; #include "font16.h" #include "font30.h" -RAM uint8_t epd_model = 0; // 0 = Undetected, 1 = BW, 2 = BWR -const char* epd_model_string[] = {"NC","BW","BWR"}; +RAM uint8_t epd_model = 0; // 0 = Undetected, 1 = BW213, 2 = BWR213, 3 = BWR154, 4 = BW213ICE +const char *epd_model_string[] = {"NC", "BW213", "BWR213", "BWR154", "213ICE"}; RAM uint8_t epd_update_state = 0; -const char* BLE_conn_string[] = {"", "B"}; +const char *BLE_conn_string[] = {"", "B"}; RAM uint8_t epd_temperature_is_read = 0; RAM uint8_t epd_temperature = 0; @@ -31,6 +33,12 @@ uint8_t epd_temp[epd_buffer_size]; // for OneBitDisplay to draw into OBDISP obd; // virtual display structure TIFFIMAGE tiff; +// With this we can force a display if it wasnt detected correctly +void set_EPD_model(uint8_t model_nr) +{ + epd_model = model_nr; +} + // Here we detect what E-Paper display is connected _attribute_ram_code_ void EPD_detect_model(void) { @@ -46,10 +54,18 @@ _attribute_ram_code_ void EPD_detect_model(void) WaitMs(10); // Here we neeed to detect it - if (EPD_BWR_detect()) + if (EPD_BWR_213_detect()) { epd_model = 2; } + else if (EPD_BWR_154_detect())// Right now this will never trigger, the 154 is same to 213BWR right now. + { + epd_model = 3; + } + else if (EPD_BW_213_ice_detect()) + { + epd_model = 4; + } else { epd_model = 1; @@ -62,10 +78,9 @@ _attribute_ram_code_ uint8_t EPD_read_temp(void) { if (epd_temperature_is_read) return epd_temperature; + if (!epd_model) - { EPD_detect_model(); - } EPD_init(); // system power @@ -78,9 +93,13 @@ _attribute_ram_code_ uint8_t EPD_read_temp(void) WaitMs(10); if (epd_model == 1) - epd_temperature = EPD_BW_read_temp(); + epd_temperature = EPD_BW_213_read_temp(); else if (epd_model == 2) - epd_temperature = EPD_BWR_read_temp(); + epd_temperature = EPD_BWR_213_read_temp(); + else if (epd_model == 3) + epd_temperature = EPD_BWR_154_read_temp(); + else if (epd_model == 4) + epd_temperature = EPD_BW_213_ice_read_temp(); EPD_POWER_OFF(); @@ -92,9 +111,7 @@ _attribute_ram_code_ uint8_t EPD_read_temp(void) _attribute_ram_code_ void EPD_Display(unsigned char *image, int size, uint8_t full_or_partial) { if (!epd_model) - { EPD_detect_model(); - } EPD_init(); // system power @@ -107,9 +124,13 @@ _attribute_ram_code_ void EPD_Display(unsigned char *image, int size, uint8_t fu WaitMs(10); if (epd_model == 1) - epd_temperature = EPD_BW_Display(image, size, full_or_partial); + epd_temperature = EPD_BW_213_Display(image, size, full_or_partial); else if (epd_model == 2) - epd_temperature = EPD_BWR_Display(image, size, full_or_partial); + epd_temperature = EPD_BWR_213_Display(image, size, full_or_partial); + else if (epd_model == 3) + epd_temperature = EPD_BWR_154_Display(image, size, full_or_partial); + else if (epd_model == 4) + epd_temperature = EPD_BW_213_ice_Display(image, size, full_or_partial); epd_temperature_is_read = 1; epd_update_state = 1; @@ -118,14 +139,16 @@ _attribute_ram_code_ void EPD_Display(unsigned char *image, int size, uint8_t fu _attribute_ram_code_ void epd_set_sleep(void) { if (!epd_model) - { EPD_detect_model(); - } if (epd_model == 1) - EPD_BW_set_sleep(); + EPD_BW_213_set_sleep(); else if (epd_model == 2) - EPD_BWR_set_sleep(); + EPD_BWR_213_set_sleep(); + else if (epd_model == 3) + EPD_BWR_154_set_sleep(); + else if (epd_model == 4) + EPD_BW_213_ice_set_sleep(); EPD_POWER_OFF(); epd_update_state = 0; @@ -154,19 +177,19 @@ _attribute_ram_code_ uint8_t epd_state_handler(void) return epd_update_state; } -_attribute_ram_code_ void FixBuffer(uint8_t *pSrc, uint8_t *pDst) +_attribute_ram_code_ void FixBuffer(uint8_t *pSrc, uint8_t *pDst, uint16_t width, uint16_t height) { int x, y; uint8_t *s, *d; - for (y = 0; y < 16; y++) + for (y = 0; y < (height / 8); y++) { // byte rows d = &pDst[y]; - s = &pSrc[y * 250]; - for (x = 0; x < 250; x++) + s = &pSrc[y * width]; + for (x = 0; x < width; x++) { - d[x * 16] = ~ucMirror[s[249 - x]]; // invert and flip - } // for x - } // for y + d[x * (height / 8)] = ~ucMirror[s[width - 1 - x]]; // invert and flip + } // for x + } // for y } _attribute_ram_code_ void TIFFDraw(TIFFDRAW *pDraw) @@ -212,11 +235,39 @@ _attribute_ram_code_ void epd_display(uint32_t time_is, uint16_t battery_mv, int { if (epd_update_state) return; - obdCreateVirtualDisplay(&obd, 250, 122, epd_temp); + + if (!epd_model) + { + EPD_detect_model(); + } + uint16_t resolution_w = 250; + uint16_t resolution_h = 128; // 122 real pixel, but needed to have a full byte + if (epd_model == 1) + { + resolution_w = 250; + resolution_h = 128; // 122 real pixel, but needed to have a full byte + } + else if (epd_model == 2) + { + resolution_w = 250; + resolution_h = 128; // 122 real pixel, but needed to have a full byte + } + else if (epd_model == 3) + { + resolution_w = 200; + resolution_h = 200; + } + else if (epd_model == 4) + { + resolution_w = 212; + resolution_h = 104; + } + + obdCreateVirtualDisplay(&obd, resolution_w, resolution_h, epd_temp); obdFill(&obd, 0, 0); // fill with white char buff[100]; - sprintf(buff, "ESL_%02X%02X%02X - %s", mac_public[2], mac_public[1], mac_public[0], epd_model_string[epd_model]); + sprintf(buff, "ESL_%02X%02X%02X %s", mac_public[2], mac_public[1], mac_public[0], epd_model_string[epd_model]); obdWriteStringCustom(&obd, (GFXfont *)&Dialog_plain_16, 1, 17, (char *)buff, 1); sprintf(buff, "%s", BLE_conn_string[ble_get_connected()]); obdWriteStringCustom(&obd, (GFXfont *)&Dialog_plain_16, 232, 20, (char *)buff, 1); @@ -226,8 +277,8 @@ _attribute_ram_code_ void epd_display(uint32_t time_is, uint16_t battery_mv, int obdWriteStringCustom(&obd, (GFXfont *)&Special_Elite_Regular_30, 10, 95, (char *)buff, 1); sprintf(buff, "Battery %dmV", battery_mv); obdWriteStringCustom(&obd, (GFXfont *)&Dialog_plain_16, 10, 120, (char *)buff, 1); - FixBuffer(epd_temp, epd_buffer); - EPD_Display(epd_buffer, epd_buffer_size, full_or_partial); + FixBuffer(epd_temp, epd_buffer, resolution_w, resolution_h); + EPD_Display(epd_buffer, resolution_w * resolution_h / 8, full_or_partial); } _attribute_ram_code_ void epd_display_char(uint8_t data) diff --git a/Firmware/src/epd.h b/Firmware/src/epd.h index d866136..5219730 100644 --- a/Firmware/src/epd.h +++ b/Firmware/src/epd.h @@ -1,9 +1,10 @@ #pragma once -#define epd_height 128 -#define epd_width 250 +#define epd_height 200 +#define epd_width 200 #define epd_buffer_size ((epd_height/8) * epd_width) +void set_EPD_model(uint8_t model_nr); void init_epd(void); uint8_t EPD_read_temp(void); void EPD_Display(unsigned char *image, int size, uint8_t full_or_partial); diff --git a/Firmware/src/epd_ble_service.c b/Firmware/src/epd_ble_service.c index c007ac8..8f07a22 100644 --- a/Firmware/src/epd_ble_service.c +++ b/Firmware/src/epd_ble_service.c @@ -15,7 +15,7 @@ extern uint8_t *epd_temp; return 0; \ } -unsigned char image[epd_buffer_size]; +extern unsigned char epd_buffer[epd_buffer_size]; unsigned int byte_pos = 0; int epd_ble_handle_write(void *p) @@ -31,13 +31,13 @@ int epd_ble_handle_write(void *p) // Clear EPD display. case 0x00: ASSERT_MIN_LEN(payload_len, 2); - memset(image, payload[1], sizeof(image)); + memset(epd_buffer, payload[1], sizeof(epd_buffer)); ble_set_connection_speed(40); return 0; // Push buffer to display. case 0x01: ble_set_connection_speed(200); - EPD_Display(image, epd_buffer_size, 1); + EPD_Display(epd_buffer, epd_buffer_size, 1); return 0; // Set byte_pos. case 0x02: @@ -46,15 +46,15 @@ int epd_ble_handle_write(void *p) return 0; // Write data to image buffer. case 0x03: - if (byte_pos + payload_len - 1 >= sizeof(image) + 1) + if (byte_pos + payload_len - 1 >= sizeof(epd_buffer) + 1) { return 0; } - memcpy(image + byte_pos, payload + 1, payload_len - 1); + memcpy(epd_buffer + byte_pos, payload + 1, payload_len - 1); byte_pos += payload_len - 1; return 0; case 0x04: // decode & display a TIFF image - epd_display_tiff(image, byte_pos); + epd_display_tiff(epd_buffer, byte_pos); return 0; default: return 0; diff --git a/Firmware/src/epd_bw.h b/Firmware/src/epd_bw.h deleted file mode 100644 index b66761b..0000000 --- a/Firmware/src/epd_bw.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -uint8_t EPD_BW_read_temp(void); -uint8_t EPD_BW_Display(unsigned char *image, int size, uint8_t full_or_partial); -void EPD_BW_set_sleep(void); \ No newline at end of file diff --git a/Firmware/src/epd_bw.c b/Firmware/src/epd_bw_213.c similarity index 68% rename from Firmware/src/epd_bw.c rename to Firmware/src/epd_bw_213.c index 5f57c89..aba88f9 100644 --- a/Firmware/src/epd_bw.c +++ b/Firmware/src/epd_bw_213.c @@ -3,28 +3,28 @@ #include "main.h" #include "epd.h" #include "epd_spi.h" -#include "epd_bw.h" +#include "epd_bw_213.h" #include "drivers.h" #include "stack/ble/ble.h" // UC8151C or similar EPD Controller -#define _refresh_time 10 -uint8_t lut_20_part[] = +#define lut_bw_213_refresh_time 10 +uint8_t lut_bw_213_20_part[] = { - 0x20, 0x00, _refresh_time, 0x01, 0x00, 0x00, 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 + 0x20, 0x00, lut_bw_213_refresh_time, 0x01, 0x00, 0x00, 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 }; -uint8_t lut_22_part[] = +uint8_t lut_bw_213_22_part[] = { - 0x22, 0x80, _refresh_time, 0x01, 0x00, 0x00, 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 + 0x22, 0x80, lut_bw_213_refresh_time, 0x01, 0x00, 0x00, 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 }; -uint8_t lut_23_part[] = +uint8_t lut_bw_213_23_part[] = { - 0x23, 0x40, _refresh_time, 0x01, 0x00, 0x00, 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 + 0x23, 0x40, lut_bw_213_refresh_time, 0x01, 0x00, 0x00, 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 }; -_attribute_ram_code_ uint8_t EPD_BW_read_temp(void) +_attribute_ram_code_ uint8_t EPD_BW_213_read_temp(void) { uint8_t epd_temperature = 0 ; EPD_WriteCmd(0x04); @@ -46,7 +46,7 @@ _attribute_ram_code_ uint8_t EPD_BW_read_temp(void) return epd_temperature; } -_attribute_ram_code_ uint8_t EPD_BW_Display(unsigned char *image, int size, uint8_t full_or_partial) +_attribute_ram_code_ uint8_t EPD_BW_213_Display(unsigned char *image, int size, uint8_t full_or_partial) { uint8_t epd_temperature = 0 ; @@ -85,10 +85,10 @@ _attribute_ram_code_ uint8_t EPD_BW_Display(unsigned char *image, int size, uint if (!full_or_partial) { - EPD_send_lut(lut_20_part, sizeof(lut_20_part)); + EPD_send_lut(lut_bw_213_20_part, sizeof(lut_bw_213_20_part)); EPD_send_empty_lut(0x21, 260); - EPD_send_lut(lut_22_part, sizeof(lut_22_part)); - EPD_send_lut(lut_23_part, sizeof(lut_23_part)); + EPD_send_lut(lut_bw_213_22_part, sizeof(lut_bw_213_22_part)); + EPD_send_lut(lut_bw_213_23_part, sizeof(lut_bw_213_23_part)); EPD_send_empty_lut(0x24, 260); EPD_WriteCmd(0x10); @@ -107,7 +107,7 @@ _attribute_ram_code_ uint8_t EPD_BW_Display(unsigned char *image, int size, uint return epd_temperature; } -_attribute_ram_code_ void EPD_BW_set_sleep(void) +_attribute_ram_code_ void EPD_BW_213_set_sleep(void) { // Vcom and data interval setting EPD_WriteCmd(0x50); diff --git a/Firmware/src/epd_bw_213.h b/Firmware/src/epd_bw_213.h new file mode 100644 index 0000000..4019d9c --- /dev/null +++ b/Firmware/src/epd_bw_213.h @@ -0,0 +1,5 @@ +#pragma once + +uint8_t EPD_BW_213_read_temp(void); +uint8_t EPD_BW_213_Display(unsigned char *image, int size, uint8_t full_or_partial); +void EPD_BW_213_set_sleep(void); \ No newline at end of file diff --git a/Firmware/src/epd_bw_213_ice.c b/Firmware/src/epd_bw_213_ice.c new file mode 100644 index 0000000..8c8dd32 --- /dev/null +++ b/Firmware/src/epd_bw_213_ice.c @@ -0,0 +1,269 @@ +#include +#include "tl_common.h" +#include "main.h" +#include "epd.h" +#include "epd_spi.h" +#include "epd_BW_213_ice.h" +#include "drivers.h" +#include "stack/ble/ble.h" + +// SSD1675 mixed with SSD1680 EPD Controller + +#define BW_213_ice_Len 50 +uint8_t LUT_BW_213_ice_part[] = { + + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + BW_213_ice_Len, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + + +}; + +_attribute_ram_code_ uint8_t EPD_BW_213_ice_detect(void) +{ + // SW Reset + EPD_WriteCmd(0x12); + WaitMs(10); + + EPD_WriteCmd(0x2F); + if(EPD_SPI_read() != 0x01) + return 0; + return 1; +} + +_attribute_ram_code_ uint8_t EPD_BW_213_ice_read_temp(void) +{ + uint8_t epd_temperature = 0 ; + + // SW Reset + EPD_WriteCmd(0x12); + + EPD_CheckStatus_inverted(100); + + // Set Analog Block control + EPD_WriteCmd(0x74); + EPD_WriteData(0x54); + // Set Digital Block control + EPD_WriteCmd(0x7E); + EPD_WriteData(0x3B); + + // ACVCOM Setting + EPD_WriteCmd(0x2B); + EPD_WriteData(0x04); + EPD_WriteData(0x63); + + // Booster soft start + EPD_WriteCmd(0x0C); + EPD_WriteData(0x8B); + EPD_WriteData(0x9C); + EPD_WriteData(0x96); + EPD_WriteData(0x0F); + + // Driver output control + EPD_WriteCmd(0x01); + EPD_WriteData(0x28); + EPD_WriteData(0x01); + EPD_WriteData(0x01); + + // Data entry mode setting + EPD_WriteCmd(0x11); + EPD_WriteData(0x01); + + // Temperature sensor control + EPD_WriteCmd(0x18); + EPD_WriteData(0x80); + + // Set RAM X- Address Start/End + EPD_WriteCmd(0x44); + EPD_WriteData(0x00); + EPD_WriteData(0x0C); + + // Set RAM Y- Address Start/End + EPD_WriteCmd(0x45); + EPD_WriteData(0x28); + EPD_WriteData(0x01); + EPD_WriteData(0x54); + EPD_WriteData(0x00); + + // Border waveform control + EPD_WriteCmd(0x3C); + EPD_WriteData(0x01); + + // Display update control + EPD_WriteCmd(0x22); + EPD_WriteData(0xA1); + + // Master Activation + EPD_WriteCmd(0x20); + + EPD_CheckStatus_inverted(100); + + // Temperature sensor read from register + EPD_WriteCmd(0x1B); + epd_temperature = EPD_SPI_read(); + EPD_SPI_read(); + + WaitMs(5); + + // Display update control + EPD_WriteCmd(0x22); + EPD_WriteData(0xB1); + + // Master Activation + EPD_WriteCmd(0x20); + + EPD_CheckStatus_inverted(100); + + // Display update control + EPD_WriteCmd(0x21); + EPD_WriteData(0x03); + + // deep sleep + EPD_WriteCmd(0x10); + EPD_WriteData(0x01); + + return epd_temperature; +} + +_attribute_ram_code_ uint8_t EPD_BW_213_ice_Display(unsigned char *image, int size, uint8_t full_or_partial) +{ + uint8_t epd_temperature = 0 ; + + // SW Reset + EPD_WriteCmd(0x12); + + EPD_CheckStatus_inverted(100); + + // Set Analog Block control + EPD_WriteCmd(0x74); + EPD_WriteData(0x54); + // Set Digital Block control + EPD_WriteCmd(0x7E); + EPD_WriteData(0x3B); + + // ACVCOM Setting + EPD_WriteCmd(0x2B); + EPD_WriteData(0x04); + EPD_WriteData(0x63); + + // Booster soft start + EPD_WriteCmd(0x0C); + EPD_WriteData(0x8B); + EPD_WriteData(0x9C); + EPD_WriteData(0x96); + EPD_WriteData(0x0F); + + // Driver output control + EPD_WriteCmd(0x01); + EPD_WriteData(0x28); + EPD_WriteData(0x01); + EPD_WriteData(0x01); + + // Data entry mode setting + EPD_WriteCmd(0x11); + EPD_WriteData(0x01); + + // Temperature sensor control + EPD_WriteCmd(0x18); + EPD_WriteData(0x80); + + // Set RAM X- Address Start/End + EPD_WriteCmd(0x44); + EPD_WriteData(0x00); + EPD_WriteData(0x0C); + + // Set RAM Y- Address Start/End + EPD_WriteCmd(0x45); + EPD_WriteData(0x28); + EPD_WriteData(0x01); + EPD_WriteData(0x54); + EPD_WriteData(0x00); + + // Border waveform control + EPD_WriteCmd(0x3C); + EPD_WriteData(0x01); + + // Display update control + EPD_WriteCmd(0x22); + EPD_WriteData(0xA1); + + // Master Activation + EPD_WriteCmd(0x20); + + EPD_CheckStatus_inverted(100); + + // Temperature sensor read from register + EPD_WriteCmd(0x1B); + epd_temperature = EPD_SPI_read(); + EPD_SPI_read(); + + WaitMs(5); + + // Display update control + EPD_WriteCmd(0x22); + EPD_WriteData(0xB1); + + // Master Activation + EPD_WriteCmd(0x20); + + EPD_CheckStatus_inverted(100); + + // Display update control + EPD_WriteCmd(0x21); + EPD_WriteData(0x03); + + // Set RAM X address + EPD_WriteCmd(0x4E); + EPD_WriteData(0x00); + + // Set RAM Y address + EPD_WriteCmd(0x4F); + EPD_WriteData(0x28); + EPD_WriteData(0x01); + + EPD_LoadImage(image, size, 0x24); + + // Display update control + EPD_WriteCmd(0x22); + EPD_WriteData(0x40); + + int i; + if (!full_or_partial) + { + EPD_WriteCmd(0x32); + for (i = 0; i < sizeof(LUT_BW_213_ice_part); i++) + { + EPD_WriteData(LUT_BW_213_ice_part[i]); + } + } + + // Display update control + EPD_WriteCmd(0x22); + EPD_WriteData(0xC7); + + // Master Activation + EPD_WriteCmd(0x20); + + return epd_temperature; +} + +_attribute_ram_code_ void EPD_BW_213_ice_set_sleep(void) +{ + // deep sleep + EPD_WriteCmd(0x10); + EPD_WriteData(0x01); + +} \ No newline at end of file diff --git a/Firmware/src/epd_bw_213_ice.h b/Firmware/src/epd_bw_213_ice.h new file mode 100644 index 0000000..86c73ef --- /dev/null +++ b/Firmware/src/epd_bw_213_ice.h @@ -0,0 +1,6 @@ +#pragma once + +uint8_t EPD_BW_213_ice_detect(void); +uint8_t EPD_BW_213_ice_read_temp(void); +uint8_t EPD_BW_213_ice_Display(unsigned char *image, int size, uint8_t full_or_partial); +void EPD_BW_213_ice_set_sleep(void); \ No newline at end of file diff --git a/Firmware/src/epd_bwr.h b/Firmware/src/epd_bwr.h deleted file mode 100644 index 21ad7d9..0000000 --- a/Firmware/src/epd_bwr.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -uint8_t EPD_BWR_detect(void); -uint8_t EPD_BWR_read_temp(void); -uint8_t EPD_BWR_Display(unsigned char *image, int size, uint8_t full_or_partial); -void EPD_BWR_set_sleep(void); \ No newline at end of file diff --git a/Firmware/src/epd_bwr_154.c b/Firmware/src/epd_bwr_154.c new file mode 100644 index 0000000..2f007dc --- /dev/null +++ b/Firmware/src/epd_bwr_154.c @@ -0,0 +1,228 @@ +#include +#include "tl_common.h" +#include "main.h" +#include "epd.h" +#include "epd_spi.h" +#include "epd_bwr_154.h" +#include "drivers.h" +#include "stack/ble/ble.h" + +// SSD1675 mixed with SSD1680 EPD Controller + +#define BWR_154_Len 50 +uint8_t LUT_bwr_154_part[] = { + +0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + +BWR_154_Len, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x22, 0x22, 0x22, 0x22, 0x22, 0x22, +0x00, 0x00, 0x00, + +}; + +#define EPD_BWR_154_test_pattern 0xA5 +_attribute_ram_code_ uint8_t EPD_BWR_154_detect(void) +{ + // SW Reset + EPD_WriteCmd(0x12); + WaitMs(10); + + EPD_WriteCmd(0x32); + int i; + for (i = 0; i < 65; i++)// This controller has a <100 bytes LUT storage so we test if thats existing. + { + EPD_WriteData(EPD_BWR_154_test_pattern); + } + EPD_WriteCmd(0x33); + for (i = 0; i < 65; i++) + { + if(EPD_SPI_read() != EPD_BWR_154_test_pattern) + return 0; + } + return 1; +} + +_attribute_ram_code_ uint8_t EPD_BWR_154_read_temp(void) +{ + uint8_t epd_temperature = 0 ; + + // SW Reset + EPD_WriteCmd(0x12); + + EPD_CheckStatus_inverted(100); + + EPD_WriteCmd(0x01); + EPD_WriteData(0x28); + EPD_WriteData(0x01); + EPD_WriteData(0x01); + + // Data entry mode setting + EPD_WriteCmd(0x11); + EPD_WriteData(0x01); + + // Set RAM X- Address Start/End + EPD_WriteCmd(0x44); + EPD_WriteData(0x00); + EPD_WriteData(0x18); + + // Set RAM Y- Address Start/End + EPD_WriteCmd(0x45); + EPD_WriteData(0x28); + EPD_WriteData(0x01); + EPD_WriteData(0x61); + EPD_WriteData(0x00); + + // Border waveform control + EPD_WriteCmd(0x3C); + EPD_WriteData(0x05); + + // Temperature sensor control + EPD_WriteCmd(0x18); + EPD_WriteData(0x80); + + // Display update control + EPD_WriteCmd(0x22); + EPD_WriteData(0xB1); + + // Master Activation + EPD_WriteCmd(0x20); + + EPD_CheckStatus_inverted(100); + + // Temperature sensor read from register + EPD_WriteCmd(0x1B); + epd_temperature = EPD_SPI_read(); + EPD_SPI_read(); + + WaitMs(5); + + // deep sleep + EPD_WriteCmd(0x10); + EPD_WriteData(0x01); + + return epd_temperature; +} + +_attribute_ram_code_ uint8_t EPD_BWR_154_Display(unsigned char *image, int size, uint8_t full_or_partial) +{ + uint8_t epd_temperature = 0 ; + + // SW Reset + EPD_WriteCmd(0x12); + + EPD_CheckStatus_inverted(100); + + // Driver output control + EPD_WriteCmd(0x01); + EPD_WriteData(0xc7); + EPD_WriteData(0x00); + EPD_WriteData(0x01); + + // Data entry mode setting + EPD_WriteCmd(0x11); + EPD_WriteData(0x01); + + // Set RAM X- Address Start/End + EPD_WriteCmd(0x44); + EPD_WriteData(0x00); + EPD_WriteData(0x18); + + // Set RAM Y- Address Start/End + EPD_WriteCmd(0x45); + EPD_WriteData(0xc7); + EPD_WriteData(0x00); + EPD_WriteData(0x00); + EPD_WriteData(0x00); + + // Border waveform control + EPD_WriteCmd(0x3C); + EPD_WriteData(0x05); + + // Temperature sensor control + EPD_WriteCmd(0x18); + EPD_WriteData(0x80); + + // Display update control + EPD_WriteCmd(0x22); + EPD_WriteData(0xB1); + + // Master Activation + EPD_WriteCmd(0x20); + + EPD_CheckStatus_inverted(100); + + // Temperature sensor read from register + EPD_WriteCmd(0x1B); + epd_temperature = EPD_SPI_read(); + EPD_SPI_read(); + + WaitMs(5); + + // Set RAM X address + EPD_WriteCmd(0x4E); + EPD_WriteData(0x00); + + // Set RAM Y address + EPD_WriteCmd(0x4F); + EPD_WriteData(0xc7); + EPD_WriteData(0x00); + + EPD_LoadImage(image, size, 0x24); + + // Set RAM X address + EPD_WriteCmd(0x4E); + EPD_WriteData(0x00); + + // Set RAM Y address + EPD_WriteCmd(0x4F); + EPD_WriteData(0xc7); + EPD_WriteData(0x00); + + EPD_WriteCmd(0x26);// RED Color TODO make something out of it :) + int i; + for (i = 0; i < size; i++) + { + EPD_WriteData(0x00); + } + + if (!full_or_partial) + { + EPD_WriteCmd(0x32); + for (i = 0; i < sizeof(LUT_bwr_154_part); i++) + { + EPD_WriteData(LUT_bwr_154_part[i]); + } + } + + // Display update control + EPD_WriteCmd(0x22); + EPD_WriteData(0xC7); + + // Master Activation + EPD_WriteCmd(0x20); + + return epd_temperature; +} + +_attribute_ram_code_ void EPD_BWR_154_set_sleep(void) +{ + // deep sleep + EPD_WriteCmd(0x10); + EPD_WriteData(0x01); + +} \ No newline at end of file diff --git a/Firmware/src/epd_bwr_154.h b/Firmware/src/epd_bwr_154.h new file mode 100644 index 0000000..65ec3c2 --- /dev/null +++ b/Firmware/src/epd_bwr_154.h @@ -0,0 +1,6 @@ +#pragma once + +uint8_t EPD_BWR_154_detect(void); +uint8_t EPD_BWR_154_read_temp(void); +uint8_t EPD_BWR_154_Display(unsigned char *image, int size, uint8_t full_or_partial); +void EPD_BWR_154_set_sleep(void); \ No newline at end of file diff --git a/Firmware/src/epd_bwr.c b/Firmware/src/epd_bwr_213.c similarity index 87% rename from Firmware/src/epd_bwr.c rename to Firmware/src/epd_bwr_213.c index caede73..3bf5c79 100644 --- a/Firmware/src/epd_bwr.c +++ b/Firmware/src/epd_bwr_213.c @@ -3,14 +3,14 @@ #include "main.h" #include "epd.h" #include "epd_spi.h" -#include "epd_bwr.h" +#include "epd_bwr_213.h" #include "drivers.h" #include "stack/ble/ble.h" // SSD1675 mixed with SSD1680 EPD Controller -#define BWR_Len 50 -uint8_t LUT_bwr_part[] = { +#define BWR_213_Len 50 +uint8_t LUT_bwr_213_part[] = { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -18,7 +18,7 @@ uint8_t LUT_bwr_part[] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -BWR_Len, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +BWR_213_Len, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -35,8 +35,8 @@ BWR_Len, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; -#define EPD_BWR_test_pattern 0xA5 -_attribute_ram_code_ uint8_t EPD_BWR_detect(void) +#define EPD_BWR_213_test_pattern 0xA5 +_attribute_ram_code_ uint8_t EPD_BWR_213_detect(void) { // SW Reset EPD_WriteCmd(0x12); @@ -44,20 +44,20 @@ _attribute_ram_code_ uint8_t EPD_BWR_detect(void) EPD_WriteCmd(0x32); int i; - for (i = 0; i < 10; i++) + for (i = 0; i < 153; i++)// This model has a 159 bytes LUT storage so we test for that { - EPD_WriteData(EPD_BWR_test_pattern); + EPD_WriteData(EPD_BWR_213_test_pattern); } EPD_WriteCmd(0x33); - for (i = 0; i < 10; i++) + for (i = 0; i < 153; i++) { - if(EPD_SPI_read() != EPD_BWR_test_pattern) + if(EPD_SPI_read() != EPD_BWR_213_test_pattern) return 0; } return 1; } -_attribute_ram_code_ uint8_t EPD_BWR_read_temp(void) +_attribute_ram_code_ uint8_t EPD_BWR_213_read_temp(void) { uint8_t epd_temperature = 0 ; @@ -138,7 +138,7 @@ _attribute_ram_code_ uint8_t EPD_BWR_read_temp(void) return epd_temperature; } -_attribute_ram_code_ uint8_t EPD_BWR_Display(unsigned char *image, int size, uint8_t full_or_partial) +_attribute_ram_code_ uint8_t EPD_BWR_213_Display(unsigned char *image, int size, uint8_t full_or_partial) { uint8_t epd_temperature = 0 ; @@ -242,9 +242,9 @@ _attribute_ram_code_ uint8_t EPD_BWR_Display(unsigned char *image, int size, uin if (!full_or_partial) { EPD_WriteCmd(0x32); - for (i = 0; i < sizeof(LUT_bwr_part); i++) + for (i = 0; i < sizeof(LUT_bwr_213_part); i++) { - EPD_WriteData(LUT_bwr_part[i]); + EPD_WriteData(LUT_bwr_213_part[i]); } } @@ -258,7 +258,7 @@ _attribute_ram_code_ uint8_t EPD_BWR_Display(unsigned char *image, int size, uin return epd_temperature; } -_attribute_ram_code_ void EPD_BWR_set_sleep(void) +_attribute_ram_code_ void EPD_BWR_213_set_sleep(void) { // deep sleep EPD_WriteCmd(0x10); diff --git a/Firmware/src/epd_bwr_213.h b/Firmware/src/epd_bwr_213.h new file mode 100644 index 0000000..7c78125 --- /dev/null +++ b/Firmware/src/epd_bwr_213.h @@ -0,0 +1,6 @@ +#pragma once + +uint8_t EPD_BWR_213_detect(void); +uint8_t EPD_BWR_213_read_temp(void); +uint8_t EPD_BWR_213_Display(unsigned char *image, int size, uint8_t full_or_partial); +void EPD_BWR_213_set_sleep(void); \ No newline at end of file diff --git a/Firmware/src/epd_spi.c b/Firmware/src/epd_spi.c index 4016f00..966673a 100644 --- a/Firmware/src/epd_spi.c +++ b/Firmware/src/epd_spi.c @@ -6,8 +6,6 @@ #include "drivers.h" #include "stack/ble/ble.h" - - _attribute_ram_code_ void EPD_init(void) { gpio_set_func(EPD_RESET, AS_GPIO); @@ -106,19 +104,25 @@ _attribute_ram_code_ void EPD_WriteData(unsigned char data) _attribute_ram_code_ void EPD_CheckStatus(int max_ms) { - // TODO implement timout to prevent endless blocking + unsigned long timeout_start = clock_time(); + unsigned long timeout_ticks = max_ms * CLOCK_16M_SYS_TIMER_CLK_1MS; WaitMs(1); while (EPD_IS_BUSY()) { + if (clock_time() - timeout_start >= timeout_ticks) + return; // Here we had a timeout } } _attribute_ram_code_ void EPD_CheckStatus_inverted(int max_ms) { - // TODO implement timout to prevent endless blocking + unsigned long timeout_start = clock_time(); + unsigned long timeout_ticks = max_ms * CLOCK_16M_SYS_TIMER_CLK_1MS; WaitMs(1); while (!EPD_IS_BUSY()) { + if (clock_time() - timeout_start >= timeout_ticks) + return; // Here we had a timeout } } diff --git a/Firmware/src/project.mk b/Firmware/src/project.mk index 6ac2e07..0de3d73 100755 --- a/Firmware/src/project.mk +++ b/Firmware/src/project.mk @@ -10,8 +10,10 @@ $(OUT_PATH)/flash.o \ $(OUT_PATH)/time.o \ $(OUT_PATH)/epd_spi.o \ $(OUT_PATH)/epd.o \ -$(OUT_PATH)/epd_bw.o \ -$(OUT_PATH)/epd_bwr.o \ +$(OUT_PATH)/epd_bw_213.o \ +$(OUT_PATH)/epd_bwr_213.o \ +$(OUT_PATH)/epd_bw_213_ice.o \ +$(OUT_PATH)/epd_bwr_154.o \ $(OUT_PATH)/ota.o \ $(OUT_PATH)/led.o \ $(OUT_PATH)/uart.o \ diff --git a/README.md b/README.md index c796fa7..0d40089 100644 --- a/README.md +++ b/README.md @@ -49,3 +49,16 @@ void SetPixel(int x, int y, uint8_t *pDisplayBuffer) *d &= ~(0x80 >> (y & 7)); // set pixel to black } ``` + + +The following hardware is currently supported, +most displays are detected automatically if that fails you can select the correct one in the OTA flashing tool. +The graphical layout is not edited for each screen size and will not fit nicely on all especially the 1.54" Version. + +## Compatible Hanshow models: +Name |Name | Case front | Case back +:-------------------------:|:-------------------------:|:-------------------------:|:-------------------------: +Stellar-MFN@ | 2,13" 212x104 | ![](/Compatible_models/Stellar-MFN%40_Front.jpg)| ![](/Compatible_models/Stellar-MFN%40_Back.jpg) +Stellar-M3N@ | 2,13" 250x122 | ![](/Compatible_models/Stellar-M3N%40_Front.jpg)| ![](/Compatible_models/Stellar-M3N%40_Back.jpg) +Stellar-MN@ | 2,13" 250x122 | ![](/Compatible_models/Stellar-MN%40_Front.jpg)| ![](/Compatible_models/Stellar-MN%40_Back.jpg) +Stellar-S3TN@ | 1,54" 200x200 | ![](/Compatible_models/Stellar-S3TN%40_Front.jpg)| ![](/Compatible_models/Stellar-S3TN%40_Back.jpg)