diff --git a/Makefile b/Makefile index 8583a25..a253361 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ IDF_PATH ?= $(shell pwd)/esp-idf IDF_EXPORT_QUIET ?= 0 SHELL := /usr/bin/env bash -.PHONY: prepare clean build flash erase monitor menuconfig image qemu install +.PHONY: prepare clean build flash erase monitor menuconfig image all: prepare build flash @@ -35,9 +35,3 @@ image: cd "$(BUILDDIR)"; dd if=bootloader/bootloader.bin bs=1 seek=4096 of=flash.bin conv=notrunc cd "$(BUILDDIR)"; dd if=partition_table/partition-table.bin bs=1 seek=36864 of=flash.bin conv=notrunc cd "$(BUILDDIR)"; dd if=main.bin bs=1 seek=65536 of=flash.bin conv=notrunc - -qemu: image - cd "$(BUILDDIR)"; qemu-system-xtensa -nographic -machine esp32 -drive 'file=flash.bin,if=mtd,format=raw' - -install: flash - diff --git a/README.md b/README.md index 55bf77b..bf0cde2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# MCH2022 ESP32 firmware: Launcher +# MCH2022 template app -This repository contains the ESP32 part of the firmware for the MCH2022 badge. This firmware allows for device testing, setup, OTA updates and of course launching apps. +This repository contains a template app for the MCH2022 badge. ## License diff --git a/bootloader_components/appfs b/bootloader_components/appfs deleted file mode 120000 index 34b25e4..0000000 --- a/bootloader_components/appfs +++ /dev/null @@ -1 +0,0 @@ -../components/appfs \ No newline at end of file diff --git a/bootloader_components/main b/bootloader_components/main deleted file mode 120000 index d14493a..0000000 --- a/bootloader_components/main +++ /dev/null @@ -1 +0,0 @@ -../components/appfs/bootloader_main \ No newline at end of file diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index fd2f49b..8115b63 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,72 +1,6 @@ idf_component_register( - SRCS "main.c" - "appfs_wrapper.c" - "fpga_test.c" - "graphics_wrapper.c" - "menu.c" - "rp2040_updater.c" - "settings.c" - "system_wrapper.c" - "wifi_connection.c" - "wifi_connect.c" - "wifi_ota.c" - "fpga_download.c" - "audio.c" - "bootscreen.c" - "menus/launcher.c" - "menus/settings.c" - "menus/start.c" - "menus/dev.c" - "menus/wifi.c" - "uninstall.c" - "file_browser.c" - "test_common.c" - "factory_test.c" - "animation.c" - "button_test.c" - "adc_test.c" - "webusb.c" - INCLUDE_DIRS "." - "include" - "menus" - EMBED_TXTFILES ${project_dir}/resources/isrgrootx1.pem - EMBED_FILES ${project_dir}/resources/wallpaper.png - ${project_dir}/resources/fpga_selftest.bin - ${project_dir}/resources/rp2040_firmware.bin - ${project_dir}/resources/boot.snd - ${project_dir}/resources/mch2022_logo.png - ${project_dir}/resources/logo_screen.png - ${project_dir}/resources/icons/dev.png - ${project_dir}/resources/icons/home.png - ${project_dir}/resources/icons/settings.png - ${project_dir}/resources/icons/apps.png - ${project_dir}/resources/icons/hatchery.png - ${project_dir}/resources/animation/animation_frame_1.png - ${project_dir}/resources/animation/animation_frame_2.png - ${project_dir}/resources/animation/animation_frame_3.png - ${project_dir}/resources/animation/animation_frame_4.png - ${project_dir}/resources/animation/animation_frame_5.png - ${project_dir}/resources/animation/animation_frame_6.png - ${project_dir}/resources/animation/animation_frame_7.png - ${project_dir}/resources/animation/animation_frame_8.png - ${project_dir}/resources/animation/animation_frame_9.png - ${project_dir}/resources/animation/animation_frame_10.png - ${project_dir}/resources/animation/animation_frame_11.png - ${project_dir}/resources/animation/animation_frame_12.png - ${project_dir}/resources/animation/animation_frame_13.png - ${project_dir}/resources/animation/animation_frame_14.png - ${project_dir}/resources/animation/animation_frame_15.png - ${project_dir}/resources/animation/animation_frame_16.png - ${project_dir}/resources/animation/animation_frame_17.png - ${project_dir}/resources/animation/animation_frame_18.png - ${project_dir}/resources/animation/animation_frame_19.png - ${project_dir}/resources/animation/animation_frame_20.png - ${project_dir}/resources/animation/animation_frame_21.png - ${project_dir}/resources/animation/animation_frame_22.png - ${project_dir}/resources/animation/animation_frame_23.png - ${project_dir}/resources/animation/animation_frame_24.png - ${project_dir}/resources/animation/animation_frame_25.png - ${project_dir}/resources/animation/animation_frame_26.png - ${project_dir}/resources/animation/animation_frame_27.png - ${project_dir}/resources/animation/animation_frame_28.png -) + SRCS + "main.c" + INCLUDE_DIRS + "." "include" +) \ No newline at end of file diff --git a/main/adc_test.c b/main/adc_test.c deleted file mode 100644 index c5db933..0000000 --- a/main/adc_test.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include -#include -#include -#include "ili9341.h" -#include "pax_gfx.h" -#include "rp2040.h" -#include "hardware.h" - -void test_adc(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341) { - bool quit = false; - - RP2040* rp2040 = get_rp2040(); - const pax_font_t* font = pax_get_font("saira regular"); - - while (!quit) { - bool error = false; - - float vbat = 0; - if (rp2040_read_vbat(rp2040, &vbat) != ESP_OK) { - error = true; - } - - float vusb = 0; - if (rp2040_read_vusb(rp2040, &vusb) != ESP_OK) { - error = true; - } - - /*uint16_t raw_temperature = 0; - if (rp2040_read_temp(rp2040, &raw_temperature) != ESP_OK) { - error = true; - } - - uint8_t charging = 0; - if (rp2040_get_charging(rp2040, &charging) != ESP_OK) { - error = true; - }*/ - - //const float conversion_factor = 3.3f / (1 << 12); // 12-bit ADC with 3.3v vref - //float vtemperature = raw_temperature * conversion_factor; // Inside of RP2040 chip - //float temperature = 27 - (vtemperature - 0.706) / 0.001721; // From https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__adc.html - - - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0x325aa8); - pax_draw_text(pax_buffer, 0xFFFFFFFF, font, 18, 0, 20*0, "Analog inputs"); - char buffer[64]; - snprintf(buffer, sizeof(buffer), "Battery voltage %f v", vbat); - pax_draw_text(pax_buffer, 0xFFFFFFFF, font, 18, 0, 20*1, buffer); - snprintf(buffer, sizeof(buffer), "USB voltage %f v", vusb); - pax_draw_text(pax_buffer, 0xFFFFFFFF, font, 18, 0, 20*2, buffer); - /*snprintf(buffer, sizeof(buffer), "Temperature %f *c", temperature); - pax_draw_text(pax_buffer, 0xFFFFFFFF, font, 18, 0, 20*3, buffer); - snprintf(buffer, sizeof(buffer), "Charging %02X", charging); - pax_draw_text(pax_buffer, 0xFFFFFFFF, font, 18, 0, 20*4, buffer);*/ - pax_draw_text(pax_buffer, 0xFFFFFFFF, font, 18, 0, 20*5, (error ? "ERROR" : "")); - ili9341_write(ili9341, pax_buffer->buf); - - rp2040_input_message_t buttonMessage = {0}; - if (xQueueReceive(buttonQueue, &buttonMessage, 250 / portTICK_PERIOD_MS) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - if (value) { - switch(pin) { - case RP2040_INPUT_BUTTON_HOME: - case RP2040_INPUT_BUTTON_BACK: - quit = true; - default: - break; - } - } - } - } -} - diff --git a/main/animation.c b/main/animation.c deleted file mode 100644 index a3589db..0000000 --- a/main/animation.c +++ /dev/null @@ -1,167 +0,0 @@ -#include -#include -#include -#include -#include "pax_gfx.h" -#include "pax_codecs.h" -#include "ili9341.h" -#include "ws2812.h" -#include "hardware.h" - -extern const uint8_t animation_frame_1_start[] asm("_binary_animation_frame_1_png_start"); -extern const uint8_t animation_frame_1_end[] asm("_binary_animation_frame_1_png_end"); -extern const uint8_t animation_frame_2_start[] asm("_binary_animation_frame_2_png_start"); -extern const uint8_t animation_frame_2_end[] asm("_binary_animation_frame_2_png_end"); -extern const uint8_t animation_frame_3_start[] asm("_binary_animation_frame_3_png_start"); -extern const uint8_t animation_frame_3_end[] asm("_binary_animation_frame_3_png_end"); -extern const uint8_t animation_frame_4_start[] asm("_binary_animation_frame_4_png_start"); -extern const uint8_t animation_frame_4_end[] asm("_binary_animation_frame_4_png_end"); -extern const uint8_t animation_frame_5_start[] asm("_binary_animation_frame_5_png_start"); -extern const uint8_t animation_frame_5_end[] asm("_binary_animation_frame_5_png_end"); -extern const uint8_t animation_frame_6_start[] asm("_binary_animation_frame_6_png_start"); -extern const uint8_t animation_frame_6_end[] asm("_binary_animation_frame_6_png_end"); -extern const uint8_t animation_frame_7_start[] asm("_binary_animation_frame_7_png_start"); -extern const uint8_t animation_frame_7_end[] asm("_binary_animation_frame_7_png_end"); -extern const uint8_t animation_frame_8_start[] asm("_binary_animation_frame_8_png_start"); -extern const uint8_t animation_frame_8_end[] asm("_binary_animation_frame_8_png_end"); -extern const uint8_t animation_frame_9_start[] asm("_binary_animation_frame_9_png_start"); -extern const uint8_t animation_frame_9_end[] asm("_binary_animation_frame_9_png_end"); -extern const uint8_t animation_frame_10_start[] asm("_binary_animation_frame_10_png_start"); -extern const uint8_t animation_frame_10_end[] asm("_binary_animation_frame_10_png_end"); -extern const uint8_t animation_frame_11_start[] asm("_binary_animation_frame_11_png_start"); -extern const uint8_t animation_frame_11_end[] asm("_binary_animation_frame_11_png_end"); -extern const uint8_t animation_frame_12_start[] asm("_binary_animation_frame_12_png_start"); -extern const uint8_t animation_frame_12_end[] asm("_binary_animation_frame_12_png_end"); -extern const uint8_t animation_frame_13_start[] asm("_binary_animation_frame_13_png_start"); -extern const uint8_t animation_frame_13_end[] asm("_binary_animation_frame_13_png_end"); -extern const uint8_t animation_frame_14_start[] asm("_binary_animation_frame_14_png_start"); -extern const uint8_t animation_frame_14_end[] asm("_binary_animation_frame_14_png_end"); -extern const uint8_t animation_frame_15_start[] asm("_binary_animation_frame_15_png_start"); -extern const uint8_t animation_frame_15_end[] asm("_binary_animation_frame_15_png_end"); -extern const uint8_t animation_frame_16_start[] asm("_binary_animation_frame_16_png_start"); -extern const uint8_t animation_frame_16_end[] asm("_binary_animation_frame_16_png_end"); -extern const uint8_t animation_frame_17_start[] asm("_binary_animation_frame_17_png_start"); -extern const uint8_t animation_frame_17_end[] asm("_binary_animation_frame_17_png_end"); -extern const uint8_t animation_frame_18_start[] asm("_binary_animation_frame_18_png_start"); -extern const uint8_t animation_frame_18_end[] asm("_binary_animation_frame_18_png_end"); -extern const uint8_t animation_frame_19_start[] asm("_binary_animation_frame_19_png_start"); -extern const uint8_t animation_frame_19_end[] asm("_binary_animation_frame_19_png_end"); -extern const uint8_t animation_frame_20_start[] asm("_binary_animation_frame_20_png_start"); -extern const uint8_t animation_frame_20_end[] asm("_binary_animation_frame_20_png_end"); -extern const uint8_t animation_frame_21_start[] asm("_binary_animation_frame_21_png_start"); -extern const uint8_t animation_frame_21_end[] asm("_binary_animation_frame_21_png_end"); -extern const uint8_t animation_frame_22_start[] asm("_binary_animation_frame_22_png_start"); -extern const uint8_t animation_frame_22_end[] asm("_binary_animation_frame_22_png_end"); -extern const uint8_t animation_frame_23_start[] asm("_binary_animation_frame_23_png_start"); -extern const uint8_t animation_frame_23_end[] asm("_binary_animation_frame_23_png_end"); -extern const uint8_t animation_frame_24_start[] asm("_binary_animation_frame_24_png_start"); -extern const uint8_t animation_frame_24_end[] asm("_binary_animation_frame_24_png_end"); -extern const uint8_t animation_frame_25_start[] asm("_binary_animation_frame_25_png_start"); -extern const uint8_t animation_frame_25_end[] asm("_binary_animation_frame_25_png_end"); -extern const uint8_t animation_frame_26_start[] asm("_binary_animation_frame_26_png_start"); -extern const uint8_t animation_frame_26_end[] asm("_binary_animation_frame_26_png_end"); -extern const uint8_t animation_frame_27_start[] asm("_binary_animation_frame_27_png_start"); -extern const uint8_t animation_frame_27_end[] asm("_binary_animation_frame_27_png_end"); -extern const uint8_t animation_frame_28_start[] asm("_binary_animation_frame_28_png_start"); -extern const uint8_t animation_frame_28_end[] asm("_binary_animation_frame_28_png_end"); - -const uint8_t* animation_frames[] = { - animation_frame_1_start, - animation_frame_2_start, - animation_frame_3_start, - animation_frame_4_start, - animation_frame_5_start, - animation_frame_6_start, - animation_frame_7_start, - animation_frame_8_start, - animation_frame_9_start, - animation_frame_10_start, - animation_frame_11_start, - animation_frame_12_start, - animation_frame_13_start, - animation_frame_14_start, - animation_frame_15_start, - animation_frame_16_start, - animation_frame_17_start, - animation_frame_18_start, - animation_frame_19_start, - animation_frame_20_start, - animation_frame_21_start, - animation_frame_22_start, - animation_frame_23_start, - animation_frame_24_start, - animation_frame_25_start, - animation_frame_26_start, - animation_frame_27_start, - animation_frame_28_start -}; - -const uint8_t* animation_frames_end[] = { - animation_frame_1_end, - animation_frame_2_end, - animation_frame_3_end, - animation_frame_4_end, - animation_frame_5_end, - animation_frame_6_end, - animation_frame_7_end, - animation_frame_8_end, - animation_frame_9_end, - animation_frame_10_end, - animation_frame_11_end, - animation_frame_12_end, - animation_frame_13_end, - animation_frame_14_end, - animation_frame_15_end, - animation_frame_16_end, - animation_frame_17_end, - animation_frame_18_end, - animation_frame_19_end, - animation_frame_20_end, - animation_frame_21_end, - animation_frame_22_end, - animation_frame_23_end, - animation_frame_24_end, - animation_frame_25_end, - animation_frame_26_end, - animation_frame_27_end, - animation_frame_28_end -}; - -void display_animation(pax_buf_t* pax_buffer, ILI9341* ili9341) { - - gpio_set_direction(GPIO_SD_PWR, GPIO_MODE_OUTPUT); - gpio_set_level(GPIO_SD_PWR, 1); - ws2812_init(GPIO_LED_DATA); - uint8_t led_data[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - ws2812_send_data(led_data, sizeof(led_data)); - - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xFFFFFF); - - for (uint8_t frame = 0; frame < 28; frame++) { - pax_buf_t image; - pax_decode_png_buf(&image, (void*) animation_frames[frame], animation_frames_end[frame] - animation_frames[frame], PAX_BUF_16_565RGB, 0); - pax_draw_image(pax_buffer, &image, 0, 0); - pax_buf_destroy(&image); - ili9341_write(ili9341, pax_buffer->buf); - uint8_t brightness = (frame > 14) ? (frame - 14) : (0); - led_data[1] = brightness; - led_data[3] = brightness; - led_data[8] = brightness; - led_data[9] = brightness / 2; - led_data[10] = brightness / 2; - led_data[14] = brightness; - ws2812_send_data(led_data, sizeof(led_data)); - } - - for (uint8_t brightness = 14; brightness < 50; brightness++) { - led_data[1] = brightness; - led_data[3] = brightness; - led_data[8] = brightness; - led_data[9] = brightness / 2; - led_data[10] = brightness / 2; - led_data[14] = brightness; - ws2812_send_data(led_data, sizeof(led_data)); - vTaskDelay(50 / portTICK_PERIOD_MS); - } -} diff --git a/main/appfs_wrapper.c b/main/appfs_wrapper.c deleted file mode 100644 index c4c022d..0000000 --- a/main/appfs_wrapper.c +++ /dev/null @@ -1,103 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "appfs.h" -#include "ili9341.h" -#include "pax_gfx.h" -#include "menu.h" -#include "rp2040.h" -#include "appfs_wrapper.h" -#include "hardware.h" -#include "system_wrapper.h" -#include "bootscreen.h" -#include "esp_sleep.h" -#include "soc/rtc.h" -#include "soc/rtc_cntl_reg.h" - -static const char *TAG = "appfs wrapper"; - -esp_err_t appfs_init(void) { - return appfsInit(APPFS_PART_TYPE, APPFS_PART_SUBTYPE); -} - -uint8_t* load_file_to_ram(FILE* fd, size_t* fsize) { - fseek(fd, 0, SEEK_END); - *fsize = ftell(fd); - fseek(fd, 0, SEEK_SET); - uint8_t* file = malloc(*fsize); - if (file == NULL) return NULL; - fread(file, *fsize, 1, fd); - return file; -} - -void appfs_boot_app(int fd) { - if (fd<0 || fd>255) { - REG_WRITE(RTC_CNTL_STORE0_REG, 0); - } else { - REG_WRITE(RTC_CNTL_STORE0_REG, 0xA5000000|fd); - } - - esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON); - esp_sleep_enable_timer_wakeup(10); - esp_deep_sleep_start(); -} - -void appfs_store_app(pax_buf_t* pax_buffer, ILI9341* ili9341, char* path, char* label) { - display_boot_screen(pax_buffer, ili9341, "Installing app..."); - esp_err_t res; - appfs_handle_t handle; - FILE* app_fd = fopen(path, "rb"); - if (app_fd == NULL) { - display_boot_screen(pax_buffer, ili9341, "Failed to open file"); - ESP_LOGE(TAG, "Failed to open file"); - vTaskDelay(100 / portTICK_PERIOD_MS); - return; - } - size_t app_size; - uint8_t* app = load_file_to_ram(app_fd, &app_size); - if (app == NULL) { - display_boot_screen(pax_buffer, ili9341, "Failed to load app to RAM"); - ESP_LOGE(TAG, "Failed to load application into RAM"); - vTaskDelay(100 / portTICK_PERIOD_MS); - return; - } - - ESP_LOGI(TAG, "Application size %d", app_size); - - res = appfsCreateFile(label, app_size, &handle); - if (res != ESP_OK) { - display_boot_screen(pax_buffer, ili9341, "Failed to create file"); - ESP_LOGE(TAG, "Failed to create file on AppFS (%d)", res); - vTaskDelay(100 / portTICK_PERIOD_MS); - free(app); - return; - } - int roundedSize=(app_size+(SPI_FLASH_MMU_PAGE_SIZE-1))&(~(SPI_FLASH_MMU_PAGE_SIZE-1)); - res = appfsErase(handle, 0, roundedSize); - if (res != ESP_OK) { - display_boot_screen(pax_buffer, ili9341, "Failed to erase file"); - ESP_LOGE(TAG, "Failed to erase file on AppFS (%d)", res); - vTaskDelay(100 / portTICK_PERIOD_MS); - free(app); - return; - } - res = appfsWrite(handle, 0, app, app_size); - if (res != ESP_OK) { - display_boot_screen(pax_buffer, ili9341, "Failed to write file"); - ESP_LOGE(TAG, "Failed to write to file on AppFS (%d)", res); - vTaskDelay(100 / portTICK_PERIOD_MS); - free(app); - return; - } - free(app); - ESP_LOGI(TAG, "Application is now stored in AppFS"); - display_boot_screen(pax_buffer, ili9341, "App installed!"); - vTaskDelay(100 / portTICK_PERIOD_MS); - return; -} diff --git a/main/audio.c b/main/audio.c deleted file mode 100644 index d40d2cb..0000000 --- a/main/audio.c +++ /dev/null @@ -1,92 +0,0 @@ -#include "audio.h" - -#include "freertos/FreeRTOS.h" -#include -#include "esp_system.h" -#include "driver/i2s.h" -#include "driver/rtc_io.h" - -#include -#include - -void _audio_init(int i2s_num) { - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = 8000, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB, - .dma_buf_count = 8, - .dma_buf_len = 256, - .intr_alloc_flags = 0, - .use_apll = false, - .bits_per_chan = I2S_BITS_PER_SAMPLE_16BIT - }; - - i2s_driver_install(i2s_num, &i2s_config, 0, NULL); - - i2s_pin_config_t pin_config = { - .mck_io_num = 0, - .bck_io_num = 4, - .ws_io_num = 12, - .data_out_num = 13, - .data_in_num = I2S_PIN_NO_CHANGE - }; - - i2s_set_pin(i2s_num, &pin_config); -} - -typedef struct _audio_player_cfg { - uint8_t* buffer; - size_t size; - bool free_buffer; -} audio_player_cfg_t; - -void audio_player_task(void* arg) { - audio_player_cfg_t* config = (audio_player_cfg_t*) arg; - size_t sample_length = config->size; - uint8_t* sample_buffer = config->buffer; - - size_t count; - size_t position = 0; - - while (position < sample_length) { - size_t length = sample_length - position; - if (length > 256) length = 256; - uint8_t buffer[256]; - memcpy(buffer, &sample_buffer[position], length); - for (size_t l = 0; l < length; l+=2) { - int16_t* sample = (int16_t*) &buffer[l]; - *sample *= 0.50; - } - i2s_write(0, buffer, length, &count, portMAX_DELAY); - if (count != length) { - printf("i2s_write_bytes: count (%d) != length (%d)\n", count, length); - abort(); - } - position += length; - } - - i2s_zero_dma_buffer(0); // Fill buffer with silence - if (config->free_buffer) free(sample_buffer); - vTaskDelete(NULL); // Tell FreeRTOS that the task is done -} - -void audio_init() { - _audio_init(0); -} - -extern const uint8_t boot_snd_start[] asm("_binary_boot_snd_start"); -extern const uint8_t boot_snd_end[] asm("_binary_boot_snd_end"); - -audio_player_cfg_t bootsound; - -void play_bootsound() { - TaskHandle_t handle; - - bootsound.buffer = boot_snd_start, - bootsound.size = boot_snd_end - boot_snd_start; - bootsound.free_buffer = false; - - xTaskCreate(&audio_player_task, "Audio player", 4096, (void*) &bootsound, 10, &handle); -} diff --git a/main/bootscreen.c b/main/bootscreen.c deleted file mode 100644 index c1fd43f..0000000 --- a/main/bootscreen.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include "pax_gfx.h" -#include "pax_codecs.h" -#include "ili9341.h" - -extern const uint8_t mch2022_logo_png_start[] asm("_binary_mch2022_logo_png_start"); -extern const uint8_t mch2022_logo_png_end[] asm("_binary_mch2022_logo_png_end"); - -void display_boot_screen(pax_buf_t* pax_buffer, ILI9341* ili9341, const char* text) { - const pax_font_t *font = pax_get_font("saira regular"); - - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xFFFFFF); - pax_buf_t logo; - pax_decode_png_buf(&logo, (void*) mch2022_logo_png_start, mch2022_logo_png_end - mch2022_logo_png_start, PAX_BUF_16_565RGB, 0); - pax_draw_image(pax_buffer, &logo, (320 / 2) - (212 / 2), ((240 - 32 - 10) / 2) - (160 / 2)); - pax_buf_destroy(&logo); - - pax_vec1_t size = pax_text_size(font, 18, text); - pax_draw_text(pax_buffer, 0xFF000000, font, 18, (320 / 2) - (size.x / 2), 240 - 32, text); - ili9341_write(ili9341, pax_buffer->buf); -} diff --git a/main/button_test.c b/main/button_test.c deleted file mode 100644 index 43b7a1b..0000000 --- a/main/button_test.c +++ /dev/null @@ -1,130 +0,0 @@ -#include -#include -#include -#include -#include -#include "ili9341.h" -#include "pax_gfx.h" -#include "rp2040.h" - -void test_buttons(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341) { - bool render = true; - bool quit = false; - - bool btn_joy_down = false; - bool btn_joy_up = false; - bool btn_joy_left = false; - bool btn_joy_right = false; - bool btn_joy_press = false; - bool btn_home = false; - bool btn_menu = false; - bool btn_select = false; - bool btn_start = false; - bool btn_accept = false; - bool btn_back = false; - - bool btn_joy_down_green = false; - bool btn_joy_up_green = false; - bool btn_joy_left_green = false; - bool btn_joy_right_green = false; - bool btn_joy_press_green = false; - bool btn_home_green = false; - bool btn_menu_green = false; - bool btn_select_green = false; - bool btn_start_green = false; - bool btn_accept_green = false; - bool btn_back_green = false; - - - while (!quit) { - rp2040_input_message_t buttonMessage = {0}; - if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - render = true; - switch(pin) { - case RP2040_INPUT_JOYSTICK_DOWN: - btn_joy_down = value; - if (value) btn_joy_down_green = true; - break; - case RP2040_INPUT_JOYSTICK_UP: - btn_joy_up = value; - if (value) btn_joy_up_green = true; - break; - case RP2040_INPUT_JOYSTICK_LEFT: - btn_joy_left = value; - if (value) btn_joy_left_green = true; - break; - case RP2040_INPUT_JOYSTICK_RIGHT: - btn_joy_right = value; - if (value) btn_joy_right_green = true; - break; - case RP2040_INPUT_JOYSTICK_PRESS: - btn_joy_press = value; - if (value) btn_joy_press_green = true; - break; - case RP2040_INPUT_BUTTON_HOME: - btn_home = value; - if (value) btn_home_green = true; - break; - case RP2040_INPUT_BUTTON_MENU: - btn_menu = value; - if (value) btn_menu_green = true; - break; - case RP2040_INPUT_BUTTON_SELECT: - btn_select = value; - if (value) btn_select_green = true; - break; - case RP2040_INPUT_BUTTON_START: - btn_start = value; - if (value) btn_start_green = true; - break; - case RP2040_INPUT_BUTTON_ACCEPT: - btn_accept = value; - if (value) btn_accept_green = true; - break; - case RP2040_INPUT_BUTTON_BACK: - btn_back = value; - if (value) btn_back_green = true; - default: - break; - } - } - - if (render) { - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0x325aa8); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, "Press HOME + START to exit"); - char buffer[64]; - snprintf(buffer, sizeof(buffer), "JOY DOWN %s", btn_joy_down ? "PRESSED" : "released"); - pax_draw_text(pax_buffer, btn_joy_down_green ? 0xFF00FF00 : 0xFFFFFFFF, NULL, 18, 0, 20*1, buffer); - snprintf(buffer, sizeof(buffer), "JOY UP %s", btn_joy_up ? "PRESSED" : "released"); - pax_draw_text(pax_buffer, btn_joy_up_green ? 0xFF00FF00 : 0xFFFFFFFF, NULL, 18, 0, 20*2, buffer); - snprintf(buffer, sizeof(buffer), "JOY LEFT %s", btn_joy_left ? "PRESSED" : "released"); - pax_draw_text(pax_buffer, btn_joy_right_green ? 0xFF00FF00 : 0xFFFFFFFF, NULL, 18, 0, 20*3, buffer); - snprintf(buffer, sizeof(buffer), "JOY RIGHT %s", btn_joy_right ? "PRESSED" : "released"); - pax_draw_text(pax_buffer, btn_joy_left_green ? 0xFF00FF00 : 0xFFFFFFFF, NULL, 18, 0, 20*4, buffer); - snprintf(buffer, sizeof(buffer), "JOY PRESS %s", btn_joy_press ? "PRESSED" : "released"); - pax_draw_text(pax_buffer, btn_joy_press_green ? 0xFF00FF00 : 0xFFFFFFFF, NULL, 18, 0, 20*5, buffer); - snprintf(buffer, sizeof(buffer), "BTN HOME %s", btn_home ? "PRESSED" : "released"); - pax_draw_text(pax_buffer, btn_home_green ? 0xFF00FF00 : 0xFFFFFFFF, NULL, 18, 0, 20*6, buffer); - snprintf(buffer, sizeof(buffer), "BTN MENU %s", btn_menu ? "PRESSED" : "released"); - pax_draw_text(pax_buffer, btn_menu_green ? 0xFF00FF00 : 0xFFFFFFFF, NULL, 18, 0, 20*7, buffer); - snprintf(buffer, sizeof(buffer), "BTN SELECT %s", btn_select ? "PRESSED" : "released"); - pax_draw_text(pax_buffer, btn_select_green ? 0xFF00FF00 : 0xFFFFFFFF, NULL, 18, 0, 20*8, buffer); - snprintf(buffer, sizeof(buffer), "BTN START %s", btn_start ? "PRESSED" : "released"); - pax_draw_text(pax_buffer, btn_start_green ? 0xFF00FF00 : 0xFFFFFFFF, NULL, 18, 0, 20*9, buffer); - snprintf(buffer, sizeof(buffer), "BTN A %s", btn_accept ? "PRESSED" : "released"); - pax_draw_text(pax_buffer, btn_accept_green ? 0xFF00FF00 : 0xFFFFFFFF, NULL, 18, 0, 20*10, buffer); - snprintf(buffer, sizeof(buffer), "BTN B %s", btn_back ? "PRESSED" : "released"); - pax_draw_text(pax_buffer, btn_back_green ? 0xFF00FF00 : 0xFFFFFFFF, NULL, 18, 0, 20*11, buffer); - ili9341_write(ili9341, pax_buffer->buf); - render = false; - } - - if (btn_home && btn_start) { - quit = true; - } - } -} - diff --git a/main/factory_test.c b/main/factory_test.c deleted file mode 100644 index 4e154c4..0000000 --- a/main/factory_test.c +++ /dev/null @@ -1,192 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "hardware.h" -#include "ili9341.h" -#include "ice40.h" -#include "rp2040.h" -#include "fpga_test.h" -#include "pax_gfx.h" -#include "test_common.h" -#include "settings.h" -#include "ws2812.h" -#include "audio.h" - -static const char *TAG = "factory"; - -/* Test routines */ - -bool test_rp2040_init(uint32_t* rc) { - esp_err_t res = bsp_rp2040_init(); - *rc = (uint32_t) res; - return (res == ESP_OK); -} - -bool test_ice40_init(uint32_t* rc) { - esp_err_t res = bsp_ice40_init(); - *rc = (uint32_t) res; - return (res == ESP_OK); -} - -bool test_bno055_init(uint32_t* rc) { - esp_err_t res = bsp_bno055_init(); - *rc = (uint32_t) res; - return (res == ESP_OK); -} - -bool test_bme680_init(uint32_t* rc) { - esp_err_t res = bsp_bme680_init(); - *rc = (uint32_t) res; - return (res == ESP_OK); -} - -bool test_stuck_buttons(uint32_t* rc) { - RP2040* rp2040 = get_rp2040(); - uint16_t state; - esp_err_t res = rp2040_read_buttons(rp2040, &state); - if (res != ESP_OK) { - *rc = 0xFFFFFFFF; - return false; - } - - state &= ~(1 << RP2040_INPUT_FPGA_CDONE); // Ignore FPGA CDONE - - *rc = state; - - return (state == 0x0000); -} - -bool test_adc_vbat(uint32_t* rc) { - float value = 0; - esp_err_t res = rp2040_read_vbat(get_rp2040(), &value); - *rc = value * 100; - return ((res == ESP_OK) && (value < 4.3) && (value > 3.9)); -} - -bool test_adc_vusb(uint32_t* rc) { - float value = 0; - esp_err_t res = rp2040_read_vusb(get_rp2040(), &value); - *rc = value * 100; - return ((res == ESP_OK) && (value > 4.5)); -} - -bool test_sd_power(uint32_t* rc) { - *rc = 0x00000000; - // Init all GPIO pins for SD card and LED - if (gpio_reset_pin(GPIO_SD_PWR) != ESP_OK) return false; - if (gpio_set_direction(GPIO_SD_PWR, GPIO_MODE_INPUT) != ESP_OK) return false; - if (gpio_reset_pin(GPIO_SD_CMD) != ESP_OK) return false; - if (gpio_set_direction(GPIO_SD_CMD, GPIO_MODE_INPUT) != ESP_OK) return false; - if (gpio_reset_pin(GPIO_SD_CLK) != ESP_OK) return false; - if (gpio_set_direction(GPIO_SD_CLK, GPIO_MODE_INPUT) != ESP_OK) return false; - if (gpio_reset_pin(GPIO_SD_D0) != ESP_OK) return false; - if (gpio_set_direction(GPIO_SD_D0, GPIO_MODE_INPUT) != ESP_OK) return false; - if (gpio_reset_pin(GPIO_LED_DATA) != ESP_OK) return false; - if (gpio_set_direction(GPIO_LED_DATA, GPIO_MODE_INPUT) != ESP_OK) return false; - - if (gpio_get_level(GPIO_SD_PWR)) {*rc = 0x01; return false;} // Check that power enable is pulled low - - if (gpio_set_direction(GPIO_SD_PWR, GPIO_MODE_OUTPUT) != ESP_OK) return false; - if (gpio_set_level(GPIO_SD_PWR, 1) != ESP_OK) return false; - - vTaskDelay(10 / portTICK_PERIOD_MS); - - // SD pins should be pulled high - if (!gpio_get_level(GPIO_SD_CMD)) {*rc = 0x02; return false;} - if (!gpio_get_level(GPIO_SD_CLK)) {*rc = 0x04; return false;} - if (!gpio_get_level(GPIO_SD_D0)) {*rc = 0x08; return false;} - - return true; -} - -bool run_basic_tests(pax_buf_t* pax_buffer, ILI9341* ili9341) { - const pax_font_t *font; - int line = 0; - bool ok = true; - - /* Screen init */ - font = pax_get_font("sky mono"); - - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0x8060f0); - ili9341_write(ili9341, pax_buffer->buf); - - /* Run mandatory tests */ - RUN_TEST_MANDATORY("RP2040", test_rp2040_init); - RUN_TEST_MANDATORY("ICE40", test_ice40_init); - RUN_TEST_MANDATORY("BNO055", test_bno055_init); - RUN_TEST_MANDATORY("BME680", test_bme680_init); - - /* Run tests */ - RUN_TEST("STUCK BUTTONS", test_stuck_buttons); - RUN_TEST("SD/LED POWER", test_sd_power); - RUN_TEST("Battery voltage", test_adc_vbat); - RUN_TEST("USB voltage", test_adc_vusb); - - -error: - /* Fail result on screen */ - if (!ok) pax_draw_text(pax_buffer, 0xffff0000, font, 36, 0, 20*line, "FAIL"); - ili9341_write(ili9341, pax_buffer->buf); - return ok; -} - -const uint8_t led_green[15] = {50, 0, 0, 50, 0, 0, 50, 0, 0, 50, 0, 0, 50, 0, 0}; -const uint8_t led_red[15] = {0, 50, 0, 0, 50, 0, 0, 50, 0, 0, 50, 0, 0, 50, 0}; -const uint8_t led_blue[15] = {0, 0, 50, 0, 0, 50, 0, 0, 50, 0, 0, 50, 0, 0, 50}; - -void factory_test(pax_buf_t* pax_buffer, ILI9341* ili9341) { - uint8_t factory_test_done = nvs_get_u8_default("system", "factory_test", 0); - if (!factory_test_done) { - bool result; - - ESP_LOGI(TAG, "Factory test start"); - - result = run_basic_tests(pax_buffer, ili9341); - - gpio_set_direction(GPIO_SD_PWR, GPIO_MODE_OUTPUT); - gpio_set_level(GPIO_SD_PWR, 1); - ws2812_init(GPIO_LED_DATA); - if (result) { - ws2812_send_data(led_blue, sizeof(led_blue)); - } else { - ws2812_send_data(led_red, sizeof(led_red)); - } - - if (!result) goto test_end; - - RP2040* rp2040 = get_rp2040(); - - result = run_fpga_tests(rp2040->queue, pax_buffer, ili9341); - if (!result) { - ws2812_send_data(led_red, sizeof(led_red)); - goto test_end; - } - - ws2812_send_data(led_green, sizeof(led_green)); - - // Wait for the operator to unplug the badge - test_end: - - if (result) { - esp_err_t res = nvs_set_u8_fixed("system", "factory_test", 1); - if (res != ESP_OK) { - ESP_LOGE(TAG, "Failed to store test result %d\n", res); - result = false; - ws2812_send_data(led_red, sizeof(led_red)); - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xa85a32); - ili9341_write(ili9341, pax_buffer->buf); - } - } - - while (true) { - if (result) play_bootsound(); - vTaskDelay(3000 / portTICK_PERIOD_MS); - } - } -} diff --git a/main/file_browser.c b/main/file_browser.c deleted file mode 100644 index 5adf658..0000000 --- a/main/file_browser.c +++ /dev/null @@ -1,227 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "esp_vfs.h" -#include "esp_vfs_fat.h" -#include "appfs.h" -#include "ili9341.h" -#include "pax_gfx.h" -#include "menu.h" -#include "rp2040.h" -#include "appfs_wrapper.h" -#include "bootscreen.h" - -static const char *TAG = "file browser"; - -void list_files_in_folder(const char* path) { - DIR* dir = opendir(path); - if (dir == NULL) { - ESP_LOGE(TAG, "Failed to open directory %s", path); - return; - } - - struct dirent *ent; - char type; - char size[12]; - char tpath[255]; - char tbuffer[80]; - struct stat sb; - struct tm *tm_info; - char *lpath = NULL; - int statok; - - uint64_t total = 0; - int nfiles = 0; - printf("T Size Date/Time Name\n"); - printf("-----------------------------------\n"); - while ((ent = readdir(dir)) != NULL) { - sprintf(tpath, path); - if (path[strlen(path)-1] != '/') { - strcat(tpath,"/"); - } - strcat(tpath,ent->d_name); - tbuffer[0] = '\0'; - - // Get file stat - statok = stat(tpath, &sb); - - if (statok == 0) { - tm_info = localtime(&sb.st_mtime); - strftime(tbuffer, 80, "%d/%m/%Y %R", tm_info); - } else { - sprintf(tbuffer, " "); - } - - if (ent->d_type == DT_REG) { - type = 'f'; - nfiles++; - if (statok) { - strcpy(size, " ?"); - } else { - total += sb.st_size; - if (sb.st_size < (1024*1024)) sprintf(size,"%8d", (int)sb.st_size); - else if ((sb.st_size/1024) < (1024*1024)) sprintf(size,"%6dKB", (int)(sb.st_size / 1024)); - else sprintf(size,"%6dMB", (int)(sb.st_size / (1024 * 1024))); - } - } else { - type = 'd'; - strcpy(size, " -"); - } - - printf("%c %s %s %s\r\n", type, size, tbuffer, ent->d_name); - } - - printf("-----------------------------------\n"); - if (total < (1024*1024)) printf(" %8d", (int)total); - else if ((total/1024) < (1024*1024)) printf(" %6dKB", (int)(total / 1024)); - else printf(" %6dMB", (int)(total / (1024 * 1024))); - printf(" in %d file(s)\n", nfiles); - printf("-----------------------------------\n"); - - closedir(dir); - free(lpath); -} - -typedef struct _file_browser_menu_args { - char type; - char path[512]; - char label[512]; -} file_browser_menu_args_t; - -void find_parent_dir(char* path, char* parent) { - size_t last_separator = 0; - for (size_t index = 0; index < strlen(path); index++) { - if (path[index] == '/') last_separator = index; - } - - strcpy(parent, path); - parent[last_separator] = '\0'; -} - -void file_browser(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341, const char* initial_path) { - display_boot_screen(pax_buffer, ili9341, "Please wait..."); - char path[512] = {0}; - strncpy(path, initial_path, sizeof(path)); - while (true) { - menu_t* menu = menu_alloc(path, 20, 18); - DIR* dir = opendir(path); - if (dir == NULL) { - if (path[0] != 0) { - ESP_LOGE(TAG, "Failed to open directory %s", path); - display_boot_screen(pax_buffer, ili9341, "Failed to open directory"); - vTaskDelay(200 / portTICK_PERIOD_MS); - } - return; - } - struct dirent *ent; - file_browser_menu_args_t* pd_args = malloc(sizeof(file_browser_menu_args_t)); - pd_args->type = 'd'; - find_parent_dir(path, pd_args->path); - menu_insert_item(menu, "../", NULL, pd_args, -1); - - while ((ent = readdir(dir)) != NULL) { - file_browser_menu_args_t* args = malloc(sizeof(file_browser_menu_args_t)); - sprintf(args->path, path); - if (path[strlen(path)-1] != '/') { - strcat(args->path,"/"); - } - strcat(args->path,ent->d_name); - - if (ent->d_type == DT_REG) { - args->type = 'f'; - } else { - args->type = 'd'; - } - - snprintf(args->label, sizeof(args->label), "%s%s", ent->d_name, (args->type == 'd') ? "/" : ""); - menu_insert_item(menu, args->label, NULL, args, -1); - } - closedir(dir); - - bool render = true; - bool renderbg = true; - bool exit = false; - file_browser_menu_args_t* menuArgs = NULL; - - while (1) { - rp2040_input_message_t buttonMessage = {0}; - if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - switch(pin) { - case RP2040_INPUT_JOYSTICK_DOWN: - if (value) { - menu_navigate_next(menu); - render = true; - } - break; - case RP2040_INPUT_JOYSTICK_UP: - if (value) { - menu_navigate_previous(menu); - render = true; - } - break; - case RP2040_INPUT_BUTTON_BACK: - if (value) { - menuArgs = pd_args; - } - break; - case RP2040_INPUT_BUTTON_ACCEPT: - case RP2040_INPUT_JOYSTICK_PRESS: - if (value) { - menuArgs = menu_get_callback_args(menu, menu_get_position(menu)); - } - break; - case RP2040_INPUT_BUTTON_HOME: - if (value) exit = true; - break; - default: - break; - } - } - - if (renderbg) { - pax_background(pax_buffer, 0xFFFFFF); - pax_noclip(pax_buffer); - const pax_font_t *font = pax_get_font("saira regular"); - pax_draw_text(pax_buffer, 0xFF000000, font, 18, 5, 240 - 19, "[A] install [B] back"); - renderbg = false; - } - - if (render) { - menu_render(pax_buffer, menu, 0, 0, 320, 220, 0xFF000000); - ili9341_write(ili9341, pax_buffer->buf); - render = false; - } - - if (menuArgs != NULL) { - if (menuArgs->type == 'd') { - strcpy(path, menuArgs->path); - break; - } else { - printf("File selected: %s\n", menuArgs->path); - appfs_store_app(pax_buffer, ili9341, menuArgs->path, menuArgs->label); - } - menuArgs = NULL; - render = true; - renderbg = true; - } - - if (exit) { - break; - } - } - - for (size_t index = 0; index < menu_get_length(menu); index++) { - free(menu_get_callback_args(menu, index)); - } - - menu_free(menu); - } -} diff --git a/main/fpga_download.c b/main/fpga_download.c deleted file mode 100644 index 7a0550f..0000000 --- a/main/fpga_download.c +++ /dev/null @@ -1,267 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "driver/uart.h" -#include "hardware.h" -#include "managed_i2c.h" -#include "pax_gfx.h" -#include "ice40.h" -#include "system_wrapper.h" -#include "graphics_wrapper.h" -#include "esp32/rom/crc.h" - -void fpga_install_uart() { - fflush(stdout); - ESP_ERROR_CHECK(uart_driver_install(0, 2048, 0, 0, NULL, 0)); - uart_config_t uart_config = { - .baud_rate = 921600, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - .source_clk = UART_SCLK_APB, - }; - ESP_ERROR_CHECK(uart_param_config(0, &uart_config)); -} - -void fpga_uninstall_uart() { - uart_driver_delete(0); -} - -bool fpga_read_stdin(uint8_t* buffer, uint32_t len, uint32_t timeout) { - int read = uart_read_bytes(0, buffer, len, timeout / portTICK_PERIOD_MS); - return (read == len); -} - -bool fpga_uart_sync(uint32_t* length, uint32_t* crc) { - uint8_t data[256]; - uart_read_bytes(0, data, sizeof(data), 10 / portTICK_PERIOD_MS); - char command[] = "FPGA"; - uart_write_bytes(0, command, 4); - uint8_t rx_buffer[4 * 3]; - fpga_read_stdin(rx_buffer, sizeof(rx_buffer), 1000); - if (memcmp(rx_buffer, "FPGA", 4) != 0) return false; - memcpy((uint8_t*) length, &rx_buffer[4 * 1], 4); - memcpy((uint8_t*) crc, &rx_buffer[4 * 2], 4); - return true; -} - -bool fpga_uart_load(uint8_t* buffer, uint32_t length) { - return fpga_read_stdin(buffer, length, 3000); -} - -void fpga_uart_mess(const char *mess) { - uart_write_bytes(0, mess, strlen(mess)); -} - -esp_err_t fpga_process_events(xQueueHandle buttonQueue, ICE40* ice40, uint16_t *key_state, uint16_t *idle_count) -{ - rp2040_input_message_t buttonMessage = {0}; - while (xQueueReceive(buttonQueue, &buttonMessage, 0) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - uint16_t key_mask = 0; - switch(pin) { - case RP2040_INPUT_JOYSTICK_DOWN: - key_mask = 1 << 0; - break; - case RP2040_INPUT_JOYSTICK_UP: - key_mask = 1 << 1; - break; - case RP2040_INPUT_JOYSTICK_LEFT: - key_mask = 1 << 2; - break; - case RP2040_INPUT_JOYSTICK_RIGHT: - key_mask = 1 << 3; - break; - case RP2040_INPUT_JOYSTICK_PRESS: - key_mask = 1 << 4; - break; - case RP2040_INPUT_BUTTON_HOME: - key_mask = 1 << 5; - break; - case RP2040_INPUT_BUTTON_MENU: - key_mask = 1 << 6; - break; - case RP2040_INPUT_BUTTON_SELECT: - key_mask = 1 << 7; - break; - case RP2040_INPUT_BUTTON_START: - key_mask = 1 << 8; - break; - case RP2040_INPUT_BUTTON_ACCEPT: - key_mask = 1 << 9; - break; - case RP2040_INPUT_BUTTON_BACK: - key_mask = 1 << 10; - default: - break; - } - if (key_mask != 0) - { - if (value) { - *key_state |= key_mask; - } - else { - *key_state &= ~key_mask; - } - - uint8_t spi_message[5] = { 0xf4 }; - spi_message[1] = *key_state >> 8; - spi_message[2] = *key_state & 0xff; - spi_message[3] = key_mask >> 8; - spi_message[4] = key_mask & 0xff; - esp_err_t res = ice40_send(ice40, spi_message, 5); - if (res != ESP_OK) { - return res; - } - } - *idle_count = 0; - } - return ESP_OK; -} - -void fpga_download(xQueueHandle buttonQueue, ICE40* ice40, pax_buf_t* pax_buffer, ILI9341* ili9341) { - char message[64]; - - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0x325aa8); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, "FPGA download mode"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*1, "Preparing..."); - ili9341_write(ili9341, pax_buffer->buf); - - fpga_install_uart(); - - ice40_disable(ice40); - ili9341_init(ili9341); - - uint8_t counter = 0; - uint32_t length = 0; - uint32_t crc = 0; - while (!fpga_uart_sync(&length, &crc)) { - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0x325aa8); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, "FPGA download mode"); - snprintf(message, sizeof(message), "Waiting for bitstream%s%s%s", (counter > 0) ? "." : " ", (counter > 1) ? "." : " ", (counter > 2) ? "." : " "); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*1, message); - ili9341_write(ili9341, pax_buffer->buf); - counter++; - if (counter > 3) counter = 0; - } - - while (true) { - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0x325aa8); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, "FPGA download mode"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*1, "Receiving bitstream..."); - ili9341_write(ili9341, pax_buffer->buf); - - uint8_t* buffer = malloc(length); - if (buffer == NULL) { - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xa85a32); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, "FPGA download mode"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*1, "Malloc failed"); - ili9341_write(ili9341, pax_buffer->buf); - vTaskDelay(1000 / portTICK_PERIOD_MS); - fpga_uninstall_uart(); - return; - } - if (!fpga_uart_load(buffer, length)) { - free(buffer); - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xa85a32); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, "FPGA download mode"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*1, "Timeout while loading"); - ili9341_write(ili9341, pax_buffer->buf); - vTaskDelay(1000 / portTICK_PERIOD_MS); - fpga_uninstall_uart(); - return; - } - - uint32_t checkCrc = crc32_le(0, buffer, length); - - if (checkCrc != crc) { - free(buffer); - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xa85a32); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, "FPGA download mode"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*1, "CRC incorrect"); - snprintf(message, sizeof(message), "Provided CRC: %08X", crc); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*2, message); - snprintf(message, sizeof(message), "Calculated CRC: %08X", checkCrc); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*3, message); - ili9341_write(ili9341, pax_buffer->buf); - vTaskDelay(1000 / portTICK_PERIOD_MS); - snprintf(message, sizeof(message), "CRC incorrect %08X %08x\n", crc, checkCrc); - fpga_uart_mess(message); - fpga_uninstall_uart(); - return; - } - fpga_uart_mess("CRC correct\n"); - - ili9341_deinit(ili9341); - ili9341_select(ili9341, false); - vTaskDelay(200 / portTICK_PERIOD_MS); - ili9341_select(ili9341, true); - - esp_err_t res = ice40_load_bitstream(ice40, buffer, length); - free(buffer); - - if (res != ESP_OK) { - ice40_disable(ice40); - ili9341_init(ili9341); - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xa85a32); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, "FPGA download mode"); - snprintf(message, sizeof(message), "Upload failed: %d", res); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*1, message); - ili9341_write(ili9341, pax_buffer->buf); - vTaskDelay(1000 / portTICK_PERIOD_MS); - snprintf(message, sizeof(message), "uploading bitstream failed with %d\n", res); - fpga_uart_mess(message); - fpga_uninstall_uart(); - return; - } - snprintf(message, sizeof(message), "bitstream has uploaded\n"); - fpga_uart_mess(message); - - // Waiting for next download and sending key strokes to FPGA - uint16_t key_state = 0; - uint16_t idle_count = 0; - while (true) { - if (idle_count >= 200) { - if (fpga_uart_sync(&length, &crc)) { - break; - } - idle_count = 0; - } - esp_err_t res = fpga_process_events(buttonQueue, ice40, &key_state, &idle_count); - if (res != ESP_OK) { - ice40_disable(ice40); - ili9341_init(ili9341); - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xa85a32); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, "FPGA download mode"); - snprintf(message, sizeof(message), "Error: %d", res); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*1, message); - ili9341_write(ili9341, pax_buffer->buf); - vTaskDelay(1000 / portTICK_PERIOD_MS); - snprintf(message, sizeof(message), "processing events failed with %d\n", res); - fpga_uart_mess(message); - fpga_uninstall_uart(); - return; - } - vTaskDelay(10 / portTICK_PERIOD_MS); - idle_count++; - } - ice40_disable(ice40); - ili9341_init(ili9341); - } -} diff --git a/main/fpga_test.c b/main/fpga_test.c deleted file mode 100644 index 8808cc3..0000000 --- a/main/fpga_test.c +++ /dev/null @@ -1,509 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "hardware.h" -#include "ili9341.h" -#include "ice40.h" -#include "rp2040.h" -#include "fpga_test.h" -#include "pax_gfx.h" -#include "test_common.h" - -extern const uint8_t fpga_selftest_bin_start[] asm("_binary_fpga_selftest_bin_start"); -extern const uint8_t fpga_selftest_bin_end[] asm("_binary_fpga_selftest_bin_end"); - - -static const char *TAG = "fpga_test"; - -/* SPI commands */ -#define SPI_CMD_NOP1 0x00 -#define SPI_CMD_SOC_MSG 0x10 -#define SPI_CMD_REG_ACCESS 0xf0 -#define SPI_CMD_LOOPBACK 0xf1 -#define SPI_CMD_LCD_PASSTHROUGH 0xf2 -#define SPI_CMD_BUTTON_REPORT 0xf4 -#define SPI_CMD_IRQ_ACK 0xfd -#define SPI_CMD_RESP_ACK 0xfe -#define SPI_CMD_NOP2 0xff - -/* Messages to self-test SoC */ -#define SOC_CMD_PING 0x00 -#define SOC_CMD_PING_PARAM 0xc0ffee -#define SOC_CMD_PING_RESP 0xcafebabe - -#define SOC_CMD_RGB_STATE_SET 0x10 -#define SOC_CMD_IRQN_SET 0x11 -#define SOC_CMD_LCD_RGB_CYCLE_SET 0x12 -#define SOC_CMD_PMOD_CYCLE_SET 0x13 -#define SOC_CMD_LCD_PASSTHROUGH_SET 0x14 - -#define SOC_CMD_PSRAM_TEST 0x20 -#define SOC_CMD_UART_LOOPBACK_TEST 0x21 -#define SOC_CMD_PMOD_OPEN_TEST 0x22 -#define SOC_CMD_PMOD_PLUG_TEST 0x23 -#define SOC_CMD_LCD_INIT_TEST 0x24 - -#define SOC_CMD_LCD_CHECK_MODE 0x30 - -#define SOC_RESP_OK 0x00000000 - - -/* SoC commands */ - -static bool soc_message(ICE40* ice40, uint8_t cmd, uint32_t param, uint32_t *resp, TickType_t ticks_to_wait) { - esp_err_t res; - uint8_t data_tx[6]; - uint8_t data_rx[6]; - - /* Default delay */ - ticks_to_wait /= 10; /* We do 10 retries */ - if (!ticks_to_wait) - ticks_to_wait = pdMS_TO_TICKS(50); - - /* Prepare message */ - data_tx[0] = SPI_CMD_SOC_MSG; - data_tx[1] = cmd; - data_tx[2] = (param >> 16) & 0xff; - data_tx[3] = (param >> 8) & 0xff; - data_tx[4] = (param ) & 0xff; - - /* Send message to PicoRV */ - res = ice40_send_turbo(ice40, data_tx, 5); - if (res != ESP_OK) { - ESP_LOGE(TAG, "SoC message TX failed"); - return false; - } - - /* Poll until we get a response */ - data_tx[0] = SPI_CMD_RESP_ACK; - - for (int i=0; i<10; i++) { - /* Poll */ - res = ice40_transaction(ice40, data_tx, 6, data_rx, 6); - if (res != ESP_OK) { - ESP_LOGE(TAG, "SoC response RX failed"); - return false; - } - - /* Was response valid ? */ - if (data_rx[1] & 0x80) - break; - - /* Wait before retry */ - vTaskDelay(ticks_to_wait); - } - - if (!(data_rx[1] & 0x80)) { - ESP_LOGE(TAG, "SoC response RX timeout"); - return false; - } - - /* Report response */ - if (resp) { - *resp = 0; - for (int i=0; i<4; i++) - *resp = (*resp << 8) | data_rx[2+i]; - } - - return true; -} - - -/* Test routines */ - -static bool test_bitstream_load(uint32_t *rc) { - ICE40* ice40 = get_ice40(); - esp_err_t res; - - res = ice40_load_bitstream(ice40, fpga_selftest_bin_start, fpga_selftest_bin_end - fpga_selftest_bin_start); - if (res != ESP_OK) { - *rc = res; - return false; - } - - *rc = 0; - return true; -} - -static bool _test_spi_loopback_one(ICE40* ice40) { - esp_err_t res; - uint8_t data_tx[257]; - uint8_t data_rx[258]; - - /* Generate pseudo random sequence */ - data_tx[1] = 1; - for (int i = 2; i < 257; i++) - data_tx[i] = (data_tx[i-1] << 1) ^ ((data_tx[i-1] & 0x80) ? 0x1d : 0x00); - - /* Send 256 bytes at high speed with echo command */ - data_tx[0] = SPI_CMD_LOOPBACK; - - res = ice40_send_turbo(ice40, data_tx, 257); - if (res != ESP_OK) { - ESP_LOGE(TAG, "SPI loopback transaction 1 failed (Turbo TX)"); - return false; - } - - /* Execute full duplex transaction with next 128 bytes */ - res = ice40_transaction(ice40, data_tx, 257, data_rx, 257); - if (res != ESP_OK) { - ESP_LOGE(TAG, "SPI loopback transaction 2 failed (Full Duplex)"); - return false; - } - - /* Validate response present */ - if ((data_rx[1] & 0x80) == 0) { - ESP_LOGE(TAG, "SPI loopback transaction 2 reports no response available\n"); - return false; - } - - /* Validate RX data (only 254 byte got read) */ - if (memcmp(&data_rx[2], &data_tx[1], 254)) { - ESP_LOGE(TAG, "SPI loopback transaction 1->2 integrity fail:\n"); - for (int i = 0; i < 254; i++) - printf("%02X%c", data_rx[i], ((i&0xf)==0xf) ? '\n' : ' '); - printf("\n"); - return false; - } - - /* Read two responses and ack them */ - for (int t = 0; t < 2; t++) { - /* Receive half duplex */ - res = ice40_receive(ice40, data_rx, 258); - if (res != ESP_OK) { - ESP_LOGE(TAG, "SPI loopback transaction 3.%d failed (Half Duplex RX)", t); - return false; - } - - /* Short acknowledge command */ - data_tx[0] = SPI_CMD_RESP_ACK; - - res = ice40_send_turbo(ice40, data_tx, 1); - if (res != ESP_OK) { - ESP_LOGE(TAG, "SPI loopback transaction 4.%d failed (Turbo ACK)", t); - return false; - } - - /* Validate response present */ - if ((data_rx[1] & 0x80) == 0) { - ESP_LOGE(TAG, "SPI loopback transaction 3.%d reports no response available\n", t); - return false; - } - - /* Validate RX data (only 254 byte got read) */ - if (memcmp(&data_rx[2], &data_tx[1], 254)) { - ESP_LOGE(TAG, "SPI loopback transaction %d->3.%d integrity fail:\n", 1+t, t); - for (int i = 0; i < 254; i++) - printf("%02X%c", data_rx[i], ((i&0xf)==0xf) ? '\n' : ' '); - printf("\n"); - return false; - } - } - - /* Check there is no more responses pending */ - data_tx[0] = SPI_CMD_NOP2; - - res = ice40_transaction(ice40, data_tx, 2, data_rx, 2); - if (res != ESP_OK) { - ESP_LOGE(TAG, "SPI loopback transaction 5 failed (Full Duplex)"); - return false; - } - - if ((data_rx[1] & 0x80) != 0) { - ESP_LOGE(TAG, "SPI loopback transaction 5 reports response available\n"); - return false; - } - - return true; -} - -static bool test_spi_loopback(uint32_t *rc) { - int i; - - ICE40* ice40 = get_ice40(); - - /* Run test 256 times */ - for (i=0; i<256; i++) { - if (!_test_spi_loopback_one(ice40)) - break; - } - - /* Failure ? */ - if (i != 256) { - *rc = i + 1; - return false; - } - - /* OK ! */ - *rc = 0; - return true; -} - -static bool test_soc_loopback(uint32_t *rc) { - ICE40* ice40 = get_ice40(); - - /* Execute command */ - if (!soc_message(ice40, SOC_CMD_PING, SOC_CMD_PING_PARAM, rc, 0)) { - *rc = -1; - return false; - } - - /* Check response */ - if (*rc != SOC_CMD_PING_RESP) - return false; - - /* Success */ - *rc = 0; - return true; -} - -static bool test_uart_loopback(uint32_t *rc) { - ICE40* ice40 = get_ice40(); - - /* Enable loopback mode of RP2040 */ - rp2040_set_fpga_loopback(get_rp2040(), true, true); - vTaskDelay(pdMS_TO_TICKS(10)); - - /* Execute command */ - if (!soc_message(ice40, SOC_CMD_UART_LOOPBACK_TEST, 0, rc, 0)) { - *rc = -1; - return false; - } - - /* Disable loopback mode of RP2040 */ - rp2040_set_fpga_loopback(get_rp2040(), true, false); - - /* Check response */ - return *rc == SOC_RESP_OK; -} - -static bool test_psram(uint32_t *rc) { - ICE40* ice40 = get_ice40(); - - /* Execute command */ - if (!soc_message(ice40, SOC_CMD_PSRAM_TEST, 0, rc, pdMS_TO_TICKS(1000))) { - *rc = -1; - return false; - } - - /* Check response */ - return *rc == SOC_RESP_OK; -} - -static bool test_irq_n(uint32_t *rc) { - ICE40* ice40 = get_ice40(); - - esp_err_t res; - - /* Set pin as input */ - res = gpio_set_direction(GPIO_INT_FPGA, GPIO_MODE_INPUT); - if (res != ESP_OK) { - *rc = 32; - return false; - } - - /* Assert interrupt line */ - if (!soc_message(ice40, SOC_CMD_IRQN_SET, 1, rc, 0)) { - *rc = -1; - return false; - } - - if (*rc != SOC_RESP_OK) - return false; - - /* Check level is 0 */ - if (gpio_get_level(GPIO_INT_FPGA) != 0) { - *rc = 16; - return false; - } - - /* Release interrupt line */ - if (!soc_message(ice40, SOC_CMD_IRQN_SET, 0, rc, 0)) { - *rc = -1; - return false; - } - - if (*rc != SOC_RESP_OK) - return false; - - /* Check level is 1 */ - if (gpio_get_level(GPIO_INT_FPGA) != 1) { - *rc = 16; - return false; - } - - return true; -} - -static bool test_lcd_mode(uint32_t *rc) { - ICE40* ice40 = get_ice40(); - esp_err_t res; - bool ok; - - /* Defaults */ - ok = true; - *rc = 0; - - /* Check state is 0 */ - if (!soc_message(ice40, SOC_CMD_LCD_CHECK_MODE, 0, rc, 0)) { - *rc = 16; - return false; - } - - if (*rc != SOC_RESP_OK) - return false; - - /* Set LCD mode to 1 */ - res = gpio_set_level(GPIO_LCD_MODE, 1); - if (res != ESP_OK) { - *rc = 32; - return false; - } - - /* Check state is 1 */ - if (!soc_message(ice40, SOC_CMD_LCD_CHECK_MODE, 1, rc, 0)) { - *rc = 17; - ok = false; - } - - if (*rc != SOC_RESP_OK) - ok = false; - - /* Set LCD mode back to 0 */ - res = gpio_set_level(GPIO_LCD_MODE, 0); - if (res != ESP_OK) { - *rc = 33; - return false; - } - - /* All good */ - return ok; -} - -static bool test_pmod_open(uint32_t *rc) { - ICE40* ice40 = get_ice40(); - /* Execute command */ - if (!soc_message(ice40, SOC_CMD_PMOD_OPEN_TEST, 0, rc, 0)) { - *rc = -1; - return false; - } - - /* Check response */ - return *rc == SOC_RESP_OK; -} - -static bool test_pmod_plug(uint32_t *rc) { - ICE40* ice40 = get_ice40(); - - /* Execute command */ - if (!soc_message(ice40, SOC_CMD_PMOD_PLUG_TEST, 0, rc, 0)) { - *rc = -1; - return false; - } - - /* Check response */ - return *rc == SOC_RESP_OK; -} - -static bool test_lcd_init(uint32_t *rc) { - ICE40* ice40 = get_ice40(); - - /* Execute command */ - if (!soc_message(ice40, SOC_CMD_LCD_INIT_TEST, 0, rc, 0)) { - *rc = -1; - return false; - } - - /* Check response */ - return *rc == SOC_RESP_OK; -} - -bool run_fpga_tests(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341) { - ICE40* ice40 = get_ice40(); - const pax_font_t *font; - int line = 0; - bool ok = true; - - /* Screen init */ - font = pax_get_font("sky mono"); - - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0x8060f0); - ili9341_write(ili9341, pax_buffer->buf); - - /* Run mandatory tests */ - RUN_TEST_MANDATORY("Bitstream load", test_bitstream_load); - RUN_TEST_MANDATORY("SPI loopback", test_spi_loopback); - RUN_TEST_MANDATORY("SoC loopback", test_soc_loopback); - - /* Set indicator to "in-progress" */ - soc_message(ice40, SOC_CMD_RGB_STATE_SET, 1, NULL, 0); - - /* Run non-interactive tests */ - RUN_TEST("UART loopback", test_uart_loopback); - RUN_TEST("PSRAM", test_psram); - RUN_TEST("IRQ_n signal", test_irq_n); - RUN_TEST("LCD_MODE signal", test_lcd_mode); - RUN_TEST("PMOD open", test_pmod_open); - - /* Show instructions for interactive test */ - /*pax_draw_text(pax_buffer, 0xffc0c0c0, font, 9, 25, 20*line+ 0, "Insert PMOD plug"); - pax_draw_text(pax_buffer, 0xffc0c0c0, font, 9, 25, 20*line+10, "Then press button for interactive test"); - pax_draw_text(pax_buffer, 0xffc0c0c0, font, 9, 25, 20*line+20, " - Check LCD color bars"); - pax_draw_text(pax_buffer, 0xffc0c0c0, font, 9, 25, 20*line+30, " - Then LCD & RGB led color cycling"); - ili9341_write(ili9341, pax_buffer->buf);*/ - - /* Wait for button */ - //wait_button(buttonQueue); - - /* Clear the instructions from buffer */ - //pax_draw_rect(pax_buffer, 0xff8060f0, 0, 20*line, 320, 240-20*line); - - /* Handover LCD to FPGA */ - ili9341_deinit(ili9341); - - /* Run interactive tests */ - //RUN_TEST("PMOD plug", test_pmod_plug); - RUN_TEST("LCD init", test_lcd_init); - - /* Wait a second (for user to see color bars) */ - vTaskDelay(pdMS_TO_TICKS(1000)); - - /* Start LCD / RGB cycling */ - soc_message(ice40, SOC_CMD_LCD_RGB_CYCLE_SET, 1, NULL, 0); - - /* Wait for button */ - RUN_TEST("LCD control", test_wait_for_response); - - /* Stop LCD / RGB cycling */ - soc_message(ice40, SOC_CMD_LCD_RGB_CYCLE_SET, 0, NULL, 0); - - /* Take control of the LCD back and refresh screen */ - ili9341_init(ili9341); - -error: - /* Update indicator */ - soc_message(ice40, SOC_CMD_RGB_STATE_SET, ok ? 2 : 3, NULL, 0); - - /* Pass / Fail result on screen */ - if (ok) - pax_draw_text(pax_buffer, 0xff00ff00, font, 36, 0, 20*line, "PASS"); - else - pax_draw_text(pax_buffer, 0xffff0000, font, 36, 0, 20*line, "FAIL"); - - ili9341_write(ili9341, pax_buffer->buf); - - /* Cleanup */ - ice40_disable(ice40); - - return ok; -} - -void fpga_test(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341) { - run_fpga_tests(buttonQueue, pax_buffer, ili9341); - test_wait_for_response(NULL); -} diff --git a/main/graphics_wrapper.c b/main/graphics_wrapper.c deleted file mode 100644 index 9192935..0000000 --- a/main/graphics_wrapper.c +++ /dev/null @@ -1,161 +0,0 @@ -#include -#include "graphics_wrapper.h" -#include "hardware.h" -#include "pax_keyboard.h" -#include "rp2040.h" - -void render_message(pax_buf_t *pax_buffer, char* message, float aPosX, float aPosY, float aWidth, float aHeight) { - pax_col_t fgColor = 0xFFFF0000; - pax_col_t bgColor = 0xFFFFD4D4; - pax_clip(pax_buffer, aPosX, aPosY, aWidth, aHeight); - pax_simple_rect(pax_buffer, bgColor, aPosX, aPosY, aWidth, aHeight); - pax_outline_rect(pax_buffer, fgColor, aPosX, aPosY, aWidth, aHeight); - pax_clip(pax_buffer, aPosX + 1, aPosY + 1, aWidth - 2, aHeight - 2); - pax_draw_text(pax_buffer, fgColor, NULL, 18, aPosX + 1, aPosY + 1, message); - pax_noclip(pax_buffer); -} - -esp_err_t graphics_task(pax_buf_t* pax_buffer, ILI9341* ili9341, menu_t* menu, char* message) { - pax_background(pax_buffer, 0xCCCCCC); - if (menu != NULL) { - menu_render(pax_buffer, menu, 10, 10, 320-20, 240-20, 0xFF000000); - } - - if (message != NULL) { - render_message(pax_buffer, message, 20, 110, 320-40, 20); - } - - return ili9341_write(ili9341, pax_buffer->buf); -} - -bool keyboard(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341, float aPosX, float aPosY, float aWidth, float aHeight, const char* aTitle, const char* aHint, char* aOutput, size_t aOutputSize) { - const pax_font_t *font = pax_get_font("saira regular"); - bool accepted = false; - pkb_ctx_t kb_ctx; - pkb_init(pax_buffer, &kb_ctx, 1024); - pkb_set_content(&kb_ctx, aOutput); - kb_ctx.kb_font = font; - kb_ctx.text_font = font; - - pax_col_t fgColor = 0xFF000000; - pax_col_t bgColor = 0xFFFFFFFF; - pax_col_t shadowColor = 0xFFC0C3C8; - pax_col_t borderColor = 0xFF0000AA; - pax_col_t titleBgColor = 0xFF080764; - pax_col_t titleColor = 0xFFFFFFFF; - pax_col_t selColor = 0xff007fff; - - kb_ctx.text_col = borderColor; - kb_ctx.sel_text_col = bgColor; - kb_ctx.sel_col = selColor; - kb_ctx.bg_col = bgColor; - - kb_ctx.kb_font_size = 18; - - float titleHeight = 20; - float hintHeight = 14; - - pax_noclip(pax_buffer); - pax_simple_rect(pax_buffer, shadowColor, aPosX+5, aPosY+5, aWidth, aHeight); - pax_simple_rect(pax_buffer, bgColor, aPosX, aPosY, aWidth, aHeight); - pax_outline_rect(pax_buffer, borderColor, aPosX, aPosY, aWidth, aHeight); - pax_simple_rect(pax_buffer, titleBgColor, aPosX, aPosY, aWidth, titleHeight); - pax_simple_line(pax_buffer, titleColor, aPosX + 1, aPosY + titleHeight, aPosX + aWidth - 2, aPosY + titleHeight - 1); - pax_clip(pax_buffer, aPosX + 1, aPosY + 1, aWidth - 2, titleHeight - 2); - pax_draw_text(pax_buffer, titleColor, font, titleHeight - 2, aPosX + 1, aPosY + 1, aTitle); - pax_clip(pax_buffer, aPosX + 1, aPosY + aHeight - hintHeight, aWidth - 2, hintHeight); - pax_draw_text(pax_buffer, borderColor, font, hintHeight - 2, aPosX + 1, aPosY + aHeight - hintHeight, aHint); - pax_noclip(pax_buffer); - - kb_ctx.x = aPosX + 1; - kb_ctx.y = aPosY + titleHeight + 1 ; - kb_ctx.width = aWidth - 2; - kb_ctx.height = aHeight - 3 - titleHeight - hintHeight; - - bool running = true; - while (running) { - rp2040_input_message_t buttonMessage = {0}; - if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - switch(pin) { - case RP2040_INPUT_JOYSTICK_DOWN: - if (value) { - pkb_press(&kb_ctx, PKB_DOWN); - } else { - pkb_release(&kb_ctx, PKB_DOWN); - } - break; - case RP2040_INPUT_JOYSTICK_UP: - if (value) { - pkb_press(&kb_ctx, PKB_UP); - } else { - pkb_release(&kb_ctx, PKB_UP); - } - break; - case RP2040_INPUT_JOYSTICK_LEFT: - if (value) { - pkb_press(&kb_ctx, PKB_LEFT); - } else { - pkb_release(&kb_ctx, PKB_LEFT); - } - break; - case RP2040_INPUT_JOYSTICK_RIGHT: - if (value) { - pkb_press(&kb_ctx, PKB_RIGHT); - } else { - pkb_release(&kb_ctx, PKB_RIGHT); - } - break; - case RP2040_INPUT_JOYSTICK_PRESS: - if (value) { - pkb_press(&kb_ctx, PKB_SHIFT); - } else { - pkb_release(&kb_ctx, PKB_SHIFT); - } - break; - case RP2040_INPUT_BUTTON_ACCEPT: - if (value) { - pkb_press(&kb_ctx, PKB_CHARSELECT); - } else { - pkb_release(&kb_ctx, PKB_CHARSELECT); - } - break; - case RP2040_INPUT_BUTTON_BACK: - if (value) { - pkb_press(&kb_ctx, PKB_DELETE_BEFORE); - } else { - pkb_release(&kb_ctx, PKB_DELETE_BEFORE); - } - break; - case RP2040_INPUT_BUTTON_SELECT: - if (value) { - pkb_press(&kb_ctx, PKB_MODESELECT); - } else { - pkb_release(&kb_ctx, PKB_MODESELECT); - } - break; - case RP2040_INPUT_BUTTON_HOME: - if (value) { - running = false; - } - break; - default: - break; - } - } - pkb_loop(&kb_ctx); - if (kb_ctx.dirty) { - pkb_redraw(pax_buffer, &kb_ctx); - ili9341_write(ili9341, pax_buffer->buf); - } - if (kb_ctx.input_accepted) { - memset(aOutput, 0, aOutputSize); - strncpy(aOutput, kb_ctx.content, aOutputSize - 1); - running = false; - accepted = true; - } - } - pkb_destroy(&kb_ctx); - return accepted; -} diff --git a/main/include/adc_test.h b/main/include/adc_test.h deleted file mode 100644 index 1a6e19d..0000000 --- a/main/include/adc_test.h +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include -#include -#include -#include -#include "ili9341.h" -#include "pax_gfx.h" - -void test_adc(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341); diff --git a/main/include/animation.h b/main/include/animation.h deleted file mode 100644 index 2f9bc39..0000000 --- a/main/include/animation.h +++ /dev/null @@ -1,4 +0,0 @@ -#include "pax_gfx.h" -#include "ili9341.h" - -void display_animation(pax_buf_t* pax_buffer, ILI9341* ili9341); diff --git a/main/include/appfs_wrapper.h b/main/include/appfs_wrapper.h deleted file mode 100644 index e9f4c48..0000000 --- a/main/include/appfs_wrapper.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "appfs.h" - -esp_err_t appfs_init(void); -uint8_t* load_file_to_ram(FILE* fd, size_t* fsize); -void appfs_boot_app(int fd); -void appfs_store_app(pax_buf_t* pax_buffer, ILI9341* ili9341, char* path, char* label); diff --git a/main/include/audio.h b/main/include/audio.h deleted file mode 100644 index a711982..0000000 --- a/main/include/audio.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -void audio_init(); -void play_bootsound(); diff --git a/main/include/bootscreen.h b/main/include/bootscreen.h deleted file mode 100644 index 9e3fac6..0000000 --- a/main/include/bootscreen.h +++ /dev/null @@ -1,4 +0,0 @@ -#include "pax_gfx.h" -#include "ili9341.h" - -void display_boot_screen(pax_buf_t* pax_buffer, ILI9341* ili9341, const char* text); diff --git a/main/include/button_test.h b/main/include/button_test.h deleted file mode 100644 index 6b16506..0000000 --- a/main/include/button_test.h +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include -#include -#include -#include -#include "ili9341.h" -#include "pax_gfx.h" - -void test_buttons(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341); diff --git a/main/include/factory_test.h b/main/include/factory_test.h deleted file mode 100644 index 5a33254..0000000 --- a/main/include/factory_test.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "ili9341.h" -#include "pax_gfx.h" - -void factory_test(pax_buf_t* pax_buffer, ILI9341* ili9341); diff --git a/main/include/file_browser.h b/main/include/file_browser.h deleted file mode 100644 index 6afd69e..0000000 --- a/main/include/file_browser.h +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include -#include -#include -#include "ili9341.h" -#include "pax_gfx.h" - -void list_files_in_folder(const char* path); -void file_browser(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341, const char* initial_path); diff --git a/main/include/fpga_download.h b/main/include/fpga_download.h deleted file mode 100644 index a10f8f0..0000000 --- a/main/include/fpga_download.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "ice40.h" -#include "pax_gfx.h" -#include "ili9341.h" -#include - -void fpga_download(xQueueHandle buttonQueue, ICE40* ice40, pax_buf_t* pax_buffer, ILI9341* ili9341); diff --git a/main/include/fpga_test.h b/main/include/fpga_test.h deleted file mode 100644 index d49c36e..0000000 --- a/main/include/fpga_test.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "hardware.h" -#include "rp2040.h" -#include "ili9341.h" -#include "ice40.h" -#include "pax_gfx.h" - -void fpga_test(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341); -bool run_fpga_tests(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341); diff --git a/main/include/graphics_wrapper.h b/main/include/graphics_wrapper.h deleted file mode 100644 index e34d852..0000000 --- a/main/include/graphics_wrapper.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "pax_gfx.h" -#include "ili9341.h" -#include "menu.h" - - -esp_err_t graphics_task(pax_buf_t* pax_buffer, ILI9341* ili9341, menu_t* menu, char* message); -bool keyboard(xQueueHandle buttonQueue, pax_buf_t* aBuffer, ILI9341* ili9341, float aPosX, float aPosY, float aWidth, float aHeight, const char* aTitle, const char* aHint, char* aOutput, size_t aOutputSize); diff --git a/main/include/main.h b/main/include/main.h new file mode 100644 index 0000000..e69de29 diff --git a/main/include/menu.h b/main/include/menu.h deleted file mode 100644 index 887bffd..0000000 --- a/main/include/menu.h +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - -#include -#include -#include - -#include "pax_gfx.h" - -typedef bool (*menu_callback_t)(); - -typedef struct _menu_item { - char* label; - menu_callback_t callback; - void* callbackArgs; - - pax_buf_t* icon; - - // Linked list - struct _menu_item* previousItem; - struct _menu_item* nextItem; -} menu_item_t; - -typedef struct menu { - char* title; - menu_item_t* firstItem; - size_t length; - size_t position; - float entry_height; - float text_height; - pax_buf_t* icon; - - pax_col_t fgColor; - pax_col_t bgColor; - pax_col_t selectedItemColor; - pax_col_t bgTextColor; - pax_col_t borderColor; - pax_col_t titleColor; - pax_col_t titleBgColor; - pax_col_t scrollbarBgColor; - pax_col_t scrollbarFgColor; - -} menu_t; - -menu_t* menu_alloc(const char* aTitle, float arg_entry_height, float arg_text_height); -void menu_free(menu_t* aMenu); -void menu_set_icon(menu_t* aMenu, pax_buf_t* icon); -bool menu_insert_item(menu_t* aMenu, const char* aLabel, menu_callback_t aCallback, void* aCallbackArgs, size_t aPosition); -bool menu_insert_item_icon(menu_t* aMenu, const char* aLabel, menu_callback_t aCallback, void* aCallbackArgs, size_t aPosition, pax_buf_t* icon); -bool menu_remove_item(menu_t* aMenu, size_t aPosition); -bool menu_navigate_to(menu_t* aMenu, size_t aPosition); -void menu_navigate_previous(menu_t* aMenu); -void menu_navigate_next(menu_t* aMenu); -size_t menu_get_position(menu_t* aMenu); -size_t menu_get_length(menu_t* aMenu); -void* menu_get_callback_args(menu_t* aMenu, size_t aPosition); -void menu_debug(menu_t* aMenu); -void menu_render(pax_buf_t *aBuffer, menu_t *aMenu, float aPosX, float aPosY, float aWidth, float aHeight, pax_col_t aColor); - -#ifdef __cplusplus -} -#endif //__cplusplus diff --git a/main/include/rp2040_updater.h b/main/include/rp2040_updater.h deleted file mode 100644 index bc16ffe..0000000 --- a/main/include/rp2040_updater.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include "pax_gfx.h" -#include "ili9341.h" - - -void rp2040_updater(RP2040* rp2040, pax_buf_t* pax_buffer, ILI9341* ili9341); diff --git a/main/include/settings.h b/main/include/settings.h deleted file mode 100644 index 7581831..0000000 --- a/main/include/settings.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "hardware.h" -#include "rp2040.h" -#include "ili9341.h" -#include "ice40.h" - -esp_err_t nvs_init(); -esp_err_t nvs_get_str_fixed(const char* nvs_namespace, const char* key, char* target, size_t target_size, size_t* size); -uint8_t nvs_get_u8_default(const char* nvs_namespace, const char* key, uint8_t default_value); -esp_err_t nvs_set_u8_fixed(const char* nvs_namespace, const char* key, uint8_t value); diff --git a/main/include/system_wrapper.h b/main/include/system_wrapper.h deleted file mode 100644 index a29f052..0000000 --- a/main/include/system_wrapper.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void restart(); diff --git a/main/include/test_common.h b/main/include/test_common.h deleted file mode 100644 index a679df6..0000000 --- a/main/include/test_common.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include -#include "ili9341.h" -#include "pax_gfx.h" - -typedef bool (*test_fn)(uint32_t *rc); - -bool test_wait_for_response(uint32_t *rc); -bool run_test(pax_buf_t* pax_buffer, const pax_font_t *font, ILI9341* ili9341, int line, const char *test_name, test_fn fn); - -#define RUN_TEST(name, fn) do {\ - ok &= run_test(pax_buffer, font, ili9341, line++, name, fn); \ -} while (0) - -#define RUN_TEST_MANDATORY(name, fn) do {\ - if (!run_test(pax_buffer, font, ili9341, line++, name, fn)) { \ - pax_draw_text(pax_buffer, 0xffff0000, font, 18, 0, 20*line, "Aborted"); \ - ili9341_write(ili9341, pax_buffer->buf); \ - ok = false; \ - goto error; \ - } \ -} while (0) - -#define RUN_TEST_BLIND(name, fn) do {\ - ok &= run_test(pax_buffer, font, NULL, line++, name, fn); \ -} while (0) diff --git a/main/include/uninstall.h b/main/include/uninstall.h deleted file mode 100644 index 56e4646..0000000 --- a/main/include/uninstall.h +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include -#include -#include -#include "pax_gfx.h" -#include "ili9341.h" - -void uninstall_browser(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341); diff --git a/main/include/webusb.h b/main/include/webusb.h deleted file mode 100644 index 2cd234c..0000000 --- a/main/include/webusb.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "ice40.h" -#include "pax_gfx.h" -#include "ili9341.h" -#include - -void webusb_main(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341); diff --git a/main/include/wifi_connect.h b/main/include/wifi_connect.h deleted file mode 100644 index ade165c..0000000 --- a/main/include/wifi_connect.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include - -bool wifi_connect_to_stored(); diff --git a/main/include/wifi_connection.h b/main/include/wifi_connection.h deleted file mode 100644 index 12ac8fd..0000000 --- a/main/include/wifi_connection.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "esp_wifi.h" -#include "esp_wifi_types.h" -#include "esp_wpa2.h" - -#define WIFI_MCH2022_SSID "MCH2022" -#define WIFI_MCH2022_USER "mch2022" -#define WIFI_MCH2022_IDENT "mch2022" -#define WIFI_MCH2022_PASSWORD "mch2022" -#define WIFI_MCH2022_AUTH WIFI_AUTH_WPA2_ENTERPRISE -#define WIFI_MCH2022_PHASE2 ESP_EAP_TTLS_PHASE2_MSCHAPV2 - -// Simpler interpretation of WiFi signal strength. -typedef enum { - WIFI_STRENGTH_VERY_BAD, - WIFI_STRENGTH_BAD, - WIFI_STRENGTH_GOOD, - WIFI_STRENGTH_VERY_GOOD, -} wifi_strength_t; - -// Thresholds for aforementioned signal strength definitions. -#define WIFI_THRESH_BAD -80 -#define WIFI_THRESH_GOOD -70 -#define WIFI_THRESH_VERY_GOOD -67 - -// Firt time initialisation of the WiFi stack. -void wifi_init(); - -// Connect to a traditional username/password WiFi network. -bool wifi_connect(const char* aSsid, const char* aPassword, wifi_auth_mode_t aAuthmode, uint8_t aRetryMax); - -// Connect to a WPA2 enterprise WiFi network. -bool wifi_connect_ent(const char* aSsid, const char *aIdent, const char *aAnonIdent, const char* aPassword, esp_eap_ttls_phase2_types phase2, uint8_t aRetryMax); - -// Scan for WiFi networks. -// Updates the APs pointer if non-null. -// Returns the number of APs found. -size_t wifi_scan(wifi_ap_record_t **aps); - -// Get the strength value for a given RSSI. -wifi_strength_t wifi_rssi_to_strength(int8_t rssi); diff --git a/main/include/wifi_ota.h b/main/include/wifi_ota.h deleted file mode 100644 index 48fa9e7..0000000 --- a/main/include/wifi_ota.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include "pax_gfx.h" -#include "ili9341.h" - -void ota_update(pax_buf_t* pax_buffer, ILI9341* ili9341); diff --git a/main/main.c b/main/main.c index 1b3dab4..73c24e9 100644 --- a/main/main.c +++ b/main/main.c @@ -1,295 +1,38 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "driver/uart.h" + +// This file contains a simple hello world app which you can base you own apps on. + +#include "main.h" #include "hardware.h" -#include "managed_i2c.h" #include "pax_gfx.h" -#include "sdcard.h" -#include "appfs.h" -#include "esp_ota_ops.h" -#include "rp2040.h" -#include "rp2040bl.h" +#include "pax_codecs.h" +#include "ili9341.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "esp_system.h" -#include "fpga_test.h" +pax_buf_t buf; +xQueueHandle buttonQueue; -#include "menu.h" -#include "system_wrapper.h" -#include "graphics_wrapper.h" -#include "appfs_wrapper.h" -#include "settings.h" -#include "wifi_connection.h" -#include "rp2040_updater.h" +static const char *TAG = "mch2022-demo-app"; -#include "ws2812.h" - -#include "esp32/rom/crc.h" - -#include "efuse.h" - -#include "wifi_ota.h" - -#include "esp_vfs.h" -#include "esp_vfs_fat.h" - -#include - -#include "audio.h" - -#include "bootscreen.h" - -#include "menus/start.h" - -#include "factory_test.h" -#include "fpga_download.h" -#include "webusb.h" - -extern const uint8_t wallpaper_png_start[] asm("_binary_wallpaper_png_start"); -extern const uint8_t wallpaper_png_end[] asm("_binary_wallpaper_png_end"); - -extern const uint8_t logo_screen_png_start[] asm("_binary_logo_screen_png_start"); -extern const uint8_t logo_screen_png_end[] asm("_binary_logo_screen_png_end"); - - -static const char *TAG = "main"; - -void display_fatal_error(pax_buf_t* pax_buffer, ILI9341* ili9341, const char* line0, const char* line1, const char* line2, const char* line3) { - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xa85a32); - if (line0 != NULL) pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, line0); - if (line1 != NULL) pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 12, 0, 20*1, line1); - if (line2 != NULL) pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 12, 0, 20*2, line2); - if (line3 != NULL) pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 12, 0, 20*3, line3); - ili9341_write(ili9341, pax_buffer->buf); +void disp_flush() { + ili9341_write(get_ili9341(), buf.buf); } -void stop() { - ESP_LOGW(TAG, "*** HALTED ***"); - gpio_set_direction(GPIO_SD_PWR, GPIO_MODE_OUTPUT); - gpio_set_level(GPIO_SD_PWR, 1); - ws2812_init(GPIO_LED_DATA); - uint8_t led_off[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - uint8_t led_red[15] = {0, 50, 0, 0, 50, 0, 0, 50, 0, 0, 50, 0, 0, 50, 0}; - uint8_t led_red2[15] = {0, 0xFF, 0, 0, 0xFF, 0, 0, 0xFF, 0, 0, 0xFF, 0, 0, 0xFF, 0}; - while (true) { - ws2812_send_data(led_red2, sizeof(led_red2)); - vTaskDelay(pdMS_TO_TICKS(200)); - ws2812_send_data(led_red, sizeof(led_red)); - vTaskDelay(pdMS_TO_TICKS(200)); - ws2812_send_data(led_off, sizeof(led_off)); - vTaskDelay(pdMS_TO_TICKS(200)); - } -} - -void app_main(void) { - esp_err_t res; - - audio_init(); - - const esp_app_desc_t *app_description = esp_ota_get_app_description(); - ESP_LOGI(TAG, "App version: %s", app_description->version); - //ESP_LOGI(TAG, "Project name: %s", app_description->project_name); - - /* Initialize memory */ - uint8_t* framebuffer = heap_caps_malloc(ILI9341_BUFFER_SIZE, MALLOC_CAP_8BIT); - if (framebuffer == NULL) { - ESP_LOGE(TAG, "Failed to allocate framebuffer"); - esp_restart(); - } - memset(framebuffer, 0, ILI9341_BUFFER_SIZE); - - pax_buf_t* pax_buffer = malloc(sizeof(pax_buf_t)); - if (framebuffer == NULL) { - ESP_LOGE(TAG, "Failed to allocate buffer for PAX graphics library"); - esp_restart(); - } - memset(pax_buffer, 0, sizeof(pax_buf_t)); - - pax_buf_init(pax_buffer, framebuffer, ILI9341_WIDTH, ILI9341_HEIGHT, PAX_BUF_16_565RGB); - - /* Initialize hardware */ - - efuse_protect(); - - if (bsp_init() != ESP_OK) { - ESP_LOGE(TAG, "Failed to initialize basic board support functions"); - esp_restart(); - } - - ILI9341* ili9341 = get_ili9341(); - if (ili9341 == NULL) { - ESP_LOGE(TAG, "ili9341 is NULL"); - esp_restart(); - } - - /* Start NVS */ - res = nvs_init(); - if (res != ESP_OK) { - ESP_LOGE(TAG, "NVS init failed: %d", res); - display_fatal_error(pax_buffer, ili9341, "Failed to initialize", "NVS failed to initialize", "Flash may be corrupted", NULL); - stop(); - } - - display_boot_screen(pax_buffer, ili9341, "Starting..."); - - if (bsp_rp2040_init() != ESP_OK) { - ESP_LOGE(TAG, "Failed to initialize the RP2040 co-processor"); - display_fatal_error(pax_buffer, ili9341, "Failed to initialize", "RP2040 co-processor error", NULL, NULL); - stop(); - } - - RP2040* rp2040 = get_rp2040(); - if (rp2040 == NULL) { - ESP_LOGE(TAG, "rp2040 is NULL"); - stop(); - } - - rp2040_updater(rp2040, pax_buffer, ili9341); // Handle RP2040 firmware update & bootloader mode - - factory_test(pax_buffer, ili9341); - - /*uint8_t rp2040_uid[8]; - if (rp2040_get_uid(rp2040, rp2040_uid) != ESP_OK) { - ESP_LOGE(TAG, "Failed to get RP2040 UID"); - display_fatal_error(pax_buffer, ili9341, "Failed to initialize", "Failed to read UID", NULL, NULL); - stop(); - } - - printf("RP2040 UID: %02X%02X%02X%02X%02X%02X%02X%02X\n", rp2040_uid[0], rp2040_uid[1], rp2040_uid[2], rp2040_uid[3], rp2040_uid[4], rp2040_uid[5], rp2040_uid[6], rp2040_uid[7]);*/ - - if (bsp_ice40_init() != ESP_OK) { - ESP_LOGE(TAG, "Failed to initialize the ICE40 FPGA"); - display_fatal_error(pax_buffer, ili9341, "Failed to initialize", "ICE40 FPGA error", NULL, NULL); - stop(); - } - - ICE40* ice40 = get_ice40(); - if (ice40 == NULL) { - ESP_LOGE(TAG, "ice40 is NULL"); - stop(); - } - - /*display_boot_screen(pax_buffer, ili9341, "Initializing BNO055..."); - - if (bsp_bno055_init() != ESP_OK) { - ESP_LOGE(TAG, "Failed to initialize the BNO055 position sensor"); - display_fatal_error(pax_buffer, ili9341, "Failed to initialize", "BNO055 sensor error", "Check I2C bus", "Remove SAO and try again"); - stop(); - } - - BNO055* bno055 = get_bno055(); - if (bno055 == NULL) { - ESP_LOGE(TAG, "bno055 is NULL"); - stop(); - }*/ - - /*display_boot_screen(pax_buffer, ili9341, "Initializing BME680..."); - - if (bsp_bme680_init() != ESP_OK) { - ESP_LOGE(TAG, "Failed to initialize the BME680 position sensor"); - display_fatal_error(pax_buffer, ili9341, "Failed to initialize", "BME680 sensor error", "Check I2C bus", "Remove SAO and try again"); - stop(); - } - - BME680* bme680 = get_bme680(); - if (bme680 == NULL) { - ESP_LOGE(TAG, "bme680 is NULL"); - stop(); - }*/ - - //display_boot_screen(pax_buffer, ili9341, "Initializing AppFS..."); - - /* Start AppFS */ - res = appfs_init(); - if (res != ESP_OK) { - ESP_LOGE(TAG, "AppFS init failed: %d", res); - display_fatal_error(pax_buffer, ili9341, "Failed to initialize", "AppFS failed to initialize", "Flash may be corrupted", NULL); - stop(); - } - - //display_boot_screen(pax_buffer, ili9341, "Initializing filesystem..."); - - /* Start internal filesystem */ - const esp_partition_t* fs_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, "locfd"); - - wl_handle_t s_wl_handle = WL_INVALID_HANDLE; - - if (fs_partition != NULL) { - const esp_vfs_fat_mount_config_t mount_config = { - .format_if_mount_failed = true, - .max_files = 5, - .allocation_unit_size = 0, - }; - esp_err_t res = esp_vfs_fat_spiflash_mount("/internal", "locfd", &mount_config, &s_wl_handle); - if (res != ESP_OK) { - ESP_LOGE(TAG, "failed to mount locfd (%d)", res); - } else { - ESP_LOGI(TAG, "Internal filesystem mounted"); - } - } else { - ESP_LOGE(TAG, "locfd partition not found"); - } - - /* Start SD card filesystem */ - res = mount_sd(GPIO_SD_CMD, GPIO_SD_CLK, GPIO_SD_D0, GPIO_SD_PWR, "/sd", false, 5); - bool sdcard_ready = (res == ESP_OK); - if (sdcard_ready) { - ESP_LOGI(TAG, "SD card filesystem mounted"); - - /* LED power is on: start LED driver and turn LEDs off */ - ws2812_init(GPIO_LED_DATA); - const uint8_t led_off[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - ws2812_send_data(led_off, sizeof(led_off)); - } else { - gpio_set_level(GPIO_SD_PWR, 0); // Disable power to LEDs and SD card - } - - /* Start WiFi */ - wifi_init(); - - /* Check WebUSB mode */ - - uint8_t webusb_mode; - res = rp2040_get_webusb_mode(rp2040, &webusb_mode); - if (res != ESP_OK) { - ESP_LOGE(TAG, "Failed to read WebUSB mode: %d", res); - display_fatal_error(pax_buffer, ili9341, "Failed to initialize", "Failed to read WebUSB mode", NULL, NULL); - stop(); - } - - ESP_LOGI(TAG, "WebUSB mode 0x%02X", webusb_mode); - - if (webusb_mode == 0x00) { // Normal boot - /* Rick that roll */ - play_bootsound(); - - /* Launcher menu */ - while (true) { - menu_start(rp2040->queue, pax_buffer, ili9341, app_description->version); - } - } else if (webusb_mode == 0x01) { - display_boot_screen(pax_buffer, ili9341, "WebUSB mode"); - while (true) { - webusb_main(rp2040->queue, pax_buffer, ili9341); - } - } else if (webusb_mode == 0x02) { - display_boot_screen(pax_buffer, ili9341, "FPGA download mode"); - while (true) { - fpga_download(rp2040->queue, get_ice40(), pax_buffer, ili9341); - } - } else { - char buffer[64]; - snprintf(buffer, sizeof(buffer), "Invalid mode 0x%02X", webusb_mode); - display_boot_screen(pax_buffer, ili9341, buffer); - } - - free(framebuffer); +void app_main() { + // Init HW. + bsp_init(); + bsp_rp2040_init(); + buttonQueue = get_rp2040()->queue; + + // Init GFX. + pax_buf_init(&buf, NULL, 320, 240, PAX_BUF_16_565RGB); + + // Show some hello world. + pax_background(&buf, 0xffff00ff); + disp_flush(); + + // Just wait. + while (1) vTaskDelay(10000); } diff --git a/main/menu.c b/main/menu.c deleted file mode 100644 index 2deba87..0000000 --- a/main/menu.c +++ /dev/null @@ -1,296 +0,0 @@ -#include -#include -#include "pax_gfx.h" -#include "pax_codecs.h" -#include "menu.h" - -menu_t* menu_alloc(const char* aTitle, float arg_entry_height, float arg_text_height) { - if (aTitle == NULL) return NULL; - menu_t* menu = malloc(sizeof(menu_t)); - if (menu == NULL) return NULL; - size_t titleSize = strlen(aTitle) + 1; - menu->title = malloc(titleSize); - if (menu->title == NULL) { - free(menu); - return NULL; - } - memcpy(menu->title, aTitle, titleSize); - menu->firstItem = NULL; - menu->length = 0; - menu->position = 0; - menu->entry_height = (arg_entry_height > 0) ? arg_entry_height : 20; - menu->text_height = (arg_text_height > 0) ? arg_text_height : (arg_entry_height - 2); - menu->icon = NULL; - - menu->fgColor = 0xFF000000; - menu->bgColor = 0xFFFFFFFF; - menu->bgTextColor = 0xFFFFFFFF; - menu->selectedItemColor = 0xFF000000; - menu->borderColor = 0x88000000; - menu->titleColor = 0xFFFFFFFF; - menu->titleBgColor = 0xFF000000; - menu->scrollbarBgColor = 0xFFCCCCCC; - menu->scrollbarFgColor = 0xFF555555; - - return menu; -} - -void _menu_free_item(menu_item_t* aMenuItem) { - free(aMenuItem->label); - free(aMenuItem); -} - -void menu_free(menu_t* aMenu) { - if (aMenu == NULL) return; - free(aMenu->title); - menu_item_t* currentItem = aMenu->firstItem; - while (currentItem != NULL) { - menu_item_t* nextItem = currentItem->nextItem; - _menu_free_item(currentItem); - currentItem = nextItem; - } - free(aMenu); -} - -void menu_set_icon(menu_t* aMenu, pax_buf_t* icon) { - aMenu->icon = icon; -} - -menu_item_t* _menu_find_item(menu_t* aMenu, size_t aPosition) { - menu_item_t* currentItem = aMenu->firstItem; - if (currentItem == NULL) return NULL; - size_t index = 0; - while (index < aPosition) { - if (currentItem->nextItem == NULL) break; - currentItem = currentItem->nextItem; - index++; - } - return currentItem; -} - -menu_item_t* _menu_find_last_item(menu_t* aMenu) { - menu_item_t* lastItem = aMenu->firstItem; - if (lastItem == NULL) return NULL; - while (lastItem->nextItem != NULL) { - lastItem = lastItem->nextItem; - } - return lastItem; -} - -bool menu_insert_item(menu_t* aMenu, const char* aLabel, menu_callback_t aCallback, void* aCallbackArgs, size_t aPosition) { - if (aMenu == NULL) return false; - menu_item_t* newItem = malloc(sizeof(menu_item_t)); - if (newItem == NULL) return false; - size_t labelSize = strlen(aLabel) + 1; - newItem->label = malloc(labelSize); - if (newItem->label == NULL) { - free(newItem); - return false; - } - memcpy(newItem->label, aLabel, labelSize); - newItem->callback = aCallback; - newItem->callbackArgs = aCallbackArgs; - newItem->icon = NULL; - if (aMenu->firstItem == NULL) { - newItem->nextItem = NULL; - newItem->previousItem = NULL; - aMenu->firstItem = newItem; - } else { - if (aPosition >= aMenu->length) { - newItem->previousItem = _menu_find_last_item(aMenu); - newItem->nextItem = NULL; - newItem->previousItem->nextItem = newItem; - } else { - newItem->nextItem = _menu_find_item(aMenu, aPosition); - newItem->previousItem = newItem->nextItem->previousItem; // Copy pointer to previous item to new item - if (newItem->nextItem != NULL) newItem->nextItem->previousItem = newItem; // Replace pointer to previous item with new item - if (newItem->previousItem != NULL) newItem->previousItem->nextItem = newItem; // Replace pointer to next item in previous item - } - } - aMenu->length++; - return true; -} - -bool menu_insert_item_icon(menu_t* aMenu, const char* aLabel, menu_callback_t aCallback, void* aCallbackArgs, size_t aPosition, pax_buf_t* icon) { - if (!menu_insert_item(aMenu, aLabel, aCallback, aCallbackArgs, aPosition)) { - return false; - } - menu_item_t* item; - if (aPosition >= aMenu->length - 1) { - item = _menu_find_last_item(aMenu); - } else { - item = _menu_find_item(aMenu, aPosition); - } - - item->icon = icon; - return true; -} - -bool menu_remove_item(menu_t* aMenu, size_t aPosition) { - if (aMenu == NULL) return false; // Can't delete an item from a menu that doesn't exist - if (aMenu->length <= aPosition) return false; // Can't delete an item that doesn't exist - menu_item_t* item; - - if (aPosition == 0) { - item = aMenu->firstItem; - if (item == NULL) return false; // Can't delete if no linked list is allocated - if (item->nextItem != NULL) { - aMenu->firstItem = item->nextItem; - aMenu->firstItem->previousItem = NULL; - } else { - aMenu->firstItem = NULL; - } - } else { - item = _menu_find_item(aMenu, aPosition); - if (item == NULL) return false; - if (item->previousItem != NULL) item->previousItem->nextItem = item->nextItem; - if (item->nextItem != NULL) item->nextItem->previousItem = item->previousItem; - } - free(item->label); - free(item); - aMenu->length--; - return true; -} - -bool menu_navigate_to(menu_t* aMenu, size_t aPosition) { - if (aMenu == NULL) return false; - if (aMenu->length < 1) return false; - aMenu->position = aPosition; - if (aMenu->position >= aMenu->length) aMenu->position = aMenu->length - 1; - return true; -} - -void menu_navigate_previous(menu_t* aMenu) { - if (aMenu == NULL) return; - if (aMenu->length < 1) return; - aMenu->position--; - if (aMenu->position > aMenu->length) { - aMenu->position = aMenu->length - 1; - } -} - -void menu_navigate_next(menu_t* aMenu) { - if (aMenu == NULL) return; - if (aMenu->length < 1) return; - aMenu->position = (aMenu->position + 1) % aMenu->length; -} - -size_t menu_get_position(menu_t* aMenu) { - return aMenu->position; -} - -size_t menu_get_length(menu_t* aMenu) { - return aMenu->length; -} - -void* menu_get_callback_args(menu_t* aMenu, size_t aPosition) { - menu_item_t* item = _menu_find_item(aMenu, aPosition); - if (item == NULL) return NULL; - return item->callbackArgs; -} - -void menu_debug(menu_t* aMenu) { - if (aMenu == NULL) { - printf("Menu pointer is NULL\n"); - return; - } - printf("Title: %s\n", aMenu->title); - printf("Length: %u\n", aMenu->length); - printf("Position: %u\n", aMenu->position); - menu_item_t* item = aMenu->firstItem; - if (item == NULL) { - printf("Menu contains no items\n"); - } else { - while (item != NULL) { - printf("> %s\n", item->label); - item = item->nextItem; - } - } - printf("------\n"); -} - -void menu_render(pax_buf_t *aBuffer, menu_t* aMenu, float aPosX, float aPosY, float aWidth, float aHeight, pax_col_t aColor) { - const pax_font_t *font = pax_get_font("saira regular"); - - float entry_height = aMenu->entry_height;//18 + 2; - float text_height = aMenu->text_height; - float text_offset = ((entry_height - text_height) / 2) + 1; - size_t maxItems = aHeight / entry_height; - - float posY = aPosY; - - pax_noclip(aBuffer); - - if (maxItems > 1) { - float offsetX = 0; - if (aMenu->icon != NULL) { - offsetX = aMenu->icon->width; - } - - maxItems--; - pax_simple_rect(aBuffer, aMenu->titleBgColor, aPosX, posY, aWidth, entry_height); - //pax_simple_line(aBuffer, aMenu->titleColor, aPosX + 1, aPosY + entry_height, aPosX + aWidth - 2, aPosY + entry_height - 1); - pax_clip(aBuffer, aPosX + 1, posY + text_offset, aWidth - 2, text_height); - pax_draw_text(aBuffer, aMenu->titleColor, font, text_height, aPosX + offsetX + 1, posY + text_offset, aMenu->title); - pax_noclip(aBuffer); - if (aMenu->icon != NULL) { - pax_draw_image(aBuffer, aMenu->icon, aPosX, posY); - } - posY += entry_height; - } - - size_t itemOffset = 0; - if (aMenu->position >= maxItems) { - itemOffset = aMenu->position - maxItems + 1; - } - - pax_outline_rect(aBuffer, aMenu->borderColor, aPosX, aPosY, aWidth, aHeight); - pax_simple_rect(aBuffer, aMenu->bgColor, aPosX, posY, aWidth, aHeight - posY + aPosY); - - for (size_t index = itemOffset; (index < itemOffset + maxItems) && (index < aMenu->length); index++) { - menu_item_t* item = _menu_find_item(aMenu, index); - if (item == NULL) { - printf("Render error: item is NULL at %u\n", index); - break; - } - - float iconWidth = 0; - if (item->icon != NULL) { - iconWidth = item->icon->width + 1; - } - - if (index == aMenu->position) { - pax_simple_rect(aBuffer, aMenu->selectedItemColor, aPosX + 1, posY, aWidth - 2, entry_height); - pax_clip(aBuffer, aPosX + 1, posY + text_offset, aWidth - 4, text_height); - pax_draw_text(aBuffer, aMenu->bgTextColor, font, text_height, aPosX + iconWidth + 1, posY + text_offset, item->label); - pax_noclip(aBuffer); - } else { - pax_simple_rect(aBuffer, aMenu->bgColor, aPosX + 1, posY, aWidth - 2, entry_height); - pax_clip(aBuffer, aPosX + 1, posY + text_offset, aWidth - 4, text_height); - pax_draw_text(aBuffer, aMenu->fgColor, font, text_height, aPosX + iconWidth + 1, posY + text_offset, item->label); - pax_noclip(aBuffer); - } - - if (item->icon != NULL) { - pax_draw_image(aBuffer, item->icon, aPosX + 1, posY); - } - - posY += entry_height; - } - - pax_clip(aBuffer, aPosX + aWidth - 5, aPosY + entry_height, 4, aHeight - 1 - entry_height); - - float fractionStart = itemOffset / (aMenu->length * 1.0); - float fractionSelected = aMenu->position / (aMenu->length * 1.0); - float fractionEnd = (itemOffset + maxItems) / (aMenu->length * 1.0); - if (fractionEnd > 1.0) fractionEnd = 1.0; - - float scrollbarHeight = aHeight - entry_height; - float scrollbarStart = scrollbarHeight * fractionStart; - float scrollbarEnd = scrollbarHeight * fractionEnd; - - pax_simple_rect(aBuffer, aMenu->scrollbarBgColor, aPosX + aWidth - 5, aPosY + entry_height - 1, 4, scrollbarHeight); - pax_simple_rect(aBuffer, aMenu->scrollbarFgColor, aPosX + aWidth - 5, aPosY + entry_height - 1 + scrollbarStart, 4, scrollbarEnd - scrollbarStart); - - pax_noclip(aBuffer); -} diff --git a/main/menus/dev.c b/main/menus/dev.c deleted file mode 100644 index 25e6126..0000000 --- a/main/menus/dev.c +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "appfs.h" -#include "ili9341.h" -#include "pax_gfx.h" -#include "pax_codecs.h" -#include "menu.h" -#include "rp2040.h" -#include "launcher.h" -#include "settings.h" -#include "dev.h" -#include "fpga_download.h" -#include "hardware.h" -#include "file_browser.h" -#include "fpga_test.h" -#include "animation.h" -#include "button_test.h" -#include "adc_test.h" - -extern const uint8_t dev_png_start[] asm("_binary_dev_png_start"); -extern const uint8_t dev_png_end[] asm("_binary_dev_png_end"); - -typedef enum action { - ACTION_NONE, - ACTION_BACK, - ACTION_FPGA_DL, - ACTION_FPGA_TEST, - ACTION_FILE_BROWSER, - ACTION_FILE_BROWSER_INT, - ACTION_ANIMATION, - ACTION_BUTTON_TEST, - ACTION_ADC_TEST -} menu_dev_action_t; - -void render_dev_help(pax_buf_t* pax_buffer) { - const pax_font_t *font = pax_get_font("saira regular"); - pax_background(pax_buffer, 0xFFFFFF); - pax_noclip(pax_buffer); - pax_draw_text(pax_buffer, 0xFF000000, font, 18, 5, 240 - 18, "[A] accept [B] back"); -} - -void menu_dev(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341) { - menu_t* menu = menu_alloc("Development tools", 34, 18); - - menu->fgColor = 0xFF000000; - menu->bgColor = 0xFFFFFFFF; - menu->bgTextColor = 0xFF000000; - menu->selectedItemColor = 0xFFfec859; - menu->borderColor = 0xFFfa448c; - menu->titleColor = 0xFFfec859; - menu->titleBgColor = 0xFFfa448c; - menu->scrollbarBgColor = 0xFFCCCCCC; - menu->scrollbarFgColor = 0xFF555555; - - pax_buf_t icon_dev; - pax_decode_png_buf(&icon_dev, (void*) dev_png_start, dev_png_end - dev_png_start, PAX_BUF_32_8888ARGB, 0); - - menu_set_icon(menu, &icon_dev); - - menu_insert_item(menu, "FPGA download mode", NULL, (void*) ACTION_FPGA_DL, -1); - menu_insert_item(menu, "FPGA selftest", NULL, (void*) ACTION_FPGA_TEST, -1); - menu_insert_item(menu, "File browser (SD card)", NULL, (void*) ACTION_FILE_BROWSER, -1); - menu_insert_item(menu, "File browser (internal)", NULL, (void*) ACTION_FILE_BROWSER_INT, -1); - menu_insert_item(menu, "Animation", NULL, (void*) ACTION_ANIMATION, -1); - menu_insert_item(menu, "Button test", NULL, (void*) ACTION_BUTTON_TEST, -1); - menu_insert_item(menu, "Analog inputs", NULL, (void*) ACTION_ADC_TEST, -1); - - bool render = true; - menu_dev_action_t action = ACTION_NONE; - - render_dev_help(pax_buffer); - - while (1) { - rp2040_input_message_t buttonMessage = {0}; - if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - switch(pin) { - case RP2040_INPUT_JOYSTICK_DOWN: - if (value) { - menu_navigate_next(menu); - render = true; - } - break; - case RP2040_INPUT_JOYSTICK_UP: - if (value) { - menu_navigate_previous(menu); - render = true; - } - break; - case RP2040_INPUT_BUTTON_HOME: - case RP2040_INPUT_BUTTON_BACK: - if (value) { - action = ACTION_BACK; - } - break; - case RP2040_INPUT_BUTTON_ACCEPT: - case RP2040_INPUT_JOYSTICK_PRESS: - case RP2040_INPUT_BUTTON_SELECT: - case RP2040_INPUT_BUTTON_START: - if (value) { - action = (menu_dev_action_t) menu_get_callback_args(menu, menu_get_position(menu)); - } - break; - default: - break; - } - } - - if (render) { - menu_render(pax_buffer, menu, 0, 0, 320, 220, 0xFF491d88); - ili9341_write(ili9341, pax_buffer->buf); - render = false; - } - - if (action != ACTION_NONE) { - if (action == ACTION_FPGA_DL) { - fpga_download(buttonQueue, get_ice40(), pax_buffer, ili9341); - } else if (action == ACTION_FPGA_TEST) { - fpga_test(buttonQueue, pax_buffer, ili9341); - } else if (action == ACTION_FILE_BROWSER) { - file_browser(buttonQueue, pax_buffer, ili9341, "/sd"); - } else if (action == ACTION_FILE_BROWSER_INT) { - file_browser(buttonQueue, pax_buffer, ili9341, "/internal"); - } else if (action == ACTION_ANIMATION) { - display_animation(pax_buffer, ili9341); - } else if (action == ACTION_BUTTON_TEST) { - test_buttons(buttonQueue, pax_buffer, ili9341); - } else if (action == ACTION_ADC_TEST) { - test_adc(buttonQueue, pax_buffer, ili9341); - } else if (action == ACTION_BACK) { - break; - } - action = ACTION_NONE; - render = true; - render_dev_help(pax_buffer); - } - } - - menu_free(menu); - - pax_buf_destroy(&icon_dev); -} diff --git a/main/menus/dev.h b/main/menus/dev.h deleted file mode 100644 index 4a93d42..0000000 --- a/main/menus/dev.h +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include -#include -#include -#include "pax_gfx.h" -#include "ili9341.h" - -void menu_dev(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341); diff --git a/main/menus/launcher.c b/main/menus/launcher.c deleted file mode 100644 index b9f204e..0000000 --- a/main/menus/launcher.c +++ /dev/null @@ -1,134 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "appfs.h" -#include "ili9341.h" -#include "pax_gfx.h" -#include "pax_codecs.h" -#include "menu.h" -#include "rp2040.h" -#include "appfs_wrapper.h" - -extern const uint8_t apps_png_start[] asm("_binary_apps_png_start"); -extern const uint8_t apps_png_end[] asm("_binary_apps_png_end"); - -typedef enum { - ACTION_NONE, - ACTION_APPFS, - ACTION_BACK -} menu_launcher_action_t; - -typedef struct { - appfs_handle_t fd; - menu_launcher_action_t action; -} menu_launcher_args_t; - -void menu_launcher(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341) { - menu_t* menu = menu_alloc("Apps", 34, 18); - - menu->fgColor = 0xFF000000; - menu->bgColor = 0xFFFFFFFF; - menu->bgTextColor = 0xFFFFFFFF; - menu->selectedItemColor = 0xFFfa448c; - menu->borderColor = 0xFF491d88; - menu->titleColor = 0xFFfa448c; - menu->titleBgColor = 0xFF491d88; - menu->scrollbarBgColor = 0xFFCCCCCC; - menu->scrollbarFgColor = 0xFF555555; - - pax_buf_t icon_apps; - pax_decode_png_buf(&icon_apps, (void*) apps_png_start, apps_png_end - apps_png_start, PAX_BUF_32_8888ARGB, 0); - - menu_set_icon(menu, &icon_apps); - - const pax_font_t *font = pax_get_font("saira regular"); - - appfs_handle_t appfs_fd = APPFS_INVALID_FD; - while (1) { - appfs_fd = appfsNextEntry(appfs_fd); - if (appfs_fd == APPFS_INVALID_FD) break; - const char* name = NULL; - appfsEntryInfo(appfs_fd, &name, NULL); - menu_launcher_args_t* args = malloc(sizeof(menu_launcher_args_t)); - args->fd = appfs_fd; - args->action = ACTION_APPFS; - menu_insert_item(menu, name, NULL, (void*) args, -1); - } - - bool render = true; - menu_launcher_args_t* menuArgs = NULL; - - pax_background(pax_buffer, 0xFFFFFF); - pax_noclip(pax_buffer); - pax_draw_text(pax_buffer, 0xFF000000, font, 18, 5, 240 - 18, "[A] start app [B] back"); - - bool quit = false; - - while (1) { - rp2040_input_message_t buttonMessage = {0}; - if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - switch(pin) { - case RP2040_INPUT_JOYSTICK_DOWN: - if (value) { - menu_navigate_next(menu); - render = true; - } - break; - case RP2040_INPUT_JOYSTICK_UP: - if (value) { - menu_navigate_previous(menu); - render = true; - } - break; - case RP2040_INPUT_BUTTON_HOME: - case RP2040_INPUT_BUTTON_BACK: - if (value) { - quit = true; - } - break; - case RP2040_INPUT_BUTTON_ACCEPT: - case RP2040_INPUT_JOYSTICK_PRESS: - case RP2040_INPUT_BUTTON_SELECT: - case RP2040_INPUT_BUTTON_START: - if (value) { - menuArgs = menu_get_callback_args(menu, menu_get_position(menu)); - } - break; - default: - break; - } - } - - if (render) { - menu_render(pax_buffer, menu, 0, 0, 320, 220, 0xFF491d88); - ili9341_write(ili9341, pax_buffer->buf); - render = false; - } - - if (menuArgs != NULL) { - if (menuArgs->action == ACTION_APPFS) { - appfs_boot_app(menuArgs->fd); - } - break; - } - - if (quit) { - break; - } - } - - for (size_t index = 0; index < menu_get_length(menu); index++) { - free(menu_get_callback_args(menu, index)); - } - - menu_free(menu); - pax_buf_destroy(&icon_apps); -} diff --git a/main/menus/launcher.h b/main/menus/launcher.h deleted file mode 100644 index 993c706..0000000 --- a/main/menus/launcher.h +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include -#include -#include -#include "pax_gfx.h" -#include "ili9341.h" - -void menu_launcher(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341); diff --git a/main/menus/settings.c b/main/menus/settings.c deleted file mode 100644 index 2057e65..0000000 --- a/main/menus/settings.c +++ /dev/null @@ -1,144 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "appfs.h" -#include "ili9341.h" -#include "pax_gfx.h" -#include "pax_codecs.h" -#include "menu.h" -#include "rp2040.h" -#include "appfs_wrapper.h" -#include "hardware.h" -#include "system_wrapper.h" -#include "bootscreen.h" -#include "wifi_connect.h" -#include "wifi_ota.h" -#include "wifi.h" -#include "uninstall.h" - -extern const uint8_t settings_png_start[] asm("_binary_settings_png_start"); -extern const uint8_t settings_png_end[] asm("_binary_settings_png_end"); - -typedef enum action { - ACTION_NONE, - ACTION_BACK, - ACTION_WIFI, - ACTION_OTA, - ACTION_RP2040_BL, - ACTION_UNINSTALL -} menu_settings_action_t; - -void render_settings_help(pax_buf_t* pax_buffer) { - const pax_font_t *font = pax_get_font("saira regular"); - pax_background(pax_buffer, 0xFFFFFF); - pax_noclip(pax_buffer); - pax_draw_text(pax_buffer, 0xFF000000, font, 18, 5, 240 - 18, "[A] accept [B] back"); -} - -void menu_settings(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341) { - menu_t* menu = menu_alloc("Settings", 34, 18); - - menu->fgColor = 0xFF000000; - menu->bgColor = 0xFFFFFFFF; - menu->bgTextColor = 0xFFFFFFFF; - menu->selectedItemColor = 0xFF491d88; - menu->borderColor = 0xFF43b5a0; - menu->titleColor = 0xFF491d88; - menu->titleBgColor = 0xFF43b5a0; - menu->scrollbarBgColor = 0xFFCCCCCC; - menu->scrollbarFgColor = 0xFF555555; - - pax_buf_t icon_settings; - pax_decode_png_buf(&icon_settings, (void*) settings_png_start, settings_png_end - settings_png_start, PAX_BUF_32_8888ARGB, 0); - - menu_set_icon(menu, &icon_settings); - - menu_insert_item(menu, "WiFi configuration", NULL, (void*) ACTION_WIFI, -1); - menu_insert_item(menu, "Firmware update", NULL, (void*) ACTION_OTA, -1); - menu_insert_item(menu, "Flash RP2040 firmware", NULL, (void*) ACTION_RP2040_BL, -1); - menu_insert_item(menu, "Uninstall app", NULL, (void*) ACTION_UNINSTALL, -1); - - bool render = true; - menu_settings_action_t action = ACTION_NONE; - - render_settings_help(pax_buffer); - - while (1) { - rp2040_input_message_t buttonMessage = {0}; - if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - switch(pin) { - case RP2040_INPUT_JOYSTICK_DOWN: - if (value) { - menu_navigate_next(menu); - render = true; - } - break; - case RP2040_INPUT_JOYSTICK_UP: - if (value) { - menu_navigate_previous(menu); - render = true; - } - break; - case RP2040_INPUT_BUTTON_HOME: - case RP2040_INPUT_BUTTON_BACK: - if (value) { - action = ACTION_BACK; - } - break; - case RP2040_INPUT_BUTTON_ACCEPT: - case RP2040_INPUT_JOYSTICK_PRESS: - case RP2040_INPUT_BUTTON_SELECT: - case RP2040_INPUT_BUTTON_START: - if (value) { - action = (menu_settings_action_t) menu_get_callback_args(menu, menu_get_position(menu)); - } - break; - default: - break; - } - } - - if (render) { - menu_render(pax_buffer, menu, 0, 0, 320, 220, 0xFF491d88); - ili9341_write(ili9341, pax_buffer->buf); - render = false; - } - - if (action != ACTION_NONE) { - if (action == ACTION_RP2040_BL) { - display_boot_screen(pax_buffer, ili9341, "Please wait..."); - rp2040_reboot_to_bootloader(get_rp2040()); - esp_restart(); - } else if (action == ACTION_OTA) { - display_boot_screen(pax_buffer, ili9341, "Connecting to WiFi..."); - if (wifi_connect_to_stored()) { - display_boot_screen(pax_buffer, ili9341, "Starting firmware update..."); - ota_update(pax_buffer, ili9341); - } else { - display_boot_screen(pax_buffer, ili9341, "Failed to connect to WiFi"); - vTaskDelay(500 / portTICK_PERIOD_MS); - } - } else if (action == ACTION_WIFI) { - menu_wifi(buttonQueue, pax_buffer, ili9341); - } else if (action == ACTION_UNINSTALL) { - uninstall_browser(buttonQueue, pax_buffer, ili9341); - } else if (action == ACTION_BACK) { - break; - } - render = true; - action = ACTION_NONE; - render_settings_help(pax_buffer); - } - } - - menu_free(menu); - pax_buf_destroy(&icon_settings); -} diff --git a/main/menus/settings.h b/main/menus/settings.h deleted file mode 100644 index baedbc1..0000000 --- a/main/menus/settings.h +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include -#include -#include -#include "pax_gfx.h" -#include "ili9341.h" - -void menu_settings(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341); diff --git a/main/menus/start.c b/main/menus/start.c deleted file mode 100644 index ce2b703..0000000 --- a/main/menus/start.c +++ /dev/null @@ -1,186 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "appfs.h" -#include "ili9341.h" -#include "pax_gfx.h" -#include "pax_codecs.h" -#include "menu.h" -#include "rp2040.h" -#include "launcher.h" -#include "settings.h" -#include "dev.h" -#include "bootscreen.h" -#include "hardware.h" -#include "math.h" - -extern const uint8_t home_png_start[] asm("_binary_home_png_start"); -extern const uint8_t home_png_end[] asm("_binary_home_png_end"); - -extern const uint8_t apps_png_start[] asm("_binary_apps_png_start"); -extern const uint8_t apps_png_end[] asm("_binary_apps_png_end"); - -extern const uint8_t hatchery_png_start[] asm("_binary_hatchery_png_start"); -extern const uint8_t hatchery_png_end[] asm("_binary_hatchery_png_end"); - -extern const uint8_t dev_png_start[] asm("_binary_dev_png_start"); -extern const uint8_t dev_png_end[] asm("_binary_dev_png_end"); - -extern const uint8_t settings_png_start[] asm("_binary_settings_png_start"); -extern const uint8_t settings_png_end[] asm("_binary_settings_png_end"); - -typedef enum action { - ACTION_NONE, - ACTION_APPS, - ACTION_HATCHERY, - ACTION_DEV, - ACTION_SETTINGS -} menu_start_action_t; - -void render_start_help(pax_buf_t* pax_buffer, const char* text) { - const pax_font_t *font = pax_get_font("saira regular"); - pax_background(pax_buffer, 0xFFFFFF); - pax_noclip(pax_buffer); - pax_draw_text(pax_buffer, 0xFF491d88, font, 18, 5, 240 - 18, "[A] accept"); - pax_vec1_t version_size = pax_text_size(font, 18, text); - pax_draw_text(pax_buffer, 0xFF491d88, font, 18, 320 - 5 - version_size.x, 240 - 18, text); -} - -void menu_start(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341, const char* version) { - menu_t* menu = menu_alloc("Main menu", 34, 18); - - menu->fgColor = 0xFF000000; - menu->bgColor = 0xFFFFFFFF; - menu->bgTextColor = 0xFF000000; - menu->selectedItemColor = 0xFFfec859; - menu->borderColor = 0xFF491d88; - menu->titleColor = 0xFFfec859; - menu->titleBgColor = 0xFF491d88; - menu->scrollbarBgColor = 0xFFCCCCCC; - menu->scrollbarFgColor = 0xFF555555; - - pax_buf_t icon_home; - pax_decode_png_buf(&icon_home, (void*) home_png_start, home_png_end - home_png_start, PAX_BUF_32_8888ARGB, 0); - pax_buf_t icon_apps; - pax_decode_png_buf(&icon_apps, (void*) apps_png_start, apps_png_end - apps_png_start, PAX_BUF_32_8888ARGB, 0); - pax_buf_t icon_hatchery; - pax_decode_png_buf(&icon_hatchery, (void*) hatchery_png_start, hatchery_png_end - hatchery_png_start, PAX_BUF_32_8888ARGB, 0); - pax_buf_t icon_dev; - pax_decode_png_buf(&icon_dev, (void*) dev_png_start, dev_png_end - dev_png_start, PAX_BUF_32_8888ARGB, 0); - pax_buf_t icon_settings; - pax_decode_png_buf(&icon_settings, (void*) settings_png_start, settings_png_end - settings_png_start, PAX_BUF_32_8888ARGB, 0); - - menu_set_icon(menu, &icon_home); - - menu_insert_item_icon(menu, "Apps", NULL, (void*) ACTION_APPS, -1, &icon_apps); - menu_insert_item_icon(menu, "Hatchery", NULL, (void*) ACTION_HATCHERY, -1, &icon_hatchery); - menu_insert_item_icon(menu, "Development tools", NULL, (void*) ACTION_DEV, -1, &icon_dev); - menu_insert_item_icon(menu, "Settings", NULL, (void*) ACTION_SETTINGS, -1, &icon_settings); - - - bool render = true; - menu_start_action_t action = ACTION_NONE; - - uint8_t analogReadTimer = 0; - float battery_voltage = 0; - float usb_voltage = 0; - //uint8_t rp2040_usb = 0; - - // Calculated: - uint8_t battery_percent = 0; - bool battery_charging = false; - - RP2040* rp2040 = get_rp2040(); - - while (1) { - rp2040_input_message_t buttonMessage = {0}; - if (xQueueReceive(buttonQueue, &buttonMessage, 100 / portTICK_PERIOD_MS) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - switch(pin) { - case RP2040_INPUT_JOYSTICK_DOWN: - if (value) { - menu_navigate_next(menu); - render = true; - } - break; - case RP2040_INPUT_JOYSTICK_UP: - if (value) { - menu_navigate_previous(menu); - render = true; - } - break; - case RP2040_INPUT_BUTTON_ACCEPT: - case RP2040_INPUT_JOYSTICK_PRESS: - case RP2040_INPUT_BUTTON_SELECT: - case RP2040_INPUT_BUTTON_START: - if (value) { - action = (menu_start_action_t) menu_get_callback_args(menu, menu_get_position(menu)); - } - break; - default: - break; - } - } - - if (analogReadTimer > 0) { - analogReadTimer--; - } else { - analogReadTimer = 10; // No need to update these values really quickly - if (rp2040_read_vbat(rp2040, &battery_voltage) != ESP_OK) { - battery_voltage = 0; - } - if (rp2040_read_vusb(rp2040, &usb_voltage) != ESP_OK) { - usb_voltage = 0; - } - - if (battery_voltage >= 3.6) { - battery_percent = ((battery_voltage - 3.6) * 100) / (4.2 - 3.6); - if (battery_percent > 100) battery_percent = 100; - } else { - battery_percent = 0; - } - - battery_charging = (usb_voltage > 4.0) && (battery_percent < 100); - - render = true; - } - - if (render) { - char textBuffer[64]; - snprintf(textBuffer, sizeof(textBuffer), "B%1.1fv U%1.1fv %03u%%%c v%s", battery_voltage, usb_voltage, battery_percent, battery_charging ? '+' : ' ', version); - render_start_help(pax_buffer, textBuffer); - menu_render(pax_buffer, menu, 0, 0, 320, 220, 0xFF491d88); - ili9341_write(ili9341, pax_buffer->buf); - render = false; - } - - if (action != ACTION_NONE) { - if (action == ACTION_APPS) { - menu_launcher(buttonQueue, pax_buffer, ili9341); - } else if (action == ACTION_HATCHERY) { - // Not implemented - display_boot_screen(pax_buffer, ili9341, "Not implemented"); - } else if (action == ACTION_SETTINGS) { - menu_settings(buttonQueue, pax_buffer, ili9341); - } else if (action == ACTION_DEV) { - menu_dev(buttonQueue, pax_buffer, ili9341); - } - action = ACTION_NONE; - render = true; - } - } - - menu_free(menu); - pax_buf_destroy(&icon_home); - pax_buf_destroy(&icon_apps); - pax_buf_destroy(&icon_hatchery); - pax_buf_destroy(&icon_dev); - pax_buf_destroy(&icon_settings); -} diff --git a/main/menus/start.h b/main/menus/start.h deleted file mode 100644 index 88c8ab7..0000000 --- a/main/menus/start.h +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include -#include -#include -#include "pax_gfx.h" -#include "ili9341.h" - -void menu_start(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341, const char* version); diff --git a/main/menus/wifi.c b/main/menus/wifi.c deleted file mode 100644 index d612074..0000000 --- a/main/menus/wifi.c +++ /dev/null @@ -1,535 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "appfs.h" -#include "ili9341.h" -#include "pax_gfx.h" -#include "menu.h" -#include "rp2040.h" -#include "appfs_wrapper.h" -#include "hardware.h" -#include "system_wrapper.h" -#include "bootscreen.h" -#include "wifi_connect.h" -#include "wifi_connection.h" -#include "wifi_ota.h" -#include "graphics_wrapper.h" - -static const char *TAG = "wifi menu"; - -typedef enum action { - /* ==== GENERIC ACTIONS ==== */ - // Nothing happens. - ACTION_NONE, - // Go back to the parent menu. - ACTION_BACK, - - /* ==== MAIN MENU ACTIONS ==== */ - // Show the current WiFi settings. - ACTION_SHOW, - // Scan for networks and pick one to connect to. - ACTION_SCAN, - // Manually edit the current WiFi settings. - ACTION_MANUAL, - - /* ==== AUTH MODES ==== */ - ACTION_AUTH_OPEN, - ACTION_AUTH_WEP, - ACTION_AUTH_WPA_PSK, - ACTION_AUTH_WPA2_PSK, - ACTION_AUTH_WPA_WPA2_PSK, - ACTION_AUTH_WPA2_ENTERPRISE, - ACTION_AUTH_WPA3_PSK, - ACTION_AUTH_WPA2_WPA3_PSK, - ACTION_AUTH_WAPI_PSK, - - /* ==== PHASE2 AUTH MODES ==== */ - ACTION_PHASE2_EAP, - ACTION_PHASE2_MSCHAPV2, - ACTION_PHASE2_MSCHAP, - ACTION_PHASE2_PAP, - ACTION_PHASE2_CHAP, -} menu_wifi_action_t; - -void render_wifi_help(pax_buf_t* pax_buffer) { - const pax_font_t *font = pax_get_font("saira regular"); - pax_background(pax_buffer, 0xFFFFFF); - pax_noclip(pax_buffer); - pax_draw_text(pax_buffer, 0xFF000000, font, 18, 5, 240 - 18, "[A] accept [B] back"); -} - -void wifi_show(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341); -void wifi_setup(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341, bool scan); -wifi_ap_record_t *wifi_scan_results(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341, size_t num_aps, wifi_ap_record_t *aps); -int wifi_auth_menu(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341, wifi_auth_mode_t default_mode); -int wifi_phase2_menu(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341, esp_eap_ttls_phase2_types default_mode); - -void menu_wifi(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341) { - menu_t* menu = menu_alloc("WiFi configuration", 34, 18); - menu_insert_item(menu, "Show current settings", NULL, (void*) ACTION_SHOW, -1); - menu_insert_item(menu, "Scan for networks", NULL, (void*) ACTION_SCAN, -1); - menu_insert_item(menu, "Configure manually", NULL, (void*) ACTION_MANUAL, -1); - - bool render = true; - menu_wifi_action_t action = ACTION_NONE; - - render_wifi_help(pax_buffer); - - while (1) { - rp2040_input_message_t buttonMessage = {0}; - if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - switch(pin) { - case RP2040_INPUT_JOYSTICK_DOWN: - if (value) { - menu_navigate_next(menu); - render = true; - } - break; - case RP2040_INPUT_JOYSTICK_UP: - if (value) { - menu_navigate_previous(menu); - render = true; - } - break; - case RP2040_INPUT_BUTTON_HOME: - case RP2040_INPUT_BUTTON_BACK: - if (value) { - action = ACTION_BACK; - } - break; - case RP2040_INPUT_BUTTON_ACCEPT: - case RP2040_INPUT_JOYSTICK_PRESS: - case RP2040_INPUT_BUTTON_SELECT: - case RP2040_INPUT_BUTTON_START: - if (value) { - action = (menu_wifi_action_t) menu_get_callback_args(menu, menu_get_position(menu)); - } - break; - default: - break; - } - } - - if (render) { - menu_render(pax_buffer, menu, 0, 0, 320, 220, 0xFF491d88); - ili9341_write(ili9341, pax_buffer->buf); - render = false; - } - - if (action != ACTION_NONE) { - if (action == ACTION_SHOW) { - wifi_show(buttonQueue, pax_buffer, ili9341); - } else if (action == ACTION_SCAN) { - wifi_setup(buttonQueue, pax_buffer, ili9341, true); - } else if (action == ACTION_MANUAL) { - wifi_setup(buttonQueue, pax_buffer, ili9341, false); - } else if (action == ACTION_BACK) { - break; - } - render = true; - action = ACTION_NONE; - render_wifi_help(pax_buffer); - } - } - - menu_free(menu); -} - -void wifi_show(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341) { - nvs_handle_t handle; - - nvs_open("system", NVS_READWRITE, &handle); - char ssid[33] = ""; - char password[33] = ""; - size_t requiredSize; - - esp_err_t res = nvs_get_str(handle, "wifi.ssid", NULL, &requiredSize); - if ((res == ESP_OK) && (requiredSize < sizeof(ssid))) { - res = nvs_get_str(handle, "wifi.ssid", ssid, &requiredSize); - } - - res = nvs_get_str(handle, "wifi.password", NULL, &requiredSize); - if ((res == ESP_OK) && (requiredSize < sizeof(password))) { - res = nvs_get_str(handle, "wifi.password", password, &requiredSize); - } - - nvs_close(handle); - - char buffer[300]; - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xFFFFFF); - snprintf(buffer, sizeof(buffer), "WiFi SSID:\n%s\nWiFi password:\n%s", ssid, password); - pax_draw_text(pax_buffer, 0xFF000000, NULL, 18, 0, 0, buffer); - ili9341_write(ili9341, pax_buffer->buf); - - bool quit = false; - while (!quit) { - rp2040_input_message_t buttonMessage = {0}; - if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - switch(pin) { - case RP2040_INPUT_BUTTON_HOME: - case RP2040_INPUT_BUTTON_BACK: - case RP2040_INPUT_BUTTON_ACCEPT: - case RP2040_INPUT_JOYSTICK_PRESS: - case RP2040_INPUT_BUTTON_SELECT: - case RP2040_INPUT_BUTTON_START: - if (value) quit = true; - break; - default: - break; - } - } - } -} - -wifi_ap_record_t *wifi_scan_results(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341, size_t num_aps, wifi_ap_record_t *aps) { - menu_t *menu = menu_alloc("Select network", 20, 18); - wifi_ap_record_t *picked = NULL; - - render_wifi_help(pax_buffer); - - for (size_t i = 0; i < num_aps; i++) { - menu_insert_item(menu, (const char*) aps[i].ssid, NULL, (void *) (i + 1), -1); - } - - bool render = true; - size_t selection = 0; - while (1) { - rp2040_input_message_t buttonMessage = {0}; - selection = -1; - if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - switch(pin) { - case RP2040_INPUT_JOYSTICK_DOWN: - if (value) { - menu_navigate_next(menu); - render = true; - } - break; - case RP2040_INPUT_JOYSTICK_UP: - if (value) { - menu_navigate_previous(menu); - render = true; - } - break; - case RP2040_INPUT_BUTTON_HOME: - case RP2040_INPUT_BUTTON_BACK: - if (value) { - selection = 0; - } - break; - case RP2040_INPUT_BUTTON_ACCEPT: - case RP2040_INPUT_JOYSTICK_PRESS: - case RP2040_INPUT_BUTTON_SELECT: - case RP2040_INPUT_BUTTON_START: - if (value) { - selection = (size_t) menu_get_callback_args(menu, menu_get_position(menu)); - } - break; - default: - break; - } - } - - if (render) { - menu_render(pax_buffer, menu, 0, 0, 320, 220, 0xFF2f55a8); - ili9341_write(ili9341, pax_buffer->buf); - render = false; - } - - if (selection != (size_t) -1) { - if (selection == 0) { - break; - } else { - // You picked one, yay! - picked = &aps[selection-1]; - break; - } - render = true; - selection = -1; - render_wifi_help(pax_buffer); - } - } - - menu_free(menu); - return picked; -} - -int wifi_auth_menu(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341, wifi_auth_mode_t default_mode) { - menu_t* menu = menu_alloc("Authentication mode", 20, 18); - menu_insert_item(menu, "Insecure", NULL, (void*) ACTION_AUTH_OPEN, -1); - menu_insert_item(menu, "WEP", NULL, (void*) ACTION_AUTH_WEP, -1); - menu_insert_item(menu, "WPA PSK", NULL, (void*) ACTION_AUTH_WPA_PSK, -1); - menu_insert_item(menu, "WPA2 PSK", NULL, (void*) ACTION_AUTH_WPA2_PSK, -1); - // menu_insert_item(menu, "QQQQQQQQQQQQ", NULL, (void*) ACTION_AUTH_WPA_WPA2_PSK, -1); - menu_insert_item(menu, "WPA2 Enterprise", NULL, (void*) ACTION_AUTH_WPA2_ENTERPRISE, -1); - menu_insert_item(menu, "WPA3 PSK", NULL, (void*) ACTION_AUTH_WPA3_PSK, -1); - // menu_insert_item(menu, "QQQQQQQQQQQQ", NULL, (void*) ACTION_AUTH_WPA2_WPA3_PSK, -1); - // menu_insert_item(menu, "WAPI PSK", NULL, (void*) ACTION_AUTH_WAPI_PSK, -1); - - bool render = true; - menu_wifi_action_t action = ACTION_NONE; - wifi_auth_mode_t pick = default_mode; - - render_wifi_help(pax_buffer); - - while (1) { - rp2040_input_message_t buttonMessage = {0}; - if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - switch(pin) { - case RP2040_INPUT_JOYSTICK_DOWN: - if (value) { - menu_navigate_next(menu); - render = true; - } - break; - case RP2040_INPUT_JOYSTICK_UP: - if (value) { - menu_navigate_previous(menu); - render = true; - } - break; - case RP2040_INPUT_BUTTON_HOME: - case RP2040_INPUT_BUTTON_BACK: - if (value) { - action = ACTION_BACK; - } - break; - case RP2040_INPUT_BUTTON_ACCEPT: - case RP2040_INPUT_JOYSTICK_PRESS: - case RP2040_INPUT_BUTTON_SELECT: - case RP2040_INPUT_BUTTON_START: - if (value) { - action = (menu_wifi_action_t) menu_get_callback_args(menu, menu_get_position(menu)); - } - break; - default: - break; - } - } - - if (render) { - menu_render(pax_buffer, menu, 0, 0, 320, 220, 0xFF2f55a8); - ili9341_write(ili9341, pax_buffer->buf); - render = false; - } - - if (action != ACTION_NONE) { - if (action == ACTION_BACK) { - break; - } else { - pick = (wifi_auth_mode_t) (action - ACTION_AUTH_OPEN); - break; - } - render = true; - action = ACTION_NONE; - render_wifi_help(pax_buffer); - } - } - - menu_free(menu); - return pick; -} - -int wifi_phase2_menu(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341, esp_eap_ttls_phase2_types default_mode) { - menu_t* menu = menu_alloc("Phase 2 authentication mode", 20, 18); - menu_insert_item(menu, "ESP", NULL, (void*) ACTION_PHASE2_EAP, -1); - menu_insert_item(menu, "MSCHAPv2", NULL, (void*) ACTION_PHASE2_MSCHAPV2, -1); - menu_insert_item(menu, "MSCHAP", NULL, (void*) ACTION_PHASE2_MSCHAP, -1); - menu_insert_item(menu, "PAP", NULL, (void*) ACTION_PHASE2_PAP, -1); - menu_insert_item(menu, "CHAP", NULL, (void*) ACTION_PHASE2_CHAP, -1); - - bool render = true; - menu_wifi_action_t action = ACTION_NONE; - esp_eap_ttls_phase2_types pick = default_mode; - - render_wifi_help(pax_buffer); - - while (1) { - rp2040_input_message_t buttonMessage = {0}; - if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - switch(pin) { - case RP2040_INPUT_JOYSTICK_DOWN: - if (value) { - menu_navigate_next(menu); - render = true; - } - break; - case RP2040_INPUT_JOYSTICK_UP: - if (value) { - menu_navigate_previous(menu); - render = true; - } - break; - case RP2040_INPUT_BUTTON_HOME: - case RP2040_INPUT_BUTTON_BACK: - if (value) { - action = ACTION_BACK; - } - break; - case RP2040_INPUT_BUTTON_ACCEPT: - case RP2040_INPUT_JOYSTICK_PRESS: - case RP2040_INPUT_BUTTON_SELECT: - case RP2040_INPUT_BUTTON_START: - if (value) { - action = (menu_wifi_action_t) menu_get_callback_args(menu, menu_get_position(menu)); - } - break; - default: - break; - } - } - - if (render) { - menu_render(pax_buffer, menu, 0, 0, 320, 220, 0xFF2f55a8); - ili9341_write(ili9341, pax_buffer->buf); - render = false; - } - - if (action != ACTION_NONE) { - if (action == ACTION_BACK) { - break; - } else { - pick = (wifi_auth_mode_t) (action - ACTION_PHASE2_EAP); - break; - } - render = true; - action = ACTION_NONE; - render_wifi_help(pax_buffer); - } - } - - menu_free(menu); - return pick; -} - -// Sorts WiFi APs by RSSI (best RSSI first in the list). -static int wifi_ap_sorter(const void *a0, const void *b0) { - const wifi_ap_record_t *a = a0; - const wifi_ap_record_t *b = b0; - return b->rssi - a->rssi; -} - -void wifi_setup(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341, bool scan) { - - char ssid[33] = {0}; - char username[33] = {0}; - char password[33] = {0}; - nvs_handle_t handle; - nvs_open("system", NVS_READWRITE, &handle); - bool accepted = true; - wifi_auth_mode_t authmode = WIFI_AUTH_WPA2_PSK; - esp_eap_ttls_phase2_types phase2 = ESP_EAP_TTLS_PHASE2_EAP; - - /* ==== scanning phase ==== */ - if (scan) { - // Show a little bit of text. - display_boot_screen(pax_buffer, ili9341, "Scanning WiFi networks..."); - - // Scan for networks. - wifi_ap_record_t *aps; - size_t n_aps = wifi_scan(&aps); - - // Sort them by RSSI. - qsort(aps, n_aps, sizeof(wifi_ap_record_t), wifi_ap_sorter); - - // Make a de-duplicated list. - wifi_ap_record_t *dedup = malloc(sizeof(wifi_ap_record_t) * n_aps); - size_t n_dedup = 0; - for (size_t i = 0; i < n_aps; ) { - for (size_t x = 0; x < n_dedup; x++) { - if (!strcmp((const char *) aps[i].ssid, (const char *) dedup[x].ssid)) goto cont; - } - dedup[n_dedup] = aps[i]; - n_dedup ++; - cont: - i++; - } - - // Open a little menu for picking a network. - wifi_ap_record_t *pick = wifi_scan_results(buttonQueue, pax_buffer, ili9341, n_dedup, dedup); - if (!pick) { - nvs_close(handle); - return; - } - // Copy the SSID in. - memcpy(ssid, pick->ssid, 33); - authmode = pick->authmode; - - // Free memories. - free(aps); - free(dedup); - } else { - size_t requiredSize; - esp_err_t res = nvs_get_str(handle, "wifi.ssid", NULL, &requiredSize); - if (res != ESP_OK) { - strcpy(ssid, ""); - strcpy(password, ""); - } else if (requiredSize < sizeof(ssid)) { - res = nvs_get_str(handle, "wifi.ssid", ssid, &requiredSize); - if (res != ESP_OK) strcpy(ssid, ""); - res = nvs_get_str(handle, "wifi.password", NULL, &requiredSize); - if (res != ESP_OK) { - strcpy(password, ""); - } else if (requiredSize < sizeof(password)) { - res = nvs_get_str(handle, "wifi.password", password, &requiredSize); - if (res != ESP_OK) strcpy(password, ""); - } - } - - // Select SSID. - accepted = keyboard(buttonQueue, pax_buffer, ili9341, 30, 30, pax_buffer->width - 60, pax_buffer->height - 60, "WiFi SSID", "Press HOME to cancel", ssid, sizeof(ssid)); - - // Select auth mode. - if (accepted) { - authmode = wifi_auth_menu(buttonQueue, pax_buffer, ili9341, -1); - accepted = authmode != -1; - } - } - - /* ==== manual entering phase ==== */ - if (authmode == WIFI_AUTH_WPA2_ENTERPRISE) { - if (accepted) { - // Phase2 method. - phase2 = wifi_phase2_menu(buttonQueue, pax_buffer, ili9341, -1); - accepted = phase2 != -1; - } - if (accepted) { - // Username. - accepted = keyboard(buttonQueue, pax_buffer, ili9341, 30, 30, pax_buffer->width - 60, pax_buffer->height - 60, "WiFi username", "Press HOME to cancel", username, sizeof(username)); - } - } - if (accepted) { - // Password. - accepted = keyboard(buttonQueue, pax_buffer, ili9341, 30, 30, pax_buffer->width - 60, pax_buffer->height - 60, "WiFi password", "Press HOME to cancel", password, sizeof(password)); - } - if (accepted) { - nvs_set_str(handle, "wifi.ssid", ssid); - nvs_set_str(handle, "wifi.password", password); - nvs_set_u8 (handle, "wifi.authmode", authmode); - if (authmode == WIFI_AUTH_WPA2_ENTERPRISE) { - nvs_set_str(handle, "wifi.username", username); - nvs_set_u8 (handle, "wifi.phase2", phase2); - } - display_boot_screen(pax_buffer, ili9341, "WiFi settings stored"); - } - nvs_close(handle); -} - diff --git a/main/menus/wifi.h b/main/menus/wifi.h deleted file mode 100644 index fa5d71c..0000000 --- a/main/menus/wifi.h +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include -#include -#include -#include "pax_gfx.h" -#include "ili9341.h" - -void menu_wifi(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341); diff --git a/main/rp2040_updater.c b/main/rp2040_updater.c deleted file mode 100644 index 41b8896..0000000 --- a/main/rp2040_updater.c +++ /dev/null @@ -1,219 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "driver/uart.h" -#include "hardware.h" -#include "managed_i2c.h" -#include "pax_gfx.h" -#include "rp2040.h" -#include "rp2040bl.h" -#include "system_wrapper.h" -#include "graphics_wrapper.h" -#include "esp32/rom/crc.h" - -extern const uint8_t rp2040_firmware_bin_start[] asm("_binary_rp2040_firmware_bin_start"); -extern const uint8_t rp2040_firmware_bin_end[] asm("_binary_rp2040_firmware_bin_end"); - -void display_rp2040_update_state(pax_buf_t* pax_buffer, ILI9341* ili9341, const char* text) { - pax_noclip(pax_buffer); - const pax_font_t* font = pax_get_font("sky mono"); - pax_background(pax_buffer, 0xFFFFFF); - pax_vec1_t title_size = pax_text_size(font, 18, "Co-processor update"); - pax_draw_text(pax_buffer, 0xFF000000, font, 18, (320 / 2) - (title_size.x / 2), 120 - 30, "Co-processor update"); - pax_vec1_t size = pax_text_size(font, 18, text); - pax_draw_text(pax_buffer, 0xFF000000, font, 18, (320 / 2) - (size.x / 2), 120 + 10, text); - ili9341_write(ili9341, pax_buffer->buf); -} - -void rp2040_updater(RP2040* rp2040, pax_buf_t* pax_buffer, ILI9341* ili9341) { - size_t firmware_size = rp2040_firmware_bin_end - rp2040_firmware_bin_start; - char message[64]; - - uint8_t fw_version; - if (rp2040_get_firmware_version(rp2040, &fw_version) != ESP_OK) { - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xa85a32); - snprintf(message, sizeof(message) - 1, "RP2040 error"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, message); - snprintf(message, sizeof(message) - 1, "Failed to read firmware version"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 13, 0, 20*1, message); - ili9341_write(ili9341, pax_buffer->buf); - restart(); - } - - if (fw_version < 0x03) { // Update required - display_rp2040_update_state(pax_buffer, ili9341, "Starting bootloader..."); - rp2040_reboot_to_bootloader(rp2040); - esp_restart(); - } - - if (fw_version == 0xFF) { // RP2040 is in bootloader mode - display_rp2040_update_state(pax_buffer, ili9341, "Starting update..."); - - uint8_t bl_version; - if (rp2040_get_bootloader_version(rp2040, &bl_version) != ESP_OK) { - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xa85a32); - snprintf(message, sizeof(message) - 1, "RP2040 update failed"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, message); - snprintf(message, sizeof(message) - 1, "Communication error (1)"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 13, 0, 20*1, message); - ili9341_write(ili9341, pax_buffer->buf); - restart(); - } - if (bl_version != 0x01) { - pax_background(pax_buffer, 0xa85a32); - snprintf(message, sizeof(message) - 1, "RP2040 update failed"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, message); - snprintf(message, sizeof(message) - 1, "Unsupported bootloader version"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 13, 0, 20*1, message); - ili9341_write(ili9341, pax_buffer->buf); - restart(); - } - - rp2040_bl_install_uart(); - - display_rp2040_update_state(pax_buffer, ili9341, "Preparing..."); - - while (true) { - vTaskDelay(1 / portTICK_PERIOD_MS); - uint8_t bl_state; - if (rp2040_get_bootloader_state(rp2040, &bl_state) != ESP_OK) { - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xa85a32); - snprintf(message, sizeof(message) - 1, "RP2040 update failed"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, message); - snprintf(message, sizeof(message) - 1, "Communication error (2)"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 13, 0, 20*1, message); - ili9341_write(ili9341, pax_buffer->buf); - restart(); - } - if (bl_state == 0xB0) { - break; - } - if (bl_state > 0xB0) { - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xa85a32); - snprintf(message, sizeof(message) - 1, "RP2040 update failed"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, message); - snprintf(message, sizeof(message) - 1, "Unknown bootloader state"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 13, 0, 20*1, message); - ili9341_write(ili9341, pax_buffer->buf); - restart(); - } - } - - display_rp2040_update_state(pax_buffer, ili9341, "Synchronizing..."); - - while (true) { - if (rp2040_bl_sync()) break; - vTaskDelay(100 / portTICK_PERIOD_MS); - } - - uint32_t flash_start = 0, flash_size = 0, erase_size = 0, write_size = 0, max_data_len = 0; - - bool success = rp2040_bl_get_info(&flash_start, &flash_size, &erase_size, &write_size, &max_data_len); - - if (!success) { - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xa85a32); - snprintf(message, sizeof(message) - 1, "RP2040 update failed"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, message); - snprintf(message, sizeof(message) - 1, "Failed to read information"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 13, 0, 20*1, message); - ili9341_write(ili9341, pax_buffer->buf); - restart(); - } - - display_rp2040_update_state(pax_buffer, ili9341, "Erasing..."); - - uint32_t erase_length = firmware_size; - erase_length = erase_length + erase_size - (erase_length % erase_size); // Round up to erase size - - if (erase_length > flash_size - erase_size) { - erase_length = flash_size - erase_size; - } - - bool eraseSuccess = rp2040_bl_erase(flash_start, flash_size - erase_size);//erase_length); < erase whole flash as workaround for a yet to be fixed bug in the calculation of erase_length - - if (!eraseSuccess) { - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xa85a32); - snprintf(message, sizeof(message) - 1, "RP2040 update failed"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, message); - snprintf(message, sizeof(message) - 1, "Failed to erase flash"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 13, 0, 20*1, message); - ili9341_write(ili9341, pax_buffer->buf); - vTaskDelay(1000 / portTICK_PERIOD_MS); - restart(); - } - - uint32_t position = 0; - uint32_t txSize = write_size; - uint8_t* txBuffer = malloc(write_size); - - uint32_t blockCrc = 0; - uint32_t totalCrc = 0; - uint32_t totalLength = 0; - - while (true) { - if ((firmware_size - position) < txSize) { - txSize = firmware_size - position; - } - - if (txSize == 0) break; - - uint8_t percentage = position * 100 / firmware_size; - - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0x325aa8); - snprintf(message, sizeof(message) - 1, "Writing... %u%%", percentage); - display_rp2040_update_state(pax_buffer, ili9341, message); - - uint32_t checkCrc = 0; - memset(txBuffer, 0, write_size); - memcpy(txBuffer, &rp2040_firmware_bin_start[position], txSize); - blockCrc = crc32_le(0, txBuffer, write_size); - totalCrc = crc32_le(totalCrc, txBuffer, write_size); - totalLength += write_size; - bool writeSuccess = rp2040_bl_write(0x10010000 + position, write_size, txBuffer, &checkCrc); - if (writeSuccess && (blockCrc == checkCrc)) { - position += txSize; - } else { - display_rp2040_update_state(pax_buffer, ili9341, "CRC mismatch"); - while (!rp2040_bl_sync()) { - vTaskDelay(20 / portTICK_PERIOD_MS); - } - } - } - - free(txBuffer); - - display_rp2040_update_state(pax_buffer, ili9341, "Finalizing..."); - - bool sealRes = rp2040_bl_seal(0x10010000, 0x10010000, totalLength, totalCrc); - - if (sealRes) { - vTaskDelay(2000 / portTICK_PERIOD_MS); - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0xCCCCCC); - memset(message, 0, sizeof(message)); - display_rp2040_update_state(pax_buffer, ili9341, "Update completed"); - rp2040_bl_go(0x10010000); - } else { - display_rp2040_update_state(pax_buffer, ili9341, "Update failed"); - vTaskDelay(1000 / portTICK_PERIOD_MS); - restart(); - } - - while (true) { - vTaskDelay(1000 / portTICK_PERIOD_MS); - } - } -} diff --git a/main/settings.c b/main/settings.c deleted file mode 100644 index 5d2eff1..0000000 --- a/main/settings.c +++ /dev/null @@ -1,84 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "ili9341.h" -#include "ice40.h" -#include "hardware.h" - -static const char *TAG = "settings"; - -esp_err_t nvs_init() { - const esp_partition_t * nvs_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL); - if (nvs_partition == NULL) return ESP_FAIL; - esp_err_t res = nvs_flash_init(); - if (res != ESP_OK) { - res = esp_partition_erase_range(nvs_partition, 0, nvs_partition->size); - if (res != ESP_OK) return res; - res = nvs_flash_init(); - if (res != ESP_OK) return res; - } - return ESP_OK; -} - -esp_err_t nvs_get_str_fixed(const char* nvs_namespace, const char* key, char* target, size_t target_size, size_t* size) { - nvs_handle_t handle; - esp_err_t res; - - res = nvs_open(nvs_namespace, NVS_READWRITE, &handle); - if (res != ESP_OK) return res; - - size_t required_size; - res = nvs_get_str(handle, key, NULL, &required_size); - if (res != ESP_OK) { - nvs_close(handle); - return res; - } - - if (required_size > target_size) { - nvs_close(handle); - return ESP_FAIL; - } - - res = nvs_get_str(handle, key, target, &required_size); - - if (size != NULL) *size = required_size; - - nvs_close(handle); - - return res; -} - -uint8_t nvs_get_u8_default(const char* nvs_namespace, const char* key, uint8_t default_value) { - nvs_handle_t handle; - esp_err_t res; - - res = nvs_open(nvs_namespace, NVS_READWRITE, &handle); - if (res != ESP_OK) return default_value; - - uint8_t target; - res = nvs_get_u8(handle, key, &target); - if (res != ESP_OK) { - nvs_close(handle); - return default_value; - } - - nvs_close(handle); - return target; -} - -esp_err_t nvs_set_u8_fixed(const char* nvs_namespace, const char* key, uint8_t value) { - nvs_handle_t handle; - esp_err_t res; - - res = nvs_open(nvs_namespace, NVS_READWRITE, &handle); - if (res != ESP_OK) return res; - - res = nvs_set_u8(handle, key, value); - nvs_close(handle); - - return res; -} diff --git a/main/system_wrapper.c b/main/system_wrapper.c deleted file mode 100644 index 30080ca..0000000 --- a/main/system_wrapper.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "system_wrapper.h" - -void restart() { - /*for (int i = 3; i >= 0; i--) { - printf("Restarting in %d seconds...\n", i); - vTaskDelay(1000 / portTICK_PERIOD_MS); - } - printf("Restarting now.\n");*/ - vTaskDelay(1000 / portTICK_PERIOD_MS); - fflush(stdout); - esp_restart(); -} diff --git a/main/test_common.c b/main/test_common.c deleted file mode 100644 index c074816..0000000 --- a/main/test_common.c +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "hardware.h" -#include "ili9341.h" -#include "ice40.h" -#include "rp2040.h" -#include "pax_gfx.h" - -typedef bool (*test_fn)(uint32_t *rc); - -bool test_wait_for_response(uint32_t *rc) { - RP2040* rp2040 = get_rp2040(); - rp2040_input_message_t button_message = {0}; - if (rc != NULL) *rc = 0; - while (1) { - if (xQueueReceive(rp2040->queue, &button_message, portMAX_DELAY) == pdTRUE) { - if (button_message.state) { - switch(button_message.input) { - case RP2040_INPUT_BUTTON_HOME: - case RP2040_INPUT_BUTTON_MENU: - case RP2040_INPUT_BUTTON_BACK: - return false; - case RP2040_INPUT_BUTTON_ACCEPT: - if (rc != NULL) *rc = 1; - return true; - default: - break; - } - } - } - } -} - -bool run_test(pax_buf_t* pax_buffer, const pax_font_t *font, ILI9341* ili9341, int line, const char *test_name, test_fn fn) { - bool test_result; - uint32_t rc; - - /* Test name */ - pax_draw_text(pax_buffer, 0xffffffff, font, 18, 0, 20*line, test_name); - if (ili9341) ili9341_write(ili9341, pax_buffer->buf); - - /* Run the test */ - test_result = fn(&rc); - - /* Display result */ - if (!test_result) { - /* Error */ - char buf[10]; - snprintf(buf, sizeof(buf), "%08x", rc); - pax_draw_text(pax_buffer, 0xffff0000, font, 18, 200, 20*line, buf); - } else { - /* OK ! */ - pax_draw_text(pax_buffer, 0xff00ff00, font, 18, 200, 20*line, " OK"); - } - - if (ili9341) ili9341_write(ili9341, pax_buffer->buf); - - /* Pass through the 'OK' status */ - return test_result; -} diff --git a/main/uninstall.c b/main/uninstall.c deleted file mode 100644 index b678f0a..0000000 --- a/main/uninstall.c +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "appfs.h" -#include "ili9341.h" -#include "pax_gfx.h" -#include "menu.h" -#include "rp2040.h" -#include "appfs_wrapper.h" -#include "hardware.h" -#include "system_wrapper.h" -#include "bootscreen.h" -#include "uninstall.h" - -static const char *TAG = "uninstaller"; - -typedef struct _uninstall_menu_args { - appfs_handle_t fd; - char name[512]; -} uninstall_menu_args_t; - -void uninstall_browser(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341) { - menu_t* menu = menu_alloc("Uninstall application", 20, 18); - const pax_font_t *font = pax_get_font("saira regular"); - - appfs_handle_t appfs_fd = APPFS_INVALID_FD; - while (1) { - appfs_fd = appfsNextEntry(appfs_fd); - if (appfs_fd == APPFS_INVALID_FD) break; - const char* name = NULL; - appfsEntryInfo(appfs_fd, &name, NULL); - uninstall_menu_args_t* args = malloc(sizeof(uninstall_menu_args_t)); - if (args == NULL) { - ESP_LOGE(TAG, "Failed to malloc() menu args"); - return; - } - args->fd = appfs_fd; - sprintf(args->name, name); - menu_insert_item(menu, name, NULL, (void*) args, -1); - } - - bool render = true; - uninstall_menu_args_t* menuArgs = NULL; - - pax_background(pax_buffer, 0xFFFFFF); - pax_noclip(pax_buffer); - pax_draw_text(pax_buffer, 0xFF000000, font, 18, 5, 240 - 18, "[A] uninstall app [B] back"); - - bool quit = false; - - while (1) { - rp2040_input_message_t buttonMessage = {0}; - if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) { - uint8_t pin = buttonMessage.input; - bool value = buttonMessage.state; - switch(pin) { - case RP2040_INPUT_JOYSTICK_DOWN: - if (value) { - menu_navigate_next(menu); - render = true; - } - break; - case RP2040_INPUT_JOYSTICK_UP: - if (value) { - menu_navigate_previous(menu); - render = true; - } - break; - case RP2040_INPUT_BUTTON_HOME: - case RP2040_INPUT_BUTTON_BACK: - if (value) { - quit = true; - } - break; - case RP2040_INPUT_BUTTON_ACCEPT: - case RP2040_INPUT_JOYSTICK_PRESS: - case RP2040_INPUT_BUTTON_SELECT: - case RP2040_INPUT_BUTTON_START: - if (value) { - menuArgs = menu_get_callback_args(menu, menu_get_position(menu)); - } - break; - default: - break; - } - } - - if (render) { - menu_render(pax_buffer, menu, 0, 0, 320, 220, 0xFF72008a); - ili9341_write(ili9341, pax_buffer->buf); - render = false; - } - - if (menuArgs != NULL) { - char message[1024]; - sprintf(message, "Uninstalling %s...", menuArgs->name); - printf("%s\n", message); - display_boot_screen(pax_buffer, ili9341, message); - appfsDeleteFile(menuArgs->name); - menuArgs = NULL; - break; - } - - if (quit) { - break; - } - } - - for (size_t index = 0; index < menu_get_length(menu); index++) { - free(menu_get_callback_args(menu, index)); - } - - menu_free(menu); -} diff --git a/main/webusb.c b/main/webusb.c deleted file mode 100644 index 995fe11..0000000 --- a/main/webusb.c +++ /dev/null @@ -1,117 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "driver/uart.h" -#include "hardware.h" -#include "managed_i2c.h" -#include "pax_gfx.h" -#include "ice40.h" -#include "system_wrapper.h" -#include "graphics_wrapper.h" -#include "esp32/rom/crc.h" - -void webusb_install_uart() { - fflush(stdout); - ESP_ERROR_CHECK(uart_driver_install(0, 2048, 0, 0, NULL, 0)); - uart_config_t uart_config = { - .baud_rate = 921600, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - .source_clk = UART_SCLK_APB, - }; - ESP_ERROR_CHECK(uart_param_config(0, &uart_config)); -} - -void webusb_uninstall_uart() { - uart_driver_delete(0); -} - -bool webusb_read_stdin(uint8_t* buffer, uint32_t len, uint32_t timeout) { - int read = uart_read_bytes(0, buffer, len, timeout / portTICK_PERIOD_MS); - return (read == len); -} - -bool webusb_uart_sync(uint32_t* length, uint32_t* crc) { - uint8_t rx_buffer[4*3]; - webusb_read_stdin(rx_buffer, sizeof(rx_buffer), 100); - if (memcmp(rx_buffer, "WUSB", 4) != 0) return false; - memcpy((uint8_t*) length, &rx_buffer[4 * 1], 4); - memcpy((uint8_t*) crc, &rx_buffer[4 * 2], 4); - return true; -} - -bool webusb_uart_load(uint8_t* buffer, uint32_t length) { - return webusb_read_stdin(buffer, length, 3000); -} - -void webusb_uart_mess(const char *mess) { - uart_write_bytes(0, mess, strlen(mess)); -} - -void webusb_print_status(pax_buf_t* pax_buffer, ILI9341* ili9341, char* message) { - pax_noclip(pax_buffer); - pax_background(pax_buffer, 0x325aa8); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*0, "WebUSB mode"); - pax_draw_text(pax_buffer, 0xFFFFFFFF, NULL, 18, 0, 20*1, message); - ili9341_write(ili9341, pax_buffer->buf); -} - -void webusb_main(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili9341) { - webusb_install_uart(); - - while (true) { - webusb_print_status(pax_buffer, ili9341, "Waiting..."); - - // 1) Wait for WUSB followed by data length as uint32 and CRC32 of the data as uint32 - uint32_t length, crc; - while (!webusb_uart_sync(&length, &crc)) { - webusb_uart_mess("WUSB"); - } - - webusb_print_status(pax_buffer, ili9341, "Receiving..."); - - // 2) Allocate RAM for the data to be received - uint8_t* buffer = malloc(length); - if (buffer == NULL) { - webusb_uart_mess("EMEM"); - webusb_print_status(pax_buffer, ili9341, "Error: malloc failed"); - vTaskDelay(100 / portTICK_PERIOD_MS); - continue; - } - - // 3) Receive data into the buffer - if (!webusb_uart_load(buffer, length)) { - free(buffer); - webusb_uart_mess("ERCV"); - webusb_print_status(pax_buffer, ili9341, "Error: receive failed"); - vTaskDelay(100 / portTICK_PERIOD_MS); - continue; - } - - // 4) Check CRC - uint32_t checkCrc = crc32_le(0, buffer, length); - - if (checkCrc != crc) { - free(buffer); - webusb_uart_mess("ECRC"); - webusb_print_status(pax_buffer, ili9341, "Error: CRC invalid"); - vTaskDelay(100 / portTICK_PERIOD_MS); - continue; - } - - webusb_uart_mess("OKOK"); - webusb_print_status(pax_buffer, ili9341, "Packet received"); - - // To-do: parse packet - } - - webusb_uninstall_uart(); -} diff --git a/main/wifi_connect.c b/main/wifi_connect.c deleted file mode 100644 index 29c20ed..0000000 --- a/main/wifi_connect.c +++ /dev/null @@ -1,104 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pax_gfx.h" -#include "system_wrapper.h" -#include "settings.h" -#include "wifi_connection.h" - -static const char *TAG = "wifi_connect"; - -bool wifi_connect_to_stored() { - bool result = false; - // Open NVS. - nvs_handle_t handle; - nvs_open("system", NVS_READWRITE, &handle); - wifi_auth_mode_t authmode = 0; - esp_eap_ttls_phase2_types phase2 = 0; - char *ssid = NULL; - char *ident = NULL; - char *anon_ident = NULL; - char *password = NULL; - size_t len; - - // Read NVS. - esp_err_t res; - // Read SSID. - res = nvs_get_str(handle, "wifi.ssid", NULL, &len); - if (res) goto errcheck; - ssid = malloc(len); - res = nvs_get_str(handle, "wifi.ssid", ssid, &len); - if (res) goto errcheck; - - // Check whether connection is enterprise. - res = nvs_get_u8(handle, "wifi.authmode", &authmode); - bool use_ent = authmode == WIFI_AUTH_WPA2_ENTERPRISE; - if (res) goto errcheck; - - if (use_ent) { - // Read enterprise-specific parameters. - - // Read phase2 mode. - res = nvs_get_u8(handle, "wifi.phase2", &phase2); - if (res) goto errcheck; - - // Read identity. - res = nvs_get_str(handle, "wifi.username", NULL, &len); - if (res) goto errcheck; - ident = malloc(len); - res = nvs_get_str(handle, "wifi.username", ident, &len); - - // Read anonymous identity. - res = nvs_get_str(handle, "wifi.anon_ident", NULL, &len); - if (res == ESP_ERR_NVS_NOT_FOUND) { - // Default is use the same thing. - anon_ident = strdup(ident); - } else { - if (res) goto errcheck; - anon_ident = malloc(len); - res = nvs_get_str(handle, "wifi.anon_ident", anon_ident, &len); - if (res) goto errcheck; - } - } - // Read password. - res = nvs_get_str(handle, "wifi.password", NULL, &len); - if (res) goto errcheck; - password = malloc(len); - res = nvs_get_str(handle, "wifi.password", password, &len); - if (res) goto errcheck; - - // Close NVS. - nvs_close(handle); - - // Open the appropriate connection. - if (use_ent) { - result = wifi_connect_ent(ssid, ident, anon_ident, password, phase2, 3); - } else { - result = wifi_connect(ssid, password, authmode, 3); - } - - errcheck: - if (res == ESP_ERR_NVS_NOT_FOUND || res == ESP_ERR_NVS_NOT_INITIALIZED) { - // When NVS is not initialised. - ESP_LOGI(TAG, "WiFi settings not stored in NVS."); - } else if (res) { - // Other errors. - ESP_LOGE(TAG, "Error connecting to WiFi: %s", esp_err_to_name(res)); - } - - // Free memory. - if (ssid) free(ssid); - if (ident) free(ident); - if (anon_ident) free(anon_ident); - if (password) free(password); - - return result; -} diff --git a/main/wifi_connection.c b/main/wifi_connection.c deleted file mode 100644 index 207069a..0000000 --- a/main/wifi_connection.c +++ /dev/null @@ -1,272 +0,0 @@ -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_system.h" -#include "esp_event.h" -#include "esp_log.h" -#include "lwip/err.h" -#include "lwip/sys.h" - -#include "wifi_connection.h" - -static const char *TAG = "wifi_connection"; - -#define WIFI_CONNECTED_BIT BIT0 -#define WIFI_FAIL_BIT BIT1 -#define WIFI_STARTED_BIT BIT2 - -static EventGroupHandle_t wifiEventGroup; - -static uint8_t retryCount = 0; -static uint8_t maxRetries = 3; -static bool isScanning = false; - -static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { - if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { - xEventGroupSetBits(wifiEventGroup, WIFI_STARTED_BIT); - if (!isScanning) { - // Connect only if we're not scanning the WiFi. - esp_wifi_connect(); - } - ESP_LOGI(TAG, "WiFi station start."); - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_STOP) { - xEventGroupClearBits(wifiEventGroup, WIFI_STARTED_BIT); - ESP_LOGI(TAG, "WiFi station stop."); - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - if (retryCount < 3) { - esp_wifi_connect(); - retryCount++; - ESP_LOGI(TAG, "Retrying connection"); - } else { - ESP_LOGI(TAG, "Connection failed"); - xEventGroupSetBits(wifiEventGroup, WIFI_FAIL_BIT); - } - } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { - ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; - ESP_LOGI(TAG, "Got ip:" IPSTR, IP2STR(&event->ip_info.ip)); - retryCount = 0; - xEventGroupSetBits(wifiEventGroup, WIFI_CONNECTED_BIT); - } -} - -void wifi_init() { - // Create an event group for WiFi things. - wifiEventGroup = xEventGroupCreate(); - - // Initialise WiFi stack. - ESP_ERROR_CHECK(esp_netif_init()); - - ESP_ERROR_CHECK(esp_event_loop_create_default()); - esp_netif_create_default_wifi_sta(); - - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - - // Register event handlers for WiFi. - esp_event_handler_instance_t instance_any_id; - esp_event_handler_instance_t instance_got_ip; - ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id)); - ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip)); - - // Turn off WiFi hardware. - ESP_ERROR_CHECK(esp_wifi_stop()); -} - -bool wifi_connect(const char* aSsid, const char* aPassword, wifi_auth_mode_t aAuthmode, uint8_t aRetryMax) { - // Set the retry counts. - retryCount = 0; - maxRetries = aRetryMax; - - // Create a config. - wifi_config_t wifi_config = {0}; - strcpy((char*) wifi_config.sta.ssid, aSsid); - strcpy((char*) wifi_config.sta.password, aPassword); - wifi_config.sta.threshold.authmode = aAuthmode; - - // Set WiFi config. - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); - // Disable 11b as NOC asked. - esp_wifi_config_11b_rate(WIFI_IF_STA, true); - // Start WiFi. - ESP_ERROR_CHECK(esp_wifi_start()); - - ESP_LOGI(TAG, "Connecting to WiFi..."); - - /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum - * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */ - EventBits_t bits = xEventGroupWaitBits(wifiEventGroup, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY); - /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually happened. */ - if (bits & WIFI_CONNECTED_BIT) { - ESP_LOGI(TAG, "Connected to WiFi"); - return true; - } else if (bits & WIFI_FAIL_BIT) { - ESP_LOGE(TAG, "Failed to connect"); - ESP_ERROR_CHECK(esp_wifi_stop()); - } else { - ESP_LOGE(TAG, "Unknown event received while waiting on connection"); - ESP_ERROR_CHECK(esp_wifi_stop()); - } - return false; -} - -bool wifi_connect_ent(const char* aSsid, const char *aIdent, const char *aAnonIdent, const char* aPassword, esp_eap_ttls_phase2_types phase2, uint8_t aRetryMax) { - retryCount = 0; - maxRetries = aRetryMax; - wifi_config_t wifi_config = {0}; - if (strlen(aSsid) > 32) { - ESP_LOGE(TAG, "SSID is too long (%zu > 32)!", strlen(aSsid)); - return false; - } - strncpy((char*) wifi_config.sta.ssid, aSsid, 32); - - // Set WiFi config. - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); - - // Set WPA2 ENT config. - esp_wifi_sta_wpa2_ent_set_identity((const uint8_t *) aAnonIdent, strlen(aAnonIdent)); - esp_wifi_sta_wpa2_ent_set_username((const uint8_t *) aIdent, strlen(aIdent)); - esp_wifi_sta_wpa2_ent_set_password((const uint8_t *) aPassword, strlen(aPassword)); - esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(phase2); - // Enable enterprise auth. - esp_wifi_sta_wpa2_ent_enable(); - // Disable 11b as NOC asked. - esp_wifi_config_11b_rate(WIFI_IF_STA, true); - // Start the connection. - esp_wifi_start(); - - ESP_LOGI(TAG, "Connecting to '%s' as '%s'/'%s': %s", aSsid, aIdent, aAnonIdent, aPassword); - ESP_LOGI(TAG, "Phase2 mode: %d", phase2); - - /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum - * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */ - EventBits_t bits = xEventGroupWaitBits(wifiEventGroup, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY); - /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually happened. */ - if (bits & WIFI_CONNECTED_BIT) { - ESP_LOGI(TAG, "Connected to WiFi"); - return true; - } else if (bits & WIFI_FAIL_BIT) { - ESP_LOGE(TAG, "Failed to connect"); - ESP_ERROR_CHECK(esp_wifi_stop()); - } else { - ESP_LOGE(TAG, "Unknown event received while waiting on connection"); - ESP_ERROR_CHECK(esp_wifi_stop()); - } - return false; -} - -// Shows a nice info message describing an AP record. -static inline void wifi_desc_record(wifi_ap_record_t *record) { - // Make a string representation of BSSID. - char *bssid_str = malloc(3*6); - if (!bssid_str) return; - snprintf(bssid_str, 3*6, "%02X:%02X:%02X:%02X:%02X:%02X", - record->bssid[0], record->bssid[1], record->bssid[2], - record->bssid[3], record->bssid[4], record->bssid[5] - ); - - // Make a string representation of 11b/g/n modes. - char *phy_str = malloc(9); - if (!phy_str) { - free(bssid_str); - return; - } - *phy_str = 0; - if (record->phy_11b | record->phy_11g | record->phy_11n) { - strcpy(phy_str, " 1"); - } - if (record->phy_11b) { - strcat(phy_str, "/b"); - } - if (record->phy_11g) { - strcat(phy_str, "/g"); - } - if (record->phy_11n) { - strcat(phy_str, "/n"); - } - phy_str[2] = '1'; - - ESP_LOGI(TAG, "AP %s %s rssi=%hhd%s", bssid_str, record->ssid, record->rssi, phy_str); - free(bssid_str); - free(phy_str); -} - -// Scan for WiFi access points. -size_t wifi_scan(wifi_ap_record_t **aps_out) { - isScanning = true; - // Scan for any non-hidden APs on all channels. - wifi_scan_config_t cfg = { - .ssid = NULL, - .bssid = NULL, - .channel = 0, - .scan_type = WIFI_SCAN_TYPE_ACTIVE, - .scan_time = { .active={ 0, 0 } }, - }; - - // Start the scan now. - ESP_LOGI(TAG, "Starting scan..."); - esp_err_t res = esp_wifi_scan_start(&cfg, true); - // Whether to call esp_wifi_stop() on finish. - bool stopWhenDone = false; - if (res == ESP_ERR_WIFI_NOT_STARTED) { - // If it complains that the wifi wasn't started, then do so. - ESP_LOGI(TAG, "Starting WiFi for scan"); - - // Set to station but don't connect. - res = esp_wifi_set_mode(WIFI_MODE_STA); - if (res) goto ohno; - - // Start WiFi. - res = esp_wifi_start(); - if (res) goto ohno; - stopWhenDone = true; - - // Await the STA started bit. - xEventGroupWaitBits(wifiEventGroup, WIFI_STARTED_BIT, pdFALSE, pdFALSE, pdMS_TO_TICKS(2000)); - - // Try again. - res = esp_wifi_scan_start(&cfg, true); - } - if (res) { - ohno: - ESP_LOGE(TAG, "Error in WiFi scan: %s", esp_err_to_name(res)); - isScanning = false; - return 0; - } - - // Allocate memory for AP list. - uint16_t num_ap = 0; - esp_wifi_scan_get_ap_num(&num_ap); - wifi_ap_record_t *aps = malloc(sizeof(wifi_ap_record_t) * num_ap); - - // Collect APs and report findings. - esp_wifi_scan_get_ap_records(&num_ap, aps); - for (uint16_t i = 0; i < num_ap; i++) { - wifi_desc_record(&aps[i]); - } - - // Clean up. - if (aps_out) { - // Output pointer is non-null, return the APs list. - *aps_out = aps; - } else { - // Output pointer is null, free the APs list. - free(aps); - } - if (stopWhenDone) { - // Stop WiFi because it was started only for this scan. - esp_wifi_stop(); - } - isScanning = false; - return num_ap; -} - -// Get the strength value for a given RSSI. -wifi_strength_t wifi_rssi_to_strength(int8_t rssi) { - if (rssi > WIFI_THRESH_VERY_GOOD) return WIFI_STRENGTH_VERY_GOOD; - else if (rssi > WIFI_THRESH_GOOD) return WIFI_STRENGTH_GOOD; - else if (rssi > WIFI_THRESH_BAD) return WIFI_STRENGTH_BAD; - else return WIFI_STRENGTH_VERY_BAD; -} diff --git a/main/wifi_ota.c b/main/wifi_ota.c deleted file mode 100644 index e31383a..0000000 --- a/main/wifi_ota.c +++ /dev/null @@ -1,227 +0,0 @@ -#include "wifi_ota.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_system.h" -#include "esp_event.h" -#include "esp_log.h" -#include "esp_ota_ops.h" -#include "esp_http_client.h" -#include "esp_https_ota.h" -#include "string.h" -#include "esp_crt_bundle.h" -#include "nvs.h" -#include "nvs_flash.h" -#include -#include "esp_wifi.h" -#include "bootscreen.h" - -#define HASH_LEN 32 - -static const char *TAG = "OTA update"; - -extern const uint8_t server_cert_pem_start[] asm("_binary_isrgrootx1_pem_start"); -extern const uint8_t server_cert_pem_end[] asm("_binary_isrgrootx1_pem_end"); - -esp_err_t _http_event_handler(esp_http_client_event_t *evt) -{ - switch (evt->event_id) { - case HTTP_EVENT_ERROR: - ESP_LOGD(TAG, "HTTP_EVENT_ERROR"); - break; - case HTTP_EVENT_ON_CONNECTED: - ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED"); - break; - case HTTP_EVENT_HEADERS_SENT: - ESP_LOGD(TAG, "HTTP_EVENT_HEADERS_SENT"); - break; - case HTTP_EVENT_ON_HEADER: - ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value); - break; - case HTTP_EVENT_ON_DATA: - ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len); - break; - case HTTP_EVENT_ON_FINISH: - ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH"); - break; - case HTTP_EVENT_DISCONNECTED: - ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED"); - break; - } - return ESP_OK; -} - -static esp_err_t validate_image_header(esp_app_desc_t *new_app_info) { - if (new_app_info == NULL) { - return ESP_ERR_INVALID_ARG; - } - - const esp_partition_t *running = esp_ota_get_running_partition(); - esp_app_desc_t running_app_info; - if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) { - ESP_LOGI(TAG, "Running firmware version: %s", running_app_info.version); - } - -/* - if (memcmp(new_app_info->version, running_app_info.version, sizeof(new_app_info->version)) == 0) { - ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update."); - return ESP_FAIL; - } -*/ - - return ESP_OK; -} - -static esp_err_t _http_client_init_cb(esp_http_client_handle_t http_client) { - esp_err_t err = ESP_OK; - /* Uncomment to add custom headers to HTTP request */ - // err = esp_http_client_set_header(http_client, "Custom-Header", "Value"); - return err; -} - -static void print_sha256(const uint8_t *image_hash, const char *label) { - char hash_print[HASH_LEN * 2 + 1]; - hash_print[HASH_LEN * 2] = 0; - for (int i = 0; i < HASH_LEN; ++i) { - sprintf(&hash_print[i * 2], "%02x", image_hash[i]); - } - ESP_LOGI(TAG, "%s %s", label, hash_print); -} - -static void get_sha256_of_partitions(void) { - uint8_t sha_256[HASH_LEN] = { 0 }; - esp_partition_t partition; - - // get sha256 digest for bootloader - partition.address = ESP_BOOTLOADER_OFFSET; - partition.size = ESP_PARTITION_TABLE_OFFSET; - partition.type = ESP_PARTITION_TYPE_APP; - esp_partition_get_sha256(&partition, sha_256); - print_sha256(sha_256, "SHA-256 for bootloader: "); - - // get sha256 digest for running partition - esp_partition_get_sha256(esp_ota_get_running_partition(), sha_256); - print_sha256(sha_256, "SHA-256 for current firmware: "); -} - -void display_ota_state(pax_buf_t* pax_buffer, ILI9341* ili9341, const char* text) { - pax_noclip(pax_buffer); - const pax_font_t* font = pax_get_font("sky mono"); - pax_background(pax_buffer, 0xFFFFFF); - pax_vec1_t title_size = pax_text_size(font, 18, "Firmware update"); - pax_draw_text(pax_buffer, 0xFF000000, font, 18, (320 / 2) - (title_size.x / 2), 120 - 30, "Firmware update"); - pax_vec1_t size = pax_text_size(font, 18, text); - pax_draw_text(pax_buffer, 0xFF000000, font, 18, (320 / 2) - (size.x / 2), 120 + 10, text); - ili9341_write(ili9341, pax_buffer->buf); -} - - -void ota_update(pax_buf_t* pax_buffer, ILI9341* ili9341) { - esp_wifi_set_ps(WIFI_PS_NONE); // Disable any WiFi power save mode - - ESP_LOGI(TAG, "Starting OTA update"); - - esp_http_client_config_t config = { - .url = "https://ota.bodge.team/mch2022.bin", - .crt_bundle_attach = esp_crt_bundle_attach, - .cert_pem = (char *)server_cert_pem_start, - .event_handler = _http_event_handler, - .keep_alive_enable = true - }; - - esp_https_ota_config_t ota_config = { - .http_config = &config, - .http_client_init_cb = _http_client_init_cb, // Register a callback to be invoked after esp_http_client is initialized -#ifdef CONFIG_EXAMPLE_ENABLE_PARTIAL_HTTP_DOWNLOAD - .partial_http_download = true, - .max_http_request_size = CONFIG_EXAMPLE_HTTP_REQUEST_SIZE, -#endif - }; - - //config.skip_cert_common_name_check = true; - - ESP_LOGI(TAG, "Attempting to download update from %s", config.url); - - display_ota_state(pax_buffer, ili9341, "Starting download..."); - - esp_https_ota_handle_t https_ota_handle = NULL; - esp_err_t err = esp_https_ota_begin(&ota_config, &https_ota_handle); - if (err != ESP_OK) { - ESP_LOGE(TAG, "ESP HTTPS OTA Begin failed"); - display_ota_state(pax_buffer, ili9341, "Failed to start download"); - vTaskDelay(5000 / portTICK_PERIOD_MS); - esp_restart(); - } - - esp_app_desc_t app_desc; - err = esp_https_ota_get_img_desc(https_ota_handle, &app_desc); - if (err != ESP_OK) { - ESP_LOGE(TAG, "esp_https_ota_read_img_desc failed"); - esp_https_ota_abort(https_ota_handle); - display_ota_state(pax_buffer, ili9341, "Failed to read image desc"); - vTaskDelay(5000 / portTICK_PERIOD_MS); - esp_restart(); - } - err = validate_image_header(&app_desc); - if (err != ESP_OK) { - ESP_LOGE(TAG, "image header verification failed"); - esp_https_ota_abort(https_ota_handle); - display_ota_state(pax_buffer, ili9341, "Image header verification failed"); - vTaskDelay(5000 / portTICK_PERIOD_MS); - esp_restart(); - } - - esp_err_t ota_finish_err = ESP_OK; - int percent_shown = -1; - while (1) { - err = esp_https_ota_perform(https_ota_handle); - if (err != ESP_ERR_HTTPS_OTA_IN_PROGRESS) { - break; - } - - int len_total = esp_https_ota_get_image_size(https_ota_handle); - int len_read = esp_https_ota_get_image_len_read(https_ota_handle); - int percent = (len_read * 100) / len_total; - - if (percent != percent_shown) { - ESP_LOGI(TAG, "Downloading %d / %d (%d%%)", len_read, len_total, percent); - percent_shown = percent; - char buffer[128]; - snprintf(buffer, sizeof(buffer), "Updating... %d%%", percent); - display_ota_state(pax_buffer, ili9341, buffer); - } - } - - if (esp_https_ota_is_complete_data_received(https_ota_handle) != true) { - // the OTA image was not completely received and user can customise the response to this situation. - ESP_LOGE(TAG, "Complete data was not received."); - display_ota_state(pax_buffer, ili9341, "Download failed"); - vTaskDelay(5000 / portTICK_PERIOD_MS); - esp_restart(); - } else { - ota_finish_err = esp_https_ota_finish(https_ota_handle); - if ((err == ESP_OK) && (ota_finish_err == ESP_OK)) { - ESP_LOGI(TAG, "ESP_HTTPS_OTA upgrade successful. Rebooting ..."); - display_ota_state(pax_buffer, ili9341, "Update installed"); - vTaskDelay(1000 / portTICK_PERIOD_MS); - esp_restart(); - } else { - if (ota_finish_err == ESP_ERR_OTA_VALIDATE_FAILED) { - ESP_LOGE(TAG, "Image validation failed, image is corrupted"); - display_ota_state(pax_buffer, ili9341, "Image validation failed"); - } else { - display_ota_state(pax_buffer, ili9341, "Update failed"); - } - ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed 0x%x", ota_finish_err); - vTaskDelay(5000 / portTICK_PERIOD_MS); - esp_restart(); - } - } - - esp_https_ota_abort(https_ota_handle); - esp_restart(); - - while (1) { - vTaskDelay(1000 / portTICK_PERIOD_MS); - } -} diff --git a/resources/animation/animation_frame_1.png b/resources/animation/animation_frame_1.png deleted file mode 100644 index d55e776..0000000 Binary files a/resources/animation/animation_frame_1.png and /dev/null differ diff --git a/resources/animation/animation_frame_10.png b/resources/animation/animation_frame_10.png deleted file mode 100644 index abe0588..0000000 Binary files a/resources/animation/animation_frame_10.png and /dev/null differ diff --git a/resources/animation/animation_frame_11.png b/resources/animation/animation_frame_11.png deleted file mode 100644 index 4e53573..0000000 Binary files a/resources/animation/animation_frame_11.png and /dev/null differ diff --git a/resources/animation/animation_frame_12.png b/resources/animation/animation_frame_12.png deleted file mode 100644 index 5b9b57d..0000000 Binary files a/resources/animation/animation_frame_12.png and /dev/null differ diff --git a/resources/animation/animation_frame_13.png b/resources/animation/animation_frame_13.png deleted file mode 100644 index 17b6ec4..0000000 Binary files a/resources/animation/animation_frame_13.png and /dev/null differ diff --git a/resources/animation/animation_frame_14.png b/resources/animation/animation_frame_14.png deleted file mode 100644 index 6b72f3f..0000000 Binary files a/resources/animation/animation_frame_14.png and /dev/null differ diff --git a/resources/animation/animation_frame_15.png b/resources/animation/animation_frame_15.png deleted file mode 100644 index 5a6d463..0000000 Binary files a/resources/animation/animation_frame_15.png and /dev/null differ diff --git a/resources/animation/animation_frame_16.png b/resources/animation/animation_frame_16.png deleted file mode 100644 index 41d3952..0000000 Binary files a/resources/animation/animation_frame_16.png and /dev/null differ diff --git a/resources/animation/animation_frame_17.png b/resources/animation/animation_frame_17.png deleted file mode 100644 index 47f6323..0000000 Binary files a/resources/animation/animation_frame_17.png and /dev/null differ diff --git a/resources/animation/animation_frame_18.png b/resources/animation/animation_frame_18.png deleted file mode 100644 index 5db8ed8..0000000 Binary files a/resources/animation/animation_frame_18.png and /dev/null differ diff --git a/resources/animation/animation_frame_19.png b/resources/animation/animation_frame_19.png deleted file mode 100644 index 3bd9465..0000000 Binary files a/resources/animation/animation_frame_19.png and /dev/null differ diff --git a/resources/animation/animation_frame_2.png b/resources/animation/animation_frame_2.png deleted file mode 100644 index ab8f15f..0000000 Binary files a/resources/animation/animation_frame_2.png and /dev/null differ diff --git a/resources/animation/animation_frame_20.png b/resources/animation/animation_frame_20.png deleted file mode 100644 index 64facb9..0000000 Binary files a/resources/animation/animation_frame_20.png and /dev/null differ diff --git a/resources/animation/animation_frame_21.png b/resources/animation/animation_frame_21.png deleted file mode 100644 index 81a5937..0000000 Binary files a/resources/animation/animation_frame_21.png and /dev/null differ diff --git a/resources/animation/animation_frame_22.png b/resources/animation/animation_frame_22.png deleted file mode 100644 index 59cfd17..0000000 Binary files a/resources/animation/animation_frame_22.png and /dev/null differ diff --git a/resources/animation/animation_frame_23.png b/resources/animation/animation_frame_23.png deleted file mode 100644 index 9d25bf6..0000000 Binary files a/resources/animation/animation_frame_23.png and /dev/null differ diff --git a/resources/animation/animation_frame_24.png b/resources/animation/animation_frame_24.png deleted file mode 100644 index 47cecee..0000000 Binary files a/resources/animation/animation_frame_24.png and /dev/null differ diff --git a/resources/animation/animation_frame_25.png b/resources/animation/animation_frame_25.png deleted file mode 100644 index 494a3cb..0000000 Binary files a/resources/animation/animation_frame_25.png and /dev/null differ diff --git a/resources/animation/animation_frame_26.png b/resources/animation/animation_frame_26.png deleted file mode 100644 index 16d73fe..0000000 Binary files a/resources/animation/animation_frame_26.png and /dev/null differ diff --git a/resources/animation/animation_frame_27.png b/resources/animation/animation_frame_27.png deleted file mode 100644 index 4ba0b0f..0000000 Binary files a/resources/animation/animation_frame_27.png and /dev/null differ diff --git a/resources/animation/animation_frame_28.png b/resources/animation/animation_frame_28.png deleted file mode 100644 index e132200..0000000 Binary files a/resources/animation/animation_frame_28.png and /dev/null differ diff --git a/resources/animation/animation_frame_3.png b/resources/animation/animation_frame_3.png deleted file mode 100644 index d55e776..0000000 Binary files a/resources/animation/animation_frame_3.png and /dev/null differ diff --git a/resources/animation/animation_frame_4.png b/resources/animation/animation_frame_4.png deleted file mode 100644 index ab8f15f..0000000 Binary files a/resources/animation/animation_frame_4.png and /dev/null differ diff --git a/resources/animation/animation_frame_5.png b/resources/animation/animation_frame_5.png deleted file mode 100644 index d55e776..0000000 Binary files a/resources/animation/animation_frame_5.png and /dev/null differ diff --git a/resources/animation/animation_frame_6.png b/resources/animation/animation_frame_6.png deleted file mode 100644 index ab8f15f..0000000 Binary files a/resources/animation/animation_frame_6.png and /dev/null differ diff --git a/resources/animation/animation_frame_7.png b/resources/animation/animation_frame_7.png deleted file mode 100644 index 8be03c6..0000000 Binary files a/resources/animation/animation_frame_7.png and /dev/null differ diff --git a/resources/animation/animation_frame_8.png b/resources/animation/animation_frame_8.png deleted file mode 100644 index e5150de..0000000 Binary files a/resources/animation/animation_frame_8.png and /dev/null differ diff --git a/resources/animation/animation_frame_9.png b/resources/animation/animation_frame_9.png deleted file mode 100644 index 31be636..0000000 Binary files a/resources/animation/animation_frame_9.png and /dev/null differ diff --git a/resources/boot.snd b/resources/boot.snd deleted file mode 100644 index 5e7e6f9..0000000 Binary files a/resources/boot.snd and /dev/null differ diff --git a/resources/fpga_selftest.bin b/resources/fpga_selftest.bin deleted file mode 100644 index a39be36..0000000 Binary files a/resources/fpga_selftest.bin and /dev/null differ diff --git a/resources/icons/apps.png b/resources/icons/apps.png deleted file mode 100644 index 535f73c..0000000 Binary files a/resources/icons/apps.png and /dev/null differ diff --git a/resources/icons/dev.png b/resources/icons/dev.png deleted file mode 100644 index 1185139..0000000 Binary files a/resources/icons/dev.png and /dev/null differ diff --git a/resources/icons/hatchery.png b/resources/icons/hatchery.png deleted file mode 100644 index 7cf5a6a..0000000 Binary files a/resources/icons/hatchery.png and /dev/null differ diff --git a/resources/icons/home.png b/resources/icons/home.png deleted file mode 100644 index 03d2f3d..0000000 Binary files a/resources/icons/home.png and /dev/null differ diff --git a/resources/icons/settings.png b/resources/icons/settings.png deleted file mode 100644 index 2f4a61c..0000000 Binary files a/resources/icons/settings.png and /dev/null differ diff --git a/resources/isrgrootx1.pem b/resources/isrgrootx1.pem deleted file mode 100644 index b85c803..0000000 --- a/resources/isrgrootx1.pem +++ /dev/null @@ -1,31 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw -TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 -WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu -ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc -h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ -0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U -A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW -T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH -B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC -B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv -KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn -OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn -jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw -qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI -rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq -hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL -ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ -3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK -NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 -ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur -TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC -jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc -oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq -4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA -mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d -emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= ------END CERTIFICATE----- diff --git a/resources/logo_screen.png b/resources/logo_screen.png deleted file mode 100644 index 6a550ea..0000000 Binary files a/resources/logo_screen.png and /dev/null differ diff --git a/resources/mch2022_logo.png b/resources/mch2022_logo.png deleted file mode 100644 index f8cc80c..0000000 Binary files a/resources/mch2022_logo.png and /dev/null differ diff --git a/resources/rp2040_firmware.bin b/resources/rp2040_firmware.bin deleted file mode 100755 index c445a28..0000000 Binary files a/resources/rp2040_firmware.bin and /dev/null differ diff --git a/resources/wallpaper.png b/resources/wallpaper.png deleted file mode 100644 index 35c3b1f..0000000 Binary files a/resources/wallpaper.png and /dev/null differ