From 7a87b798713cf477c8e25899fd81fa475ea665c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 5 Oct 2025 15:36:08 +0200 Subject: [PATCH] Convert flash_addr to struct flash_region. flash_region storage flash address and length, which a operation is needed. --- cmd_parser.c | 13 +++++---- httpd/httpd.c | 23 +++++++++++----- rtl837x_common.h | 5 ++++ rtl837x_flash.c | 72 +++++++++++++++++++++++++----------------------- rtl837x_flash.h | 6 ++-- rtlplayground.c | 18 +++++++----- 6 files changed, 80 insertions(+), 57 deletions(-) diff --git a/cmd_parser.c b/cmd_parser.c index 41e4f3b..ee06b95 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -33,7 +33,7 @@ extern __code uint8_t * __code greeting; extern __code uint8_t * __code hex; extern __xdata uint8_t flash_buf[512]; -extern __xdata uint32_t flash_addr; +extern __xdata struct flash_region_t flash_region; __xdata uint8_t vlan_names[VLAN_NAMES_SIZE]; __xdata uint16_t vlan_ptr; @@ -497,7 +497,8 @@ void cmd_parser(void) __banked } if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'd') { print_string("\nDUMPING FLASH\n"); - flash_addr = 0; + flash_region.addr = 0; + flash_region.len = 255; flash_dump(255); } if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'j') { @@ -513,7 +514,8 @@ void cmd_parser(void) __banked print_string("\nFLASH FAST MODE\n"); flash_init(1); print_string("\nNow dumping flash\n"); - flash_addr = 0; + flash_region.addr = 0; + flash_region.len = 255; flash_dump(255); } if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'e') { @@ -524,8 +526,9 @@ void cmd_parser(void) __banked print_string("\nFLASH write\n"); for (uint8_t i = 0; i < 20; i++) flash_buf[i] = greeting[i]; - flash_addr = 0x20000; - flash_write_bytes(flash_buf, 20); + flash_region.addr = 0x200000; + flash_region.len = 20; + flash_write_bytes(flash_buf); } if (cmd_compare(0, "port") && cmd_words_b[1] > 0) { print_string("\nPORT "); diff --git a/httpd/httpd.c b/httpd/httpd.c index 4436458..434ec2f 100644 --- a/httpd/httpd.c +++ b/httpd/httpd.c @@ -17,10 +17,11 @@ extern __code struct f_data f_data[]; extern __code fcall_ptr f_calls[]; extern __code char * __code mime_strings[]; -extern __xdata uint32_t flash_addr; +extern __xdata struct flash_region_t flash_region; // Flash buffer to optimize flash writing speed, write_len is the current filling position extern __xdata uint8_t flash_buf[512]; +__xdata uint32_t uptr; // Current flash write position __xdata uint16_t write_len; __xdata uint8_t outbuf[TCP_OUTBUF_SIZE]; @@ -214,7 +215,10 @@ uint8_t stream_upload(__xdata uint16_t bptr) if (!boundary[bindex]) { s->tstate = TSTATE_NONE; print_string("len 2: "); print_short(write_len); write_char(' '); - flash_write_bytes(flash_buf, write_len); + flash_region.addr = uptr; + flash_region.len = write_len; + flash_write_bytes(flash_buf); + 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("Upload to flash done, will reset!\n"); @@ -235,7 +239,10 @@ uint8_t stream_upload(__xdata uint16_t bptr) flash_buf[write_len++] = p[bptr++]; if (write_len >= 256) { print_string("len: "); print_short(write_len); write_char(' '); - flash_write_bytes(flash_buf, write_len); + flash_region.addr = uptr; + flash_region.len = write_len; + flash_write_bytes(flash_buf); + uptr += write_len; write_len = 0; } bindex = 0; @@ -297,7 +304,7 @@ void handle_post(void) print_string("Have content octets\n"); p += 4; // Skip \r\n\r\n sequence at end of preamble of part - flash_addr = FIRMWARE_UPLOAD_START; + uptr = FIRMWARE_UPLOAD_START; bindex = 0; write_len = 0; stream_upload(p - uip_appdata); @@ -437,8 +444,9 @@ void httpd_appcall(void) print_string("call done\n"); mpos += CMARK_S; len_left -= mpos; - flash_addr = f_data[entry].start + mpos; - flash_find_mark("#{", len_left); + flash_region.addr = f_data[entry].start + mpos; + flash_addr = f_data[entry].start + f_data[entry].len - len_left; + flash_find_mark("#{"); print_string("mpos now: "); print_short(mpos); write_char('\n'); } print_string("At end mpos: "); print_short(mpos); write_char('\n'); @@ -447,7 +455,8 @@ void httpd_appcall(void) slen += len_left; } else { print_string("MIME: "); print_string(mime_strings[f_data[entry].mime]); write_char('\n'); - flash_addr = f_data[entry].start; + flash_region.addr = f_data[entry].start; + flash_region.len = len_left; flash_read_bulk(outbuf + slen, len_left); slen += len_left; } diff --git a/rtl837x_common.h b/rtl837x_common.h index 35d1e49..c04fbb3 100644 --- a/rtl837x_common.h +++ b/rtl837x_common.h @@ -50,6 +50,11 @@ struct uip_eth_addr { uint8_t addr[6]; }; +struct flash_region_t { + uint32_t addr; + uint16_t len; +}; + extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2]; diff --git a/rtl837x_flash.c b/rtl837x_flash.c index 674c735..2530452 100644 --- a/rtl837x_flash.c +++ b/rtl837x_flash.c @@ -10,7 +10,8 @@ __xdata uint8_t dio_enabled; __xdata uint8_t markbuf[16]; extern __xdata uint16_t mpos; -__xdata uint32_t flash_addr; +__xdata struct flash_region_t flash_region; + // For the flash commands, see e.g. Windbond W25Q32JV datasheet #define CMD_WRITE_STATUS 0x01 @@ -206,10 +207,10 @@ void flash_dump(uint8_t len) // Read 4 bytes SFR_FLASH_TCONF = 4; while (len) { - SFR_FLASH_ADDR16 = flash_addr >> 16; - SFR_FLASH_ADDR8 = flash_addr >> 8; - SFR_FLASH_ADDR0 = flash_addr; - flash_addr += 4; + SFR_FLASH_ADDR16 = flash_region.addr >> 16; + SFR_FLASH_ADDR8 = flash_region.addr >> 8; + SFR_FLASH_ADDR0 = flash_region.addr; + flash_region.addr += 4; SFR_FLASH_EXEC_GO = 1; while(SFR_FLASH_EXEC_BUSY); @@ -233,7 +234,7 @@ void flash_dump(uint8_t len) * Reads bulk data of length len from the flash memory starging at address src * and writes the data into a buffer pointed to by dst in XMEM */ -void flash_read_bulk(__xdata uint8_t *dst, register uint16_t len) +void flash_read_bulk(__xdata uint8_t *dst) { short status; do { @@ -251,28 +252,30 @@ void flash_read_bulk(__xdata uint8_t *dst, register uint16_t len) SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks after read? } // Read 4 bytes - SFR_FLASH_TCONF = 4; - while (len) { - SFR_FLASH_ADDR16 = flash_addr >> 16; - SFR_FLASH_ADDR8 = flash_addr >> 8; - SFR_FLASH_ADDR0 = flash_addr; - flash_addr += 4; + while (1) { + SFR_FLASH_ADDR16 = flash_region.addr >> 16; + SFR_FLASH_ADDR8 = flash_region.addr >> 8; + SFR_FLASH_ADDR0 = flash_region.addr; + flash_region.addr += 4; + + SFR_FLASH_TCONF = 4; SFR_FLASH_EXEC_GO = 1; while(SFR_FLASH_EXEC_BUSY); *dst++ = SFR_FLASH_DATA0; - if (len == 1) - return; + if (flash_region.len == 1) + break; *dst++ = SFR_FLASH_DATA8; - if (len == 2) - return; + if (flash_region.len == 2) + break; *dst++ = SFR_FLASH_DATA16; - if (len == 3) - return; + if (flash_region.len == 3) + break; *dst++ = SFR_FLASH_DATA24; - - len -= 4; + if (flash_region.len == 4) + break; + flash_region.len -= 4; } } @@ -412,24 +415,21 @@ void flash_sector_erase(uint32_t addr) } -void flash_write_bytes(__xdata uint8_t *ptr, __xdata uint16_t len) +void flash_write_bytes(__xdata uint8_t *ptr) { - __xdata uint8_t exit_loop = 0; - - write_char('>'); print_long(flash_addr); write_char(':'); print_short(len); write_char('-'); print_byte(*ptr); write_char('\n'); - while(1) { + write_char('>'); print_long(flash_region.addr); write_char(':'); print_short(flash_region.len); write_char('-'); print_byte(*ptr); write_char('\n'); + while(1) { flash_write_enable(); SFR_FLASH_CMD = CMD_PAGE_PROGRAM; SFR_FLASH_TCONF = 0x40 | 8 | 4; // Bytes written is 4, 8 enables write, 0x40 is unknown // Last transfer? - if (len < 5) { - SFR_FLASH_TCONF = 8 | len; - exit_loop = 1; + if (flash_region.len < 5) { + SFR_FLASH_TCONF = 8 | flash_region.len; } - SFR_FLASH_ADDR16 = flash_addr >> 16; - SFR_FLASH_ADDR8 = flash_addr >> 8; - SFR_FLASH_ADDR0 = flash_addr; + SFR_FLASH_ADDR16 = flash_region.addr >> 16; + SFR_FLASH_ADDR8 = flash_region.addr >> 8; + SFR_FLASH_ADDR0 = flash_region.addr; SFR_FLASH_DATA0 = *ptr++; SFR_FLASH_DATA8 = *ptr++; SFR_FLASH_DATA16 = *ptr++; @@ -437,11 +437,13 @@ void flash_write_bytes(__xdata uint8_t *ptr, __xdata uint16_t len) // Execute transfer, we wait for completion at top of loop SFR_FLASH_EXEC_GO = 1; - if (exit_loop) + + if (flash_region.len < 5) break; - len -= 4; - flash_addr += 4; - } + + flash_region.len -= 4; + flash_region.addr += 4; + }; while (flash_read_status() & 0x1); flash_configure_mmio(); diff --git a/rtl837x_flash.h b/rtl837x_flash.h index de81bd2..43a1948 100644 --- a/rtl837x_flash.h +++ b/rtl837x_flash.h @@ -4,11 +4,11 @@ void flash_init(uint8_t enable_dio); void flash_read_uid(void); void flash_write_enable(void); -void flash_dump(register uint8_t len); +void flash_dump(uint8_t len); void flash_read_jedecid(void); void flash_read_security(uint32_t addr, uint8_t len); void flash_sector_erase(uint32_t addr); -void flash_read_bulk(__xdata uint8_t *dst, __xdata uint16_t len); -void flash_write_bytes(__xdata uint8_t *ptr, __xdata uint16_t len); +void flash_read_bulk(__xdata uint8_t *dst); +void flash_write_bytes(__xdata uint8_t *ptr); void flash_find_mark( __code uint8_t *mark, __xdata uint16_t len); #endif diff --git a/rtlplayground.c b/rtlplayground.c index d011dde..b4aeb73 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -70,7 +70,7 @@ __xdata uint8_t sfr_data[4]; extern __xdata uint8_t cmd_buffer[SBUF_SIZE]; extern __xdata uint8_t gpio_last_value[8]; -extern __xdata uint32_t flash_addr; +extern __xdata struct flash_region_t flash_region; __code uint8_t * __code greeting = "\nA minimal prompt to explore the RTL8372:\n"; __code uint8_t * __code hex = "0123456789abcdef"; @@ -1700,8 +1700,10 @@ void bootloader(void) flash_init(0); // Check update in progress and move blocks - flash_addr = FIRMWARE_UPLOAD_START; - flash_read_bulk(flash_buf, 0x100); + flash_region.addr = FIRMWARE_UPLOAD_START; + flash_region.len = 0x100; + 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"); @@ -1711,13 +1713,15 @@ void bootloader(void) for (__xdata uint16_t i=0; i < 960; i++) { print_string("Writing block: "); print_short(dest); - flash_addr = source; - flash_read_bulk(flash_buf, 0x200); + flash_region.addr = source; + flash_region.len = 0x200; + flash_read_bulk(flash_buf); write_char('\n'); if (!(i & 0x7)) flash_sector_erase(dest); - flash_addr = dest; - flash_write_bytes(flash_buf, 0x200); + flash_region.addr = dest; + flash_region.len = 0x200; + flash_write_bytes(flash_buf); dest += 0x200; source += 0x200; }