Browse Source

esp32: don't start the network if spiram doesn't work

If the spiram heap cannot be initialized, then don't start the wifi
and httpd stack; reserve memory for running the upgrade procedure if
necessary.

Unfortunately this also means it is extremely handicapped. Not sure
what to do about that, I'm afraid...
H. Peter Anvin 1 year ago
parent
commit
963947f4d5

+ 2 - 0
common/sysvars.vars

@@ -66,5 +66,7 @@ net.sta.mac		mac
 net.sta.ssid		str
 heap.sram.free		uint
 heap.sram.max		uint
+heap.sram.size		uint
 heap.spiram.free	uint
 heap.spiram.max		uint
+heap.spiram.size	uint

+ 10 - 0
esp32/max80/common.h

@@ -48,6 +48,15 @@ typedef void *token_t;
 typedef int (*read_func_t)(token_t token, void *buf, size_t len);
 typedef int (*write_func_t)(token_t token, const void *buf, size_t len);
 
+/*
+ * Bad SPIRAM memory?
+ */
+extern_c bool _spiram_broken;
+static inline bool spiram_broken(void)
+{
+    return _spiram_broken;
+}
+
 /*
  * Sleep thread...
  */
@@ -106,3 +115,4 @@ extern_c void print_time(const char *msg, const struct timeval *tv);
 extern_c volatile bool do_log_config_status;
 extern_c void __fmt_printf(2,3)
   logmsg(const char *module, const char *fmt, ...);
+extern_c void heap_info(void);

+ 17 - 25
esp32/max80/fwupdate.c

@@ -27,49 +27,41 @@
 #define FWUPDATE_STACK		8192
 #define FWUPDATE_PRIORITY	3
 
-static void heap_info(void)
+static inline void spz_heap_info(bool always)
 {
-#if DEBUG > 1
-    MSG("Heap: sram ");
-    MSG("%u/", heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL));
-    MSG("%u, spiram ", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
-    MSG("%u/", heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM));
-    MSG("%u\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
-#endif
+    if (DEBUG || always)
+	heap_info();
 }
 
-static void *spz_calloc(void *opaque, unsigned int items, unsigned int size)
-{
-    spz_stream *spz = opaque;
-    heap_info();
-    MSG("spz_calloc(%u,%u) = %u = ", items, size, items*size);
-    void *p = calloc(items, size);
-    CMSG("%p\n", p);
-    heap_info();
-    if (!p)
-	spz->err = Z_MEM_ERROR;
-    return p;
-}
 static void *spz_malloc(void *opaque, unsigned int size)
 {
     spz_stream *spz = opaque;
-    heap_info();
     MSG("spz_malloc(%u) = ", size);
     void *p = malloc(size);
     CMSG("%p\n", p);
-    heap_info();
-    if (!p)
+    spz_heap_info(!p);
+    if (!p) {
 	spz->err = Z_MEM_ERROR;
+	printf("[FWUP] Out of memory error!\n");
+    }
+    return p;
+}
+static void *spz_calloc(void *opaque, unsigned int items, unsigned int size)
+{
+    size_t bytes = items*size;
+    void *p = spz_malloc(opaque, bytes);
+    if (likely(p))
+	memset(p, 0, bytes);
+
     return p;
 }
 
 static void spz_free(void *opaque, void *ptr)
 {
-    heap_info();
     MSG("spz_free(%p)\n", ptr);
     (void)opaque;
     free(ptr);
-    heap_info();
+    spz_heap_info(false);
 }
 
 int spz_read_data(spz_stream *spz, void *buf, size_t len)

+ 18 - 7
esp32/max80/max80.ino

@@ -44,25 +44,32 @@ void setup_usb_ids()
     USB.serialNumber(serial_number);
 }
 
-static void heap_info()
+bool _spiram_broken;
+
+void heap_info()
 {
     size_t il = heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL);
     size_t ia = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
+    size_t it = heap_caps_get_total_size(MALLOC_CAP_INTERNAL);
     size_t sl = heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM);
     size_t sa = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
+    size_t st = heap_caps_get_total_size(MALLOC_CAP_SPIRAM);
 
     char msg_buffer[128];
     snprintf(msg_buffer, sizeof msg_buffer,
-	     "Heap: sram %zu/%zu, spiram %zu/%zu\r\n",
-	     il, ia, sl, sa);
+	     "Heap: sram %zu/%zu/%zu, spiram %zu/%zu/%zu\r\n",
+	     il, ia, it, sl, sa, st);
 
     fputs(msg_buffer, stdout);
     Serial.print(msg_buffer);
 
     setvar_uint(status_heap_sram_max, il);
     setvar_uint(status_heap_sram_free, ia);
+    setvar_uint(status_heap_sram_size, it);
     setvar_uint(status_heap_spiram_max, sl);
     setvar_uint(status_heap_spiram_free, sa);
+    setvar_uint(status_heap_spiram_size, st);
+    _spiram_broken = st == 0;
 }
 
 #if 0
@@ -125,7 +132,6 @@ void setup() {
 
     // Enable external PSRAM for heap
     heap_caps_malloc_extmem_enable(3000); // >= 3K allocations in PSRAM
-    heap_info();
 
     TTY::init();
     Serial.print("\r\n*** Hello, World! ***\r\n");
@@ -143,13 +149,18 @@ void setup() {
     set_build_status_info();
     fpga_service_init();
     fpga_service_enable(true);
-    SetupWiFi();
+    if (spiram_broken()) {
+	const char spiram_broken_msg[] =
+	    "WARNING: SPIRAM broken, not starting network\r\n";
+	fputs(spiram_broken_msg, stdout);
+	Serial.print(spiram_broken_msg);
+    } else {
+	SetupWiFi();
+    }
     Serial.println("[RDY]");
     sysvar_print_updates = true;
     do_log_config_status = true; // Print configuration from main loop
     led_set(LED_BLUE, LED_ON);	// Software ready
-
-    heap_info();
 }
 
 static inline char task_state(eTaskState state)

+ 7 - 5
esp32/max80/spiflash.c

@@ -354,12 +354,14 @@ int spiflash_write_spz(spz_stream *spz,
     pinMode(PIN_FPGA_READY,    INPUT);
     pinMode(PIN_FPGA_BOARD_ID, INPUT);
 
-    MSG("waiting for FPGA bypass to be ready..");
-    while (digitalRead(PIN_FPGA_READY) != LOW) {
-	CMSG(".");
-	yield();
+    if (digitalRead(PIN_FPGA_READY) == LOW) {
+	MSG("waiting for FPGA bypass to be ready..");
+	while (digitalRead(PIN_FPGA_READY) != LOW) {
+	    CMSG(".");
+	    yield();
+	}
+	CMSG("\n");
     }
-    CMSG("\n");
     MSG("FPGA bypass ready, board version v%c.\n",
 	digitalRead(PIN_FPGA_BOARD_ID) ? '1' : '2');
 

BIN
esp32/output/max80.ino.bin


+ 3 - 3
fpga/max80.qpf

@@ -19,15 +19,15 @@
 #
 # Quartus Prime
 # Version 22.1std.2 Build 922 07/20/2023 SC Lite Edition
-# Date created = 19:21:31  September 30, 2023
+# Date created = 15:41:59  October 01, 2023
 #
 # -------------------------------------------------------------------------- #
 
 QUARTUS_VERSION = "22.1"
-DATE = "19:21:31  September 30, 2023"
+DATE = "15:41:59  October 01, 2023"
 
 # Revisions
 
-PROJECT_REVISION = "v1"
 PROJECT_REVISION = "v2"
+PROJECT_REVISION = "v1"
 PROJECT_REVISION = "bypass"

BIN
fpga/output/bypass.jic


BIN
fpga/output/max80.fw


BIN
fpga/output/v1.fw


BIN
fpga/output/v1.jic


BIN
fpga/output/v1.sof


BIN
fpga/output/v2.fw


BIN
fpga/output/v2.jic


BIN
fpga/output/v2.sof


+ 1 - 1
rv32/checksum.h

@@ -1,4 +1,4 @@
 #ifndef CHECKSUM_H
 #define CHECKSUM_H
-#define SDRAM_SUM 0x60fea695
+#define SDRAM_SUM 0x92273ba2
 #endif