252 lines
5.5 KiB
C++
252 lines
5.5 KiB
C++
#include "ROMWireProtocol.h"
|
|
|
|
#include "XModem.h"
|
|
|
|
#define DATA_LEN 128
|
|
#define CONTAINER_LEN 512
|
|
#define ID_LEN 1
|
|
|
|
enum {
|
|
CMD_INVALID,
|
|
CMD_WRITE,
|
|
CMD_TEST,
|
|
CMD_DUMP,
|
|
CMD_ERASE
|
|
};
|
|
|
|
|
|
char line[120];
|
|
byte* sendBuffer[64];
|
|
byte cmd = NULL;
|
|
|
|
XModem xmodem;
|
|
|
|
bool receiveBlockHandler(void *blk_id, size_t idSize, byte *data, size_t dataSize) {
|
|
unsigned int id = *((int *) blk_id);
|
|
unsigned long page = (id - 1) * DATA_LEN;
|
|
for (int i = 0; i < dataSize; i++) {
|
|
unsigned long index = i + page;
|
|
programData(data[i], index);
|
|
//programData(id, i);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void blockLookupHandler(void *blk_id, size_t idSize, byte *send_data, size_t dataSize) {
|
|
//uint8_t blkId = blk_id;
|
|
uint16_t id = *((uint16_t *) blk_id);
|
|
// TODO: This was close to working
|
|
//byte id = *((byte *) blk_id);
|
|
unsigned long page = (id - 1) * DATA_LEN;
|
|
for (int i = 0; i < dataSize; i++) {
|
|
unsigned long index = i + page;
|
|
send_data[i] = readData(index);
|
|
}
|
|
}
|
|
|
|
void setup() {
|
|
// Debug trigger
|
|
pinMode(10, OUTPUT);
|
|
digitalWrite(10, LOW);
|
|
// put your setup code here, to run once:
|
|
setCtrlPins();
|
|
|
|
setAddrPinsOut();
|
|
setDataPinsOut();
|
|
//setDataPinsOut();
|
|
|
|
Serial.begin(4800, SERIAL_8N1);
|
|
xmodem.begin(Serial, XModem::ProtocolType::XMODEM);
|
|
xmodem.setRecieveBlockHandler(receiveBlockHandler);
|
|
xmodem.setBlockLookupHandler(blockLookupHandler);
|
|
xmodem.setIdSize(ID_LEN);
|
|
//xmodem.allowNonSequentailBlocks(true);
|
|
delay(2);
|
|
Serial.println("Started Serial COM.");
|
|
}
|
|
|
|
|
|
/*
|
|
* Function grabbed from TommyPROM library
|
|
* Copyright Tom Nisbet
|
|
*/
|
|
char *readLine(char *buffer, int len) {
|
|
for (int ix = 0; ix < len; ix++) {
|
|
buffer[ix] = 0;
|
|
}
|
|
|
|
char c = ' ';
|
|
int ix = 0;
|
|
do {
|
|
if (Serial.available()) {
|
|
c = Serial.read();
|
|
if ((c == '\b') && (ix > 0)) {
|
|
--ix;
|
|
}
|
|
buffer[ix++] = c;
|
|
Serial.write(c);
|
|
}
|
|
} while ((c != '\n') && (c != '\r') && (ix < len));
|
|
|
|
buffer[ix - 1] = 0;
|
|
return buffer;
|
|
}
|
|
|
|
/*
|
|
* Function modified from TommyPROM library
|
|
* Copyright Tom Nisbet
|
|
*/
|
|
byte parseCommand(char c) {
|
|
byte cmd = CMD_INVALID;
|
|
|
|
if ((c >= 'A') && (c <= 'Z')) {
|
|
c |= 0x20;
|
|
}
|
|
|
|
switch (c) {
|
|
case 'w': cmd = CMD_WRITE; break;
|
|
case 't': cmd = CMD_TEST; break;
|
|
case 'd': cmd = CMD_DUMP; break;
|
|
case 'e': cmd = CMD_ERASE; break;
|
|
default: cmd = CMD_INVALID; break;
|
|
}
|
|
|
|
return cmd;
|
|
}
|
|
|
|
|
|
|
|
void loop() {
|
|
// put your main code here, to run repeatedly:
|
|
//programData(0x3F, 0x0000);
|
|
|
|
//byte data = readData(0x0000);
|
|
// Serial.print("data: ");
|
|
//Serial.print("Data returned: ");
|
|
//Serial.println(data, HEX);
|
|
// Serial.println("\n");
|
|
//delay(1);
|
|
|
|
if (cmd == NULL) {
|
|
Serial.print("\n>");
|
|
readLine(line, sizeof(line));
|
|
Serial.flush();
|
|
cmd = parseCommand(line[0]);
|
|
}
|
|
|
|
switch (cmd) {
|
|
case CMD_WRITE:
|
|
setDataPinsOut();
|
|
Serial.println("Burn new ROM: Waiting for an xmodem transfer..");
|
|
if (xmodem.receive() == true) {
|
|
delay(1000);
|
|
Serial.println("Finished burning firmware.");
|
|
cmd = NULL;
|
|
}
|
|
break;
|
|
case CMD_TEST:
|
|
Serial.println("Testing with a read/write cycle");
|
|
programData(0x3F, 0x0000);
|
|
Serial.println("Wrote: 0x3F");
|
|
setDataPinsIn();
|
|
delay(500);
|
|
Serial.print("Received: ");
|
|
Serial.println(readData(0x0000), HEX);
|
|
cmd = NULL;
|
|
break;
|
|
case CMD_DUMP:
|
|
//setDataPinsIn();
|
|
//delay(500);
|
|
Serial.println("Waiting to send dump via xmodem...");
|
|
dumpROM();
|
|
// for(int i = 0; i < 20; i++) {
|
|
// Serial.println(readData(0x1000), HEX);
|
|
// }
|
|
//cmd = NULL;
|
|
break;
|
|
case CMD_ERASE:
|
|
eraseROM();
|
|
cmd = NULL;
|
|
break;
|
|
|
|
case CMD_INVALID:
|
|
default:
|
|
Serial.println("NOR Flasher v1.0 Alpha");
|
|
Serial.println();
|
|
Serial.println("Commands: ");
|
|
Serial.println("w\twrite new firmware");
|
|
Serial.println("d\tdump firmware");
|
|
Serial.println("t\tdo a test write and then read");
|
|
Serial.println("e\terase chip");
|
|
Serial.println();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void dumpROM() {
|
|
setDataPinsIn();
|
|
|
|
struct XModem::bulk_data container;
|
|
|
|
//byte *id = (byte *) malloc(2);
|
|
byte id[CONTAINER_LEN];
|
|
size_t data_len[CONTAINER_LEN];
|
|
byte * data_arr[CONTAINER_LEN];
|
|
|
|
// unsigned long long temp = 1;
|
|
// for(size_t i = 0; i < ID_LEN; ++i) {
|
|
// id[ID_LEN - i - 1] = (byte *) (temp & 0xFF);
|
|
// temp >>= 8;
|
|
// }
|
|
|
|
//size_t * data_len = malloc(2);
|
|
for(int i = 0; i < CONTAINER_LEN; i++) {
|
|
id[i] = i + 1;
|
|
data_len[i] = DATA_LEN;
|
|
data_arr[i] = NULL;
|
|
}
|
|
|
|
container.data_arr = data_arr;
|
|
container.len_arr = data_len;//(size_t*) 512;
|
|
container.id_arr = id;
|
|
container.count = CONTAINER_LEN;
|
|
|
|
xmodem.send_bulk_data(container);
|
|
|
|
free(id);
|
|
free(data_len);
|
|
|
|
delay(500);
|
|
Serial.println("Finished sending ROM dump.");
|
|
cmd = NULL;
|
|
// for(int i = 0; i < 512; i++) {
|
|
// for(int d = 0; d < 128; d++) {
|
|
// sendBuffer[d] = readData(d * i);
|
|
// }
|
|
// xmodem.send(sendBuffer, 64);
|
|
// }
|
|
// if(xmodem.lookup_send(1) == true) {
|
|
// delay(1000);
|
|
// Serial.println("Finished transferring firmware dump.");
|
|
// cmd = NULL;
|
|
// }
|
|
// for (int i = 0; i < 10; i++) {
|
|
// byte data = readData(0x0000 | i);
|
|
// //Serial.println(data, HEX);
|
|
// }
|
|
}
|
|
|
|
void eraseROM() {
|
|
setDataPinsOut();
|
|
|
|
writeByte(0xAA, 0x5555);
|
|
writeByte(0x55, 0x2AAA);
|
|
writeByte(0x80, 0x5555);
|
|
writeByte(0xAA, 0x5555);
|
|
writeByte(0x55, 0x2AAA);
|
|
writeByte(0x10, 0x5555);
|
|
|
|
delay(100);
|
|
setDataPinsIn();
|
|
} |