diff --git a/ESP32_AP-Flasher/src/usbflasher.cpp b/ESP32_AP-Flasher/src/usbflasher.cpp index 1a100c33..a7bd5e9f 100644 --- a/ESP32_AP-Flasher/src/usbflasher.cpp +++ b/ESP32_AP-Flasher/src/usbflasher.cpp @@ -20,6 +20,7 @@ USBCDC USBSerial; #include "web.h" #include "webflasher.h" #include "zbs_interface.h" +#include "cc_interface.h" QueueHandle_t flasherCmdQueue; @@ -310,6 +311,7 @@ typedef enum { CMD_SELECT_ZBS243 = 60, CMD_SELECT_NRF82511 = 61, + CMD_SELECT_CC = 62, CMD_SELECT_PORT = 70, @@ -323,15 +325,17 @@ typedef enum { CMD_WRITE_ERROR = 99, } ZBS_UART_PROTO; -uint32_t FLASHER_VERSION = 0x00000031; +uint32_t FLASHER_VERSION = 0x00000032; #define CONTROLLER_ZBS243 0 #define CONTROLLER_NRF82511 1 +#define CONTROLLER_CC 2 uint8_t selectedController = 0; uint8_t selectedFlasherPort; uint32_t currentFlasherOffset; flasher* zbsflasherp = nullptr; nrfswd* nrfflasherp = nullptr; +CC_interface *ccflasherp = nullptr; void processFlasherCommand(struct flasherCommand* cmd, uint8_t transportType) { uint8_t* tempbuffer; @@ -400,6 +404,9 @@ void processFlasherCommand(struct flasherCommand* cmd, uint8_t transportType) { } else if (selectedController == CONTROLLER_ZBS243) { if (zbsflasherp == nullptr) return; zbsflasherp->zbs->erase_flash(); + } else if (selectedController == CONTROLLER_CC) { + if (ccflasherp == nullptr) return; + ccflasherp->erase_chip(); } sendFlasherAnswer(CMD_ERASE_FLASH, NULL, 0, transportType); break; @@ -451,6 +458,14 @@ void processFlasherCommand(struct flasherCommand* cmd, uint8_t transportType) { currentFlasherOffset = 0; selectedController = CONTROLLER_NRF82511; break; + case CMD_SELECT_CC: + ccflasherp = new CC_interface; + ccflasherp->begin(FLASHER_EXT_CLK,FLASHER_EXT_MISO,FLASHER_EXT_RESET); + temp_buff[0] = 1; + sendFlasherAnswer(CMD_SELECT_CC, temp_buff, 1,transportType); + currentFlasherOffset = 0; + selectedController = CONTROLLER_CC; + break; case CMD_READ_FLASH: wsSerial("> read flash"); uint8_t* bufferp; @@ -481,6 +496,19 @@ void processFlasherCommand(struct flasherCommand* cmd, uint8_t transportType) { sendFlasherAnswer(CMD_READ_FLASH, bufferp, cur_len, transportType); if (bufferp != nullptr) free(bufferp); } + } else if (selectedController == CONTROLLER_CC) { + if (ccflasherp == nullptr) return; + if (currentFlasherOffset >= 32768) { + sendFlasherAnswer(CMD_COMPLETE, temp_buff, 1,transportType); + } else { + bufferp = (uint8_t*)malloc(1024); + if (bufferp == nullptr) return; + cur_len = (32768 - currentFlasherOffset >= 1024) ? 1024 : 32768 - currentFlasherOffset; + ccflasherp->read_code_memory(currentFlasherOffset,cur_len,bufferp); + currentFlasherOffset += cur_len; + sendFlasherAnswer(CMD_READ_FLASH, bufferp, cur_len,transportType); + free(bufferp); + } } break; case CMD_READ_INFOPAGE: @@ -550,6 +578,15 @@ void processFlasherCommand(struct flasherCommand* cmd, uint8_t transportType) { currentFlasherOffset += cmd->len; sendFlasherAnswer(CMD_WRITE_FLASH, NULL, 0, transportType); } + } else if (selectedController == CONTROLLER_CC) { + if (currentFlasherOffset >= 32768) { + sendFlasherAnswer(CMD_COMPLETE, temp_buff, 1, transportType); + } else { + if (ccflasherp == nullptr) return; + ccflasherp->write_code_memory(currentFlasherOffset, cmd->data, cmd->len); + currentFlasherOffset += cmd->len; + sendFlasherAnswer(CMD_WRITE_FLASH, NULL, 0, transportType); + } } break; case CMD_WRITE_INFOPAGE: @@ -603,6 +640,10 @@ void processFlasherCommand(struct flasherCommand* cmd, uint8_t transportType) { cmdSerial.println("Not yet implemented!"); } break; + + default: + cmdSerial.printf("Ignored flasher command 0x%x.\r\n",cmd->command); + break; } } @@ -618,6 +659,10 @@ void flasherCommandTimeout() { delete nrfflasherp; nrfflasherp = nullptr; } + if (ccflasherp != nullptr) { + delete ccflasherp; + ccflasherp = nullptr; + } lastCmdTimeStamp = 0; } diff --git a/Tag_Flasher/ESP32_Flasher/include/cc_interface.h b/Tag_Flasher/ESP32_Flasher/include/cc_interface.h new file mode 100644 index 00000000..c4053800 --- /dev/null +++ b/Tag_Flasher/ESP32_Flasher/include/cc_interface.h @@ -0,0 +1,58 @@ +#pragma once +#include + +typedef void (*callbackPtr)(uint8_t percent); + +class CC_interface +{ + public: + uint16_t begin(uint8_t CC, uint8_t DD, uint8_t RESET); + void set_callback(callbackPtr callBack = nullptr); + uint8_t set_lock_byte(uint8_t lock_byte); + uint8_t erase_chip(); + void read_code_memory(uint16_t address, uint16_t len, uint8_t buffer[]); + void read_xdata_memory(uint16_t address, uint16_t len, uint8_t buffer[]); + void write_xdata_memory(uint16_t address, uint16_t len, uint8_t buffer[]); + void set_pc(uint16_t address); + uint8_t clock_init(); + uint8_t write_code_memory(uint16_t address, uint8_t buffer[], int len); + uint8_t verify_code_memory(uint16_t address, uint8_t buffer[], int len); + uint8_t opcode(uint8_t opCode); + uint8_t opcode(uint8_t opCode, uint8_t opCode1); + uint8_t opcode(uint8_t opCode, uint8_t opCode1, uint8_t opCode2); + uint8_t WR_CONFIG(uint8_t config); + uint8_t WD_CONFIG(); + /* Send one byte and return one byte as answer */ + uint8_t send_cc_cmdS(uint8_t cmd); + /* Send one byte and returns two bytes as answer */ + uint16_t send_cc_cmd(uint8_t cmd); + void cc_send_byte(uint8_t in_byte); + uint8_t cc_receive_byte(); + void enable_cc_debug(); + void reset_cc(); + + private: + boolean dd_direction = 0; // 0=OUT 1=IN + uint8_t _CC_PIN = -1; + uint8_t _DD_PIN = -1; + uint8_t _RESET_PIN = -1; + uint8_t flash_opcode[30] = { + 0x75, 0xAD, 0x00, // Set Flash Address HIGH + 0x75, 0xAC, 0x00, // Set Flash Address LOW + 0x90, 0xF0, 0x00, // Set RAM Address to 0xF000 + 0x75, 0xAE, 0x02, // Enable Flash Writing + 0x7D, 0x08, // Set Loop value to Half size as we write 2bytes at once 0x100 + 0xE0, // Put DPTR to A + 0xF5, 0xAF, // Put A to FWDATA + 0xA3, // Increase DPTR; + 0xE0, // Put DPTR to A + 0xF5, 0xAF, // Put A to FWDATA + 0xA3, // Increase DPTR + 0xE5, 0xAE, // Wait till writing is done + 0x20, 0xE6, 0xFB, + 0xDD, 0xF1, // Loop trough all bytes + 0xA5 // Breakpoint + }; + callbackPtr _callback = nullptr; +}; + diff --git a/Tag_Flasher/ESP32_Flasher/src/cc_interface.cpp b/Tag_Flasher/ESP32_Flasher/src/cc_interface.cpp new file mode 100644 index 00000000..7b78d63a --- /dev/null +++ b/Tag_Flasher/ESP32_Flasher/src/cc_interface.cpp @@ -0,0 +1,397 @@ +#include +#include "cc_interface.h" + +uint16_t CC_interface::begin(uint8_t CC, uint8_t DD, uint8_t RESET) +{ + _CC_PIN = CC; + _DD_PIN = DD; + _RESET_PIN = RESET; + + pinMode(_CC_PIN, OUTPUT); + pinMode(_DD_PIN, OUTPUT); + pinMode(_RESET_PIN, OUTPUT); + digitalWrite(_CC_PIN, LOW); + digitalWrite(_DD_PIN, HIGH); + digitalWrite(_RESET_PIN, HIGH); + + enable_cc_debug(); + uint16_t device_id_answer = send_cc_cmd(0x68); + opcode(0x00); // NOP + clock_init(); // Even with failed clock init return the device id, because if the device is locked setting clock will fail + return device_id_answer; +} + +void CC_interface::set_callback(callbackPtr callBack) +{ + _callback = callBack; +} + +uint8_t CC_interface::set_lock_byte(uint8_t lock_byte) +{ + lock_byte = lock_byte & 0x1f; // Max lock byte value + WR_CONFIG(0x01); // Select flash info Page + opcode(0x00); // NOP + + opcode(0xE5, 0x92); + opcode(0x75, 0x92, 0x00); + opcode(0xE5, 0x83); + opcode(0xE5, 0x82); + opcode(0x90, 0xF0, 0x00); + opcode(0x74, 0xFF); + opcode(0xF0); + opcode(0xA3); // Increase Pointer + opcode(0x74, lock_byte); // Transmit the set lock byte + opcode(0xF0); + opcode(0xA3); // Increase Pointer + opcode(0x90, 0x00, 0x00); + opcode(0x75, 0x92, 0x00); + opcode(0x74, 0x00); + + opcode(0x00); // NOP + + opcode(0xE5, 0x92); + opcode(0x75, 0x92, 0x00); + opcode(0xE5, 0x83); + opcode(0xE5, 0x82); + opcode(0x90, 0xF8, 0x00); + opcode(0x74, 0xF0); + opcode(0xF0); + opcode(0xA3); // Increase Pointer + opcode(0x74, 0x00); + opcode(0xF0); + opcode(0xA3); // Increase Pointer + opcode(0x74, 0xDF); + opcode(0xF0); + opcode(0xA3); // Increase Pointer + opcode(0x74, 0xAF); + opcode(0xF0); + opcode(0xA3); // Increase Pointer + opcode(0x74, 0x00); + opcode(0xF0); + opcode(0xA3); // Increase Pointer + opcode(0x74, 0x02); + opcode(0xF0); + opcode(0xA3); // Increase Pointer + opcode(0x74, 0x12); + opcode(0xF0); + opcode(0xA3); // Increase Pointer + opcode(0x74, 0x4A); + opcode(0xF0); + opcode(0xA3); // Increase Pointer + opcode(0x90, 0x00, 0x00); + opcode(0x75, 0x92, 0x00); + opcode(0x74, 0x00); + + opcode(0x00); // NOP + + opcode(0xE5, 0xC6); + opcode(0x74, 0x00); + opcode(0x75, 0xAB, 0x23); + opcode(0x75, 0xD5, 0xF8); + opcode(0x75, 0xD4, 0x00); + opcode(0x75, 0xD6, 0x01); + opcode(0x75, 0xAD, 0x00); + opcode(0x75, 0xAC, 0x00); + opcode(0x75, 0xAE, 0x02); + + opcode(0x00); // NOP + + opcode(0xE5, 0xAE); + opcode(0x74, 0x00); + + return WR_CONFIG(0x00); // Select normal flash page +} + +uint8_t CC_interface::erase_chip() +{ + opcode(0x00); // NOP + send_cc_cmdS(0x14); + int timeout = millis() + 100; + while (!(send_cc_cmdS(0x34) & 0x80)) + { + if (millis() > timeout) + { + return 1; + } + } + return 0; +} + +void CC_interface::read_code_memory(uint16_t address, uint16_t len, uint8_t buffer[]) +{ + int last_callback = 0; + opcode(0x75, 0xc7, 0x01); + opcode(0x90, address >> 8, address); + for (int i = 0; i < len; i++) + { + opcode(0xe4); + buffer[i] = opcode(0x93); + opcode(0xa3); + if (i - last_callback > 100) + { + last_callback = i; + if (_callback != nullptr) + { + uint8_t percent = ((float)((float)i / (float)len) * 100.0); + if (percent < 0) + percent = 0; + if (percent > 100) + percent = 100; + _callback(percent); + } + } + } + if (_callback != nullptr) + _callback(100); +} + +void CC_interface::read_xdata_memory(uint16_t address, uint16_t len, uint8_t buffer[]) +{ + opcode(0x90, address >> 8, address); + for (int i = 0; i < len; i++) + { + buffer[i] = opcode(0xe0); + opcode(0xa3); + } +} + +void CC_interface::write_xdata_memory(uint16_t address, uint16_t len, uint8_t buffer[]) +{ + opcode(0x90, address >> 8, address); + for (int i = 0; i < len; i++) + { + opcode(0x74, buffer[i]); + opcode(0xf0); + opcode(0xa3); + } +} + +void CC_interface::set_pc(uint16_t address) +{ + opcode(0x02, address >> 8, address); +} + +uint8_t CC_interface::clock_init() +{ + opcode(0x75, 0xc6, 0x00); + int timeout = millis() + 100; + while (!(opcode(0xe5, 0xbe) & 0x40)) + { + if (millis() > timeout) + { + return 1; + } + } + return 0; +} + +uint8_t CC_interface::write_code_memory(uint16_t address, uint8_t buffer[], int len) +{ + int entry_len = len; + if (len % 2 != 0) + len++; + int position = 0; + int len_per_transfer = 64; + address = address / 2; + while (len) + { + flash_opcode[2] = (address >> 8) & 0xff; + flash_opcode[5] = address & 0xff; + flash_opcode[13] = (len > len_per_transfer) ? (len_per_transfer / 2) : (len / 2); + write_xdata_memory(0xf000, len_per_transfer, &buffer[position]); + write_xdata_memory(0xf100, sizeof(flash_opcode), flash_opcode); + opcode(0x75, 0xC7, 0x51); + set_pc(0xf100); + send_cc_cmdS(0x4c); + int timeout = millis() + 500; + while (!(send_cc_cmdS(0x34) & 0x08)) + { + if (millis() > timeout) + { + if (_callback != nullptr) + _callback(0); + return 1; + } + } + if (_callback != nullptr) + { + uint8_t percent = 100 - ((float)((float)len / (float)entry_len) * 100.0); + if (percent < 0) + percent = 0; + if (percent > 100) + percent = 100; + _callback(percent); + } + len -= flash_opcode[13] * 2; + position += flash_opcode[13] * 2; + address += flash_opcode[13]; + } + if (_callback != nullptr) + _callback(100); + return 0; +} + +uint8_t CC_interface::verify_code_memory(uint16_t address, uint8_t buffer[], int len) +{ + int last_callback = 0; + opcode(0x75, 0xc7, 0x01); + opcode(0x90, address >> 8, address); + for (int i = 0; i < len; i++) + { + opcode(0xe4); + if (buffer[i] != opcode(0x93)) + { + if (_callback != nullptr) + _callback(0); + return 1; + } + opcode(0xa3); + if (i - last_callback > 100) + { + last_callback = i; + if (_callback != nullptr) + { + uint8_t percent = ((float)((float)i / (float)len) * 100.0); + if (percent < 0) + percent = 0; + if (percent > 100) + percent = 100; + _callback(percent); + } + } + } + if (_callback != nullptr) + _callback(100); + return 0; +} + +uint8_t CC_interface::opcode(uint8_t opCode) +{ + cc_send_byte(0x55); + cc_send_byte(opCode); + return cc_receive_byte(); +} + +uint8_t CC_interface::opcode(uint8_t opCode, uint8_t opCode1) +{ + cc_send_byte(0x56); + cc_send_byte(opCode); + cc_send_byte(opCode1); + return cc_receive_byte(); +} + +uint8_t CC_interface::opcode(uint8_t opCode, uint8_t opCode1, uint8_t opCode2) +{ + cc_send_byte(0x57); + cc_send_byte(opCode); + cc_send_byte(opCode1); + cc_send_byte(opCode2); + return cc_receive_byte(); +} + +uint8_t CC_interface::WR_CONFIG(uint8_t config) +{ + cc_send_byte(0x1d); + cc_send_byte(config); + return cc_receive_byte(); +} + +uint8_t CC_interface::WD_CONFIG() +{ + cc_send_byte(0x24); + return cc_receive_byte(); +} + +uint8_t CC_interface::send_cc_cmdS(uint8_t cmd) +{ + cc_send_byte(cmd); + return cc_receive_byte(); +} + +uint16_t CC_interface::send_cc_cmd(uint8_t cmd) +{ + cc_send_byte(cmd); + return (cc_receive_byte() << 8) + cc_receive_byte(); +} + +void CC_interface::cc_send_byte(uint8_t in_byte) +{ + if (dd_direction == 1) + { + dd_direction = 0; + pinMode(_DD_PIN, OUTPUT); + digitalWrite(_DD_PIN, LOW); + } + for (int i = 8; i; i--) + { + if (in_byte & 0x80) + digitalWrite(_DD_PIN, HIGH); + else + digitalWrite(_DD_PIN, LOW); + + digitalWrite(_CC_PIN, HIGH); + in_byte <<= 1; + delayMicroseconds(5); + digitalWrite(_CC_PIN, LOW); + } +} + +uint8_t CC_interface::cc_receive_byte() +{ + uint8_t out_byte = 0x00; + if (dd_direction == 0) + { + dd_direction = 1; + pinMode(_DD_PIN, INPUT); + digitalWrite(_DD_PIN, LOW); + } + for (int i = 8; i; i--) + { + digitalWrite(_CC_PIN, HIGH); + delayMicroseconds(5); + out_byte <<= 1; + if (digitalRead(_DD_PIN)) + out_byte |= 0x01; + digitalWrite(_CC_PIN, LOW); + delayMicroseconds(5); + } + return out_byte; +} + +void CC_interface::enable_cc_debug() +{ + if (dd_direction == 0) + { + dd_direction = 1; + pinMode(_DD_PIN, INPUT); + digitalWrite(_DD_PIN, HIGH); + } + delay(5); + digitalWrite(_RESET_PIN, LOW); + delay(2); + digitalWrite(_CC_PIN, HIGH); + delayMicroseconds(5); + digitalWrite(_CC_PIN, LOW); + delayMicroseconds(5); + digitalWrite(_CC_PIN, HIGH); + delayMicroseconds(5); + digitalWrite(_CC_PIN, LOW); + delay(2); + digitalWrite(_RESET_PIN, HIGH); + delay(2); +} + +void CC_interface::reset_cc() +{ + if (dd_direction == 0) + { + dd_direction = 1; + pinMode(_DD_PIN, INPUT); + digitalWrite(_DD_PIN, HIGH); + } + delay(5); + digitalWrite(_RESET_PIN, LOW); + delay(5); + digitalWrite(_RESET_PIN, HIGH); + delay(2); +} diff --git a/Tag_Flasher/ESP32_Flasher/src/usbflasher.cpp b/Tag_Flasher/ESP32_Flasher/src/usbflasher.cpp index 29a26dfa..570c3afb 100644 --- a/Tag_Flasher/ESP32_Flasher/src/usbflasher.cpp +++ b/Tag_Flasher/ESP32_Flasher/src/usbflasher.cpp @@ -7,6 +7,7 @@ #include "settings.h" #include "swd.h" #include "zbs_interface.h" +#include "cc_interface.h" USBCDC USBSerial; @@ -302,6 +303,7 @@ typedef enum { CMD_SELECT_ZBS243 = 60, CMD_SELECT_NRF82511 = 61, + CMD_SELECT_CC = 62, CMD_SELECT_EEPROM_PT = 69, CMD_SELECT_PORT = 70, @@ -316,15 +318,17 @@ typedef enum { CMD_WRITE_EEPROM = 91 } ZBS_UART_PROTO; -uint32_t FLASHER_VERSION = 0x00000030; +uint32_t FLASHER_VERSION = 0x00000032; #define CONTROLLER_ZBS243 0 #define CONTROLLER_NRF82511 1 +#define CONTROLLER_CC 2 uint8_t selectedController = 0; uint8_t selectedFlasherPort; uint32_t currentFlasherOffset = 0; flasher* zbsflasherp; nrfswd* nrfflasherp; +CC_interface *ccflasherp; uint8_t waitSerialReply() { uint8_t cmd[4] = {0}; @@ -472,6 +476,10 @@ void processFlasherCommand(struct flasherCommand* cmd) { nrfflasherp->nrf_soft_reset(); delete nrfflasherp; nrfflasherp = nullptr; + } else if (ccflasherp != nullptr) { + ccflasherp->reset_cc(); + delete ccflasherp; + ccflasherp = nullptr; } else { pinMode(FLASHER_EXT_RESET, OUTPUT); digitalWrite(FLASHER_EXT_RESET, LOW); @@ -485,6 +493,9 @@ void processFlasherCommand(struct flasherCommand* cmd) { } else if (selectedController == CONTROLLER_ZBS243) { if (zbsflasherp == nullptr) return; zbsflasherp->zbs->erase_flash(); + } else if (selectedController == CONTROLLER_CC) { + if (ccflasherp == nullptr) return; + ccflasherp->erase_chip(); } sendFlasherAnswer(CMD_ERASE_FLASH, NULL, 0); break; @@ -501,6 +512,9 @@ void processFlasherCommand(struct flasherCommand* cmd) { if (selectedController == CONTROLLER_NRF82511) { if (nrfflasherp == nullptr) return; nrfflasherp->nrf_erase_all(); + } else if (selectedController == CONTROLLER_CC) { + if (ccflasherp == nullptr) return; + ccflasherp->erase_chip(); } sendFlasherAnswer(CMD_ERASE_ALL, NULL, 0); break; @@ -515,8 +529,15 @@ void processFlasherCommand(struct flasherCommand* cmd) { currentFlasherOffset = 0; selectedController = CONTROLLER_ZBS243; break; + case CMD_SELECT_CC: + ccflasherp = new CC_interface; + ccflasherp->begin(FLASHER_EXT_CLK,FLASHER_EXT_MISO,FLASHER_EXT_RESET); + temp_buff[0] = 1; + sendFlasherAnswer(CMD_SELECT_CC, temp_buff, 1); + currentFlasherOffset = 0; + selectedController = CONTROLLER_CC; + break; case CMD_SELECT_NRF82511: - // powerControl(true, (uint8_t*)powerPins2, 4); nrfflasherp = new nrfswd(FLASHER_EXT_MISO, FLASHER_EXT_CLK); nrfflasherp->showDebug = false; @@ -567,6 +588,19 @@ void processFlasherCommand(struct flasherCommand* cmd) { sendFlasherAnswer(CMD_READ_FLASH, bufferp, cur_len); if (bufferp != nullptr) free(bufferp); } + } else if (selectedController == CONTROLLER_CC) { + if (ccflasherp == nullptr) return; + if (currentFlasherOffset >= 32768) { + sendFlasherAnswer(CMD_COMPLETE, temp_buff, 1); + } else { + bufferp = (uint8_t*)malloc(256); + if (bufferp == nullptr) return; + cur_len = (32768 - currentFlasherOffset >= 256) ? 256 : 32768 - currentFlasherOffset; + ccflasherp->read_code_memory(currentFlasherOffset,cur_len,bufferp); + currentFlasherOffset += cur_len; + sendFlasherAnswer(CMD_READ_FLASH, bufferp, cur_len); + free(bufferp); + } } else { Serial0.printf("No controller type selected\n"); } @@ -632,6 +666,15 @@ void processFlasherCommand(struct flasherCommand* cmd) { currentFlasherOffset += cmd->len; sendFlasherAnswer(CMD_WRITE_FLASH, NULL, 0); } + } else if (selectedController == CONTROLLER_CC) { + if (currentFlasherOffset >= 32768) { + sendFlasherAnswer(CMD_COMPLETE, temp_buff, 1); + } else { + if (ccflasherp == nullptr) return; + ccflasherp->write_code_memory(currentFlasherOffset, cmd->data, cmd->len); + currentFlasherOffset += cmd->len; + sendFlasherAnswer(CMD_WRITE_FLASH, NULL, 0); + } } break; case CMD_WRITE_INFOPAGE: @@ -687,6 +730,10 @@ void flasherCommandTimeout() { delete nrfflasherp; nrfflasherp = nullptr; } + if (ccflasherp != nullptr) { + delete ccflasherp; + ccflasherp = nullptr; + } lastCmdTimeStamp = 0; } diff --git a/Tag_Flasher/OEPL-Flasher.py b/Tag_Flasher/OEPL-Flasher.py index dab91a57..0cc026c0 100644 --- a/Tag_Flasher/OEPL-Flasher.py +++ b/Tag_Flasher/OEPL-Flasher.py @@ -21,6 +21,7 @@ CMD_SELECT_ZBS243 = 60 CMD_SELECT_NRF82511 = 61 +CMD_SELECT_CC = 62 CMD_SELECT_EEPROM_PT = 69 @@ -140,8 +141,8 @@ def validate_arguments(args): list_available_com_ports() return False if args.command: - if not (args.nrf82511 or args.zbs243): - print("Either -nrf82511 or -zbs243 option is required.") + if not (args.nrf82511 or args.zbs243 or args.ccxxxx): + print("Either -nrf82511, -zbs243 or -ccxxxx option is required.") return False if not (args.internalap or args.external or args.altradio): print("Using external port") @@ -161,6 +162,19 @@ def validate_arguments(args): if args.command == "read" and len(args.filename) < 2: print("Please specify a file to save read data") return False + if args.ccxxxx: + if args.infopage: + print("-ccxxxx does not support --infopage") + return False + if args.eeprom: + print("-ccxxxx does not support --eeprom argument"); + return False + if args.command == "autoflash": + print("-ccxxxx does not support autoflash command."); + return False + if args.command == "debug": + print("-ccxxxx does not support debug command."); + return False return True @@ -295,6 +309,9 @@ def main(): help="nRF82511 programming") parser.add_argument("-z", "--zbs243", action="store_true", help="ZBS243 programming") + parser.add_argument("-c", "--ccxxxx", action="store_true", + help="CCxxxx programming") + parser.add_argument("--internalap", action="store_true", help="Selects the internal accesspoint port") parser.add_argument("-e", "--external", action="store_true", @@ -379,6 +396,9 @@ def main(): send_cmd(CMD_SELECT_NRF82511, bytearray([])) if args.zbs243: send_cmd(CMD_SELECT_ZBS243, bytearray([])) + if args.ccxxxx: + send_cmd(CMD_SELECT_CC, bytearray([])) + cmd, answer = wait_for_command() if (answer[0] == 1): diff --git a/Tag_Flasher/README.md b/Tag_Flasher/README.md index 2ae414bc..6a48fe34 100644 --- a/Tag_Flasher/README.md +++ b/Tag_Flasher/README.md @@ -5,6 +5,7 @@ You can use the following flasher-scripts to program various types of tags with * ZBS243-based tags * nRF52-based tags * 88MZ100-based tags +* cc1110-based tags This is the schematic for the flasher, including a pinout for the debug-header that is used by quite a few Solum tags. This flasher is also compatible with the OEPL-AP-Flasher jig/programming boards. ![image](https://github.com/jjwbruijn/OpenEPaperLink/assets/2544995/1fa5bef8-6624-4e53-9caa-aeaaf4dbdc55) @@ -18,18 +19,18 @@ This is what it looks like with the wires connected. I've chosen to use 0.635mm * R - required * O - optional -| Flasher Pin | Cable Pin | ESP32-S2 Pin | ZBS | nRF | 88mz100 | -| :---------: | :-------: | :------------: | :---: | :---: | :-----: | -| VCC | 1 | 16, 17, 18, 21 | R | R | R | -| CS | 2 | 34 | R | | | -| GND | 3 | GND | R | R | R | -| CLK | 4 | 33 | R | R | | -| TXD | 5 | 36 | O | O | R | -| MISO | 6 | 35 | R | R | | -| TEST | 7 | 38 | | | | -| MOSI | 8 | 37 | R | | | -| RXD | 9 | 40 | O | O | R | -| RSET | 10 | 39 | R | | O | +| Flasher Pin | Cable Pin | ESP32-S2 Pin | ZBS | nRF | 88mz100 | CC1110 | +| :---------: | :-------: | :------------: | :---: | :---: | :-----: | :----: | +| VCC | 1 | 16, 17, 18, 21 | R | R | R | R | +| CS | 2 | 34 | R | | | | +| GND | 3 | GND | R | R | R | R | +| CLK | 4 | 33 | R | R | | (DC) R | +| TXD | 5 | 36 | O | O | R | | +| MISO | 6 | 35 | R | R | | (DD) R | +| TEST | 7 | 38 | | | | | +| MOSI | 8 | 37 | R | | | | +| RXD | 9 | 40 | O | O | R | | +| RESET | 10 | 39 | R | | O | R | Not all connections are required by all tags! If you want to solder fewer wires, skip the optional and unused ones. @@ -43,7 +44,7 @@ Also, the precompiled binaries are part of any [release](https://github.com/jjwb This script connects to the S2-mini's serial port and enables flashing to ZBS243 and nRF52811-based tags. ```shell -usage: OEPL-Flasher.py [-h] [-p PORT] [-f] [-i] [-n] [-z] [--internalap] [-e] [--altradio] [--pt] {read,write,autoflash,debug} [filename] +usage: OEPL-Flasher.py [-h] [-p PORT] [-f] [-i] [-n] [-z] [-c] [--internalap] [-e] [--altradio] [--pt] {read,write,autoflash,debug} [filename] OpenEPaperLink Flasher for AP/Flasher board @@ -59,6 +60,7 @@ options: -i, --infopage Write to the infopage/UICR -n, --nrf82511 nRF82511 programming -z, --zbs243 ZBS243 programming + -c, --ccxxxx CCxxxx programming --internalap Selects the internal accesspoint port -e, --external Selects the external(side) port --altradio Selects the alternate radio port @@ -102,9 +104,24 @@ The Tag-Flasher is used in serial passthrough-mode in order to flash the 88MZ100 python3 .\88MZ100-OEPL-Flasher.py COM31 write_flash '0130c8144117.bin' ``` +## TI CC1110-based + +Use with the -c option for CC1110. Neigher Autoflash is currently not implemented on the Tag_Flasher/S2 version. + +The CC1110 does not have an infopage nor is the Tag's EEPROM accessable. + +```shell +python3 OEPL-Flasher.py -e -c -p COM31 read blaat.bin --flash +``` + +See this [page](https://github.com/OpenEPaperLink/OpenEPaperLink/wiki/Chroma-Series-SubGhz-Tags#flashing-cc1110-based-chroma-tags) +on the Wiki for additional information. + ## Credits Much code was reused from ATC1441's various flashers * [ATC1441's ESP32-NRF52-SWD](https://github.com/atc1441/ESP32_nRF52_SWD) * [ATC1441's ZBS-Flasher](https://github.com/atc1441/ZBS_Flasher) * [ATC1441's 88MZ100 Flasher](https://github.com/atc1441/88MZ100/tree/master/88MZ100_Flasher) +* [ATC1441's ESP_CC_Flasher](https://github.com/atc1441/ESP_CC_Flasher) +