12 static uint8_t checksum(uint8_t * buff, int len)
17 for (i=0;i<len;i++) sum += buff[i];
21 void print_memory(uint16_t addr, const unsigned char * buff, int words)
23 int len = (words * 5) + 16;
24 char * line = malloc(len);
26 out += snprintf(out, len-strlen(line), "Mem %04X: ", addr);
28 const unsigned char *p = &buff[0];
29 for (int i=0; i<words; i++) {
30 out += snprintf(out, len-strlen(line), "%02X%02X ", p[0], p[1] );
37 void dumpbuff(const unsigned char * buff, int charlen)
39 int len = (charlen * 3) + 16;
40 char * line = malloc(len);
42 out += snprintf(out, len-strlen(line), "Dump: ");
44 const unsigned char *p = &buff[0];
45 for (int i=0; i<charlen; i++) {
46 out += snprintf(out, len-strlen(line), "%02X ", p[0] );
53 int loader_readmem(port_t * pt, uint16_t addr, uint8_t * memory, int words)
55 int len = (words * 2) + 4;
56 unsigned char * buff = malloc(len);
58 /* request to read memory block */
61 buff[2] = addr & 0xFF;
62 buff[3] = checksum(buff, 3);
64 int ret = serial_write(pt, buff, 4);
65 if (ret <= 0) return 1;
69 /* read the response */
70 if (serial_read(pt, buff, 1)<=0) return 1;
73 loge("ReadMem %04X: Loader gave error", addr);
78 loge("ReadMem %04X: Unknown response to read 0x%02X '%c'", addr, buff[0], buff[0]);
82 /* now read the address, and check it matches */
83 ret = serial_read(pt, &buff[1], len-1);
85 loge("ReadMem %04X: Error read response", addr);
89 loge("ReadMem %04X: Short read %d of %d", addr, ret, len-1);
93 int sum = checksum(buff, len-1);
94 if ((sum & 0xFF) != buff[len-1]) {
95 loge("ReadMem %04X: Bad checksum. %02X != %02X", addr, sum & 0xFF, buff[len-1]);
99 uint16_t realaddr = (buff[1]<<8) | buff[2];
100 if (realaddr != addr) {
101 loge("ReadMem %04X: Actual Address %04X", addr, realaddr);
104 logd("ReadMem %04X: Read Successful", realaddr);
106 memcpy(memory, &buff[3], (words * 2));
113 int loader_writemem(port_t * pt, uint16_t addr, uint8_t * memory, int words)
115 int len = (words * 2) + 4;
116 uint8_t * buff = malloc((words * 2) + 4);
118 /* request to read memory block */
121 buff[2] = addr & 0xFF;
123 unsigned char * p = memory;
124 unsigned char * q = &buff[3];
125 for (int i=0; i<words; i++) {
129 *q = checksum(buff, len-1) & 0xFF;
131 logd("WriteMem %04X: Sending Write request", addr);
132 int ret = serial_write(pt, buff, len);
133 if (ret <= 0) { free(buff); return 1; }
135 logd("WriteMem %04X: Awaiting Write confirmation", addr);
136 /* read the response */
137 if (serial_read(pt, buff, 1)<=0) { free(buff); return 1; }
139 if (buff[0] == 'E') {
140 loge("WriteMem %04X: Bootloader gave an error", addr);
145 if (buff[0] != 'W') {
146 loge("WriteMem %04X: unknown reponse '%c'", addr, buff[0]);
151 /* now read the address, and check it matches */
152 ret = serial_read(pt, &buff[1], 3);
154 loge("WriteMem %04X: Error reading rest of response %d of %d", addr, ret, 3);
159 uint16_t realaddr = (buff[1]<<8) | buff[2];
160 if (realaddr != addr) {
161 loge("WriteMem %04X: Actual location %04X", addr, realaddr);
165 int sum = checksum(buff, 3);
167 if ((sum & 0xFF) != buff[3]) {
168 loge("WriteMem %04X: Bad checksum on confirmation. %02X != %02X", addr, sum & 0xFF, buff[3]);
174 logd("WriteMem %04X: Write confirmed.", realaddr);
181 * Connect to the bootloader
182 * read the start of bootloader address
184 int loader_connect(port_t * pt, uint16_t *maxmem, uint16_t *devid)
186 if (pt == NULL) return 1;
188 logd("Connect: Assert break and wait for acknowledgement");
191 unsigned char buff[10];
195 logi("Please reset the device to enter bootloader mode");
197 while ((ret=serial_read(pt, buff, 1))> 0) {
201 logd("Connect: Want ESC (0x06) got 0x%02X ret=%d", buff[0], ret);
208 loge("Connect: Serial port closed");
210 loge("Connect: read error: %s", strerror(errno));
214 /* Next we should see 'B' 'L' */
215 while ((ret=serial_read(pt, &buff[1], 2))> 0) {
216 if (buff[1] == 'B' && buff[2] == 'L') {
220 logd("Connect: Want 'BL' got '%c%c' ret=%d", buff[1], buff[2], ret);
227 loge("Connect: Serial port closed");
229 loge("Connect: read error: %s", strerror(errno));
233 /* turn break off now we are in bootloader mode */
238 loge("Connect: Could not find bootloader");
242 logd("Connect: Release break. Read memory size.");
244 /* now read the bootloaders location, and thus mem size */
245 ret=serial_read(pt, &buff[3], 5);
249 loge("Connect: Serial port closed");
251 loge("Connect: read error: %s", strerror(errno));
255 if (buff[7] != (checksum(buff,7) & 0xFF)) {
256 loge("Connect: Bad checksum");
260 *devid = (buff[3] << 8) | buff[4];
261 logd("Connect: Device ID: 0x%04X", *devid);
263 *maxmem = (buff[5] << 8) | buff[6];
264 logd("Connect: Memory Size: 0x%04X", *maxmem);