From 6a32bf69c588bf9bb88e0b57af88c8bd877988e6 Mon Sep 17 00:00:00 2001 From: Saurabh Singh Date: Fri, 13 Oct 2023 23:09:08 -0400 Subject: [PATCH] garbage cleanup --- sw/bootloader/hydrogensoc.json | 4 - sw/bootloader_old/Makefile | 18 -- sw/bootloader_old/bootloader.c | 163 --------------- sw/bootloader_old/crt0.S | 24 --- sw/bootloader_old/link_app.lds | 89 -------- sw/bootloader_old/link_bootloader.lds | 86 -------- sw/bootloader_old/xmodem.c | 243 ---------------------- sw/bootloader_old/xmodem.h | 35 ---- sw/bootloader_old/xmsend.py | 287 -------------------------- 9 files changed, 949 deletions(-) delete mode 100644 sw/bootloader/hydrogensoc.json delete mode 100644 sw/bootloader_old/Makefile delete mode 100644 sw/bootloader_old/bootloader.c delete mode 100644 sw/bootloader_old/crt0.S delete mode 100644 sw/bootloader_old/link_app.lds delete mode 100644 sw/bootloader_old/link_bootloader.lds delete mode 100644 sw/bootloader_old/xmodem.c delete mode 100644 sw/bootloader_old/xmodem.h delete mode 100755 sw/bootloader_old/xmsend.py diff --git a/sw/bootloader/hydrogensoc.json b/sw/bootloader/hydrogensoc.json deleted file mode 100644 index 8dc93a63..00000000 --- a/sw/bootloader/hydrogensoc.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "BOOTROM" : ["0x00010000", "4096", "h", "rom.hex"], - "BOOTRAM" : ["0x20008000", "16384", "h", "ram.hex"] -} \ No newline at end of file diff --git a/sw/bootloader_old/Makefile b/sw/bootloader_old/Makefile deleted file mode 100644 index d97c5a92..00000000 --- a/sw/bootloader_old/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -EXEC:= bootloader.elf - -CFLAGS:= -mabi=ilp32 -march=rv32i -nostartfiles -ffreestanding -DTARGET_HYDROGENSOC -Os -CFLAGS+= -I $(RVATOM_LIB)/include -LFLAGS:= -L $(RVATOM_LIB)/ -T link_bootloader.lds -lcatom -Xlinker -Map $(EXEC).map - -default: boot - -.PHONY: boot -boot: $(EXEC) - -$(EXEC): xmodem.c bootloader.c crt0.S - riscv64-unknown-elf-gcc $(CFLAGS) -o $@ $^ $(LFLAGS) - riscv64-unknown-elf-objdump -htd $@ > $@.objdump - -.PHONY: clean -clean: - rm -f *.o *.objdump *.map *.elf \ No newline at end of file diff --git a/sw/bootloader_old/bootloader.c b/sw/bootloader_old/bootloader.c deleted file mode 100644 index 07f4e517..00000000 --- a/sw/bootloader_old/bootloader.c +++ /dev/null @@ -1,163 +0,0 @@ -#include "platform.h" -#include -// #include -// #include -#include - -// #define GPIO_PIN_MODESEL 0 -// #define GPIO_PIN_LED0 0 -// #define GPIO_PIN_LED1 0 - -// #define AUTOBOOT_WAIT 5 - -#include "xmodem.h" - -// #define REQUIRE_KEYPRESS_BEFORE_BOOT -// #define SILENT - -#ifdef SILENT -#define D(x) -#else -#define D(x) x -#endif - -extern int __approm_start; -extern int __approm_size; -// extern int _stack_pointer; -// extern int _global_pointer; - -// Function pointer for jumping to user application. -typedef void (*fnc_ptr)(void); - -void puts(char *ptr); -void print_hex(unsigned int val, int digits); - -void init() -{ - // Init UART - // UART_Config uart_cfg = { - // .baud = 115200, - // .rx_enable = true, - // .tx_enable = true, - // .dual_stop_bits = false, - // .enable_parity_bit = false, - // .even_parity = false, - // .loopback_enable = false - // }; - // serial_init(&uart_cfg); - - // Init GPIO - // gpio_setmode(GPIO_PIN_MODESEL, INPUT); - // gpio_setmode(GPIO_PIN_LED0, OUTPUT); - // gpio_setmode(GPIO_PIN_LED1, OUTPUT); -} - - -void jump_to_application(void) -{ - #ifdef REQUIRE_KEYPRESS_BEFORE_BOOT - puts("\nPress ENTER to continue boot...\n"); - while(serial_read()!='\r') - {/* wait */} - #endif - - // Function pointer to the address of the user application - fnc_ptr app_main = (fnc_ptr)(&__approm_start); - - serial_write('\n'); - // deinit - // deinit(); - - // change stack pointer & global pointer - // asm volatile("la sp, %0": "=r"(_stack_pointer)); - // print_appl(100); - // jump to app - app_main(); -} - -void puts(char *ptr) -{ - while (*ptr) - { - if (*ptr == '\n') - serial_write('\r'); - serial_write(*ptr++); - } -} - -#ifdef PRINT_APPL_CODE -void print_hex(unsigned int val, int digits) -{ - for (int i = (4 * digits) - 4; i >= 0; i -= 4) - { - serial_write("0123456789abcdef"[(val >> i) % 16]); - } -} - -void print_appl() -{ - puts("\n"); - uint32_t *addr = (uint32_t *)&__approm_start; - uint32_t size = (uint32_t)&__approm_size; - for (uint32_t i = 0; i < size; i++) - { - uint32_t instr = *addr; - puts("0x"); - print_hex((uint32_t)addr++, 8); - puts(": "); - print_hex(instr, 8); - puts("\n"); - } -} -#endif - -int main() -{ - - // Initialize - init(); - - // Print header - puts("*** Atom Bootloader ***\n"); - - // Check Modesel - // bool modesel = true; //gpio_read(GPIO_PIN_MODESEL); - // if(modesel != true) - // { - // // puts("Jumping to application @ "); puthex(__approm_start, 8, false); putchar('\n'); - // jump_to_application(); - // /* UNREACHABLE */ - // } - - // Get Executable from UART - - // puts("Send a binary file with xmodem protocol to update firmware\n"); - // gpio_write(GPIO_PIN_LED0, HIGH); // indicate that we are in recieve mode - xmod_status s = xmodemReceive((uint8_t *)&__approm_start, (unsigned)&__approm_size); - if (s == S_EOT) { - // puts("Jumping to Application\n-----------------------------------------------\n"); - jump_to_application(); - } else { - return 0; - // puts("Failed to recieve executable, try again\n"); - } - // print_appl(); - /* APPLICATION */ - - // we only reach here if we have error - // puts("Failed to recieve executable, try again\n"); - - // uint32_t app_base = __approm_start; - // uint8_t * dptr = (uint8_t*)app_base; - - // W25Q64_init(); - // puts("Copying... "); - // W25Q64_read(dptr, __approm_size, FLASH_ADDR); - // puts("ok\n"); - - // puts("Booting... \n"); - // asm volatile ("jalr ra, %0" : : "r" (app_base)); - - while (1) - ; -} diff --git a/sw/bootloader_old/crt0.S b/sw/bootloader_old/crt0.S deleted file mode 100644 index da072b67..00000000 --- a/sw/bootloader_old/crt0.S +++ /dev/null @@ -1,24 +0,0 @@ -/* - ======================================== - Startup code for Atom - ======================================== -*/ - -.section .boot, "ax", @progbits -.global _start -.global _exit - -_start: - # ===== initialization ===== - - # initialize sp & gp - la sp, _stack_pointer # set stack pointer - la gp, _global_pointer # set global pointer - - # ===== Call main ===== - jal main - - -_exit: - ebreak # Exit simulation - j _exit diff --git a/sw/bootloader_old/link_app.lds b/sw/bootloader_old/link_app.lds deleted file mode 100644 index 57ba4cca..00000000 --- a/sw/bootloader_old/link_app.lds +++ /dev/null @@ -1,89 +0,0 @@ -/* - LINKER SCRIPT - - @See : https://sourceware.org/binutils/docs/ld/Basic-Script-Concepts.html - @See : https://interrupt.memfault.com/blog/how-to-write-linker-scripts-for-firmware - @See : https://github.com/pulp-platform/pulp-riscv-gnu-toolchain/blob/master/riscv.ld -*/ - -OUTPUT_ARCH( "riscv" ) -ENTRY(_start) - -/* MEMORY LAYOUT */ -MEMORY -{ - BOOTROM (rx) : ORIGIN = 0x00010000, LENGTH = 3K - BOOTRAM (rwx): ORIGIN = 0x00010c00, LENGTH = 1K - - APPROM (rx) : ORIGIN = 0x00011000, LENGTH = 12K - APPRAM (rwx): ORIGIN = 0x20000000, LENGTH = 32K -} - -SECTIONS -{ - /* ==== ROM ==== */ - .text : - { - /* ----- Initialization Code ----- */ - *(.boot*) - - /* ----- Code ----- */ - /* Load all text sections (from all files) */ - *(.text) - *(.text.*) - - . = ALIGN(4); - - /* ----- Read Only Data ----- */ - *(.rodata) - *(.rodata.*) - - . = ALIGN(4); - _etext = .; - - } > APPROM - - - - /* ==== RAM ==== */ - /* The .data section contains static variables which have an initial value at boot. */ - .data : - { - _sdata = .; - - /* ----- Initialized Data ----- */ - *(.data) - *(.data.*) - - /* ----- Static Data ----- */ - . = ALIGN(16); - _global_pointer = . + 0x800; - - *(.sdata) - *(.sdata.*) - *(.srodata.*) - - . = ALIGN(4); - _edata = .; - - } > APPRAM AT> APPROM - - - /* ----- Uninitialized Data ----- */ - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { _sbss = .; - *(.bss) - *(.bss.*) - *(COMMON) - - . = ALIGN(4); - _ebss = .; - - } > APPRAM AT> APPROM - - _end = .; -} - -PROVIDE(_start_heap = _ebss); -PROVIDE(_stack_pointer = ORIGIN(APPRAM) + LENGTH(APPRAM)); \ No newline at end of file diff --git a/sw/bootloader_old/link_bootloader.lds b/sw/bootloader_old/link_bootloader.lds deleted file mode 100644 index 41d52759..00000000 --- a/sw/bootloader_old/link_bootloader.lds +++ /dev/null @@ -1,86 +0,0 @@ -/* - LINKER SCRIPT - - @See : https://sourceware.org/binutils/docs/ld/Basic-Script-Concepts.html - @See : https://interrupt.memfault.com/blog/how-to-write-linker-scripts-for-firmware - @See : https://github.com/pulp-platform/pulp-riscv-gnu-toolchain/blob/master/riscv.ld -*/ - -OUTPUT_ARCH( "riscv" ) -ENTRY(_start) - -/* MEMORY LAYOUT */ -MEMORY -{ - BOOTROM (rx) : ORIGIN = 0x00010000, LENGTH = 3K - BOOTRAM (rwx): ORIGIN = 0x00010c00, LENGTH = 1K - - APPROM (rx) : ORIGIN = 0x00011000, LENGTH = 12K - APPRAM (rwx): ORIGIN = 0x20000000, LENGTH = 32K -} - -__bootrom_start = ORIGIN(BOOTROM); -__bootrom_size = LENGTH(BOOTROM); - -__approm_start = ORIGIN(APPROM); -__approm_size = LENGTH(APPROM); - -SECTIONS -{ - /* ==== ROM ==== */ - .text : - { - /* ----- Initialization Code ----- */ - *(.boot*) - *(.text) - *(.text.*) - *(.rodata) - *(.rodata.*) - . = ALIGN(4); - - } > BOOTROM - - - - /* ==== RAM ==== */ - /* The .data section contains static variables which have an initial value at boot. */ - .data : - { - . = ALIGN(4); - /* ----- Initialized Data ----- */ - _sdata = .; - - *(.data) - *(.data.*) - - . = ALIGN(4); - _edata = .; - - /* ----- Static Data ----- */ - . = ALIGN(16); - _global_pointer = . + 0x800; - - *(.sdata) - *(.sdata.*) - *(.srodata.*) - - . = ALIGN(4); - } > BOOTRAM - - /* ----- Uninitialized Data ----- */ - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { _sbss = .; - *(.bss) - *(.bss.*) - *(COMMON) - - . = ALIGN(4); - _ebss = .; - } > BOOTRAM - - _end = . ; -} - -PROVIDE(_start_heap = _ebss); -PROVIDE(_stack_pointer = ORIGIN(BOOTRAM) + LENGTH(BOOTRAM)); \ No newline at end of file diff --git a/sw/bootloader_old/xmodem.c b/sw/bootloader_old/xmodem.c deleted file mode 100644 index 6aa2acbe..00000000 --- a/sw/bootloader_old/xmodem.c +++ /dev/null @@ -1,243 +0,0 @@ -#include "xmodem.h" -#include "platform.h" -#include "serial.h" - -////////////////////////////////////////////////////////// -// Utility Functions - -#define CSR_CYCLE 0xc00 -#define CSR_CYCLEH 0xc80 - -/** - * @brief Reads CSR register - */ -inline uint32_t __attribute__ ((always_inline)) CSR_read(const int csr_id) -{ - register uint32_t csr_data; - asm volatile ("csrr %[result], %[input_i]" : [result] "=r" (csr_data) : [input_i] "i" (csr_id)); - return csr_data; -} - -/** - * @brief Return no of cycles elapsed by core - * @return uint64_t - */ -uint64_t cycles() -{ - union - { - uint64_t uint64; - uint32_t uint32[sizeof(uint64_t)/2]; - } cycles; - - register uint32_t tmp1, tmp2, tmp3; - while(1) - { - tmp1 = CSR_read(CSR_CYCLEH); - tmp2 = CSR_read(CSR_CYCLE); - tmp3 = CSR_read(CSR_CYCLEH); - if (tmp1 == tmp3) - { - break; - } - } - - cycles.uint32[0] = tmp2; - cycles.uint32[1] = tmp3; - - return cycles.uint64; -} - -////////////////////////////////////////////////////////// -// IO Functions - -/** - * @brief gets a char from uart - * @param timeout_cycles timeout (in cycles) - * @return int - */ -static int _inbyte(uint64_t timeout_cycles) -{ - uint64_t t0 = cycles(); - while (!bitcheck(REG32(UART_ADDR, UART_REG_LSR), 0)) { - if (cycles() > (t0 + timeout_cycles)) - return -1; // Timeout - } - return (int) REG8(UART_ADDR, UART_REG_RBR); -} - -/** - * @brief Sends a char to uart - * @param c char - */ -static void _outbyte(unsigned char c) -{ - while(!bitcheck(REG32(UART_ADDR, UART_REG_LSR), 1)) { - asm volatile(""); - // udelay(1000); - } - REG8(UART_ADDR, UART_REG_THR) = c; -} - -/** - * @brief Flushes uart rxbuf - */ -void flush_input() -{ - while(bitcheck(REG32(UART_ADDR, UART_REG_LSR), 0)) - REG8(UART_ADDR, UART_REG_RBR); -} - -/** - * @brief Flushes uart txbuf - */ -void flush_output() -{ - while(!bitcheck(REG32(UART_ADDR, UART_REG_LCR), 1)) { - asm volatile(""); - } -} - -////////////////////////////////////////////////////////////// -// CRC Functions - -const uint16_t crc16tab[256]= { - 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, - 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, - 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, - 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, - 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, - 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, - 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, - 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, - 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, - 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, - 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, - 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, - 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, - 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, - 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, - 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, - 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, - 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, - 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, - 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, - 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, - 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, - 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, - 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, - 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, - 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, - 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, - 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, - 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, - 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, - 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, - 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 -}; - -uint16_t crc16_ccitt(const void *buf, int len) -{ - register int counter; - register uint16_t crc = 0; - for( counter = 0; counter < len; counter++) - crc = ((crc<<8)&0xff00) ^ crc16tab[((crc>>8)&0xff) ^ (*(char *)buf++ & 0x00FF)]; - return crc; -} - -////////////////////////////////////////////////////////////// -// Xmodem Functions -////////////////////////////////////////////////////////////// -int get_packet(uint8_t pkt_num, uint8_t *buf) -{ - uint8_t n = _inbyte(10*DELAY_PRESCALAR_MSEC); - uint8_t ni = _inbyte(10*DELAY_PRESCALAR_MSEC); - for(uint8_t i=0; i<128; i++) - buf[i] = _inbyte(10*DELAY_PRESCALAR_MSEC); - uint8_t chk_msb = _inbyte(10*DELAY_PRESCALAR_MSEC); - uint8_t chk_lsb = _inbyte(10*DELAY_PRESCALAR_MSEC); - uint16_t crc = crc16_ccitt(buf, 128); - uint8_t crc_msb = (uint8_t)(crc >> 8); - uint8_t crc_lsb = (uint8_t)crc; - - // check crc - if((n == pkt_num) && ni == (255-pkt_num) - && (crc_msb == chk_msb) && (crc_lsb == chk_lsb)) - return SUCCESS; - return FAILURE; -} - - -xmod_status xmodemReceive(uint8_t * bf, unsigned len) -{ - // Clear recieve buffer - flush_input(); - - // Flush output buffer - flush_output(); - - // SPAM till SOH - bool got_soh = false; - for(uint8_t i=0; i<100; i++) - { - _outbyte('C'); - int c = _inbyte(100*DELAY_PRESCALAR_MSEC); - if (c == (int)-1) - continue; // not heard from sender - - if(c == (int)SOH) { - got_soh = true; - break; - } - else if(c==EOT) - return S_EOT; // normal end of transmission - else if(c==CAN) - return S_TERM; // terminated by host - else { - return UNKCHAR; // unknown char - } - } - - if(!got_soh) { - _outbyte(CAN); - _outbyte(CAN); - _outbyte(CAN); - return TIMEOUT; // connection timeout - } - - - int packetnum = 0; - while(packetnum - -#define DELAY_PRESCALAR_MSEC 250 // sim - -#define CLK_FREQ 12000000 -// #define DELAY_PRESCALAR_USEC CLK_FREQ/1000000 -// #define DELAY_PRESCALAR_MSEC CLK_FREQ/1000 -// #define DELAY_PRESCALAR_SEC CLK_FREQ - -#define SOH 0x01 -#define STX 0x02 -#define EOT 0x04 -#define ACK 0x06 -#define NAK 0x15 -#define CAN 0x18 -#define CTRLZ 0x1A - -typedef enum { - OK = 0, - NOK = 1, - S_EOT = 2, - S_TERM = 3, - R_TERM = 4, - UNKCHAR = 5, - TIMEOUT = 6, - SUCCESS = 7, - FAILURE = 8 -} xmod_status; - -xmod_status xmodemReceive(uint8_t * bf, unsigned len); - - -#endif // __XMODEM_H__ \ No newline at end of file diff --git a/sw/bootloader_old/xmsend.py b/sw/bootloader_old/xmsend.py deleted file mode 100755 index 94269b5f..00000000 --- a/sw/bootloader_old/xmsend.py +++ /dev/null @@ -1,287 +0,0 @@ -#! /usr/bin/python3 - -import serial -import crc16 -import signal -import time -import sys - -# Ignore deprecation warnings from crc16 -import warnings -warnings.filterwarnings("ignore", category=DeprecationWarning) - - -# InterByteDelay = 0.2 # SIM_WITH_TRACE: simulation with trace -InterByteDelay = 0.005 # NORMAL SIM: 0.001 works, for safety we chose this -# InterByteDelay = 0.0001 # FPGA: - -############################################################################# -## UTIL - - -def ctrl_c_handler(signum, frame): # TODO: at ctrl c, finish current packet and send CAN - exit(1) - - -class Logger: - DEBUG=0 - INFO=1 - WARN=2 - ERROR=3 - CRITICAL=4 - def __init__(self, lvl=1, file=None): - self.lvl = lvl - self.file=file - self.fh = None if file==None else open(self.file, 'w') - - def set_level(self, lvl:int): - self.lvl = lvl - - def get_level(self): - return self.lvl - - def debug(self, msg): - if self.lvl <= self.DEBUG: - print("DEBUG: ", msg, file=(sys.stdout if self.file == None else self.fh), flush=True) - - def info(self, msg): - if self.lvl <= self.INFO: - print("INFO: ", msg, file=(sys.stdout if self.file == None else self.fh), flush=True) - - def warn(self, msg): - if self.lvl <= self.WARN: - print("WARN: ", msg, file=(sys.stderr if self.file == None else self.fh), flush=True) - - def error(self, msg): - if self.lvl <= self.ERROR: - print("ERROR: ", msg, file=(sys.stderr if self.file == None else self.fh), flush=True) - - def critical(self, msg, abort=True): - if self.lvl <= self.CRITICAL: - print("CRITICAL: ", msg, file=(sys.stderr if self.file == None else self.fh), flush=True) - if abort: - exit(1) - - -def progressbar(total, progress, prefix=''): - """ - Displays or updates a console progress bar. - Original source: https://stackoverflow.com/a/15860757/1391441 - """ - barLength, status = 20, "" - progr = float(progress) / float(total) - if progr >= 1.: - progr, status = 1, "\r\n" - block = int(round(barLength * progr)) - text = "\r{:s}[{}] {:.0f}% ({}/{}) {}".format(prefix, - "#" * block + "-" * (barLength - block), - round(progr * 100, 0), - int(progress), int(total), - status) - sys.stdout.write(text) - sys.stdout.flush() - - -############################################################################# -## XMODEM - - -class XMODEM: - SOH = b'\x01' - STX = b'\x02' - EOT = b'\x04' - ACK = b'\x06' - DLE = b'\x10' - NAK = b'\x15' - CAN = b'\x18' - CRC = b'C' - - def __init__(self, port, baud, checksum_type='CRC', verbose=False, show_progress=False): - self.ser_port_name = port - self.ser_port_baud = baud - self.ser_port_timeout = 10 - self.inter_out_byte_delay = InterByteDelay - self.checksumType = checksum_type - self.binfile = None - self.ser = None - self.show_progress = show_progress - self.lg = Logger(Logger.ERROR if self.show_progress else verbose) - - def pack_file(self, file_name): - fcontents = [] - - try: - f = open(file_name, "rb") - except IOError: - self.lg.error("File can't be opened") - exit(1) - - while 1: - packet = f.read(128) - if len(packet) < 128: - while len(packet) < 128: - packet = bytearray(packet) - packet.append(0x1A) - packet = bytes(packet) - fcontents.append(packet) - break - fcontents.append(packet) - return fcontents - - def open_serial(self): - ser = serial.Serial() - ser.baudrate = self.ser_port_baud - ser.port = self.ser_port_name - ser.timeout = self.ser_port_timeout - ser.parity = serial.PARITY_NONE - ser.stopbits = serial.STOPBITS_ONE - ser.bytesize = serial.EIGHTBITS - ser.open() - return ser - - def close_serial(self): - self.ser.close() - - def send(self, file): - packed_file = self.pack_file(file) - - self.lg.info("file: {:s}".format(file)) - self.lg.info("size: {:d} bytes".format(len(packed_file)*128)) - self.lg.info("packets: {:d}".format(len(packed_file))) - - # Open Serial Port - self.ser = self.open_serial() - self.lg.info("opened serial port '{:s}' at baud {:d}".format(self.ser_port_name, self.ser_port_baud)) - - # GET NAK/C :Determine Checksum Type - incoming_msg = b'' - counter = 0 - - self.lg.info("Waiting for reciever ping...") - while incoming_msg != XMODEM.NAK and incoming_msg !=XMODEM.CRC and counter < 6: - incoming_msg = self.ser.read(1) - if incoming_msg == XMODEM.NAK: - self.checksumType = "algebraic" - if incoming_msg == XMODEM.CRC: - self.checksumType = "CRC" - counter += 1 - - index = 0 - packet_nr = 1 - if incoming_msg != XMODEM.NAK and incoming_msg != XMODEM.CRC: - exit(3) - - self.lg.info("Starting transfer... [checksum type:{:s}]".format(self.checksumType)) - if self.show_progress: - progressbar(len(packed_file), 0, 'sending: ') - - # Send Packets - while index != len(packed_file): - - self.send_packet(packet_nr, packed_file[index]) - self.lg.info("sent packet {:d}/{:d}".format(packet_nr, len(packed_file))) - - if self.show_progress: - progressbar(len(packed_file), packet_nr, 'sending: ') - - incoming_msg = self.ser.read() - self.lg.debug("got: 0x{:s}".format(str(incoming_msg))) - - if incoming_msg == XMODEM.ACK: - self.lg.debug("received ACK") - index += 1 - packet_nr += 1 - if packet_nr == 256: - packet_nr = 1 - pass - elif incoming_msg == XMODEM.NAK: - self.lg.debug("received NAK") - pass - elif incoming_msg == XMODEM.CAN: - self.lg.info("received CAN, exiting") - exit(4) - break - self.ser.read(self.ser.in_waiting) - - self.ser.timeout = 2 - self.lg.info("Finished transfer!") - while True: - self.lg.debug("sending EOT") - self.out_byte(XMODEM.EOT) - rid = self.ser.read() - if rid == XMODEM.ACK: - self.lg.debug("received ACK") - break - if rid == XMODEM.CAN: - self.log("received CAN") - break - self.ser.read(self.ser.in_waiting) - - # Close Serial - self.close_serial() - self.lg.info('serial port closed') - - def send_packet(self, packet_nr, packet): - ctrl_sum = self.checksum(packet) - packet_to_send = bytearray(XMODEM.SOH) - packet_to_send += bytearray(packet_nr.to_bytes(1, 'big')) - packet_to_send += bytearray((255 - packet_nr).to_bytes(1, 'big')) - packet_to_send += packet - if self.checksumType == "algebraic": - ctrl_sum = bytearray(ctrl_sum.to_bytes(1, 'big')) - else: - ctrl_sum = bytearray(ctrl_sum.to_bytes(2, 'big')) - packet_to_send += ctrl_sum - packet_to_send = bytes(packet_to_send) - - if self.lg.get_level() <= Logger.DEBUG: - self.print_packet(packet_to_send) - - for b in packet_to_send: - self.out_byte(int.to_bytes(b, 1, 'big')) - - def checksum(self, block): - if self.checksumType == "algebraic": - suma = 0 - for i in block: - suma += i - suma = suma % 256 - return suma - elif self.checksumType == "CRC": - crc = crc16.crc16xmodem(block) - return crc - pass - return 0 - - def print_packet(self, packet): - print('[ SOH, n={:d}, ~n={:d},'.format(packet[1], packet[2])) - - i = 3 - while i < 128+3: - print("{:0>2x}".format(packet[i]), end='\n' if (i-3)%16==15 else ' ') - i+=1 - print('chksum= 0x{:0>2x}{:0>2x}]'.format(packet[131], packet[132])) - - def out_byte(self, byte): - self.ser.write(byte) - time.sleep(self.inter_out_byte_delay) - - - -if __name__ == '__main__': - import argparse - parser = argparse.ArgumentParser(description='Send File to Serial Port using Xmodem Protocol') - parser.add_argument('-v', '--verbose', type=int, default=Logger.WARN, help='0:debug, 1:info, 2:warn, 2:error, 3:critical (default:2)') - parser.add_argument('-p', '--show-progress', action='store_true', help='show progress bar') - parser.add_argument('port', type=str, help='serial port') - parser.add_argument('-b', '--baud', type=int, default=115200, help='serial port baud rate (default:115200)') - parser.add_argument('binfile', type=str, help='binary file to be sent') - - args = parser.parse_args() - - signal.signal(signal.SIGINT, ctrl_c_handler) - - xm = XMODEM(args.port, args.baud, 'CRC', verbose=args.verbose, show_progress=args.show_progress) - xm.send(args.binfile) - -