// #define DEBUG #define BAUD_RATE 115200 #include "common.h" #include "fpga.h" #include "wifi.h" #include "config.h" #include "led.h" #include #include #define PIN_USB_PWR_EN 7 #define PIN_USB_PWR_SINK 8 static void dump_config() { printf("--- Configuration:\n"); write_env(stdout, false); write_env(stdout, true); printf("--- End configuration\n"); } uint8_t max80_board_version; static void init_hw() { // Start out with disabled shared I/O pins for (int i = 1; i <= 18; i++) pinMode(i, INPUT); // 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(100); pinMode(PIN_USB_PWR_EN, INPUT_PULLUP); delayMicroseconds(50); pinMode(PIN_USB_PWR_EN, INPUT); delayMicroseconds(50); max80_board_version = digitalRead(PIN_USB_PWR_EN) ? 1 : 2; pinMode(PIN_USB_PWR_EN, OUTPUT); digitalWrite(PIN_USB_PWR_EN, 0); // Configure LEDs led_init(); led_set(LED_BLUE, LED_FLASH); // ESP32 software initializing // Enable external PSRAM for heap heap_caps_malloc_extmem_enable(2048); // >= 2K allocations in PSRAM printf("[PCB] MAX80 board version: %u\n", max80_board_version); setenv_ul("status.max80.hw.ver", max80_board_version); } void setup() { const char *fwdate = __DATE__ " " __TIME__; printf("[START] MAX80 firmware compiled on %s\n", fwdate); init_hw(); fpga_service_init(); init_config(); setenv("status.max80.fw.date", fwdate, 1); fpga_service_enable(true); SetupWiFi(); printf("[RDY]\n"); dump_config(); led_set(LED_BLUE, LED_ON); // Software ready printf("Total heap: %d\n" "Free heap: %d\n" "Total PSRAM: %d\n" "Free PSRAM: %d\n", ESP.getHeapSize(), ESP.getFreeHeap(), ESP.getPsramSize(), ESP.getFreePsram()); } 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() { printf("loop task: %s\n", pcTaskGetName(xTaskGetCurrentTaskHandle())); printf("idle task: %s\n", pcTaskGetName(xTaskGetIdleTaskHandle())); dump_tasks(); putchar('\n'); vTaskDelay(120 * configTICK_RATE_HZ); }