// Convert a 16-bit unsigned value into ASCII characters and dump it out // to the serial port. void serialWriteInt(unsigned int data) { uint8_t tenth = 0; uint8_t thou = 0; uint8_t huns = 0; uint8_t tens = 0; uint8_t ones = 0; // This is an awkward shifting/dividing method of isolating the individual // digits of the number. I'm sure there's a better way, but done is. tenth = (data/10000); data -= tenth*10000; thou = (uint8_t)(data/1000); data -= (uint16_t)thou*1000; huns = (uint8_t)(data/100); data -= (uint16_t)huns*100; tens = (uint8_t)(data/10); ones = (uint8_t)(data%10); tenth += 48; thou += 48; huns += 48; tens += 48; ones += 48; // Write the individual digits out, followed by a line feed and CR. serialWriteChar(tenth); serialWriteChar(thou); serialWriteChar(huns); serialWriteChar(tens); serialWriteChar(ones); serialNewline(); }
// serialWrite() takes a pointer to a string and iterates over that string // until it finds the C end-of-string character ('\0'). It's a blocking // operation and does not return until the print operation is completed. void serialWrite(char* data) { do { serialWriteChar((char)*data); // Print the first character. data++; // Increment the pointer. } while (*data != '\0'); // Check for the end of the string. serialNewline(); }
void serialNewline(void) { serialWriteChar((char)'\n'); serialWriteChar((char)'\r'); }
int main(int argc, char *argv[]) { FILE *fp; char c; time_t start = time(NULL), end; if ((argc < 3) || (argc > 4)) { printf("Usage:\n%s /dev/port /path/to.hex [q]\n", argv[0]); return 1; } // Open HEX File if ((fp = fopen(argv[2], "r")) == NULL) { printf("Could not open file %s\n", argv[2]); return 1; } // Read it's contents if (readHex(fp) != 0) { printf("Could not parse HEX file %s\n", argv[2]); fclose(fp); return 1; } fclose(fp); if (!isValid()) { printf("HEX-File not valid!\n"); freeHex(); return 1; } uint32_t min = minAddress(); uint32_t max = maxAddress(); uint32_t length = dataLength(); printf("Hex File Path : %s\n", argv[2]); printf("Minimum Address : 0x%X\n", min); printf("Maximum Address : 0x%X\n", max); printf("Data payload : %i bytes\n\n", length); uint8_t *d = (uint8_t *)malloc(length * sizeof(uint8_t)); if (d == NULL) { fprintf(stderr, "Not enough memory (%lu bytes)!\n", length * sizeof(uint8_t)); freeHex(); return 1; } parseData(d); freeHex(); // Open serial port if ((fd = serialOpen(argv[1], 38400, 1)) == -1) { printf("Could not open port %s\n", argv[1]); free(d); return 1; } signal(SIGINT, intHandler); signal(SIGQUIT, intHandler); ping: printf("Pinging bootloader... Stop with CTRL+C\n"); if (argc > 3) { c = argv[3][0]; } else { c = 'f'; } serialWriteChar(fd, c); usleep(PINGDELAY * 1000); if ((serialReadRaw(fd, &c, 1) != 1) || (c != OKAY)) { goto ping; } printf("Got response... Acknowledging...\n"); serialWriteChar(fd, CONFIRM); serialReadChar(fd, &c); if (c != ACK) { printf("Invalid acknowledge! Trying again...\n", c, c); goto ping; } printf("Connection established successfully!\n"); printf("Sending target address...\n"); serialWriteChar(fd, (min & 0xFF000000) >> 24); serialWriteChar(fd, (min & 0x00FF0000) >> 16); serialWriteChar(fd, (min & 0x0000FF00) >> 8); serialWriteChar(fd, min & 0x000000FF); serialReadChar(fd, &c); if (c != OKAY) { printf("Invalid acknowledge from YASAB!\n", c, c); free(d); serialClose(fd); return 1; } printf("Sending data length...\n"); serialWriteChar(fd, (length & 0xFF000000) >> 24); serialWriteChar(fd, (length & 0x00FF0000) >> 16); serialWriteChar(fd, (length & 0x0000FF00) >> 8); serialWriteChar(fd, length & 0x000000FF); serialReadChar(fd, &c); if (c != OKAY) { printf("Invalid acknowledge from YASAB (%x)!\n", c, c); free(d); serialClose(fd); return 1; } printf("\n\n"); for (uint32_t i = 0; i < length; i++) { serialWriteChar(fd, d[i]); if (serialHasChar(fd)) { serialReadChar(fd, &c); if (c == OKAY) { printNextPage(); } else if (c == ERROR) { printf("YASAB aborted the connection!\n"); free(d); serialClose(fd); return 1; } else { printf("Unknown answer from YASAB (%x)!\n", c, c); } } printProgress(i + 1, length); } end = time(NULL); printf("\n\nUpload finished after %3.1f seconds.\n", difftime(end, start)); printf("YASAB - Yet another simple AVR Bootloader\n"); printf("By xythobuz - Visit www.xythobuz.org\n"); free(d); serialClose(fd); return 0; }