From ac4f0d410f58705cbce22c180df0e2653c32fedd Mon Sep 17 00:00:00 2001 From: logicog Date: Tue, 14 Oct 2025 19:17:12 +0200 Subject: [PATCH 1/6] Add CRC16 initial code --- Makefile | 5 +- crc16.asm | 121 ++++++++++++++++++++++++++++++++++++++++++++++++ rtlplayground.c | 72 ++++++++++++++++++++-------- 3 files changed, 177 insertions(+), 21 deletions(-) create mode 100644 crc16.asm diff --git a/Makefile b/Makefile index 613a0c3..4cea7b8 100644 --- a/Makefile +++ b/Makefile @@ -40,6 +40,9 @@ clean: $(BUILDDIR)crtstart.rel: crtstart.asm $(ASM) $(AFLAGS) -o $@ $< +$(BUILDDIR)crc16.rel: crc16.asm + $(ASM) $(AFLAGS) -o $@ $< + $(BUILDDIR)%.rel: %.c $(CC) $(CC_FLAGS) -o $@ -c $< @@ -47,7 +50,7 @@ $(BUILDDIR)%.rel: $(BUILDDIR)%.asm ${ASM} ${AFLAGS} -o $@ $< # mv -f $(addprefix $(basename $^), .lst .rel .sym) . -$(BUILDDIR)rtlplayground.ihx: $(BUILDDIR)crtstart.rel $(OBJS) +$(BUILDDIR)rtlplayground.ihx: $(BUILDDIR)crtstart.rel $(OBJS) $(BUILDDIR)crc16.rel $(CC) $(CC_FLAGS) -Wl-bHOME=${BOOTLOADER_ADDRESS} -Wl-bBANK1=0x14000 -Wl-r -o $@ $^ $(BUILDDIR)rtlplayground.img: $(BUILDDIR)rtlplayground.ihx diff --git a/crc16.asm b/crc16.asm new file mode 100644 index 0000000..4f1be7a --- /dev/null +++ b/crc16.asm @@ -0,0 +1,121 @@ +; +; CRC16 calculation module +; + .globl _crc_value + .globl _crc16 + .equ BANK, 0x96 +; .equ DPS, 0x86 +; Variable in XMEM holding current CRC16 value, being updated + .area XSEG (XDATA) +_crc_value:: + .ds 2 + +;------------------------------------------------------- +; CRC16 subroutine +; - dptr points to byte to be CRCd in xmem +; - algorithm uses table lookup +;------------------------------------------------------- + .area HOME (CODE) + .area CSEG (CODE) +; .area BANK1 (CODE) +_crc16: + mov BANK, #1 + push dph + push dpl + movx a, @dptr +; inc DPS + mov b, a + mov dptr, #_crc_value + movx a, @dptr + + xrl a, b ; create index into tables + push a ; save index + mov dptr, #crc16_table_l ; low part of table address + movc a, @a+dptr ; get low byte + mov b, a + + mov dptr, #_crc_value + 1 + movx a, @dptr + + xrl a, b + mov dptr, #_crc_value + movx @dptr, a ; save result low part + mov dptr, #crc16_table_h ; high part of table address + pop a ; restore index + movc a, @a+dptr + mov dptr, #_crc_value+1 + movx @dptr, a ; save result high part + pop dpl + pop dph +; clr DPS + ret + + .area BANK1 (CODE) + +crc16_table_l: + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41 + .byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40 + +crc16_table_h: + .byte #0x00, #0xc0, #0xc1, #0x01, #0xc3, #0x03, #0x02, #0xc2 + .byte #0xc6, #0x06, #0x07, #0xc7, #0x05, #0xc5, #0xc4, #0x04 + .byte #0xcc, #0x0c, #0x0d, #0xcd, #0x0f, #0xcf, #0xce, #0x0e + .byte #0x0a, #0xca, #0xcb, #0x0b, #0xc9, #0x09, #0x08, #0xc8 + .byte #0xd8, #0x18, #0x19, #0xd9, #0x1b, #0xdb, #0xda, #0x1a + .byte #0x1e, #0xde, #0xdf, #0x1f, #0xdd, #0x1d, #0x1c, #0xdc + .byte #0x14, #0xd4, #0xd5, #0x15, #0xd7, #0x17, #0x16, #0xd6 + .byte #0xd2, #0x12, #0x13, #0xd3, #0x11, #0xd1, #0xd0, #0x10 + .byte #0xf0, #0x30, #0x31, #0xf1, #0x33, #0xf3, #0xf2, #0x32 + .byte #0x36, #0xf6, #0xf7, #0x37, #0xf5, #0x35, #0x34, #0xf4 + .byte #0x3c, #0xfc, #0xfd, #0x3d, #0xff, #0x3f, #0x3e, #0xfe + .byte #0xfa, #0x3a, #0x3b, #0xfb, #0x39, #0xf9, #0xf8, #0x38 + .byte #0x28, #0xe8, #0xe9, #0x29, #0xeb, #0x2b, #0x2a, #0xea + .byte #0xee, #0x2e, #0x2f, #0xef, #0x2d, #0xed, #0xec, #0x2c + .byte #0xe4, #0x24, #0x25, #0xe5, #0x27, #0xe7, #0xe6, #0x26 + .byte #0x22, #0xe2, #0xe3, #0x23, #0xe1, #0x21, #0x20, #0xe0 + .byte #0xa0, #0x60, #0x61, #0xa1, #0x63, #0xa3, #0xa2, #0x62 + .byte #0x66, #0xa6, #0xa7, #0x67, #0xa5, #0x65, #0x64, #0xa4 + .byte #0x6c, #0xac, #0xad, #0x6d, #0xaf, #0x6f, #0x6e, #0xae + .byte #0xaa, #0x6a, #0x6b, #0xab, #0x69, #0xa9, #0xa8, #0x68 + .byte #0x78, #0xb8, #0xb9, #0x79, #0xbb, #0x7b, #0x7a, #0xba + .byte #0xbe, #0x7e, #0x7f, #0xbf, #0x7d, #0xbd, #0xbc, #0x7c + .byte #0xb4, #0x74, #0x75, #0xb5, #0x77, #0xb7, #0xb6, #0x76 + .byte #0x72, #0xb2, #0xb3, #0x73, #0xb1, #0x71, #0x70, #0xb0 + .byte #0x50, #0x90, #0x91, #0x51, #0x93, #0x53, #0x52, #0x92 + .byte #0x96, #0x56, #0x57, #0x97, #0x55, #0x95, #0x94, #0x54 + .byte #0x9c, #0x5c, #0x5d, #0x9d, #0x5f, #0x9f, #0x9e, #0x5e + .byte #0x5a, #0x9a, #0x9b, #0x5b, #0x99, #0x59, #0x58, #0x98 + .byte #0x88, #0x48, #0x49, #0x89, #0x4b, #0x8b, #0x8a, #0x4a + .byte #0x4e, #0x8e, #0x8f, #0x4f, #0x8d, #0x4d, #0x4c, #0x8c + .byte #0x44, #0x84, #0x85, #0x45, #0x87, #0x47, #0x46, #0x86 + .byte #0x82, #0x42, #0x43, #0x83, #0x41, #0x81, #0x80, #0x40 diff --git a/rtlplayground.c b/rtlplayground.c index 5ce107c..b3c77fd 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -16,6 +16,10 @@ #include "uip/uip.h" #include "uip/uip_arp.h" +extern __xdata uint16_t crc_value; +__xdata uint8_t crc_testbytes[10]; +void crc16(__xdata uint8_t *v) __naked; + // Upload Firmware to 1M #define FIRMWARE_UPLOAD_START 0x100000 @@ -1705,37 +1709,65 @@ void bootloader(void) flash_read_bulk(flash_buf); if (flash_buf[0] == 0x00 && flash_buf[1] == 0x40) { - print_string("Update in progress, moving firmware to start of FLASH!\n"); - __xdata uint32_t dest = 0x0; __xdata uint32_t source = FIRMWARE_UPLOAD_START; - // A 512kByte = 4MBit Flash has 128*8=1024 512k blocks, we copy only 120 - for (__xdata uint16_t i=0; i < 960; i++) { - print_string("Writing block: "); - print_short(dest); + __xdata uint16_t i = 0; + __xdata uint16_t j = 0; + __xdata uint8_t * __xdata bptr; + print_string("Identified update image. Checking integrity...\n"); + + crc_value = 0x0000; + for (i = 0; i < 1024; i++) { flash_region.addr = source; flash_region.len = 0x200; flash_read_bulk(flash_buf); - write_char('\n'); - if (!(i & 0x7)) { - flash_region.addr = dest; - flash_sector_erase(); - } - flash_region.addr = dest; - flash_region.len = 0x200; - flash_write_bytes(flash_buf); - dest += 0x200; + bptr = flash_buf; + for (j = 0; j < 0x200; j++) + crc16(bptr++); source += 0x200; + print_short(crc_value); write_char(' '); } - print_string("Deleting uploaded flash image\n"); + if (crc_value == 0xb001) { + print_string("Checksum OK\n"); + print_string("Update in progress, moving firmware to start of FLASH!\n"); + source = FIRMWARE_UPLOAD_START; + // A 512kByte = 4MBit Flash has 128*8=1024 512k blocks, we copy only 120 + for (i = 0; i < 960; i++) { + print_string("Writing block: "); + print_short(dest); + flash_region.addr = source; + flash_region.len = 0x200; + flash_read_bulk(flash_buf); + write_char('\n'); + if (!(i & 0x7)) { + flash_region.addr = dest; + flash_sector_erase(); + } + flash_region.addr = dest; + flash_region.len = 0x200; + flash_write_bytes(flash_buf); + dest += 0x200; + source += 0x200; + } + print_string("Deleting uploaded flash image\n"); + dest = FIRMWARE_UPLOAD_START; + for (register uint8_t i=0; i < 128; i++) { + flash_region.addr = dest; + flash_sector_erase(); + dest += 0x1000; + } + print_string("Resetting now"); + delay(200); + reset_chip(); + } + print_string("Checksum incorrect, please upload the image again\n"); + print_string("Erasing bad uploaded flash image\n"); dest = FIRMWARE_UPLOAD_START; - for (register uint8_t i=0; i < 120; i++) { - flash_region.addr = dest; + for (register uint8_t i=0; i < 128; i++) { + flash_region.addr = dest; flash_sector_erase(); dest += 0x1000; } - print_string("Resetting now"); - reset_chip(); } // Reset NIC From 8499e9e46448cba99d9fb93e89d2c0dd5cb63740 Mon Sep 17 00:00:00 2001 From: logicog Date: Wed, 15 Oct 2025 20:17:34 +0200 Subject: [PATCH 2/6] Add CRC-16 calculator for a firmware image --- tools/Makefile | 5 +- tools/crc_calculator.c | 179 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 tools/crc_calculator.c diff --git a/tools/Makefile b/tools/Makefile index 87333ed..cca21a7 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -2,7 +2,7 @@ CC = gcc CCFLAGS = -Wall -o BUILDDIR = output/ -all: create_build_dir $(BUILDDIR)injector $(BUILDDIR)fileadder $(BUILDDIR)httpd_sim +all: create_build_dir $(BUILDDIR)injector $(BUILDDIR)fileadder $(BUILDDIR)httpd_sim $(BUILDDIR)crc_calculator create_build_dir: mkdir -p $(BUILDDIR) @@ -16,5 +16,8 @@ $(BUILDDIR)injector: injector.c $(BUILDDIR)fileadder: fileadder.c gcc $^ $(CCFLAGS) $@ +$(BUILDDIR)crc_calculator: crc_calculator.c + gcc $^ $(CCFLAGS) $@ + $(BUILDDIR)httpd_sim: httpd_sim.c httpd_sim.h gcc $< $(CCFLAGS) $@ -I/usr/include/json-c -ljson-c diff --git a/tools/crc_calculator.c b/tools/crc_calculator.c new file mode 100644 index 0000000..4089fea --- /dev/null +++ b/tools/crc_calculator.c @@ -0,0 +1,179 @@ +/* + * Calculator for the CRC16 as described in AN27 by Dallas Semiconductor + * http://www.microshadow.com/files/files8051/app27.pdf + * The implementation in C is based on the code given in + * https://carta.tech/man-pages/man3/_crc_ibutton_update.3avr.html + * The polynomial of the CRC is 0xa001: x^16 + x^15 + x^2 + 1 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +// Use a 4MB buffer, the same as the flash rom size +#define BUFFER_SIZE 0x400000 +char buffer[BUFFER_SIZE]; + +struct arguments { + char *input_file; + char *output_file; + bool update; + bool verify; +}; + +const char *argp_program_version = "crc_calculator 0.1"; +const char *argp_program_bug_address = "https://github.com/logicog/RTLPlayground/issues"; +static char doc[] = "Calculate (and optionally update) the CRC of an image"; +static char args_doc[] = "crc_calculator [options] INPUT_IMAGE"; +static struct argp_option options[] = { + { "output", 'o', "FILE", 0, "Output image file name instead of overwriting input image"}, + { "update", 'u', 0, OPTION_ARG_OPTIONAL, "Update the image with the CRC"}, + { "verify", 'v', 0, OPTION_ARG_OPTIONAL, "Verify the CRC of the file"}, + { 0 } +}; + + +uint16_t crc16_update(uint16_t crc, uint8_t a) +{ + crc ^= a; + for (int i = 0; i < 8; ++i) + crc = crc & 1 ? (crc >> 1) ^ 0xA001 : crc >> 1; + + return crc; +} + + +static error_t parse_opt(int key, char *arg, struct argp_state *state) +{ + struct arguments *arguments = state->input; + switch (key) { + case 'u': + arguments->update = true; + break; + case 'v': + arguments->verify = true; + break; + case 'o': + arguments->output_file = arg; + break; + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + + +static struct argp argp = { + options, parse_opt, args_doc, doc, 0, 0, 0 +}; + + +int main(int argc, char **argv) +{ + struct arguments arguments; + int arg_index; + char tmpfilename[] = "crc_XXXXXX"; + uint16_t crc = 0; + FILE *inptr; + int outptr; + int range; + + arguments.input_file = NULL; + arguments.output_file = NULL; + arguments.update = false; + arguments.verify = false; + + argp_parse(&argp, argc, argv, 0, &arg_index, &arguments); + if (!arg_index) + argp_usage (0); + + memset(buffer, 0, BUFFER_SIZE); + + size_t filesize = 0; + if (argv[arg_index]) { + inptr = fopen(argv[arg_index], "rb"); + if (inptr == NULL) { + printf("Cannot open input file %s\n", argv[arg_index]); + return 5; + } + + fseek(inptr, 0L, SEEK_END); + filesize = ftell(inptr); + rewind(inptr); + printf("Input file size: %ld\n", filesize); + if (filesize > BUFFER_SIZE) { + printf("File too large.\n"); + return 5; + } + size_t bytes_read = fread(buffer, 1, sizeof(buffer), inptr); + + printf("Bytes read: %ld\n", bytes_read); + + if (bytes_read != filesize) { + printf("Error reading input file.\n"); + return 5; + } + fclose(inptr); + } + + range = filesize; + if (!arguments.verify) { + if (arguments.update) { + range -= 2; + } else if (arguments.output_file) { + filesize += 2; + } + } + + for (int i = 0; i < range; i++) + crc = crc16_update(crc, buffer[i]); + + printf("CRC16 is: 0x%04x\n", crc); + + if (arguments.verify) { + if (crc == 0xb001) { + printf("Checksum OK\n"); + return 0; + } else { + printf("Checksum Incorrect\n"); + return 5; + } + } + + // We have to create a new image with updated CRC + if (arguments.update || arguments.output_file) { + crc ^= 0xffff; + printf("Setting CRC bytes at position: 0x%x to CRC 1s complement 0x%04x\n", range, crc); + // The CRC algorithm expects as input always first the LO-Byte + buffer[range] = crc; + buffer[range + 1] = crc >> 8; + + if (!arguments.update) + outptr = creat(arguments.output_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + else + outptr = mkstemp(tmpfilename); + + if (!outptr) { + printf("Cannot open %s\n", arguments.output_file); + return 5; + } + size_t written = write(outptr, buffer, filesize); + + if (written != filesize) { + printf("Error writing output file.\n"); + return 5; + } + close(outptr); + + if (arguments.update) + rename(tmpfilename, argv[arg_index]); + } + + return 0; +} From 4d17d9ff001ee938e99e39ccf86e45762eaa5ac6 Mon Sep 17 00:00:00 2001 From: logicog Date: Wed, 15 Oct 2025 20:21:58 +0200 Subject: [PATCH 3/6] Add CRC verification --- httpd/httpd.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/httpd/httpd.c b/httpd/httpd.c index 289308a..ab135a4 100644 --- a/httpd/httpd.c +++ b/httpd/httpd.c @@ -49,6 +49,9 @@ __xdata uint16_t short_parsed; #define TSTATE_CLOSED 3 #define TSTATE_POST 4 +extern __xdata uint16_t crc_value; +void crc16(__xdata uint8_t *v) __naked; + inline uint8_t is_separator(uint8_t c) { @@ -224,6 +227,12 @@ uint8_t stream_upload(uint16_t bptr) uptr += write_len; write_len = 0; // TODO: This is a bit premature, what about a nice web-page saying the device will reset??? + print_string("CRC16: "); print_short(crc_value); write_char('\n'); + if (crc_value == 0xb001) { + print_string("Checksum OK."); + } else { + print_string("Checksum incorrect!"); + } print_string("Upload to flash done, will reset!\n"); reset_chip(); if (bptr >= uip_len) @@ -231,6 +240,7 @@ uint8_t stream_upload(uint16_t bptr) return 1; } if (p[bptr] == boundary[bindex]) { + crc16(p + bptr); bptr++; bindex++; } else { @@ -239,6 +249,7 @@ uint8_t stream_upload(uint16_t bptr) write_len += bindex; bindex = 0; } + crc16(p + bptr); flash_buf[write_len++] = p[bptr++]; if (write_len >= FLASHMEM_PAGE_SIZE) { print_string("len: "); print_short(write_len); write_char(' '); @@ -313,6 +324,7 @@ void handle_post(void) p += 4; // Skip \r\n\r\n sequence at end of preamble of part uptr = FIRMWARE_UPLOAD_START; + crc_value = 0; bindex = 0; write_len = 0; stream_upload(p - uip_appdata); From f3ff8eed428e96e4da7fea195e54a62564f4f1e1 Mon Sep 17 00:00:00 2001 From: logicog Date: Wed, 15 Oct 2025 20:25:09 +0200 Subject: [PATCH 4/6] Make use of CRC checksum calculation when building image --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 4cea7b8..11f9293 100644 --- a/Makefile +++ b/Makefile @@ -64,6 +64,7 @@ $(BUILDDIR)rtlplayground.bin: $(BUILDDIR)rtlplayground.img dd if=$< skip=80 bs=1024 >>$@ tools/$(BUILDDIR)fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@ tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data $@ + tools/$(BUILDDIR)crc_calculator -u $@ .PHONY: clean all $(SUBDIRS) From 9c062edc753d52415d2360736c2328d159e0fb87 Mon Sep 17 00:00:00 2001 From: logicog Date: Sun, 26 Oct 2025 14:20:07 +0100 Subject: [PATCH 5/6] Fix CRC calculation during upload --- httpd/httpd.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/httpd/httpd.c b/httpd/httpd.c index ab135a4..950e5f4 100644 --- a/httpd/httpd.c +++ b/httpd/httpd.c @@ -50,6 +50,7 @@ __xdata uint16_t short_parsed; #define TSTATE_POST 4 extern __xdata uint16_t crc_value; +__xdata uint16_t crc_final; void crc16(__xdata uint8_t *v) __naked; @@ -187,13 +188,15 @@ __xdata uint8_t *scan_header(__xdata uint8_t *p) content_type += 30; uint8_t i = 0; while (content_type[i] != '\r' && content_type[i] != '\n') { - boundary[i + 2] = content_type[i]; + boundary[i + 4] = content_type[i]; i++; } - // The boundary between parts is "--" + the boundary given in the header - boundary[0] = '-'; - boundary[1] = '-'; - boundary[i + 2] = 0; + // The boundary between parts is "\r\n--" + the boundary given in the header + boundary[0] = '\r'; + boundary[1] = '\n'; + boundary[2] = '-'; + boundary[3] = '-'; + boundary[i + 4] = 0; } return p; } @@ -227,8 +230,8 @@ uint8_t stream_upload(uint16_t bptr) uptr += write_len; write_len = 0; // TODO: This is a bit premature, what about a nice web-page saying the device will reset??? - print_string("CRC16: "); print_short(crc_value); write_char('\n'); - if (crc_value == 0xb001) { + print_string("CRC16: "); print_short(crc_final); write_char('\n'); + if (crc_final == 0xb001) { print_string("Checksum OK."); } else { print_string("Checksum incorrect!"); @@ -240,6 +243,8 @@ uint8_t stream_upload(uint16_t bptr) return 1; } if (p[bptr] == boundary[bindex]) { + if (!bindex) + crc_final = crc_value; crc16(p + bptr); bptr++; bindex++; @@ -253,6 +258,7 @@ uint8_t stream_upload(uint16_t bptr) flash_buf[write_len++] = p[bptr++]; if (write_len >= FLASHMEM_PAGE_SIZE) { print_string("len: "); print_short(write_len); write_char(' '); + print_string("CRC16: "); print_short(crc_value); write_char('\n'); flash_region.addr = uptr; flash_region.len = FLASHMEM_PAGE_SIZE; flash_write_bytes(flash_buf); From eb0e4df5ea4d1aec92e46dae8ac6217167f9fba8 Mon Sep 17 00:00:00 2001 From: logicog Date: Sun, 26 Oct 2025 14:20:30 +0100 Subject: [PATCH 6/6] Fix reset after image upload --- rtlplayground.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/rtlplayground.c b/rtlplayground.c index b3c77fd..5b59d75 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -1044,6 +1044,7 @@ void sleep(uint16_t t) void reset_chip(void) { REG_SET(RTL837X_REG_RESET, 1); + while(1); } @@ -1703,6 +1704,24 @@ void bootloader(void) print_string(" Flash controller\n"); flash_init(0); + // Reset NIC + reg_bit_set(0x24, 2); + do { + reg_read(0x24); + } while (SFR_DATA_0 & 0x4); + print_string("NIC reset\n"); + + uip_ipaddr(&uip_hostaddr, ownIP[0], ownIP[1], ownIP[2], ownIP[3]); + uip_ipaddr(&uip_draddr, gatewayIP[0], gatewayIP[1], gatewayIP[2], gatewayIP[3]); + uip_ipaddr(&uip_netmask, netmask[0], netmask[1], netmask[2], netmask[3]); + + REG_SET(0x7f94, 0x0); + if (isRTL8373) + rtl8373_init(); + else + rtl8372_init(); + delay(1000); + // Check update in progress and move blocks flash_region.addr = FIRMWARE_UPLOAD_START; flash_region.len = 0x100; @@ -1722,10 +1741,13 @@ void bootloader(void) flash_region.len = 0x200; flash_read_bulk(flash_buf); bptr = flash_buf; - for (j = 0; j < 0x200; j++) + for (j = 0; j < 0x200; j++) { + print_byte(*bptr); write_char(' '); crc16(bptr++); + print_short(crc_value); write_char(':'); + } source += 0x200; - print_short(crc_value); write_char(' '); + write_char('\n'); print_short(crc_value); write_char(' '); } if (crc_value == 0xb001) { print_string("Checksum OK\n"); @@ -1770,24 +1792,6 @@ void bootloader(void) } } - // Reset NIC - reg_bit_set(0x24, 2); - do { - reg_read(0x24); - } while (SFR_DATA_0 & 0x4); - print_string("NIC reset\n"); - - uip_ipaddr(&uip_hostaddr, ownIP[0], ownIP[1], ownIP[2], ownIP[3]); - uip_ipaddr(&uip_draddr, gatewayIP[0], gatewayIP[1], gatewayIP[2], gatewayIP[3]); - uip_ipaddr(&uip_netmask, netmask[0], netmask[1], netmask[2], netmask[3]); - - REG_SET(0x7f94, 0x0); - if (isRTL8373) - rtl8373_init(); - else - rtl8372_init(); - delay(1000); - #ifdef DEBUG // This register seems to work on the RTL8373 only if also the SDS // Is correctly configured. Therefore, we can test it, here...