get stuff to work, mostly. Programming command etc. are still a hazard
This commit is contained in:
parent
a5a3a99fa4
commit
bbd127da3f
47
src/main.c
47
src/main.c
|
@ -29,6 +29,30 @@ static uint16_t DATA_vectors[0x10] = {
|
|||
static uint16_t dumpmem_ram[256>>1];
|
||||
static uint16_t dumpmem_flash[8192>>1];*/
|
||||
|
||||
static uint8_t DATA_test_rom[256] = { // RL78
|
||||
0xce, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6e, 0x7f, 0xe8,
|
||||
0x85, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xd9,
|
||||
0x00, 0xfd, 0xdd, 0x00, 0xfd, 0xee, 0x00, 0xef, 0xfe, 0x71, 0x7b, 0xfa, 0xd7,
|
||||
0x71, 0x38, 0x23, 0xff, 0x71, 0x38, 0x33, 0x00, 0x71, 0x68, 0x77, 0x00, 0x71,
|
||||
0x38, 0x53, 0x00, 0xd7, 0x71, 0x30, 0x03, 0xff, 0x00, 0x00, 0x71, 0x38, 0x03,
|
||||
0xff, 0xef, 0xf4, 0xd7, 0xd7, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
|
||||
|
||||
static void test_sbw(void) {
|
||||
gpio_init(PINOUT_SBW_TCK);
|
||||
gpio_set_function(PINOUT_SBW_TCK, GPIO_FUNC_SIO);
|
||||
|
@ -178,9 +202,11 @@ static void tool78_testtest() {
|
|||
}
|
||||
|
||||
static void tool78_prototest() {
|
||||
struct tool78_hw* hw = &tool78_hw_rl78_uart1;
|
||||
|
||||
tool78_silicon_sig_t sig;
|
||||
memset(&sig, 0, sizeof sig);
|
||||
enum tool78_stat st = tool78_init(&tool78_hw_rl78_uart1, &sig);
|
||||
enum tool78_stat st = tool78_init_sfp(&tool78_hw_rl78_uart1, &sig);
|
||||
printf("result: 0x%02x. sig:\n", st);
|
||||
for (size_t i = 0; i < sizeof(struct tool78_silicon_sig_rl78); ++i)
|
||||
printf("0x%02x ", ((const uint8_t*)&sig)[i]);
|
||||
|
@ -196,12 +222,31 @@ static void tool78_prototest() {
|
|||
printf("secget: 0x%02x\n", st);
|
||||
printf("sec: flg=%02x bot=%02x fsws=%04x fswe=%04x\n", sec.flg, sec.bot, sec.fsws, sec.fswe);
|
||||
|
||||
//st = tool78_do_security_release(&tool78_hw_rl78_uart1);
|
||||
//printf("sec rel: 0x%02x\n", st);
|
||||
|
||||
/*st = tool78_do_block_blank_check(hw, 0, 0x0ff, false);
|
||||
printf("blank check: 0x%02x\n", st);
|
||||
|
||||
st = tool78_do_programming(hw, 0, 0x000ff, DATA_test_rom);
|
||||
printf("programming: 0x%02x\n", st);*/
|
||||
|
||||
st = tool78_do_verify(hw, 0, 0x0ff, DATA_test_rom);
|
||||
printf("verify: 0x%02x\n", st);
|
||||
}
|
||||
|
||||
static void tool78_ocdtest() {
|
||||
uint8_t passwd[10] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
|
||||
uint16_t ver=0;
|
||||
enum tool78_stat st = tool78_init_ocd(&tool78_hw_rl78_uart1, &ver, passwd);
|
||||
printf("result: 0x%02x ver=%04x\n", st, ver);
|
||||
}
|
||||
|
||||
int main() {
|
||||
stdio_init_all();
|
||||
//tool78_testtest();
|
||||
tool78_prototest();
|
||||
//tool78_ocdtest();
|
||||
//piotest();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -106,14 +106,15 @@ static const struct delayvalues delays[23] = {
|
|||
|
||||
static enum tool78_stat tool78_data_send(struct tool78_hw* hw,
|
||||
int len, const uint8_t* data, bool final_block) {
|
||||
//printf("datasend: len=%d data=%02x %02x %02x ...\n", len, data[0], data[1], data[2]);
|
||||
if (len == 0) return tool78_stat_ack;
|
||||
if (len > 0x100) return tool78_stat_internal_error;
|
||||
len &= 0xff;
|
||||
uint8_t lenfield = len & 0xff;
|
||||
|
||||
uint8_t pre[2], // soh, len
|
||||
post[2]; // cksum, etx
|
||||
pre[0] = tool78_frame_soh;
|
||||
pre[1] = len;
|
||||
uint8_t pre[2], // stx, len
|
||||
post[2]; // cksum, etx/etb
|
||||
pre[0] = tool78_frame_stx;
|
||||
pre[1] = lenfield;
|
||||
post[0] = 0; // checksum
|
||||
post[1] = final_block ? tool78_frame_etx : tool78_frame_etb;
|
||||
|
||||
|
@ -122,12 +123,17 @@ static enum tool78_stat tool78_data_send(struct tool78_hw* hw,
|
|||
if (len) r = tool78_digest_checksum8(r, len, data);
|
||||
post[0] = r;
|
||||
|
||||
//printf("data cksum=%02x\n", r);
|
||||
|
||||
int rr = hw->send(2, pre, -1);
|
||||
if (rr != 3) return tool78_stat_internal_error;
|
||||
if (rr != 2) return tool78_stat_internal_error;
|
||||
|
||||
if (len) {
|
||||
rr = hw->send(len, data, -1);
|
||||
if (rr != len) return tool78_stat_internal_error;
|
||||
if (rr != len) {
|
||||
//printf("data not sent properly: %d\n", r);
|
||||
return tool78_stat_internal_error;
|
||||
}
|
||||
}
|
||||
|
||||
rr = hw->send(2, post, -1);
|
||||
|
@ -138,7 +144,7 @@ static enum tool78_stat tool78_data_send(struct tool78_hw* hw,
|
|||
|
||||
static enum tool78_stat tool78_cmd_send(struct tool78_hw* hw, uint8_t cmd,
|
||||
int len, const uint8_t* data) {
|
||||
if (len > 0x100) return tool78_stat_internal_error;
|
||||
if (len >= 0x100) return tool78_stat_internal_error;
|
||||
uint8_t lenfield = len &= 0xff;
|
||||
|
||||
busy_wait_us_32(tCOM); // aka tSN6(/tDN6?) (reset?) or tMB (others?)
|
||||
|
@ -315,14 +321,24 @@ enum tool78_stat tool78_do_baud_rate_set(struct tool78_hw* hw) {
|
|||
st = tool78_wait_status(hw, 3, tWT10); // aka tCS6
|
||||
//printf("brs stat=0x%02x\n", st);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
// let's ignore the two data bytes for now
|
||||
|
||||
|
||||
// now at 115.2kbaud, so let the physical layer switch to it
|
||||
hw->set_baudrate(115200);
|
||||
|
||||
hw->flags |= tool78_hw_flag_done_reset;
|
||||
|
||||
// let's ignore the two data bytes for now
|
||||
|
||||
st = tool78_do_reset(hw);
|
||||
if (hw->flags & tool78_hw_flag_do_ocd) {
|
||||
// wait for ack 0x00 byte
|
||||
uint8_t byte = 0xff;
|
||||
int rr = hw->recv(1, &byte, 10000);
|
||||
if (rr != 1) st = tool78_stat_timeout_error;
|
||||
else if (byte != 0) st = tool78_stat_protocol_error;
|
||||
else st = tool78_stat_ack;
|
||||
} else {
|
||||
st = tool78_do_reset(hw);
|
||||
}
|
||||
break;
|
||||
case tool78_mcu_78k0: default:
|
||||
return tool78_stat_bad_mcu_for_cmd;
|
||||
|
@ -374,6 +390,8 @@ enum tool78_stat tool78_do_chip_erase(struct tool78_hw* hw) {
|
|||
|
||||
enum tool78_stat tool78_do_block_erase(struct tool78_hw* hw, uint32_t start, uint32_t end) {
|
||||
bool isrl78 = (hw->target & tool78_mcu_mask) == tool78_mcu_rl78;
|
||||
if (isrl78) end = 0xffffff;
|
||||
if (start >= end) return 0;
|
||||
|
||||
uint8_t data[6];
|
||||
// on the rl78, the end address is ignored/unused and it's little-endian
|
||||
|
@ -403,6 +421,7 @@ enum tool78_stat tool78_do_block_erase(struct tool78_hw* hw, uint32_t start, uin
|
|||
|
||||
enum tool78_stat tool78_do_programming(struct tool78_hw* hw, uint32_t start,
|
||||
uint32_t end, const uint8_t* src) {
|
||||
if (start >= end) return 0;
|
||||
bool isrl78 = (hw->target & tool78_mcu_mask) == tool78_mcu_rl78;
|
||||
|
||||
uint8_t data[6];
|
||||
|
@ -428,17 +447,20 @@ enum tool78_stat tool78_do_programming(struct tool78_hw* hw, uint32_t start,
|
|||
st = tool78_wait_status(hw, 1, tWT3); // aka tCS5
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
int nblocks = ((end - start + 255) / 256);
|
||||
for (size_t off = 0; off < end - start; off += 256) {
|
||||
size_t nbytes = end - start + 1;
|
||||
int nblocks = ((nbytes + 255) / 256);
|
||||
for (size_t off = 0; off < nbytes; off += 256) {
|
||||
busy_wait_us_32(tSD5); // aka tFD3
|
||||
|
||||
size_t todo = (end - start) - off;
|
||||
size_t todo = nbytes - off;
|
||||
if (todo > 256) todo = 256;
|
||||
bool finalblk = off + 256 >= (end - start);
|
||||
bool finalblk = off + 256 >= nbytes;
|
||||
//printf("prgmdata@%zu = %02x %02x %02x ...\n", off, src[off], src[off+1], src[off+2]);
|
||||
st = tool78_data_send(hw, todo, &src[off], finalblk);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
st = tool78_wait_status(hw, 2, tWT4); // aka tDS5
|
||||
st = tool78_wait_status(hw, 2, tWT4*10); // aka tDS5
|
||||
printf("prgm %zu st=%02x %02x fin=%c\n", off, st, databuf[1], finalblk?'t':'f');
|
||||
if (st != tool78_stat_ack) return st;
|
||||
st = databuf[1];
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
@ -452,6 +474,7 @@ enum tool78_stat tool78_do_programming(struct tool78_hw* hw, uint32_t start,
|
|||
|
||||
enum tool78_stat tool78_do_verify(struct tool78_hw* hw, uint32_t start,
|
||||
uint32_t end, const uint8_t* src) {
|
||||
if (start >= end) return 0;
|
||||
bool isrl78 = (hw->target & tool78_mcu_mask) == tool78_mcu_rl78;
|
||||
|
||||
uint8_t data[6];
|
||||
|
@ -477,13 +500,14 @@ enum tool78_stat tool78_do_verify(struct tool78_hw* hw, uint32_t start,
|
|||
st = tool78_wait_status(hw, 1, tWT6); // aka tCS2
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
//int nblocks = ((end - start + 255) / 256);
|
||||
size_t nbytes = end - start + 1;
|
||||
//int nblocks = ((nbytes + 255) / 256);
|
||||
for (size_t off = 0; off < end - start; off += 256) {
|
||||
busy_wait_us_32(tSD2); // aka tFD3
|
||||
|
||||
size_t todo = (end - start) - off;
|
||||
size_t todo = nbytes - off;
|
||||
if (todo > 256) todo = 256;
|
||||
bool finalblk = off + 256 >= (end - start);
|
||||
bool finalblk = off + 256 >= nbytes;
|
||||
st = tool78_data_send(hw, todo, &src[off], finalblk);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
|
@ -498,6 +522,7 @@ enum tool78_stat tool78_do_verify(struct tool78_hw* hw, uint32_t start,
|
|||
|
||||
enum tool78_stat tool78_do_block_blank_check(struct tool78_hw* hw,
|
||||
uint32_t start, uint32_t end, bool check_flash_opt /* RL78 only */) {
|
||||
if (start >= end) return 0;
|
||||
bool isrl78 = (hw->target & tool78_mcu_mask) == tool78_mcu_rl78;
|
||||
|
||||
uint8_t data[7];
|
||||
|
@ -518,7 +543,8 @@ enum tool78_stat tool78_do_block_blank_check(struct tool78_hw* hw,
|
|||
data[5] = (end >> 0) & 0xff;
|
||||
}
|
||||
|
||||
int nblocks = ((end - start + 255) / 256);
|
||||
size_t nbytes = end - start + 1;
|
||||
int nblocks = ((nbytes + 255) / 256);
|
||||
enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_block_blank_check,
|
||||
isrl78 ? 7 : 6, data);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
@ -563,10 +589,7 @@ enum tool78_stat tool78_do_silicon_signature(struct tool78_hw* hw,
|
|||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
//gpio_put(18, false);
|
||||
// TODO: tool78_data_wait()
|
||||
//do {
|
||||
st = tool78_data_recv(hw, (uint8_t*)sig_dest, nbyte, tFD2); // aka tSD11
|
||||
//} while (st == tool78_stat_busy);
|
||||
st = tool78_data_recv(hw, (uint8_t*)sig_dest, nbyte, tFD2); // aka tSD11
|
||||
//gpio_put(18, true);
|
||||
//printf("silisig: data 0x%02x\n", st);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
@ -604,6 +627,7 @@ enum tool78_stat tool78_do_version_get(struct tool78_hw* hw, tool78_version_t* v
|
|||
|
||||
enum tool78_stat tool78_do_checksum(struct tool78_hw* hw, uint32_t start,
|
||||
uint32_t end, uint16_t* ckout) {
|
||||
if (end <= start) return 0;
|
||||
bool isrl78 = (hw->target & tool78_mcu_mask) == tool78_mcu_rl78;
|
||||
|
||||
uint8_t data[6];
|
||||
|
@ -733,9 +757,114 @@ enum tool78_stat tool78_do_security_release(struct tool78_hw* hw) {
|
|||
|
||||
// ----
|
||||
|
||||
enum tool78_stat tool78_init(struct tool78_hw* hw, tool78_silicon_sig_t* sig) {
|
||||
int tool78_ocd_version(struct tool78_hw* hw, uint16_t* ver) {
|
||||
busy_wait_ms(1);
|
||||
|
||||
uint8_t bytes[3];
|
||||
bytes[0] = tool78ocd_cmd_version;
|
||||
int rr = hw->send(1, &bytes[0], -1);
|
||||
|
||||
// bytes[0] is tool78ocd_cmd_version echoed back
|
||||
rr = hw->recv(3, bytes, 100000);
|
||||
if (rr != 3) return -1;
|
||||
|
||||
*ver = bytes[1] | ((uint16_t)bytes[2] << 8);
|
||||
printf("ver=%04x\n", *ver);
|
||||
return 0;
|
||||
}
|
||||
int tool78_ocd_connect(struct tool78_hw* hw, const uint8_t passwd[10], uint8_t ck_off) {
|
||||
busy_wait_ms(1);
|
||||
uint8_t stuff[11];
|
||||
uint8_t connst, cksum;
|
||||
stuff[0] = tool78ocd_cmd_connect;
|
||||
int rr = hw->send(1, &stuff[0], -1);
|
||||
|
||||
// stuff[1] is tool78ocd_cmd_connect echoed back
|
||||
rr = hw->recv(2, &stuff[1], 100000);
|
||||
connst=stuff[2];
|
||||
if (rr != 2) return -1;
|
||||
|
||||
memcpy(stuff, passwd, 10);
|
||||
cksum = stuff[10] = tool78_calc_ocd_checksum8(10, passwd) + ck_off;
|
||||
|
||||
busy_wait_ms(1);
|
||||
rr = hw->send(11, stuff, -1);
|
||||
|
||||
// stuff[9] is the checksum byte echoed back
|
||||
rr = hw->recv(2, &stuff[9], 100000);
|
||||
if (rr != 2) return -2;
|
||||
|
||||
printf("cksum=0x%02x conn=%02x pw=%02x\n",
|
||||
cksum, connst, stuff[10]);
|
||||
|
||||
return (uint32_t)connst | ((uint32_t)stuff[10] << 8);
|
||||
}
|
||||
int tool78_ocd_read(struct tool78_hw* hw, uint16_t off, uint8_t len,
|
||||
uint8_t* data) {
|
||||
busy_wait_ms(1);
|
||||
|
||||
uint8_t hdr[4];
|
||||
hdr[0] = tool78ocd_cmd_read;
|
||||
hdr[1] = off & 0xff;
|
||||
hdr[2] = off >> 8;
|
||||
hdr[3] = len;
|
||||
|
||||
int rr = hw->send(sizeof hdr, hdr, -1);
|
||||
|
||||
rr = hw->recv(len, data, 1000*len);
|
||||
printf("ocd read %d\n", rr);
|
||||
return (rr == len) ? 0 : -1;
|
||||
}
|
||||
int tool78_ocd_write(struct tool78_hw* hw, uint16_t addr, uint8_t len,
|
||||
const uint8_t* data) {
|
||||
busy_wait_ms(1);
|
||||
|
||||
uint8_t hdr[4];
|
||||
hdr[0] = tool78ocd_cmd_write;
|
||||
hdr[1] = addr & 0xff;
|
||||
hdr[2] = addr >> 8;
|
||||
hdr[3] = len;
|
||||
|
||||
int rr = hw->send(sizeof hdr, hdr, -1);
|
||||
rr = hw->send(len, data, -1);
|
||||
|
||||
rr = hw->recv(1, hdr, 1000*len);
|
||||
if (rr != 1) return -1;
|
||||
|
||||
return (hdr[0] == tool78ocd_cmd_write) ? 0 : -2;
|
||||
}
|
||||
int tool78_ocd_exec(struct tool78_hw* hw) {
|
||||
busy_wait_ms(1);
|
||||
|
||||
uint8_t hdr[1];
|
||||
hdr[0] = tool78ocd_cmd_exec;
|
||||
|
||||
int rr = hw->send(sizeof hdr, hdr, -1);
|
||||
|
||||
rr = hw->recv(1, hdr, 1000);
|
||||
if (rr != 1) return -1;
|
||||
|
||||
return (hdr[0] == tool78ocd_cmd_exec) ? 0 : -2;
|
||||
}
|
||||
int tool78_ocd_leave(struct tool78_hw* hw, bool exit_to_ram) {
|
||||
busy_wait_ms(1);
|
||||
|
||||
uint8_t hdr[2];
|
||||
hdr[0] = exit_to_ram ? tool78ocd_cmd_exit_ram : tool78ocd_cmd_exit_reti;
|
||||
|
||||
int rr = hw->send(1, hdr, -1);
|
||||
|
||||
rr = hw->recv(1, &hdr[1], 1000);
|
||||
if (rr != 1) return -1;
|
||||
|
||||
return (hdr[0] == hdr[1]) ? 0 : -2;
|
||||
}
|
||||
|
||||
// ----
|
||||
|
||||
static enum tool78_stat tool78_init_common(struct tool78_hw* hw) {
|
||||
if (!hw) return tool78_stat_internal_error;
|
||||
hw->flags = 0;
|
||||
hw->flags &= ~tool78_hw_flag_done_reset;
|
||||
|
||||
enum tool78_stat st = tool78_stat_ack;
|
||||
for (size_t i = 0; i < 16; ++i) {
|
||||
|
@ -745,7 +874,7 @@ enum tool78_stat tool78_init(struct tool78_hw* hw, tool78_silicon_sig_t* sig) {
|
|||
if ((hw->target & tool78_mcu_mask) != tool78_mcu_rl78) {
|
||||
st = tool78_do_reset(hw);
|
||||
printf("done reset st=0x%02x\n", st);
|
||||
} //else printf("no reset to do (rl78)\n");
|
||||
}
|
||||
if (st == tool78_stat_timeout_error) {
|
||||
hw->deinit();
|
||||
continue;
|
||||
|
@ -759,6 +888,13 @@ enum tool78_stat tool78_init(struct tool78_hw* hw, tool78_silicon_sig_t* sig) {
|
|||
printf("baudrate result=0x%02x\n", st);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
enum tool78_stat tool78_init_sfp(struct tool78_hw* hw, tool78_silicon_sig_t* sig) {
|
||||
enum tool78_stat st = tool78_init_common(hw);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
st = tool78_do_silicon_signature(hw, sig);
|
||||
printf("sig result=0x%02x\n", st);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
@ -766,3 +902,22 @@ enum tool78_stat tool78_init(struct tool78_hw* hw, tool78_silicon_sig_t* sig) {
|
|||
return st;
|
||||
}
|
||||
|
||||
enum tool78_stat tool78_init_ocd(struct tool78_hw* hw, uint16_t* ver,
|
||||
const uint8_t passwd[10]) {
|
||||
hw->flags |= tool78_hw_flag_do_ocd;
|
||||
int st = tool78_init_common(hw);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
st = tool78_ocd_version(hw, ver);
|
||||
|
||||
uint8_t i = 0;
|
||||
do {
|
||||
st = tool78_ocd_connect(hw, passwd, i);
|
||||
++i;
|
||||
|
||||
if (i == 0) break;
|
||||
} while ((st & 0xff00) == 0xf300 && (st & 0xff) == 0xf1);
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,23 @@ enum tool78_stat tool78_do_security_release(struct tool78_hw* hw);
|
|||
|
||||
// ----
|
||||
|
||||
enum tool78_stat tool78_init(struct tool78_hw* hw, tool78_silicon_sig_t* sig);
|
||||
//int tool78_ocd_reset(struct tool78_hw* hw);
|
||||
int tool78_ocd_version(struct tool78_hw* hw, uint16_t* ver);
|
||||
int tool78_ocd_connect(struct tool78_hw* hw, const uint8_t passwd[10], uint8_t ck_off);
|
||||
int tool78_ocd_read(struct tool78_hw* hw, uint16_t off, uint8_t len,
|
||||
uint8_t* data); // only is able to read from 0xf0000
|
||||
int tool78_ocd_write(struct tool78_hw* hw, uint16_t addr, uint8_t len,
|
||||
const uint8_t* data);
|
||||
int tool78_ocd_exec(struct tool78_hw* hw); // call 0xf07e0
|
||||
int tool78_ocd_leave(struct tool78_hw* hw, bool exit_to_ram);
|
||||
|
||||
// ----
|
||||
|
||||
enum tool78_stat tool78_init_sfp(struct tool78_hw* hw, tool78_silicon_sig_t* sig);
|
||||
enum tool78_stat tool78_init_ocd(struct tool78_hw* hw, uint16_t* ver,
|
||||
const uint8_t passwd[10]);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -125,10 +125,9 @@ enum tool78_stat {
|
|||
// these commands use a checksum that is the bitwise complement from the usual
|
||||
// checksum (used in the flash programming protocol)
|
||||
enum tool78ocd_cmd {
|
||||
tool78ocd_cmd_reset = 0x00,
|
||||
//tool78ocd_cmd_reset = 0x00,
|
||||
tool78ocd_cmd_version = 0x90, // also called "ping"
|
||||
// also called "unlock", as it *always* required a 10-byte passphrase (but
|
||||
// not always checked, depending on protection status)
|
||||
// also called "unlock", as it requires a 10-byte passphrase
|
||||
tool78ocd_cmd_connect = 0x91,
|
||||
// read from memory?
|
||||
tool78ocd_cmd_read = 0x92,
|
||||
|
@ -163,7 +162,13 @@ static inline uint8_t tool78_calc_checksum8(size_t len, const uint8_t* data) {
|
|||
return tool78_digest_checksum8(0, len, data);
|
||||
}
|
||||
static inline uint8_t tool78_calc_ocd_checksum8(size_t len, const uint8_t* data) {
|
||||
return ~tool78_calc_checksum8(len, data);
|
||||
//return /*~*/(tool78_calc_checksum8(len, data)/*+1*/)&0xff;
|
||||
uint8_t r = 0;
|
||||
for (size_t i = 0; i < len; ++i) r = r + data[i];
|
||||
r = (r - 1) & 0xff;
|
||||
// if corrupt checksum:
|
||||
r = (r + 1) & 0xff;
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline uint16_t tool78_digest_checksum16(uint16_t r, size_t len, const uint8_t* data) {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
enum tool78_hw_flags {
|
||||
tool78_hw_flag_done_reset = 1<<0,
|
||||
tool78_hw_flag_do_ocd = 1<<1,
|
||||
};
|
||||
|
||||
struct tool78_hw {
|
||||
|
|
|
@ -54,6 +54,8 @@ end:
|
|||
static bool t78k0_spi_init(void) {
|
||||
if (!tool78_hw_init_help(NULL, &tool78_spi_program, &vars)) return false;
|
||||
|
||||
if (tool78_hw_rl78_uart2.flags & tool78_hw_flag_do_ocd)
|
||||
return false; // OCD not supported with this phy
|
||||
vars.exclusive = false;
|
||||
vars.bitswap = false;
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ static bool t78k0_uart2_init(void) {
|
|||
if (!tool78_hw_init_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
|
||||
&vars)) return false;
|
||||
|
||||
if (tool78_hw_rl78_uart2.flags & tool78_hw_flag_do_ocd)
|
||||
return false; // OCD not supported with this phy
|
||||
vars.exclusive = false;
|
||||
vars.bitswap = true;
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ static bool t78k0_uart2_extclk_init(void) {
|
|||
if (!tool78_hw_init_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
|
||||
&vars)) return false;
|
||||
|
||||
if (tool78_hw_rl78_uart2.flags & tool78_hw_flag_do_ocd)
|
||||
return false; // OCD not supported with this phy
|
||||
vars.exclusive = false;
|
||||
vars.bitswap = true;
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ static bool t78k0r_uart1_init(void) {
|
|||
if (!tool78_hw_init_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
|
||||
&vars)) return false;
|
||||
|
||||
if (tool78_hw_rl78_uart2.flags & tool78_hw_flag_do_ocd)
|
||||
return false; // OCD not supported with this phy
|
||||
vars.exclusive = true;
|
||||
vars.bitswap = true;
|
||||
|
||||
|
|
|
@ -18,18 +18,20 @@ static bool trl78_uart1_init(void) {
|
|||
if (!tool78_hw_init_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
|
||||
&vars)) return false;
|
||||
|
||||
tool78_hw_rl78_uart1.flags = 0; // TODO: also in all other hw impls!
|
||||
vars.exclusive = true;
|
||||
vars.bitswap = true;
|
||||
|
||||
tool78_entryseq_rl78(tool78_entry_rl78_uart1);
|
||||
enum tool78_entry typ = (tool78_hw_rl78_uart1.flags & tool78_hw_flag_do_ocd)
|
||||
? tool78_entry_rl78_ocd : tool78_entry_rl78_uart1;
|
||||
|
||||
tool78_entryseq_rl78(typ);
|
||||
|
||||
tool78_uart_rx_program_init(PINOUT_TOOL78_PIO, vars.smrx, vars.rxoff,
|
||||
PINOUT_TOOL78_RL78_TOOL0, 115200, true);
|
||||
tool78_uart_tx_program_init(PINOUT_TOOL78_PIO, vars.smtx, vars.txoff,
|
||||
PINOUT_TOOL78_RL78_TOOL0, 115200, true);
|
||||
|
||||
uint8_t byte = (uint8_t)tool78_entry_rl78_uart1;
|
||||
uint8_t byte = (uint8_t)typ;
|
||||
trl78_uart1_send(1, &byte, -1);
|
||||
|
||||
busy_wait_us_32(70); // tMB
|
||||
|
|
|
@ -18,6 +18,8 @@ static bool trl78_uart2_init(void) {
|
|||
if (!tool78_hw_init_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
|
||||
&vars)) return false;
|
||||
|
||||
if (tool78_hw_rl78_uart2.flags & tool78_hw_flag_do_ocd)
|
||||
return false; // OCD not supported with this phy
|
||||
vars.exclusive = false;
|
||||
vars.bitswap = true;
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ def main():
|
|||
parser = argparse.ArgumentParser(
|
||||
description="Convert data files into byte arrays in a C header")
|
||||
|
||||
parser.add_argument('--width', type=int, default=16, help="data width")
|
||||
parser.add_argument('input', nargs='*', action='append',
|
||||
help="Input data file to convert to a header file. If "
|
||||
+"none are specified, data is read from standard input.")
|
||||
|
@ -60,7 +61,9 @@ def main():
|
|||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
data = struct.unpack('<'+('H'*(len(data)//2)), data)
|
||||
wlut = {8:'B',16:'H',32:'I',64:'Q'}
|
||||
denom= args.width//8
|
||||
data = struct.unpack('<'+((wlut[args.width])*(len(data)//denom)), data)
|
||||
|
||||
# add it to the list
|
||||
datafiles[name] = data
|
||||
|
@ -76,8 +79,8 @@ def main():
|
|||
# variable name is "DATA_<datafile>"
|
||||
# (width=84 is the equivalent of 16 bytes/line)
|
||||
headersrc = '\n\n'.join(
|
||||
"static uint16_t DATA_%s[%d] = {\n%s\n};" % (name, len(data), \
|
||||
textwrap.fill(','.join("0x%04x" % b for b in data), width=81,
|
||||
"static uint%d_t DATA_%s[%d] = {\n%s\n};" % (args.width, name, len(data), \
|
||||
textwrap.fill(', '.join(("0x%0"+str(args.width//4)+"x") % b for b in data), width=81,
|
||||
initial_indent=" ", subsequent_indent=" ")
|
||||
) for name, data in datafiles.items()
|
||||
)
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
trace.log
|
||||
*.bin
|
||||
*.h
|
||||
*.elf
|
||||
*.map
|
||||
*.o
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
AS := rl78-elf-gcc
|
||||
LD := rl78-elf-gcc
|
||||
OBJCOPY := rl78-elf-objcopy
|
||||
|
||||
all: test-rom.bin test-dbg.bin
|
||||
|
||||
test.S.o: test.S
|
||||
$(AS) -c -o "$@" "$<"
|
||||
romhdr.S.o: romhdr.S
|
||||
$(AS) -c -o "$@" "$<"
|
||||
|
||||
OBJFILES := test.S.o romhdr.S.o
|
||||
|
||||
test-%.elf test-%.elf.map: $(OBJFILES) link-%.ld
|
||||
$(LD) -o "$@" $(OBJFILES) -T link-$*.ld -Wl,-Map="$@.map" -nostdlib -nostartfiles
|
||||
|
||||
test-%.bin: test-%.elf
|
||||
$(OBJCOPY) -O binary "$<" "$@"
|
||||
|
||||
clean:
|
||||
@$(RM) -v test-*.bin test-*.bin.h test-*.elf test-*.elf.map test.S.o
|
||||
.KEEP: test-rom.elf test-dbg.elf
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
#define P0 0xfff00
|
||||
#define P2 0xfff02
|
||||
#define P3 0xfff03
|
||||
#define P12 0xfff0c
|
||||
#define P13 0xfff0d
|
||||
|
||||
#define PM0 0xfff20
|
||||
#define PM2 0xfff22
|
||||
#define PM3 0xfff23
|
||||
|
||||
#define TXD1 0xfff44
|
||||
#define SDR02 0xfff44
|
||||
#define RXD1 0xfff46
|
||||
#define SDR03 0xfff46
|
||||
|
||||
; PMC: processor mode control
|
||||
|
||||
#define PU0 0xf0030
|
||||
#define PU3 0xf0033
|
||||
#define PU12 0xf003c
|
||||
|
||||
#define PIM0 0xf0040
|
||||
#define PIM3 0xf0043
|
||||
#define POM0 0xf0050
|
||||
#define POM3 0xf0053
|
||||
#define PMC0 0xf0060
|
||||
#define PMC2 0xf0062
|
||||
#define PMC3 0xf0063
|
||||
|
||||
#define NFEN0 0xf0070
|
||||
#define NFEN1 0xf0071
|
||||
|
||||
#define PIOR0 0xf0077
|
||||
#define PIOR1 0xf0079
|
||||
#define PIOR2 0xf0075
|
||||
#define PIOR3 0xf007c
|
||||
|
||||
#define IAWCTL 0xf0078
|
||||
|
||||
#define PMS 0xf007b
|
||||
|
||||
#define DFLCTL 0xf0090
|
||||
|
||||
#define PER0 0xf00f0
|
||||
#define PRR0 0xf00f1
|
||||
#define PER1 0xf00fa
|
||||
#define PRR1 0xf00fb
|
||||
#define PER2 0xf00fc
|
||||
#define PRR2 0xf00fd
|
||||
|
||||
#define SSR02 0xf0104
|
||||
#define SSR03 0xf0106
|
||||
#define SIR02 0xf010c
|
||||
#define SIR03 0xf010e
|
||||
#define SMR02 0xf0114
|
||||
#define SMR03 0xf0116
|
||||
#define SCR02 0xf011c
|
||||
#define SCR03 0xf011e
|
||||
|
||||
#define SE0 0xf0120
|
||||
#define SS0 0xf0122
|
||||
#define ST0 0xf0124
|
||||
#define SPS0 0xf0126
|
||||
#define SO0 0xf0128
|
||||
#define SOE0 0xf012a
|
||||
#define SOL0 0xf0134
|
||||
#define SSC0 0xf0138
|
||||
|
||||
#define INTFE 0xf0448
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
OUTPUT_FORMAT("elf32-rl78","elf32-rl78","elf32-rl78")
|
||||
OUTPUT_ARCH(rl78)
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0xf07e0, LENGTH = 0x100/*idk*/
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
.hdr :
|
||||
{
|
||||
BYTE(0xe0); BYTE(0x07); /* address */
|
||||
BYTE(SIZEOF(.text));
|
||||
} > ram
|
||||
.text :
|
||||
{
|
||||
/*ABSOLUTE(.) = 0xf07e3;*/
|
||||
*(.text* .rodata* .data*)
|
||||
} > ram
|
||||
.bss :
|
||||
{
|
||||
*(.bss)
|
||||
} > ram =0x00
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.vectors)
|
||||
*(.callt)
|
||||
*(.option)
|
||||
*(.password)
|
||||
*(.plt)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
OUTPUT_FORMAT("elf32-rl78","elf32-rl78","elf32-rl78")
|
||||
OUTPUT_ARCH(rl78)
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
/*data (rwx) : ORIGIN = 0x0200, LENGTH = 0x100
|
||||
text (rx) : ORIGIN = 0xf800, LENGTH = 0x800 - 0x20
|
||||
vectors (rw) : ORIGIN = 0xffe0, LENGTH = 0x20*/
|
||||
|
||||
rom (rx) : ORIGIN = 0x00000, LENGTH = 0x04000
|
||||
/* vectors, boot clusters, etc.: part of ^ */
|
||||
ram (rwx) : ORIGIN = 0xff900, LENGTH = (0xffee0 - 0xff900)
|
||||
|
||||
/*
|
||||
* 16k code flash: 00000..03FFF
|
||||
* 2k data flash: F1000..F17FF
|
||||
* 1.5k ram: FF900..FFEDF
|
||||
*
|
||||
* boot clusters: +00000; +01000
|
||||
* vectors: 00000..0007F
|
||||
* callt: 00080..000BF
|
||||
* option byte: 000C0..000C3
|
||||
* debugpasswd: 000C4..000CD
|
||||
*
|
||||
* flash block = 0x400 bytes => 0x10 blocks
|
||||
*
|
||||
* vectors:
|
||||
* 000: RESET/POR/WDT/TRAP/RPE/...
|
||||
* 004: INTWDTI/INTSRO
|
||||
* 006: INTLVI
|
||||
* 008: INTP0
|
||||
* 00A: INTP1
|
||||
* ...
|
||||
* .14: INTP6
|
||||
* 016: INTST0/INTCSI00/INTIIC00
|
||||
* 018: INTSR0/INTCSI01/INTIIC01
|
||||
* 01e: INTSRE0
|
||||
* 020: INTTM00
|
||||
* 022: INTST1/INTCSI10/INTIIC10
|
||||
* 024: INTSR1/INTCSI11/INTIIC11
|
||||
* 026: INTSRE1
|
||||
* bluh bluh not really interesting
|
||||
* 07E: BRK
|
||||
*
|
||||
* 02000..03FFF mirrored to F2000..F3FFF (if enabmed in PMC)
|
||||
*
|
||||
* IO regs:
|
||||
* serial data reg 00: TXD0/SIO00/SDR00 = 0xfff10
|
||||
* serial data reg 01: RXD0/SIO01/SDR01 = 0xfff12
|
||||
* serial data reg 02: TXD1/SIO10/SDR02 = 0xfff44
|
||||
* serial data reg 03: RXD1/SIO11/SDR03 = 0xfff42
|
||||
*
|
||||
* port mode reg? PMx = 0xFFF2x
|
||||
*
|
||||
* port input mode PIMx = 0xF004x
|
||||
* port output mode POMx = 0xF005x
|
||||
* port mode control PMCx = 0xF006x
|
||||
* port mode select PMS = 0xF007B
|
||||
* peripheral io redirection regs?
|
||||
* flash operating mode FLMODE = 0xF00AA
|
||||
* serial status reg SSR0x = F010(x*2)
|
||||
* serial mode reg SMR0x = F011(x*2)
|
||||
* serial comm ops setting SCR0x = F011(8+x*2)
|
||||
* + channel enable, start stop, clocksel, output, output enable, output level, standby control
|
||||
* interrupt stuff at 0xF0441+...
|
||||
*
|
||||
* F0090: rom enable flag etc : DFLCTL bit 0 (enable dataflash access?)
|
||||
* F0800: request data etc (not interesting here)
|
||||
* F0803=1
|
||||
* F0880=4
|
||||
* F0880: also rom enable bit?
|
||||
* FLMODE (voltages stuff, bluh), FLMWRP(?) (enable prev reg), PMMC (also voltages)
|
||||
*
|
||||
* TXD1 enable = PMC20=0 PM20=0 P20=1
|
||||
* RXD1 enable = PMC31=0 PM31=1
|
||||
*
|
||||
* WDT: WDTE (enable reg) + option byte C0: set WDTON bit to 0 (bit 4)
|
||||
*
|
||||
* serial: UART1: ch2
|
||||
* 8n1 lsbfirst
|
||||
* PER0: bit 2 hi
|
||||
* PRR0: bit 2 lo
|
||||
* SPSm: 0b0100<<4 (125kbaud?)
|
||||
* SMRmn:
|
||||
* SEm SSm STm SOEm SOm SOLm SSCm ISC
|
||||
*
|
||||
* opt C1: 0b00000010 // 0x1a?
|
||||
* opt C2: 0b11101001 // 0x2d?
|
||||
* opt C3: 0b10000101 == 0x85
|
||||
* C4..CD: 00 ...
|
||||
*/
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
.btc0 :
|
||||
{
|
||||
. = 0x00000;
|
||||
KEEP(*(.vectors))
|
||||
. = 0x00080;
|
||||
KEEP(*(.callt))
|
||||
. = 0x000c0;
|
||||
KEEP(*(.option))
|
||||
. = 0x000c4;
|
||||
KEEP(*(.password))
|
||||
. = 0x000ce;
|
||||
*(.text.btc0)
|
||||
} > rom =0xff
|
||||
/* TODO: btc1? */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(2);
|
||||
*(.text .rodata* .eh_frame_hdr)
|
||||
. = ALIGN(256);
|
||||
/*KEEP(*(.eh_frame) *(.gcc_except_table*))
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
PROVIDE (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE (__init_array_end = .);
|
||||
PROVIDE (__fini_array_start = .);
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE (__fini_array_end = .);
|
||||
LONG(0);*/ /* Sentinel. */
|
||||
/* gcc uses crtbegin.o to find the start of the constructors, so
|
||||
we make sure it is first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not actually link against
|
||||
crtbegin.o; the linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it doesn't matter which
|
||||
directory crtbegin.o is in. */
|
||||
/*KEEP (*crtbegin*.o(.ctors))*/
|
||||
/* We don't want to include the .ctor section from from the
|
||||
crtend.o file until after the sorted ctors. The .ctor section
|
||||
from the crtend file contains the end of ctors marker and it
|
||||
must be last */
|
||||
/*KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
KEEP (*crtbegin*.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))*/
|
||||
} > rom =0xff
|
||||
|
||||
.data :
|
||||
{
|
||||
__data_vma_start = ABSOLUTE(.);
|
||||
__data_lma_start = SIZEOF(.text);
|
||||
*(.data)
|
||||
}
|
||||
__data_size = SIZEOF(.data);
|
||||
.bss :
|
||||
{
|
||||
__bss_start = ABSOLUTE(.);
|
||||
*(.bss .sbss)
|
||||
} >ram
|
||||
__bss_size = SIZEOF(.bss);
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.plt)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
.section .vectors, "a", %progbits
|
||||
|
||||
_VECTORS:
|
||||
_vtor_RST:
|
||||
.2byte _start
|
||||
/* other vectors... */
|
||||
.2byte 0xffff
|
||||
|
||||
.section .callt, "a", %progbits
|
||||
|
||||
_CALLT:
|
||||
.2byte 0xffff
|
||||
|
||||
.section .option, "a", %progbits
|
||||
|
||||
/* option bytes */
|
||||
_OPTION:
|
||||
/* 0x000C0: wdt settings */
|
||||
.byte 0x6e /* wdt disable */
|
||||
/* 0x000C1: */
|
||||
.byte 0x7f /* LVD reset, 2.81V */
|
||||
/* 0x000C2: */
|
||||
.byte 0xe8 /* HSmode, HOCO@32MHz */
|
||||
/* 0x000C3: debug settings */
|
||||
.byte 0x85
|
||||
|
||||
.section .password, "a", %progbits
|
||||
|
||||
/* debugger password: ten 0xff bytes */
|
||||
_PASSWORD:
|
||||
.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
/*#include "romhdr.S"*/
|
||||
#include "hw.S"
|
||||
|
||||
/*
|
||||
ch2&3: TxD1,RxD1
|
||||
*/
|
||||
|
||||
/* allegedly there's a subroutine at 0xEFFA1 that sends a single byte over the TOOL0 line */
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
call !hw_init
|
||||
call !port_init
|
||||
call !port_toggle
|
||||
|
||||
1: br $1b
|
||||
|
||||
hw_init:
|
||||
di
|
||||
; systeminit
|
||||
; PIOR = 0
|
||||
|
||||
; ADPC = 1
|
||||
; PMC bit = 0
|
||||
|
||||
; PM1 = 6(?)
|
||||
; CMC = 0
|
||||
; MSTOP,XTSTOP bits = 1,1
|
||||
; MCM0 bit = 0 ; hi-speed OCO clock as main clock
|
||||
; CSS bit = 0 ; main system clock = periph clock
|
||||
|
||||
; PER0 SAU1EN bit (3) = 1
|
||||
; SPS0 = 0x44 ; or *12? ; CK00,CK01 @ 2MHz
|
||||
|
||||
; ST0 = 0xf ; stop all channels
|
||||
; STMK0,STIF0 bits = 1,0 ; disable interrupts
|
||||
; SRMK0,SRIF0 bits = 1,0 ; disable interrupts
|
||||
; SREK0,SREF0 bits = 1,0 ; disable interrupts
|
||||
; SMR00 = 0x22 ; ch0clock = CK00, start trig=sw falling edge, UART mode, xferend irq en
|
||||
; SCR00 = 0x8297 ; tx only, clock type 1, error irq en, even parity, lsbfirst, 8bit data, 1bit stop
|
||||
; SDR00 = 0xce00 ; opclk/208
|
||||
; NFEN0 = 0x0001 ; RxD noise filter enable
|
||||
; SIR01 = 0x0007 ; clear error
|
||||
; SMR01 = 0x0122 ; ch1clock = CK00; start trig=RxD falling edge, UART mode, xferend irq en
|
||||
; SCR01 = 0x4697 ; rx only, clock type 1, error irq en, even parity, lsbfirst, 8bit data, 1bit stop
|
||||
; SDR01 = 0xce00 ; opclk/208 ; use opclk/17 (0x0f00) instead for 115.2kbaud?
|
||||
; SO00,SOE00 bits = 1,1 ; prepare using ch0
|
||||
; PM1 PM11 bit = 1 ; RxD pin as input
|
||||
; P1,PM1 P12,PM12 bits = 1,0 ; TxD as output
|
||||
|
||||
; SO00 bit = 1 ; TxD output level
|
||||
; SOE00 bit = 1 ; enable UART
|
||||
; SS00,SS01 bits = 1,1 ; enable UART
|
||||
|
||||
; TXD0 = data ; xmit
|
||||
|
||||
;ei ; nah
|
||||
ret
|
||||
|
||||
port_init:
|
||||
; P33 as output using GPIO
|
||||
; PM3 bit 3 = 0
|
||||
; PU3 bit 3 = 0 (no pullup)
|
||||
; PMC3 bit 3 = 0 (digital IO)
|
||||
; PIOR0 bit 6 = 0
|
||||
; POM3 bit 3 = 0
|
||||
; toggle P3 bit 3
|
||||
clr1 !PM3.3
|
||||
clr1 !PU3.3
|
||||
clr1 !PIOR0.6
|
||||
clr1 !POM3.3
|
||||
ret
|
||||
|
||||
port_toggle:
|
||||
set1 !P3.3
|
||||
nop
|
||||
nop
|
||||
clr1 !P3.3
|
||||
br $port_toggle
|
||||
|
||||
uart_init:
|
||||
;; PMC00=0 PM00=1 ; RxD1 en
|
||||
; PIO2.3 = 1
|
||||
; PMC20=0 PM20=0 P20=1 ; TxD1 en
|
||||
ret
|
||||
|
||||
uart_send_byte:
|
||||
; todo
|
||||
; TODO: wait for sent?
|
||||
ret
|
||||
|
Loading…
Reference in New Issue