Added support for TI CCxxxx chips to Tag_Flasher, AP_and_Flasher and Mini_AP_v4.

This commit is contained in:
Skip Hansen
2024-07-26 16:56:56 -07:00
parent d0ccd8ff09
commit 73e472ec21
6 changed files with 602 additions and 18 deletions

View File

@@ -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;
}

View File

@@ -0,0 +1,58 @@
#pragma once
#include <Arduino.h>
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;
};

View File

@@ -0,0 +1,397 @@
#include <Arduino.h>
#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);
}

View File

@@ -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;
}

View File

@@ -21,6 +21,7 @@ CMD_PASS_THROUGH = 50
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):

View File

@@ -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)