| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 | // #define DEBUG#define BAUD_RATE 115200#include "common.h"#include "pins.h"#include "fpga.h"#include "wifi.h"#include "config.h"#include "led.h"#include "tty.h"#include "boardinfo_esp.h"#include <freertos/task_snapshot.h>#include <esp_heap_caps.h>#include <esp_task_wdt.h>#include <esp_mac.h>#include <USB.h>#include <HardwareSerial.h>#include <core_version.h>volatile bool do_log_config_status;uint8_t efuse_default_mac[6];char serial_number[16];		// Canonical board serial numbervoid setup_usb_ids(){    uint8_t * const mac = efuse_default_mac;    esp_efuse_mac_get_default(mac);    snprintf(serial_number, sizeof serial_number, "%02X%02X%02X-%02X%02X%02X",	     mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);    USB.VID(0x4680);    USB.PID(0x0882);    USB.firmwareVersion(1);	// Do something smarter here    USB.productName("MAX80 Network Controller");    USB.manufacturerName("Peter & Per");    USB.serialNumber(serial_number);}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/%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 0static void dump_config(){    printf("--- Configuration:\n");    write_sysvars(stdout, false);    printf("--- Status:\n");    write_sysvars(stdout, true);    printf("--- End configuration and status\n");}#endifstatic void init_hw(){    // Start out with disabled shared I/O pins    for (int i = 1; i <= 18; i++)	pinMode(i, INPUT);    // Query board info    board_info_init();    // Make sure FPGA nCE input (board 2.1+) is not accidentally pulled high    fpga_enable_nce();    // Configure USB power control. Try to detect 36k pulldown    // resistor on USB_PWR_EN first, to determine board version 2    // (on board v1, this pin in N/C.)    //    // This detection algorithm is sketchy at best. In the end the    // better option probably would be to use the ADC mode of the input    // pin...    pinMode(PIN_USB_PWR_SINK, OUTPUT);		// IO8: USB_PWR_SINK    digitalWrite(PIN_USB_PWR_SINK, 0);		// This is a power sink    pinMode(PIN_USB_PWR_EN, OUTPUT);    digitalWrite(PIN_USB_PWR_EN, 0);    delayMicroseconds(50);    // Configure LEDs    led_init();    led_set(LED_BLUE, LED_FLASH);	// ESP32 software initializing}#define _tostring(x) #x#define tostring(x) _tostring(x)static const char fwdate[] = __DATE__ " " __TIME__;static const char arduino_esp32_ver[] = tostring(ARDUINO_ESP32_GIT_DESC);static void set_build_status_info(){    setvar_str(status_max80_fw_date, fwdate);    setvar_str(status_max80_fw_esp32_arduino, arduino_esp32_ver);    setvar_str(status_max80_fw_esp32_idf, IDF_VER);}void setup() {    init_hw();    // Enable external PSRAM for heap    heap_caps_malloc_extmem_enable(3000); // >= 3K allocations in PSRAM    TTY::init();    Serial.print("\r\n*** Hello, World! ***\r\n");    sysvar_init();    heap_info();    printf("[FW]   MAX80 firmware compiled on %s\n", fwdate);    printf("[PCB]  MAX80 board version: %s\n", board_info.version_str);    setvar_str(status_max80_hw_ver, board_info.version_str);    printf("[PCB]  MAX80 serial number: %s\n", serial_number);    setvar_str(status_max80_hw_serial, serial_number);    Serial.println("MAX80 start");    init_config();    set_build_status_info();    fpga_service_init();    fpga_service_enable(true);    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}static inline char task_state(eTaskState state){    switch (state) {    case eInvalid:	return 'X';    case eReady:    case eRunning:	return 'R';    case eBlocked:	return 'D';    case eSuspended:	return 'S';    case eDeleted:	return 'Z';    default:	return '?';    }}static void dump_tasks(void){    TaskHandle_t task = NULL;    while (1) {	task = pxTaskGetNext(task);	if (!task)	    break;	printf("%-16s %c %2u\n",	       pcTaskGetName(task),	       task_state(eTaskGetState(task)),	       uxTaskPriorityGet(task));    }}void loop() {    if (0) {	printf("loop task: %s\n", pcTaskGetName(xTaskGetCurrentTaskHandle()));	printf("idle task: %s\n", pcTaskGetName(xTaskGetIdleTaskHandle()));	dump_tasks();	heap_info();	putchar('\n');    }    if (do_log_config_status) {	do_log_config_status = false;	heap_info();	log_config_status();    }    fflush(stdout);    TTY::ping();    vTaskDelay(5 * configTICK_RATE_HZ);}
 |