mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 00:04:28 +01:00
Added support for TI CCxxxx chips to Tag_Flasher, AP_and_Flasher and Mini_AP_v4.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
58
Tag_Flasher/ESP32_Flasher/include/cc_interface.h
Normal file
58
Tag_Flasher/ESP32_Flasher/include/cc_interface.h
Normal 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;
|
||||
};
|
||||
|
||||
397
Tag_Flasher/ESP32_Flasher/src/cc_interface.cpp
Normal file
397
Tag_Flasher/ESP32_Flasher/src/cc_interface.cpp
Normal 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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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.
|
||||

|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user