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 "web.h"
#include "webflasher.h" #include "webflasher.h"
#include "zbs_interface.h" #include "zbs_interface.h"
#include "cc_interface.h"
QueueHandle_t flasherCmdQueue; QueueHandle_t flasherCmdQueue;
@@ -310,6 +311,7 @@ typedef enum {
CMD_SELECT_ZBS243 = 60, CMD_SELECT_ZBS243 = 60,
CMD_SELECT_NRF82511 = 61, CMD_SELECT_NRF82511 = 61,
CMD_SELECT_CC = 62,
CMD_SELECT_PORT = 70, CMD_SELECT_PORT = 70,
@@ -323,15 +325,17 @@ typedef enum {
CMD_WRITE_ERROR = 99, CMD_WRITE_ERROR = 99,
} ZBS_UART_PROTO; } ZBS_UART_PROTO;
uint32_t FLASHER_VERSION = 0x00000031; uint32_t FLASHER_VERSION = 0x00000032;
#define CONTROLLER_ZBS243 0 #define CONTROLLER_ZBS243 0
#define CONTROLLER_NRF82511 1 #define CONTROLLER_NRF82511 1
#define CONTROLLER_CC 2
uint8_t selectedController = 0; uint8_t selectedController = 0;
uint8_t selectedFlasherPort; uint8_t selectedFlasherPort;
uint32_t currentFlasherOffset; uint32_t currentFlasherOffset;
flasher* zbsflasherp = nullptr; flasher* zbsflasherp = nullptr;
nrfswd* nrfflasherp = nullptr; nrfswd* nrfflasherp = nullptr;
CC_interface *ccflasherp = nullptr;
void processFlasherCommand(struct flasherCommand* cmd, uint8_t transportType) { void processFlasherCommand(struct flasherCommand* cmd, uint8_t transportType) {
uint8_t* tempbuffer; uint8_t* tempbuffer;
@@ -400,6 +404,9 @@ void processFlasherCommand(struct flasherCommand* cmd, uint8_t transportType) {
} else if (selectedController == CONTROLLER_ZBS243) { } else if (selectedController == CONTROLLER_ZBS243) {
if (zbsflasherp == nullptr) return; if (zbsflasherp == nullptr) return;
zbsflasherp->zbs->erase_flash(); zbsflasherp->zbs->erase_flash();
} else if (selectedController == CONTROLLER_CC) {
if (ccflasherp == nullptr) return;
ccflasherp->erase_chip();
} }
sendFlasherAnswer(CMD_ERASE_FLASH, NULL, 0, transportType); sendFlasherAnswer(CMD_ERASE_FLASH, NULL, 0, transportType);
break; break;
@@ -451,6 +458,14 @@ void processFlasherCommand(struct flasherCommand* cmd, uint8_t transportType) {
currentFlasherOffset = 0; currentFlasherOffset = 0;
selectedController = CONTROLLER_NRF82511; selectedController = CONTROLLER_NRF82511;
break; 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: case CMD_READ_FLASH:
wsSerial("> read flash"); wsSerial("> read flash");
uint8_t* bufferp; uint8_t* bufferp;
@@ -481,6 +496,19 @@ void processFlasherCommand(struct flasherCommand* cmd, uint8_t transportType) {
sendFlasherAnswer(CMD_READ_FLASH, bufferp, cur_len, transportType); sendFlasherAnswer(CMD_READ_FLASH, bufferp, cur_len, transportType);
if (bufferp != nullptr) free(bufferp); 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; break;
case CMD_READ_INFOPAGE: case CMD_READ_INFOPAGE:
@@ -550,6 +578,15 @@ void processFlasherCommand(struct flasherCommand* cmd, uint8_t transportType) {
currentFlasherOffset += cmd->len; currentFlasherOffset += cmd->len;
sendFlasherAnswer(CMD_WRITE_FLASH, NULL, 0, transportType); 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; break;
case CMD_WRITE_INFOPAGE: case CMD_WRITE_INFOPAGE:
@@ -603,6 +640,10 @@ void processFlasherCommand(struct flasherCommand* cmd, uint8_t transportType) {
cmdSerial.println("Not yet implemented!"); cmdSerial.println("Not yet implemented!");
} }
break; break;
default:
cmdSerial.printf("Ignored flasher command 0x%x.\r\n",cmd->command);
break;
} }
} }
@@ -618,6 +659,10 @@ void flasherCommandTimeout() {
delete nrfflasherp; delete nrfflasherp;
nrfflasherp = nullptr; nrfflasherp = nullptr;
} }
if (ccflasherp != nullptr) {
delete ccflasherp;
ccflasherp = nullptr;
}
lastCmdTimeStamp = 0; 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 "settings.h"
#include "swd.h" #include "swd.h"
#include "zbs_interface.h" #include "zbs_interface.h"
#include "cc_interface.h"
USBCDC USBSerial; USBCDC USBSerial;
@@ -302,6 +303,7 @@ typedef enum {
CMD_SELECT_ZBS243 = 60, CMD_SELECT_ZBS243 = 60,
CMD_SELECT_NRF82511 = 61, CMD_SELECT_NRF82511 = 61,
CMD_SELECT_CC = 62,
CMD_SELECT_EEPROM_PT = 69, CMD_SELECT_EEPROM_PT = 69,
CMD_SELECT_PORT = 70, CMD_SELECT_PORT = 70,
@@ -316,15 +318,17 @@ typedef enum {
CMD_WRITE_EEPROM = 91 CMD_WRITE_EEPROM = 91
} ZBS_UART_PROTO; } ZBS_UART_PROTO;
uint32_t FLASHER_VERSION = 0x00000030; uint32_t FLASHER_VERSION = 0x00000032;
#define CONTROLLER_ZBS243 0 #define CONTROLLER_ZBS243 0
#define CONTROLLER_NRF82511 1 #define CONTROLLER_NRF82511 1
#define CONTROLLER_CC 2
uint8_t selectedController = 0; uint8_t selectedController = 0;
uint8_t selectedFlasherPort; uint8_t selectedFlasherPort;
uint32_t currentFlasherOffset = 0; uint32_t currentFlasherOffset = 0;
flasher* zbsflasherp; flasher* zbsflasherp;
nrfswd* nrfflasherp; nrfswd* nrfflasherp;
CC_interface *ccflasherp;
uint8_t waitSerialReply() { uint8_t waitSerialReply() {
uint8_t cmd[4] = {0}; uint8_t cmd[4] = {0};
@@ -472,6 +476,10 @@ void processFlasherCommand(struct flasherCommand* cmd) {
nrfflasherp->nrf_soft_reset(); nrfflasherp->nrf_soft_reset();
delete nrfflasherp; delete nrfflasherp;
nrfflasherp = nullptr; nrfflasherp = nullptr;
} else if (ccflasherp != nullptr) {
ccflasherp->reset_cc();
delete ccflasherp;
ccflasherp = nullptr;
} else { } else {
pinMode(FLASHER_EXT_RESET, OUTPUT); pinMode(FLASHER_EXT_RESET, OUTPUT);
digitalWrite(FLASHER_EXT_RESET, LOW); digitalWrite(FLASHER_EXT_RESET, LOW);
@@ -485,6 +493,9 @@ void processFlasherCommand(struct flasherCommand* cmd) {
} else if (selectedController == CONTROLLER_ZBS243) { } else if (selectedController == CONTROLLER_ZBS243) {
if (zbsflasherp == nullptr) return; if (zbsflasherp == nullptr) return;
zbsflasherp->zbs->erase_flash(); zbsflasherp->zbs->erase_flash();
} else if (selectedController == CONTROLLER_CC) {
if (ccflasherp == nullptr) return;
ccflasherp->erase_chip();
} }
sendFlasherAnswer(CMD_ERASE_FLASH, NULL, 0); sendFlasherAnswer(CMD_ERASE_FLASH, NULL, 0);
break; break;
@@ -501,6 +512,9 @@ void processFlasherCommand(struct flasherCommand* cmd) {
if (selectedController == CONTROLLER_NRF82511) { if (selectedController == CONTROLLER_NRF82511) {
if (nrfflasherp == nullptr) return; if (nrfflasherp == nullptr) return;
nrfflasherp->nrf_erase_all(); nrfflasherp->nrf_erase_all();
} else if (selectedController == CONTROLLER_CC) {
if (ccflasherp == nullptr) return;
ccflasherp->erase_chip();
} }
sendFlasherAnswer(CMD_ERASE_ALL, NULL, 0); sendFlasherAnswer(CMD_ERASE_ALL, NULL, 0);
break; break;
@@ -515,8 +529,15 @@ void processFlasherCommand(struct flasherCommand* cmd) {
currentFlasherOffset = 0; currentFlasherOffset = 0;
selectedController = CONTROLLER_ZBS243; selectedController = CONTROLLER_ZBS243;
break; 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: case CMD_SELECT_NRF82511:
// powerControl(true, (uint8_t*)powerPins2, 4); // powerControl(true, (uint8_t*)powerPins2, 4);
nrfflasherp = new nrfswd(FLASHER_EXT_MISO, FLASHER_EXT_CLK); nrfflasherp = new nrfswd(FLASHER_EXT_MISO, FLASHER_EXT_CLK);
nrfflasherp->showDebug = false; nrfflasherp->showDebug = false;
@@ -567,6 +588,19 @@ void processFlasherCommand(struct flasherCommand* cmd) {
sendFlasherAnswer(CMD_READ_FLASH, bufferp, cur_len); sendFlasherAnswer(CMD_READ_FLASH, bufferp, cur_len);
if (bufferp != nullptr) free(bufferp); 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 { } else {
Serial0.printf("No controller type selected\n"); Serial0.printf("No controller type selected\n");
} }
@@ -632,6 +666,15 @@ void processFlasherCommand(struct flasherCommand* cmd) {
currentFlasherOffset += cmd->len; currentFlasherOffset += cmd->len;
sendFlasherAnswer(CMD_WRITE_FLASH, NULL, 0); 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; break;
case CMD_WRITE_INFOPAGE: case CMD_WRITE_INFOPAGE:
@@ -687,6 +730,10 @@ void flasherCommandTimeout() {
delete nrfflasherp; delete nrfflasherp;
nrfflasherp = nullptr; nrfflasherp = nullptr;
} }
if (ccflasherp != nullptr) {
delete ccflasherp;
ccflasherp = nullptr;
}
lastCmdTimeStamp = 0; lastCmdTimeStamp = 0;
} }

View File

@@ -21,6 +21,7 @@ CMD_PASS_THROUGH = 50
CMD_SELECT_ZBS243 = 60 CMD_SELECT_ZBS243 = 60
CMD_SELECT_NRF82511 = 61 CMD_SELECT_NRF82511 = 61
CMD_SELECT_CC = 62
CMD_SELECT_EEPROM_PT = 69 CMD_SELECT_EEPROM_PT = 69
@@ -140,8 +141,8 @@ def validate_arguments(args):
list_available_com_ports() list_available_com_ports()
return False return False
if args.command: if args.command:
if not (args.nrf82511 or args.zbs243): if not (args.nrf82511 or args.zbs243 or args.ccxxxx):
print("Either -nrf82511 or -zbs243 option is required.") print("Either -nrf82511, -zbs243 or -ccxxxx option is required.")
return False return False
if not (args.internalap or args.external or args.altradio): if not (args.internalap or args.external or args.altradio):
print("Using external port") print("Using external port")
@@ -161,6 +162,19 @@ def validate_arguments(args):
if args.command == "read" and len(args.filename) < 2: if args.command == "read" and len(args.filename) < 2:
print("Please specify a file to save read data") print("Please specify a file to save read data")
return False 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 return True
@@ -295,6 +309,9 @@ def main():
help="nRF82511 programming") help="nRF82511 programming")
parser.add_argument("-z", "--zbs243", action="store_true", parser.add_argument("-z", "--zbs243", action="store_true",
help="ZBS243 programming") help="ZBS243 programming")
parser.add_argument("-c", "--ccxxxx", action="store_true",
help="CCxxxx programming")
parser.add_argument("--internalap", action="store_true", parser.add_argument("--internalap", action="store_true",
help="Selects the internal accesspoint port") help="Selects the internal accesspoint port")
parser.add_argument("-e", "--external", action="store_true", parser.add_argument("-e", "--external", action="store_true",
@@ -379,6 +396,9 @@ def main():
send_cmd(CMD_SELECT_NRF82511, bytearray([])) send_cmd(CMD_SELECT_NRF82511, bytearray([]))
if args.zbs243: if args.zbs243:
send_cmd(CMD_SELECT_ZBS243, bytearray([])) send_cmd(CMD_SELECT_ZBS243, bytearray([]))
if args.ccxxxx:
send_cmd(CMD_SELECT_CC, bytearray([]))
cmd, answer = wait_for_command() cmd, answer = wait_for_command()
if (answer[0] == 1): 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 * ZBS243-based tags
* nRF52-based tags * nRF52-based tags
* 88MZ100-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. 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) ![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 * R - required
* O - optional * O - optional
| Flasher Pin | Cable Pin | ESP32-S2 Pin | ZBS | nRF | 88mz100 | | Flasher Pin | Cable Pin | ESP32-S2 Pin | ZBS | nRF | 88mz100 | CC1110 |
| :---------: | :-------: | :------------: | :---: | :---: | :-----: | | :---------: | :-------: | :------------: | :---: | :---: | :-----: | :----: |
| VCC | 1 | 16, 17, 18, 21 | R | R | R | | VCC | 1 | 16, 17, 18, 21 | R | R | R | R |
| CS | 2 | 34 | R | | | | CS | 2 | 34 | R | | | |
| GND | 3 | GND | R | R | R | | GND | 3 | GND | R | R | R | R |
| CLK | 4 | 33 | R | R | | | CLK | 4 | 33 | R | R | | (DC) R |
| TXD | 5 | 36 | O | O | R | | TXD | 5 | 36 | O | O | R | |
| MISO | 6 | 35 | R | R | | | MISO | 6 | 35 | R | R | | (DD) R |
| TEST | 7 | 38 | | | | | TEST | 7 | 38 | | | | |
| MOSI | 8 | 37 | R | | | | MOSI | 8 | 37 | R | | | |
| RXD | 9 | 40 | O | O | R | | RXD | 9 | 40 | O | O | R | |
| RSET | 10 | 39 | R | | O | | 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. 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. This script connects to the S2-mini's serial port and enables flashing to ZBS243 and nRF52811-based tags.
```shell ```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 OpenEPaperLink Flasher for AP/Flasher board
@@ -59,6 +60,7 @@ options:
-i, --infopage Write to the infopage/UICR -i, --infopage Write to the infopage/UICR
-n, --nrf82511 nRF82511 programming -n, --nrf82511 nRF82511 programming
-z, --zbs243 ZBS243 programming -z, --zbs243 ZBS243 programming
-c, --ccxxxx CCxxxx programming
--internalap Selects the internal accesspoint port --internalap Selects the internal accesspoint port
-e, --external Selects the external(side) port -e, --external Selects the external(side) port
--altradio Selects the alternate radio 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' 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 ## Credits
Much code was reused from ATC1441's various flashers Much code was reused from ATC1441's various flashers
* [ATC1441's ESP32-NRF52-SWD](https://github.com/atc1441/ESP32_nRF52_SWD) * [ATC1441's ESP32-NRF52-SWD](https://github.com/atc1441/ESP32_nRF52_SWD)
* [ATC1441's ZBS-Flasher](https://github.com/atc1441/ZBS_Flasher) * [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 88MZ100 Flasher](https://github.com/atc1441/88MZ100/tree/master/88MZ100_Flasher)
* [ATC1441's ESP_CC_Flasher](https://github.com/atc1441/ESP_CC_Flasher)