Prototype 4
This commit is contained in:
parent
fd5d4da353
commit
e42aefed7f
17 changed files with 463 additions and 284 deletions
|
@ -5,7 +5,6 @@ idf_component_register(
|
||||||
"appfs"
|
"appfs"
|
||||||
"bus-i2c"
|
"bus-i2c"
|
||||||
"i2c-bno055"
|
"i2c-bno055"
|
||||||
"i2c-pca9555"
|
|
||||||
"pax-graphics"
|
"pax-graphics"
|
||||||
"renze-graphics"
|
"renze-graphics"
|
||||||
"sdcard"
|
"sdcard"
|
||||||
|
|
|
@ -8,41 +8,44 @@
|
||||||
|
|
||||||
static const char *TAG = "hardware";
|
static const char *TAG = "hardware";
|
||||||
|
|
||||||
static PCA9555 dev_pca9555 = {0};
|
|
||||||
static BNO055 dev_bno055 = {0};
|
static BNO055 dev_bno055 = {0};
|
||||||
static ILI9341 dev_ili9341 = {0};
|
static ILI9341 dev_ili9341 = {0};
|
||||||
static ICE40 dev_ice40 = {0};
|
static ICE40 dev_ice40 = {0};
|
||||||
static RP2040 dev_rp2040 = {0};
|
static RP2040 dev_rp2040 = {0};
|
||||||
|
|
||||||
esp_err_t ice40_get_done_wrapper(bool* done) {
|
esp_err_t ice40_get_done_wrapper(bool* done) {
|
||||||
return pca9555_get_gpio_value(&dev_pca9555, PCA9555_PIN_FPGA_CDONE, done);
|
uint8_t buttons[2];
|
||||||
|
esp_err_t res = rp2040_read_buttons(&dev_rp2040, buttons);
|
||||||
|
if (res != ESP_OK) return res;
|
||||||
|
*done = !((buttons[0] >> 5) & 0x01);
|
||||||
|
printf("FPGA done is %u\n", *done);
|
||||||
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t ice40_set_reset_wrapper(bool reset) {
|
esp_err_t ice40_set_reset_wrapper(bool reset) {
|
||||||
return pca9555_set_gpio_value(&dev_pca9555, PCA9555_PIN_FPGA_RESET, reset);
|
printf("FPGA reset set to %u\n", reset);
|
||||||
|
esp_err_t res = rp2040_set_fpga(&dev_rp2040, reset);
|
||||||
|
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ili9341_set_lcd_mode(bool mode) {
|
void ili9341_set_lcd_mode(bool mode) {
|
||||||
ESP_LOGI(TAG, "LCD mode switch to %s", mode ? "FPGA" : "ESP32");
|
ESP_LOGI(TAG, "LCD mode switch to %s", mode ? "FPGA" : "ESP32");
|
||||||
rp2040_set_lcd_mode(&dev_rp2040, (lcd_mode_t) mode);
|
esp_err_t res = gpio_set_level(GPIO_LCD_MODE, mode);
|
||||||
|
if (res != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Setting LCD mode failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t _bus_init() {
|
static esp_err_t _bus_init() {
|
||||||
esp_err_t res;
|
esp_err_t res;
|
||||||
|
|
||||||
// System I2C bus
|
// I2C bus
|
||||||
res = i2c_init(I2C_BUS_SYS, GPIO_I2C_SYS_SDA, GPIO_I2C_SYS_SCL, I2C_SPEED_SYS, false, false);
|
res = i2c_init(I2C_BUS_SYS, GPIO_I2C_SYS_SDA, GPIO_I2C_SYS_SCL, I2C_SPEED_SYS, false, false);
|
||||||
if (res != ESP_OK) {
|
if (res != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Initializing system I2C bus failed");
|
ESP_LOGE(TAG, "Initializing system I2C bus failed");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// User I2C bus
|
|
||||||
res = i2c_init(I2C_BUS_EXT, GPIO_I2C_EXT_SDA, GPIO_I2C_EXT_SCL, I2C_SPEED_EXT, false, false);
|
|
||||||
if (res != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "Initializing user I2C bus failed");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SPI bus
|
// SPI bus
|
||||||
spi_bus_config_t busConfiguration = {0};
|
spi_bus_config_t busConfiguration = {0};
|
||||||
|
@ -63,7 +66,8 @@ static esp_err_t _bus_init() {
|
||||||
|
|
||||||
// Board init
|
// Board init
|
||||||
|
|
||||||
esp_err_t board_init() {
|
esp_err_t board_init(bool* aLcdReady) {
|
||||||
|
if (aLcdReady != NULL) *aLcdReady = false;
|
||||||
esp_err_t res;
|
esp_err_t res;
|
||||||
|
|
||||||
// Interrupts
|
// Interrupts
|
||||||
|
@ -77,10 +81,36 @@ esp_err_t board_init() {
|
||||||
res = _bus_init();
|
res = _bus_init();
|
||||||
if (res != ESP_OK) return res;
|
if (res != ESP_OK) return res;
|
||||||
|
|
||||||
|
// LCD display
|
||||||
|
dev_ili9341.spi_bus = SPI_BUS;
|
||||||
|
dev_ili9341.pin_cs = GPIO_SPI_CS_LCD;
|
||||||
|
dev_ili9341.pin_dcx = GPIO_SPI_DC_LCD;
|
||||||
|
dev_ili9341.pin_reset = GPIO_LCD_RESET;
|
||||||
|
dev_ili9341.rotation = 1;
|
||||||
|
dev_ili9341.color_mode = true; // Blue and red channels are swapped
|
||||||
|
dev_ili9341.spi_speed = 60000000; // 60MHz
|
||||||
|
dev_ili9341.spi_max_transfer_size = SPI_MAX_TRANSFER_SIZE;
|
||||||
|
dev_ili9341.callback = ili9341_set_lcd_mode; // Callback for changing LCD mode between ESP32 and FPGA
|
||||||
|
|
||||||
|
res = gpio_set_direction(GPIO_LCD_MODE, GPIO_MODE_OUTPUT);
|
||||||
|
if (res != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Initializing LCD mode GPIO failed");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ili9341_init(&dev_ili9341);
|
||||||
|
if (res != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Initializing LCD failed");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aLcdReady != NULL) *aLcdReady = true;
|
||||||
|
|
||||||
// RP2040 co-processor
|
// RP2040 co-processor
|
||||||
dev_rp2040.i2c_bus = I2C_BUS_SYS;
|
dev_rp2040.i2c_bus = I2C_BUS_SYS;
|
||||||
dev_rp2040.i2c_address = RP2040_ADDR;
|
dev_rp2040.i2c_address = RP2040_ADDR;
|
||||||
dev_rp2040.pin_interrupt = GPIO_INT_RP2040;
|
dev_rp2040.pin_interrupt = GPIO_INT_RP2040;
|
||||||
|
dev_rp2040.queue = xQueueCreate(8, sizeof(rp2040_input_message_t));
|
||||||
|
|
||||||
res = rp2040_init(&dev_rp2040);
|
res = rp2040_init(&dev_rp2040);
|
||||||
if (res != ESP_OK) {
|
if (res != ESP_OK) {
|
||||||
|
@ -88,45 +118,13 @@ esp_err_t board_init() {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PCA9555 IO expander on system I2C bus
|
|
||||||
res = pca9555_init(&dev_pca9555, I2C_BUS_SYS, PCA9555_ADDR, GPIO_INT_PCA9555);
|
|
||||||
if (res != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "Initializing PCA9555 failed");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = pca9555_set_gpio_direction(&dev_pca9555, PCA9555_PIN_FPGA_RESET, true);
|
|
||||||
if (res != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "Setting the FPGA reset pin on the PCA9555 to output failed");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = pca9555_set_gpio_value(&dev_pca9555, PCA9555_PIN_FPGA_RESET, false);
|
|
||||||
if (res != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "Setting the FPGA reset pin on the PCA9555 to low failed");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
pca9555_set_gpio_polarity(&dev_pca9555, PCA9555_PIN_BTN_START, true);
|
|
||||||
pca9555_set_gpio_polarity(&dev_pca9555, PCA9555_PIN_BTN_SELECT, true);
|
|
||||||
pca9555_set_gpio_polarity(&dev_pca9555, PCA9555_PIN_BTN_MENU, true);
|
|
||||||
pca9555_set_gpio_polarity(&dev_pca9555, PCA9555_PIN_BTN_HOME, true);
|
|
||||||
pca9555_set_gpio_polarity(&dev_pca9555, PCA9555_PIN_BTN_JOY_LEFT, true);
|
|
||||||
pca9555_set_gpio_polarity(&dev_pca9555, PCA9555_PIN_BTN_JOY_PRESS, true);
|
|
||||||
pca9555_set_gpio_polarity(&dev_pca9555, PCA9555_PIN_BTN_JOY_DOWN, true);
|
|
||||||
pca9555_set_gpio_polarity(&dev_pca9555, PCA9555_PIN_BTN_JOY_UP, true);
|
|
||||||
pca9555_set_gpio_polarity(&dev_pca9555, PCA9555_PIN_BTN_JOY_RIGHT, true);
|
|
||||||
pca9555_set_gpio_polarity(&dev_pca9555, PCA9555_PIN_BTN_BACK, true);
|
|
||||||
pca9555_set_gpio_polarity(&dev_pca9555, PCA9555_PIN_BTN_ACCEPT, true);
|
|
||||||
dev_pca9555.pin_state = 0;
|
|
||||||
|
|
||||||
// FPGA
|
// FPGA
|
||||||
dev_ice40.spi_bus = SPI_BUS;
|
dev_ice40.spi_bus = SPI_BUS;
|
||||||
dev_ice40.pin_cs = GPIO_SPI_CS_FPGA;
|
dev_ice40.pin_cs = GPIO_SPI_CS_FPGA;
|
||||||
dev_ice40.pin_done = -1;
|
dev_ice40.pin_done = -1;
|
||||||
dev_ice40.pin_reset = -1;
|
dev_ice40.pin_reset = -1;
|
||||||
dev_ice40.pin_int = GPIO_INT_FPGA;
|
dev_ice40.pin_int = GPIO_INT_FPGA;
|
||||||
dev_ice40.spi_speed = 23000000; // 23MHz
|
dev_ice40.spi_speed = 10000000; // 10 MHz //23000000; // 23MHz
|
||||||
dev_ice40.spi_max_transfer_size = SPI_MAX_TRANSFER_SIZE;
|
dev_ice40.spi_max_transfer_size = SPI_MAX_TRANSFER_SIZE;
|
||||||
dev_ice40.get_done = ice40_get_done_wrapper;
|
dev_ice40.get_done = ice40_get_done_wrapper;
|
||||||
dev_ice40.set_reset = ice40_set_reset_wrapper;
|
dev_ice40.set_reset = ice40_set_reset_wrapper;
|
||||||
|
@ -137,23 +135,6 @@ esp_err_t board_init() {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LCD display
|
|
||||||
dev_ili9341.spi_bus = SPI_BUS;
|
|
||||||
dev_ili9341.pin_cs = GPIO_SPI_CS_LCD;
|
|
||||||
dev_ili9341.pin_dcx = GPIO_SPI_DC_LCD;
|
|
||||||
dev_ili9341.pin_reset = -1;
|
|
||||||
dev_ili9341.rotation = 1;
|
|
||||||
dev_ili9341.color_mode = true; // Blue and red channels are swapped
|
|
||||||
dev_ili9341.spi_speed = 60000000; // 60MHz
|
|
||||||
dev_ili9341.spi_max_transfer_size = SPI_MAX_TRANSFER_SIZE;
|
|
||||||
dev_ili9341.callback = ili9341_set_lcd_mode; // Callback for changing LCD mode between ESP32 and FPGA
|
|
||||||
|
|
||||||
res = ili9341_init(&dev_ili9341);
|
|
||||||
if (res != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "Initializing LCD failed");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BNO055 sensor on system I2C bus
|
// BNO055 sensor on system I2C bus
|
||||||
|
|
||||||
res = bno055_init(&dev_bno055, I2C_BUS_SYS, BNO055_ADDR, GPIO_INT_BNO055, true);
|
res = bno055_init(&dev_bno055, I2C_BUS_SYS, BNO055_ADDR, GPIO_INT_BNO055, true);
|
||||||
|
@ -164,10 +145,6 @@ esp_err_t board_init() {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
PCA9555* get_pca9555() {
|
|
||||||
return &dev_pca9555;
|
|
||||||
}
|
|
||||||
|
|
||||||
BNO055* get_bno055() {
|
BNO055* get_bno055() {
|
||||||
return &dev_bno055;
|
return &dev_bno055;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,52 +3,35 @@
|
||||||
#include <sdkconfig.h>
|
#include <sdkconfig.h>
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
#include <driver/spi_master.h>
|
#include <driver/spi_master.h>
|
||||||
#include "pca9555.h"
|
|
||||||
#include "bno055.h"
|
#include "bno055.h"
|
||||||
#include "ili9341.h"
|
#include "ili9341.h"
|
||||||
#include "ice40.h"
|
#include "ice40.h"
|
||||||
#include "rp2040.h"
|
#include "rp2040.h"
|
||||||
|
|
||||||
// Interrupts
|
// Interrupts
|
||||||
#define GPIO_INT_RP2040 0
|
#define GPIO_INT_RP2040 34
|
||||||
#define GPIO_INT_PCA9555 34
|
|
||||||
#define GPIO_INT_BNO055 36
|
#define GPIO_INT_BNO055 36
|
||||||
#define GPIO_INT_FPGA 39
|
#define GPIO_INT_FPGA 39
|
||||||
|
|
||||||
// SD card
|
// SD card
|
||||||
#define SD_PWR 5
|
#define SD_PWR 19 // Also LED power
|
||||||
#define SD_D0 2
|
#define SD_D0 2
|
||||||
#define SD_CLK 14
|
#define SD_CLK 14
|
||||||
#define SD_CMD 15
|
#define SD_CMD 15
|
||||||
|
|
||||||
|
// LEDs
|
||||||
|
#define GPIO_LED_DATA 5
|
||||||
|
|
||||||
// I2S audio
|
// I2S audio
|
||||||
#define GPIO_I2S_CLK 14
|
#define GPIO_I2S_CLK 14
|
||||||
#define GPIO_I2S_DATA 13
|
#define GPIO_I2S_DATA 13
|
||||||
#define GPIO_I2S_LR 4
|
#define GPIO_I2S_LR 4
|
||||||
|
|
||||||
// System I2C bus
|
// I2C bus
|
||||||
#define GPIO_I2C_SYS_SCL 21
|
#define GPIO_I2C_SYS_SCL 21
|
||||||
#define GPIO_I2C_SYS_SDA 22
|
#define GPIO_I2C_SYS_SDA 22
|
||||||
#define I2C_BUS_SYS 0
|
#define I2C_BUS_SYS 0
|
||||||
#define I2C_SPEED_SYS 20000 // 20 kHz
|
#define I2C_SPEED_SYS 8000 // 8 kHz //20000 // 20 kHz
|
||||||
|
|
||||||
// PCA9555 IO expander
|
|
||||||
#define PCA9555_ADDR 0x26
|
|
||||||
#define PCA9555_PIN_RP2040_RESET 0
|
|
||||||
#define PCA9555_PIN_RP2040_BOOTSEL 1
|
|
||||||
#define PCA9555_PIN_FPGA_RESET 2
|
|
||||||
#define PCA9555_PIN_FPGA_CDONE 3
|
|
||||||
#define PCA9555_PIN_BTN_START 5
|
|
||||||
#define PCA9555_PIN_BTN_SELECT 6
|
|
||||||
#define PCA9555_PIN_BTN_MENU 7
|
|
||||||
#define PCA9555_PIN_BTN_HOME 8
|
|
||||||
#define PCA9555_PIN_BTN_JOY_LEFT 9
|
|
||||||
#define PCA9555_PIN_BTN_JOY_PRESS 10
|
|
||||||
#define PCA9555_PIN_BTN_JOY_DOWN 11
|
|
||||||
#define PCA9555_PIN_BTN_JOY_UP 12
|
|
||||||
#define PCA9555_PIN_BTN_JOY_RIGHT 13
|
|
||||||
#define PCA9555_PIN_BTN_BACK 14
|
|
||||||
#define PCA9555_PIN_BTN_ACCEPT 15
|
|
||||||
|
|
||||||
// RP2040 co-processor
|
// RP2040 co-processor
|
||||||
#define RP2040_ADDR 0x17
|
#define RP2040_ADDR 0x17
|
||||||
|
@ -56,27 +39,24 @@
|
||||||
// BNO055 sensor
|
// BNO055 sensor
|
||||||
#define BNO055_ADDR 0x28
|
#define BNO055_ADDR 0x28
|
||||||
|
|
||||||
// User I2C bus
|
|
||||||
#define GPIO_I2C_EXT_SCL 25
|
|
||||||
#define GPIO_I2C_EXT_SDA 26
|
|
||||||
#define I2C_BUS_EXT 1
|
|
||||||
#define I2C_SPEED_EXT 100000 // 100 kHz
|
|
||||||
|
|
||||||
// SPI bus
|
// SPI bus
|
||||||
#define GPIO_SPI_CLK 18
|
#define GPIO_SPI_CLK 18
|
||||||
#define GPIO_SPI_MOSI 23
|
#define GPIO_SPI_MOSI 23
|
||||||
#define GPIO_SPI_MISO 35
|
#define GPIO_SPI_MISO 35
|
||||||
#define GPIO_SPI_CS_RP2040 19
|
#define GPIO_SPI_CS_RP2040 19
|
||||||
#define GPIO_SPI_CS_FPGA 27
|
#define GPIO_SPI_CS_FPGA 27
|
||||||
#define GPIO_SPI_CS_LCD 32
|
|
||||||
#define GPIO_SPI_DC_LCD 33
|
|
||||||
#define SPI_BUS VSPI_HOST
|
#define SPI_BUS VSPI_HOST
|
||||||
#define SPI_MAX_TRANSFER_SIZE 4094
|
#define SPI_MAX_TRANSFER_SIZE 4094
|
||||||
#define SPI_DMA_CHANNEL 2
|
#define SPI_DMA_CHANNEL 2
|
||||||
|
|
||||||
esp_err_t board_init();
|
// LCD display
|
||||||
|
#define GPIO_LCD_RESET 25
|
||||||
|
#define GPIO_LCD_MODE 26
|
||||||
|
#define GPIO_SPI_CS_LCD 32
|
||||||
|
#define GPIO_SPI_DC_LCD 33
|
||||||
|
|
||||||
|
esp_err_t board_init(bool* aLcdReady);
|
||||||
|
|
||||||
PCA9555* get_pca9555();
|
|
||||||
BNO055* get_bno055();
|
BNO055* get_bno055();
|
||||||
ILI9341* get_ili9341();
|
ILI9341* get_ili9341();
|
||||||
ICE40* get_ice40();
|
ICE40* get_ice40();
|
||||||
|
|
|
@ -11,12 +11,52 @@
|
||||||
|
|
||||||
static const char *TAG = "RP2040";
|
static const char *TAG = "RP2040";
|
||||||
|
|
||||||
|
inline void _send_input_change(RP2040* device, uint8_t input, bool value) {
|
||||||
|
rp2040_input_message_t message;
|
||||||
|
message.input = input;
|
||||||
|
message.state = value;
|
||||||
|
xQueueSend(device->queue, &message, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rp2040_intr_task(void *arg) {
|
||||||
|
RP2040* device = (RP2040*) arg;
|
||||||
|
uint32_t state;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (xSemaphoreTake(device->_intr_trigger, portMAX_DELAY)) {
|
||||||
|
esp_err_t res = i2c_read_reg(device->i2c_bus, device->i2c_address, RP2040_REG_INPUT1, (uint8_t*) &state, 4);
|
||||||
|
if (res != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "RP2040 interrupt task failed to read from RP2040");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ESP_LOGW(TAG, "RP2040 input state %08x", state);
|
||||||
|
uint16_t interrupt = state >> 16;
|
||||||
|
uint16_t values = state & 0xFFFF;
|
||||||
|
for (uint8_t index = 0; index < 16; index++) {
|
||||||
|
if ((interrupt >> index) & 0x01) {
|
||||||
|
_send_input_change(device, index, (values >> index) & 0x01);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void rp2040_intr_handler(void *arg) {
|
||||||
|
/* in interrupt handler context */
|
||||||
|
RP2040* device = (RP2040*) arg;
|
||||||
|
xSemaphoreGiveFromISR(device->_intr_trigger, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t rp2040_init(RP2040* device) {
|
esp_err_t rp2040_init(RP2040* device) {
|
||||||
esp_err_t res;
|
esp_err_t res;
|
||||||
|
|
||||||
uint8_t firmware_version;
|
uint8_t firmware_version;
|
||||||
res = rp2040_get_firmware_version(device, &firmware_version);
|
res = rp2040_get_firmware_version(device, &firmware_version);
|
||||||
if (res != ESP_OK) return res;
|
if (res != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to read firmware version");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
if (firmware_version != 1) {
|
if (firmware_version != 1) {
|
||||||
ESP_LOGE(TAG, "Unsupported RP2040 firmware version (%u) found", firmware_version);
|
ESP_LOGE(TAG, "Unsupported RP2040 firmware version (%u) found", firmware_version);
|
||||||
|
@ -24,10 +64,40 @@ esp_err_t rp2040_init(RP2040* device) {
|
||||||
}
|
}
|
||||||
|
|
||||||
res = i2c_read_reg(device->i2c_bus, device->i2c_address, RP2040_REG_GPIO_DIR, &device->_gpio_direction, 1);
|
res = i2c_read_reg(device->i2c_bus, device->i2c_address, RP2040_REG_GPIO_DIR, &device->_gpio_direction, 1);
|
||||||
if (res != ESP_OK) return res;
|
if (res != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to read GPIO direction");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
res = i2c_read_reg(device->i2c_bus, device->i2c_address, RP2040_REG_GPIO_OUT, &device->_gpio_value, 1);
|
res = i2c_read_reg(device->i2c_bus, device->i2c_address, RP2040_REG_GPIO_OUT, &device->_gpio_value, 1);
|
||||||
if (res != ESP_OK) return res;
|
if (res != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to read GPIO state");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create interrupt trigger
|
||||||
|
device->_intr_trigger = xSemaphoreCreateBinary();
|
||||||
|
if (device->_intr_trigger == NULL) return ESP_ERR_NO_MEM;
|
||||||
|
|
||||||
|
//Attach interrupt to interrupt pin
|
||||||
|
if (device->pin_interrupt >= 0) {
|
||||||
|
res = gpio_isr_handler_add(device->pin_interrupt, rp2040_intr_handler, (void*) device);
|
||||||
|
if (res != ESP_OK) return res;
|
||||||
|
|
||||||
|
gpio_config_t io_conf = {
|
||||||
|
.intr_type = GPIO_INTR_NEGEDGE,
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pin_bit_mask = 1LL << device->pin_interrupt,
|
||||||
|
.pull_down_en = 0,
|
||||||
|
.pull_up_en = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
res = gpio_config(&io_conf);
|
||||||
|
if (res != ESP_OK) return res;
|
||||||
|
|
||||||
|
xTaskCreate(&rp2040_intr_task, "RP2040 interrupt", 4096, (void*) device, 10, &device->_intr_task_handle);
|
||||||
|
xSemaphoreGive(device->_intr_trigger);
|
||||||
|
}
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
@ -68,22 +138,6 @@ esp_err_t rp2040_set_gpio_value(RP2040* device, uint8_t gpio, bool value) {
|
||||||
return i2c_write_reg_n(device->i2c_bus, device->i2c_address, RP2040_REG_GPIO_OUT, &device->_gpio_value, 1);
|
return i2c_write_reg_n(device->i2c_bus, device->i2c_address, RP2040_REG_GPIO_OUT, &device->_gpio_value, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t rp2040_get_lcd_mode(RP2040* device, lcd_mode_t* mode) {
|
|
||||||
return i2c_read_reg(device->i2c_bus, device->i2c_address, RP2040_REG_LCD_MODE, (uint8_t*) mode, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t rp2040_set_lcd_mode(RP2040* device, lcd_mode_t mode) {
|
|
||||||
esp_err_t res;
|
|
||||||
lcd_mode_t verification;
|
|
||||||
do {
|
|
||||||
res = i2c_write_reg_n(device->i2c_bus, device->i2c_address, RP2040_REG_LCD_MODE, (uint8_t*) &mode, 1);
|
|
||||||
if (res != ESP_OK) return res;
|
|
||||||
res = rp2040_get_lcd_mode(device, &verification);
|
|
||||||
if (res != ESP_OK) return res;
|
|
||||||
} while (verification != mode);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t rp2040_get_lcd_backlight(RP2040* device, uint8_t* brightness) {
|
esp_err_t rp2040_get_lcd_backlight(RP2040* device, uint8_t* brightness) {
|
||||||
return i2c_read_reg(device->i2c_bus, device->i2c_address, RP2040_REG_LCD_BACKLIGHT, brightness, 1);
|
return i2c_read_reg(device->i2c_bus, device->i2c_address, RP2040_REG_LCD_BACKLIGHT, brightness, 1);
|
||||||
}
|
}
|
||||||
|
@ -92,44 +146,11 @@ esp_err_t rp2040_set_lcd_backlight(RP2040* device, uint8_t brightness) {
|
||||||
return i2c_write_reg_n(device->i2c_bus, device->i2c_address, RP2040_REG_LCD_BACKLIGHT, &brightness, 1);
|
return i2c_write_reg_n(device->i2c_bus, device->i2c_address, RP2040_REG_LCD_BACKLIGHT, &brightness, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t rp2040_get_led_mode(RP2040* device, bool* enabled, bool* automatic_flush) {
|
esp_err_t rp2040_set_fpga(RP2040* device, bool enabled) {
|
||||||
uint8_t value;
|
uint8_t value = enabled ? 0x01 : 0x00;
|
||||||
esp_err_t res = i2c_read_reg(device->i2c_bus, device->i2c_address, RP2040_REG_LED_MODE, &value, 1);
|
return i2c_write_reg_n(device->i2c_bus, device->i2c_address, RP2040_REG_FPGA, &value, 1);
|
||||||
if (res != ESP_OK) return res;
|
|
||||||
*enabled = (value >> 0) & 0x01;
|
|
||||||
*automatic_flush = (value >> 1) & 0x01;
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t rp2040_set_led_mode(RP2040* device, bool enabled, bool automatic_flush) {
|
esp_err_t rp2040_read_buttons(RP2040* device, uint16_t* value) {
|
||||||
uint8_t value = enabled | (automatic_flush << 1);
|
return i2c_read_reg(device->i2c_bus, device->i2c_address, RP2040_REG_INPUT1, (uint8_t*) value, 2);
|
||||||
return i2c_write_reg_n(device->i2c_bus, device->i2c_address, RP2040_REG_LED_MODE, &value, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t rp2040_get_led_value(RP2040* device, uint8_t led, uint8_t* red, uint8_t* green, uint8_t* blue) {
|
|
||||||
if (led > 5) return ESP_ERR_NOT_FOUND;
|
|
||||||
uint8_t value[3];
|
|
||||||
esp_err_t res = i2c_read_reg(device->i2c_bus, device->i2c_address, RP2040_REG_LED_R0 + (led * 3), value, 3);
|
|
||||||
if (res != ESP_OK) return res;
|
|
||||||
*red = value[0];
|
|
||||||
*green = value[1];
|
|
||||||
*blue = value[2];
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t rp2040_set_led_value(RP2040* device, uint8_t led, uint8_t red, uint8_t green, uint8_t blue) {
|
|
||||||
if (led > 5) return ESP_ERR_NOT_FOUND;
|
|
||||||
uint8_t value[3];
|
|
||||||
value[0] = red;
|
|
||||||
value[1] = green;
|
|
||||||
value[2] = blue;
|
|
||||||
return i2c_write_reg_n(device->i2c_bus, device->i2c_address, RP2040_REG_LED_R0 + (led * 3), value, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t rp2040_get_led_values(RP2040* device, uint8_t* buffer) {
|
|
||||||
return i2c_read_reg(device->i2c_bus, device->i2c_address, RP2040_REG_LED_R0, buffer, 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t rp2040_set_led_values(RP2040* device, uint8_t* buffer) {
|
|
||||||
return i2c_write_reg_n(device->i2c_bus, device->i2c_address, RP2040_REG_LED_R0, buffer, 15);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,36 +6,106 @@
|
||||||
#include <freertos/FreeRTOS.h>
|
#include <freertos/FreeRTOS.h>
|
||||||
#include <freertos/semphr.h>
|
#include <freertos/semphr.h>
|
||||||
#include <freertos/task.h>
|
#include <freertos/task.h>
|
||||||
|
#include <freertos/queue.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RP2040_REG_FW_VER = 0,
|
RP2040_REG_FW_VER = 0,
|
||||||
RP2040_REG_GPIO_DIR,
|
RP2040_REG_GPIO_DIR,
|
||||||
RP2040_REG_GPIO_IN,
|
RP2040_REG_GPIO_IN,
|
||||||
RP2040_REG_GPIO_OUT,
|
RP2040_REG_GPIO_OUT,
|
||||||
RP2040_REG_LCD_MODE,
|
|
||||||
RP2040_REG_LCD_BACKLIGHT,
|
RP2040_REG_LCD_BACKLIGHT,
|
||||||
RP2040_REG_LED_MODE,
|
RP2040_REG_FPGA,
|
||||||
RP2040_REG_LED_R0,
|
RP2040_REG_INPUT1,
|
||||||
RP2040_REG_LED_G0,
|
RP2040_REG_INPUT2,
|
||||||
RP2040_REG_LED_B0,
|
RP2040_REG_INTERRUPT1,
|
||||||
RP2040_REG_LED_R1,
|
RP2040_REG_INTERRUPT2,
|
||||||
RP2040_REG_LED_G1,
|
RP2040_REG_ADC_TRIGGER,
|
||||||
RP2040_REG_LED_B1,
|
RP2040_REG_ADC_VALUE_VUSB1,
|
||||||
RP2040_REG_LED_R2,
|
RP2040_REG_ADC_VALUE_VUSB2,
|
||||||
RP2040_REG_LED_G2,
|
RP2040_REG_ADC_VALUE_VBAT1,
|
||||||
RP2040_REG_LED_B2,
|
RP2040_REG_ADC_VALUE_VBAT2,
|
||||||
RP2040_REG_LED_R3,
|
RP2040_REG_USB,
|
||||||
RP2040_REG_LED_G3,
|
RP2040_REG_SCRATCH0, // Used by the ESP32 to store boot parameters, can also be read and written to from WebUSB
|
||||||
RP2040_REG_LED_B3,
|
RP2040_REG_SCRATCH1,
|
||||||
RP2040_REG_LED_R4,
|
RP2040_REG_SCRATCH2,
|
||||||
RP2040_REG_LED_G4,
|
RP2040_REG_SCRATCH3,
|
||||||
RP2040_REG_LED_B4,
|
RP2040_REG_SCRATCH4,
|
||||||
|
RP2040_REG_SCRATCH5,
|
||||||
|
RP2040_REG_SCRATCH6,
|
||||||
|
RP2040_REG_SCRATCH7,
|
||||||
|
RP2040_REG_SCRATCH8,
|
||||||
|
RP2040_REG_SCRATCH9,
|
||||||
|
RP2040_REG_SCRATCH10,
|
||||||
|
RP2040_REG_SCRATCH11,
|
||||||
|
RP2040_REG_SCRATCH12,
|
||||||
|
RP2040_REG_SCRATCH13,
|
||||||
|
RP2040_REG_SCRATCH14,
|
||||||
|
RP2040_REG_SCRATCH15,
|
||||||
|
RP2040_REG_SCRATCH16,
|
||||||
|
RP2040_REG_SCRATCH17,
|
||||||
|
RP2040_REG_SCRATCH18,
|
||||||
|
RP2040_REG_SCRATCH19,
|
||||||
|
RP2040_REG_SCRATCH20,
|
||||||
|
RP2040_REG_SCRATCH21,
|
||||||
|
RP2040_REG_SCRATCH22,
|
||||||
|
RP2040_REG_SCRATCH23,
|
||||||
|
RP2040_REG_SCRATCH24,
|
||||||
|
RP2040_REG_SCRATCH25,
|
||||||
|
RP2040_REG_SCRATCH26,
|
||||||
|
RP2040_REG_SCRATCH27,
|
||||||
|
RP2040_REG_SCRATCH28,
|
||||||
|
RP2040_REG_SCRATCH29,
|
||||||
|
RP2040_REG_SCRATCH30,
|
||||||
|
RP2040_REG_SCRATCH31,
|
||||||
|
RP2040_REG_SCRATCH32,
|
||||||
|
RP2040_REG_SCRATCH33,
|
||||||
|
RP2040_REG_SCRATCH34,
|
||||||
|
RP2040_REG_SCRATCH35,
|
||||||
|
RP2040_REG_SCRATCH36,
|
||||||
|
RP2040_REG_SCRATCH37,
|
||||||
|
RP2040_REG_SCRATCH38,
|
||||||
|
RP2040_REG_SCRATCH39,
|
||||||
|
RP2040_REG_SCRATCH40,
|
||||||
|
RP2040_REG_SCRATCH41,
|
||||||
|
RP2040_REG_SCRATCH42,
|
||||||
|
RP2040_REG_SCRATCH43,
|
||||||
|
RP2040_REG_SCRATCH44,
|
||||||
|
RP2040_REG_SCRATCH45,
|
||||||
|
RP2040_REG_SCRATCH46,
|
||||||
|
RP2040_REG_SCRATCH47,
|
||||||
|
RP2040_REG_SCRATCH48,
|
||||||
|
RP2040_REG_SCRATCH49,
|
||||||
|
RP2040_REG_SCRATCH50,
|
||||||
|
RP2040_REG_SCRATCH51,
|
||||||
|
RP2040_REG_SCRATCH52,
|
||||||
|
RP2040_REG_SCRATCH53,
|
||||||
|
RP2040_REG_SCRATCH54,
|
||||||
|
RP2040_REG_SCRATCH55,
|
||||||
|
RP2040_REG_SCRATCH56,
|
||||||
|
RP2040_REG_SCRATCH57,
|
||||||
|
RP2040_REG_SCRATCH58,
|
||||||
|
RP2040_REG_SCRATCH59,
|
||||||
|
RP2040_REG_SCRATCH60,
|
||||||
|
RP2040_REG_SCRATCH61,
|
||||||
|
RP2040_REG_SCRATCH62,
|
||||||
|
RP2040_REG_SCRATCH63
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
enum {
|
||||||
LCD_MODE_SPI = 0,
|
RP2040_INPUT_BUTTON_HOME = 0,
|
||||||
LCD_MODE_PARALLEL = 1
|
RP2040_INPUT_BUTTON_MENU,
|
||||||
} lcd_mode_t;
|
RP2040_INPUT_BUTTON_START,
|
||||||
|
RP2040_INPUT_BUTTON_ACCEPT,
|
||||||
|
RP2040_INPUT_BUTTON_BACK,
|
||||||
|
RP2040_INPUT_FPGA_CDONE,
|
||||||
|
RP2040_INPUT_BATTERY_CHARGING,
|
||||||
|
RP2040_INPUT_BUTTON_SELECT,
|
||||||
|
RP2040_INPUT_JOYSTICK_LEFT,
|
||||||
|
RP2040_INPUT_JOYSTICK_PRESS,
|
||||||
|
RP2040_INPUT_JOYSTICK_DOWN,
|
||||||
|
RP2040_INPUT_JOYSTICK_UP,
|
||||||
|
RP2040_INPUT_JOYSTICK_RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
typedef void (*rp2040_intr_t)();
|
typedef void (*rp2040_intr_t)();
|
||||||
|
|
||||||
|
@ -43,14 +113,19 @@ typedef struct {
|
||||||
int i2c_bus;
|
int i2c_bus;
|
||||||
int i2c_address;
|
int i2c_address;
|
||||||
int pin_interrupt;
|
int pin_interrupt;
|
||||||
|
xQueueHandle queue;
|
||||||
rp2040_intr_t _intr_handler;
|
rp2040_intr_t _intr_handler;
|
||||||
TaskHandle_t _intr_task_handle;
|
TaskHandle_t _intr_task_handle;
|
||||||
xSemaphoreHandle _intr_trigger;
|
xSemaphoreHandle _intr_trigger;
|
||||||
xSemaphoreHandle _mux;
|
|
||||||
uint8_t _gpio_direction;
|
uint8_t _gpio_direction;
|
||||||
uint8_t _gpio_value;
|
uint8_t _gpio_value;
|
||||||
} RP2040;
|
} RP2040;
|
||||||
|
|
||||||
|
typedef struct _rp2040_input_message {
|
||||||
|
uint8_t input;
|
||||||
|
bool state;
|
||||||
|
} rp2040_input_message_t;
|
||||||
|
|
||||||
esp_err_t rp2040_init(RP2040* device);
|
esp_err_t rp2040_init(RP2040* device);
|
||||||
|
|
||||||
esp_err_t rp2040_get_firmware_version(RP2040* device, uint8_t* version);
|
esp_err_t rp2040_get_firmware_version(RP2040* device, uint8_t* version);
|
||||||
|
@ -61,17 +136,9 @@ esp_err_t rp2040_set_gpio_dir(RP2040* device, uint8_t gpio, bool direction);
|
||||||
esp_err_t rp2040_get_gpio_value(RP2040* device, uint8_t gpio, bool* value);
|
esp_err_t rp2040_get_gpio_value(RP2040* device, uint8_t gpio, bool* value);
|
||||||
esp_err_t rp2040_set_gpio_value(RP2040* device, uint8_t gpio, bool value);
|
esp_err_t rp2040_set_gpio_value(RP2040* device, uint8_t gpio, bool value);
|
||||||
|
|
||||||
esp_err_t rp2040_get_lcd_mode(RP2040* device, lcd_mode_t* mode);
|
|
||||||
esp_err_t rp2040_set_lcd_mode(RP2040* device, lcd_mode_t mode);
|
|
||||||
|
|
||||||
esp_err_t rp2040_get_lcd_backlight(RP2040* device, uint8_t* brightness);
|
esp_err_t rp2040_get_lcd_backlight(RP2040* device, uint8_t* brightness);
|
||||||
esp_err_t rp2040_set_lcd_backlight(RP2040* device, uint8_t brightness);
|
esp_err_t rp2040_set_lcd_backlight(RP2040* device, uint8_t brightness);
|
||||||
|
|
||||||
esp_err_t rp2040_get_led_mode(RP2040* device, bool* enabled, bool* automatic_flush);
|
esp_err_t rp2040_set_fpga(RP2040* device, bool enabled);
|
||||||
esp_err_t rp2040_set_led_mode(RP2040* device, bool enabled, bool automatic_flush);
|
|
||||||
|
|
||||||
esp_err_t rp2040_get_led_value(RP2040* device, uint8_t led, uint8_t* red, uint8_t* green, uint8_t* blue);
|
esp_err_t rp2040_read_buttons(RP2040* device, uint16_t* value);
|
||||||
esp_err_t rp2040_set_led_value(RP2040* device, uint8_t led, uint8_t red, uint8_t green, uint8_t blue);
|
|
||||||
|
|
||||||
esp_err_t rp2040_get_led_values(RP2040* device, uint8_t* buffer); // Expects a buffer that can fit 15 bytes (R, G, B * 5 LEDs)
|
|
||||||
esp_err_t rp2040_set_led_values(RP2040* device, uint8_t* buffer); // Expects a buffer that can contains 15 bytes (R, G, B * 5 LEDs)
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1c2b5241dd00d2fddb45d20f3c4a426fa379fa95
|
Subproject commit 4263f4f60d3d410ebf2ae88a7a26b23bd08eedde
|
|
@ -1 +1 @@
|
||||||
Subproject commit c83ac9b467d73595ebd6f15f6f444068fe2d3198
|
Subproject commit 4bc90991a83df4e733705cc7c89906c64756e0f2
|
4
components/ws2812/CMakeLists.txt
Normal file
4
components/ws2812/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
idf_component_register(
|
||||||
|
SRCS "ws2812.c"
|
||||||
|
INCLUDE_DIRS include
|
||||||
|
)
|
35
components/ws2812/include/ws2812.h
Normal file
35
components/ws2812/include/ws2812.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <esp_err.h>
|
||||||
|
#include <driver/gpio.h>
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the leds driver. (configure SPI bus and GPIO pins)
|
||||||
|
* @return ESP_OK on success; any other value indicates an error
|
||||||
|
*/
|
||||||
|
extern esp_err_t ws2812_init(gpio_num_t aGpioPin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable power to the leds bar.
|
||||||
|
* @return ESP_OK on success; any other value indicates an error
|
||||||
|
*/
|
||||||
|
extern esp_err_t ws2812_enable(int gpio_pin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable power to the leds bar.
|
||||||
|
* @return ESP_OK on success; any other value indicates an error
|
||||||
|
*/
|
||||||
|
extern esp_err_t ws2812_disable(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send color-data to the leds bus.
|
||||||
|
* @param data the data-bytes to send on the bus.
|
||||||
|
* @param len the data-length.
|
||||||
|
* @return ESP_OK on success; any other value indicates an error
|
||||||
|
*/
|
||||||
|
extern esp_err_t ws2812_send_data(uint8_t *data, int len);
|
||||||
|
|
||||||
|
__END_DECLS
|
124
components/ws2812/ws2812.c
Normal file
124
components/ws2812/ws2812.c
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
//This driver uses the ESP32 RMT peripheral to drive "Neopixel" compatible LEDs
|
||||||
|
//The usage of the RMT peripheral has been implemented using work by JSchaenzie:
|
||||||
|
//you can find his work at https://github.com/JSchaenzle/ESP32-NeoPixel-WS2812-RMT
|
||||||
|
|
||||||
|
#include <sdkconfig.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <freertos/FreeRTOS.h>
|
||||||
|
#include <freertos/task.h>
|
||||||
|
#include <esp_err.h>
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
#include <driver/gpio.h>
|
||||||
|
#include <driver/rmt.h>
|
||||||
|
|
||||||
|
static const char *TAG = "ws2812";
|
||||||
|
|
||||||
|
#define WS2812_RMT_CHANNEL RMT_CHANNEL_0
|
||||||
|
|
||||||
|
#define T0H 14 // 0 bit high time
|
||||||
|
#define T1H 52 // 1 bit high time
|
||||||
|
#define TL 52 // low time for either bit
|
||||||
|
|
||||||
|
static bool gActive = false;
|
||||||
|
rmt_item32_t* gBuffer = NULL;
|
||||||
|
int gBufferLength = 0;
|
||||||
|
gpio_num_t gPin;
|
||||||
|
|
||||||
|
esp_err_t ws2812_init(gpio_num_t aGpioPin) {
|
||||||
|
if (gActive) return ESP_OK;
|
||||||
|
gpio_config_t io_conf = {
|
||||||
|
.intr_type = GPIO_INTR_DISABLE,
|
||||||
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
|
.pin_bit_mask = 1LL << aGpioPin,
|
||||||
|
.pull_down_en = 0,
|
||||||
|
.pull_up_en = 0,
|
||||||
|
};
|
||||||
|
esp_err_t res = gpio_config(&io_conf);
|
||||||
|
if (res != ESP_OK) return res;
|
||||||
|
rmt_config_t config;
|
||||||
|
config.rmt_mode = RMT_MODE_TX;
|
||||||
|
config.channel = WS2812_RMT_CHANNEL;
|
||||||
|
config.gpio_num = aGpioPin;
|
||||||
|
config.mem_block_num = 3;
|
||||||
|
config.tx_config.loop_en = false;
|
||||||
|
config.tx_config.carrier_en = false;
|
||||||
|
config.tx_config.idle_output_en = true;
|
||||||
|
config.tx_config.idle_level = 0;
|
||||||
|
config.clk_div = 2;
|
||||||
|
res = rmt_config(&config);
|
||||||
|
if (res != ESP_OK) return res;
|
||||||
|
res = rmt_driver_install(config.channel, 0, 0);
|
||||||
|
if (res != ESP_OK) return res;
|
||||||
|
gActive = true;
|
||||||
|
gPin = aGpioPin;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t ws2812_deinit(void) {
|
||||||
|
if (!gActive) return ESP_OK;
|
||||||
|
esp_err_t res = rmt_driver_uninstall(WS2812_RMT_CHANNEL);
|
||||||
|
if (res != ESP_OK) return res;
|
||||||
|
gpio_config_t io_conf = {
|
||||||
|
.intr_type = GPIO_INTR_DISABLE,
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pin_bit_mask = 1LL << gPin,
|
||||||
|
.pull_down_en = 0,
|
||||||
|
.pull_up_en = 0,
|
||||||
|
};
|
||||||
|
res = gpio_config(&io_conf);
|
||||||
|
if (res != ESP_OK) return res;
|
||||||
|
gActive = false;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t ws2812_prepare_data(uint8_t *data, int len)
|
||||||
|
{
|
||||||
|
if (gBuffer != NULL) return ESP_FAIL;
|
||||||
|
gBuffer = calloc(len * 8, sizeof(rmt_item32_t));
|
||||||
|
if (gBuffer == NULL) return ESP_FAIL;
|
||||||
|
gBufferLength = len * 8;
|
||||||
|
for (uint32_t pos = 0; pos < len; pos++) {
|
||||||
|
uint32_t mask = 1 << 7;
|
||||||
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
|
bool bit = data[pos] & mask;
|
||||||
|
gBuffer[pos*8 + i] = bit ?
|
||||||
|
(rmt_item32_t){{{T1H, 1, TL, 0}}} :
|
||||||
|
(rmt_item32_t){{{T0H, 1, TL, 0}}};
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t ws2812_free_data() {
|
||||||
|
if (!gBuffer) return ESP_FAIL;
|
||||||
|
free(gBuffer);
|
||||||
|
gBuffer = NULL;
|
||||||
|
gBufferLength = 0;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t ws2812_send_data(uint8_t *data, int len)
|
||||||
|
{
|
||||||
|
if (!gActive) return ESP_FAIL;
|
||||||
|
esp_err_t res = ws2812_prepare_data(data, len);
|
||||||
|
if (res != ESP_OK) return res;
|
||||||
|
res = rmt_write_items(WS2812_RMT_CHANNEL, gBuffer, gBufferLength, false);
|
||||||
|
if (res != ESP_OK) {
|
||||||
|
ws2812_free_data();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
res = rmt_wait_tx_done(WS2812_RMT_CHANNEL, portMAX_DELAY);
|
||||||
|
if (res != ESP_OK) {
|
||||||
|
ws2812_free_data();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
res = ws2812_free_data();
|
||||||
|
return res;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS "main.c" "menu.c" "fpga_test.c" "pax_keyboard.c" "button_wrapper.c" "system_wrapper.c" "appfs_wrapper.c" "graphics_wrapper.c" "settings.c" "wifi_connection.c"
|
SRCS "main.c" "menu.c" "fpga_test.c" "pax_keyboard.c" "system_wrapper.c" "appfs_wrapper.c" "graphics_wrapper.c" "settings.c" "wifi_connection.c"
|
||||||
INCLUDE_DIRS "." "include"
|
INCLUDE_DIRS "." "include"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
#include "button_wrapper.h"
|
|
||||||
|
|
||||||
xQueueHandle queue;
|
|
||||||
|
|
||||||
void button_handler(uint8_t pin, bool value) {
|
|
||||||
button_message_t message;
|
|
||||||
message.button = pin;
|
|
||||||
message.state = value;
|
|
||||||
xQueueSend(queue, &message, portMAX_DELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void button_init(PCA9555* aPca9555, xQueueHandle aQueue) {
|
|
||||||
queue = aQueue;
|
|
||||||
pca9555_set_interrupt_handler(aPca9555, PCA9555_PIN_BTN_START, button_handler);
|
|
||||||
pca9555_set_interrupt_handler(aPca9555, PCA9555_PIN_BTN_SELECT, button_handler);
|
|
||||||
pca9555_set_interrupt_handler(aPca9555, PCA9555_PIN_BTN_MENU, button_handler);
|
|
||||||
pca9555_set_interrupt_handler(aPca9555, PCA9555_PIN_BTN_HOME, button_handler);
|
|
||||||
pca9555_set_interrupt_handler(aPca9555, PCA9555_PIN_BTN_JOY_LEFT, button_handler);
|
|
||||||
pca9555_set_interrupt_handler(aPca9555, PCA9555_PIN_BTN_JOY_PRESS, button_handler);
|
|
||||||
pca9555_set_interrupt_handler(aPca9555, PCA9555_PIN_BTN_JOY_DOWN, button_handler);
|
|
||||||
pca9555_set_interrupt_handler(aPca9555, PCA9555_PIN_BTN_JOY_UP, button_handler);
|
|
||||||
pca9555_set_interrupt_handler(aPca9555, PCA9555_PIN_BTN_JOY_RIGHT, button_handler);
|
|
||||||
pca9555_set_interrupt_handler(aPca9555, PCA9555_PIN_BTN_BACK, button_handler);
|
|
||||||
pca9555_set_interrupt_handler(aPca9555, PCA9555_PIN_BTN_ACCEPT, button_handler);
|
|
||||||
}
|
|
|
@ -7,8 +7,8 @@
|
||||||
#include "fpga.h"
|
#include "fpga.h"
|
||||||
#include "ili9341.h"
|
#include "ili9341.h"
|
||||||
#include "ice40.h"
|
#include "ice40.h"
|
||||||
|
#include "rp2040.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
#include "button_wrapper.h"
|
|
||||||
|
|
||||||
static const char *TAG = "fpga_test";
|
static const char *TAG = "fpga_test";
|
||||||
|
|
||||||
|
@ -139,12 +139,12 @@ void fpga_test(ILI9341* ili9341, ICE40* ice40, xQueueHandle buttonQueue) {
|
||||||
|
|
||||||
bool waitForChoice = true;
|
bool waitForChoice = true;
|
||||||
while (waitForChoice) {
|
while (waitForChoice) {
|
||||||
button_message_t buttonMessage = {0};
|
rp2040_input_message_t buttonMessage = {0};
|
||||||
printf("Waiting for button press...\n");
|
printf("Waiting for button press...\n");
|
||||||
if (xQueueReceive(buttonQueue, &buttonMessage, portMAX_DELAY) == pdTRUE) {
|
if (xQueueReceive(buttonQueue, &buttonMessage, portMAX_DELAY) == pdTRUE) {
|
||||||
printf("Button: %u, %u\n", buttonMessage.button, buttonMessage.state);
|
printf("Button: %u, %u\n", buttonMessage.input, buttonMessage.state);
|
||||||
if (buttonMessage.state) {
|
if (buttonMessage.state) {
|
||||||
switch(buttonMessage.button) {
|
/*switch(buttonMessage.button) {
|
||||||
case PCA9555_PIN_BTN_HOME:
|
case PCA9555_PIN_BTN_HOME:
|
||||||
case PCA9555_PIN_BTN_MENU:
|
case PCA9555_PIN_BTN_MENU:
|
||||||
case PCA9555_PIN_BTN_BACK:
|
case PCA9555_PIN_BTN_BACK:
|
||||||
|
@ -156,7 +156,7 @@ void fpga_test(ILI9341* ili9341, ICE40* ice40, xQueueHandle buttonQueue) {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "graphics_wrapper.h"
|
#include "graphics_wrapper.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
#include "pax_keyboard.h"
|
#include "pax_keyboard.h"
|
||||||
#include "button_wrapper.h"
|
#include "rp2040.h"
|
||||||
|
|
||||||
void render_message(pax_buf_t *aBuffer, char* message, float aPosX, float aPosY, float aWidth, float aHeight) {
|
void render_message(pax_buf_t *aBuffer, char* message, float aPosX, float aPosY, float aWidth, float aHeight) {
|
||||||
pax_col_t fgColor = 0xFFFF0000;
|
pax_col_t fgColor = 0xFFFF0000;
|
||||||
|
@ -70,68 +70,68 @@ bool keyboard(xQueueHandle buttonQueue, pax_buf_t* aBuffer, ILI9341* ili9341, ui
|
||||||
|
|
||||||
bool running = true;
|
bool running = true;
|
||||||
while (running) {
|
while (running) {
|
||||||
button_message_t buttonMessage = {0};
|
rp2040_input_message_t buttonMessage = {0};
|
||||||
if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) {
|
if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) {
|
||||||
uint8_t pin = buttonMessage.button;
|
uint8_t pin = buttonMessage.input;
|
||||||
bool value = buttonMessage.state;
|
bool value = buttonMessage.state;
|
||||||
switch(pin) {
|
switch(pin) {
|
||||||
case PCA9555_PIN_BTN_JOY_DOWN:
|
case RP2040_INPUT_JOYSTICK_DOWN:
|
||||||
if (value) {
|
if (value) {
|
||||||
pkb_press(&kb_ctx, PKB_DOWN);
|
pkb_press(&kb_ctx, PKB_DOWN);
|
||||||
} else {
|
} else {
|
||||||
pkb_release(&kb_ctx, PKB_DOWN);
|
pkb_release(&kb_ctx, PKB_DOWN);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_JOY_UP:
|
case RP2040_INPUT_JOYSTICK_UP:
|
||||||
if (value) {
|
if (value) {
|
||||||
pkb_press(&kb_ctx, PKB_UP);
|
pkb_press(&kb_ctx, PKB_UP);
|
||||||
} else {
|
} else {
|
||||||
pkb_release(&kb_ctx, PKB_UP);
|
pkb_release(&kb_ctx, PKB_UP);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_JOY_LEFT:
|
case RP2040_INPUT_JOYSTICK_LEFT:
|
||||||
if (value) {
|
if (value) {
|
||||||
pkb_press(&kb_ctx, PKB_LEFT);
|
pkb_press(&kb_ctx, PKB_LEFT);
|
||||||
} else {
|
} else {
|
||||||
pkb_release(&kb_ctx, PKB_LEFT);
|
pkb_release(&kb_ctx, PKB_LEFT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_JOY_RIGHT:
|
case RP2040_INPUT_JOYSTICK_RIGHT:
|
||||||
if (value) {
|
if (value) {
|
||||||
pkb_press(&kb_ctx, PKB_RIGHT);
|
pkb_press(&kb_ctx, PKB_RIGHT);
|
||||||
} else {
|
} else {
|
||||||
pkb_release(&kb_ctx, PKB_RIGHT);
|
pkb_release(&kb_ctx, PKB_RIGHT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_JOY_PRESS:
|
case RP2040_INPUT_JOYSTICK_PRESS:
|
||||||
if (value) {
|
if (value) {
|
||||||
pkb_press(&kb_ctx, PKB_SHIFT);
|
pkb_press(&kb_ctx, PKB_SHIFT);
|
||||||
} else {
|
} else {
|
||||||
pkb_release(&kb_ctx, PKB_SHIFT);
|
pkb_release(&kb_ctx, PKB_SHIFT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_ACCEPT:
|
case RP2040_INPUT_BUTTON_ACCEPT:
|
||||||
if (value) {
|
if (value) {
|
||||||
pkb_press(&kb_ctx, PKB_CHARSELECT);
|
pkb_press(&kb_ctx, PKB_CHARSELECT);
|
||||||
} else {
|
} else {
|
||||||
pkb_release(&kb_ctx, PKB_CHARSELECT);
|
pkb_release(&kb_ctx, PKB_CHARSELECT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_BACK:
|
case RP2040_INPUT_BUTTON_BACK:
|
||||||
if (value) {
|
if (value) {
|
||||||
pkb_press(&kb_ctx, PKB_DELETE_BEFORE);
|
pkb_press(&kb_ctx, PKB_DELETE_BEFORE);
|
||||||
} else {
|
} else {
|
||||||
pkb_release(&kb_ctx, PKB_DELETE_BEFORE);
|
pkb_release(&kb_ctx, PKB_DELETE_BEFORE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_SELECT:
|
case RP2040_INPUT_BUTTON_SELECT:
|
||||||
if (value) {
|
if (value) {
|
||||||
pkb_press(&kb_ctx, PKB_MODESELECT);
|
pkb_press(&kb_ctx, PKB_MODESELECT);
|
||||||
} else {
|
} else {
|
||||||
pkb_release(&kb_ctx, PKB_MODESELECT);
|
pkb_release(&kb_ctx, PKB_MODESELECT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_HOME:
|
case RP2040_INPUT_BUTTON_HOME:
|
||||||
if (value) {
|
if (value) {
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sdkconfig.h>
|
|
||||||
#include <freertos/FreeRTOS.h>
|
|
||||||
#include <freertos/queue.h>
|
|
||||||
#include "hardware.h"
|
|
||||||
|
|
||||||
typedef struct _button_message {
|
|
||||||
uint8_t button;
|
|
||||||
bool state;
|
|
||||||
} button_message_t;
|
|
||||||
|
|
||||||
void button_init(PCA9555* aPca9555, xQueueHandle aQueue);
|
|
77
main/main.c
77
main/main.c
|
@ -21,13 +21,14 @@
|
||||||
#include "fpga_test.h"
|
#include "fpga_test.h"
|
||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "button_wrapper.h"
|
|
||||||
#include "system_wrapper.h"
|
#include "system_wrapper.h"
|
||||||
#include "graphics_wrapper.h"
|
#include "graphics_wrapper.h"
|
||||||
#include "appfs_wrapper.h"
|
#include "appfs_wrapper.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "wifi_connection.h"
|
#include "wifi_connection.h"
|
||||||
|
|
||||||
|
#include "ws2812.h"
|
||||||
|
|
||||||
static const char *TAG = "main";
|
static const char *TAG = "main";
|
||||||
|
|
||||||
typedef enum action {
|
typedef enum action {
|
||||||
|
@ -85,24 +86,24 @@ void menu_launcher(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili
|
||||||
menu_args_t* menuArgs = NULL;
|
menu_args_t* menuArgs = NULL;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
button_message_t buttonMessage = {0};
|
rp2040_input_message_t buttonMessage = {0};
|
||||||
if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) {
|
if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) {
|
||||||
uint8_t pin = buttonMessage.button;
|
uint8_t pin = buttonMessage.input;
|
||||||
bool value = buttonMessage.state;
|
bool value = buttonMessage.state;
|
||||||
switch(pin) {
|
switch(pin) {
|
||||||
case PCA9555_PIN_BTN_JOY_DOWN:
|
case RP2040_INPUT_JOYSTICK_DOWN:
|
||||||
if (value) {
|
if (value) {
|
||||||
menu_navigate_next(menu);
|
menu_navigate_next(menu);
|
||||||
render = true;
|
render = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_JOY_UP:
|
case RP2040_INPUT_JOYSTICK_UP:
|
||||||
if (value) {
|
if (value) {
|
||||||
menu_navigate_previous(menu);
|
menu_navigate_previous(menu);
|
||||||
render = true;
|
render = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_ACCEPT:
|
case RP2040_INPUT_BUTTON_ACCEPT:
|
||||||
if (value) {
|
if (value) {
|
||||||
menuArgs = menu_get_callback_args(menu, menu_get_position(menu));
|
menuArgs = menu_get_callback_args(menu, menu_get_position(menu));
|
||||||
}
|
}
|
||||||
|
@ -155,24 +156,24 @@ void menu_wifi_settings(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341
|
||||||
menu_args_t* menuArgs = NULL;
|
menu_args_t* menuArgs = NULL;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
button_message_t buttonMessage = {0};
|
rp2040_input_message_t buttonMessage = {0};
|
||||||
if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) {
|
if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) {
|
||||||
uint8_t pin = buttonMessage.button;
|
uint8_t pin = buttonMessage.input;
|
||||||
bool value = buttonMessage.state;
|
bool value = buttonMessage.state;
|
||||||
switch(pin) {
|
switch(pin) {
|
||||||
case PCA9555_PIN_BTN_JOY_DOWN:
|
case RP2040_INPUT_JOYSTICK_DOWN:
|
||||||
if (value) {
|
if (value) {
|
||||||
menu_navigate_next(menu);
|
menu_navigate_next(menu);
|
||||||
render = true;
|
render = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_JOY_UP:
|
case RP2040_INPUT_JOYSTICK_UP:
|
||||||
if (value) {
|
if (value) {
|
||||||
menu_navigate_previous(menu);
|
menu_navigate_previous(menu);
|
||||||
render = true;
|
render = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_ACCEPT:
|
case RP2040_INPUT_BUTTON_ACCEPT:
|
||||||
if (value) {
|
if (value) {
|
||||||
menuArgs = menu_get_callback_args(menu, menu_get_position(menu));
|
menuArgs = menu_get_callback_args(menu, menu_get_position(menu));
|
||||||
}
|
}
|
||||||
|
@ -204,15 +205,6 @@ void app_main(void) {
|
||||||
esp_err_t res;
|
esp_err_t res;
|
||||||
|
|
||||||
/* Initialize memory */
|
/* Initialize memory */
|
||||||
|
|
||||||
xQueueHandle buttonQueue = xQueueCreate(10, sizeof(button_message_t));
|
|
||||||
|
|
||||||
if (buttonQueue == NULL) {
|
|
||||||
ESP_LOGE(TAG, "Failed to allocate queue");
|
|
||||||
restart();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t* framebuffer = heap_caps_malloc(ILI9341_BUFFER_SIZE, MALLOC_CAP_8BIT);
|
uint8_t* framebuffer = heap_caps_malloc(ILI9341_BUFFER_SIZE, MALLOC_CAP_8BIT);
|
||||||
if (framebuffer == NULL) {
|
if (framebuffer == NULL) {
|
||||||
ESP_LOGE(TAG, "Failed to allocate framebuffer");
|
ESP_LOGE(TAG, "Failed to allocate framebuffer");
|
||||||
|
@ -232,9 +224,14 @@ void app_main(void) {
|
||||||
|
|
||||||
/* Initialize hardware */
|
/* Initialize hardware */
|
||||||
|
|
||||||
res = board_init();
|
bool lcdReady = false;
|
||||||
|
res = board_init(&lcdReady);
|
||||||
|
|
||||||
if (res != ESP_OK) {
|
if (res != ESP_OK) {
|
||||||
|
if (lcdReady) {
|
||||||
|
ILI9341* ili9341 = get_ili9341();
|
||||||
|
graphics_task(pax_buffer, ili9341, framebuffer, NULL, "HARDWARE ERROR");
|
||||||
|
}
|
||||||
printf("Failed to initialize hardware!\n");
|
printf("Failed to initialize hardware!\n");
|
||||||
restart();
|
restart();
|
||||||
}
|
}
|
||||||
|
@ -243,13 +240,7 @@ void app_main(void) {
|
||||||
ICE40* ice40 = get_ice40();
|
ICE40* ice40 = get_ice40();
|
||||||
BNO055* bno055 = get_bno055();
|
BNO055* bno055 = get_bno055();
|
||||||
RP2040* rp2040 = get_rp2040();
|
RP2040* rp2040 = get_rp2040();
|
||||||
PCA9555* pca9555 = get_pca9555();
|
|
||||||
|
|
||||||
graphics_task(pax_buffer, ili9341, framebuffer, NULL, "Button init...");
|
|
||||||
button_init(pca9555, buttonQueue);
|
|
||||||
|
|
||||||
rp2040_set_led_mode(rp2040, true, true);
|
|
||||||
|
|
||||||
graphics_task(pax_buffer, ili9341, framebuffer, NULL, "AppFS init...");
|
graphics_task(pax_buffer, ili9341, framebuffer, NULL, "AppFS init...");
|
||||||
res = appfs_init();
|
res = appfs_init();
|
||||||
if (res != ESP_OK) {
|
if (res != ESP_OK) {
|
||||||
|
@ -275,16 +266,38 @@ void app_main(void) {
|
||||||
if (sdcard_ready) {
|
if (sdcard_ready) {
|
||||||
graphics_task(pax_buffer, ili9341, framebuffer, NULL, "SD card mounted");
|
graphics_task(pax_buffer, ili9341, framebuffer, NULL, "SD card mounted");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ws2812_init(GPIO_LED_DATA);
|
||||||
|
uint8_t ledBuffer[15] = {50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
ws2812_send_data(ledBuffer, sizeof(ledBuffer));
|
||||||
|
|
||||||
|
//fpga_test(ili9341, ice40, rp2040->queue);
|
||||||
|
|
||||||
|
/*while (true) {
|
||||||
|
uint16_t state;
|
||||||
|
rp2040_read_buttons(rp2040, &state);
|
||||||
|
printf("Button state: %04X\n", state);
|
||||||
|
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||||
|
ledBuffer[1] = 255;
|
||||||
|
ws2812_send_data(ledBuffer, sizeof(ledBuffer));
|
||||||
|
vTaskDelay(200 / portTICK_PERIOD_MS);
|
||||||
|
ledBuffer[1] = 0;
|
||||||
|
ledBuffer[0] = 255;
|
||||||
|
ws2812_send_data(ledBuffer, sizeof(ledBuffer));
|
||||||
|
fpga_test(ili9341, ice40, rp2040->queue);
|
||||||
|
ledBuffer[0] = 0;
|
||||||
|
ws2812_send_data(ledBuffer, sizeof(ledBuffer));
|
||||||
|
}*/
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
menu_action_t menu_action;
|
menu_action_t menu_action;
|
||||||
appfs_handle_t appfs_fd;
|
appfs_handle_t appfs_fd;
|
||||||
menu_launcher(buttonQueue, pax_buffer, ili9341, framebuffer, &menu_action, &appfs_fd);
|
menu_launcher(rp2040->queue, pax_buffer, ili9341, framebuffer, &menu_action, &appfs_fd);
|
||||||
if (menu_action == ACTION_APPFS) {
|
if (menu_action == ACTION_APPFS) {
|
||||||
appfs_boot_app(appfs_fd);
|
appfs_boot_app(appfs_fd);
|
||||||
} else if (menu_action == ACTION_FPGA) {
|
} else if (menu_action == ACTION_FPGA) {
|
||||||
graphics_task(pax_buffer, ili9341, framebuffer, NULL, "FPGA TEST");
|
graphics_task(pax_buffer, ili9341, framebuffer, NULL, "FPGA TEST");
|
||||||
fpga_test(ili9341, ice40, buttonQueue);
|
fpga_test(ili9341, ice40, rp2040->queue);
|
||||||
} else if (menu_action == ACTION_INSTALLER) {
|
} else if (menu_action == ACTION_INSTALLER) {
|
||||||
graphics_task(pax_buffer, ili9341, framebuffer, NULL, "INSTALLER");
|
graphics_task(pax_buffer, ili9341, framebuffer, NULL, "INSTALLER");
|
||||||
//appfs_store_app();
|
//appfs_store_app();
|
||||||
|
@ -313,7 +326,7 @@ void app_main(void) {
|
||||||
graphics_task(pax_buffer, ili9341, framebuffer, NULL, "Firmware update...");
|
graphics_task(pax_buffer, ili9341, framebuffer, NULL, "Firmware update...");
|
||||||
} else if (menu_action == ACTION_SETTINGS) {
|
} else if (menu_action == ACTION_SETTINGS) {
|
||||||
while (true) {
|
while (true) {
|
||||||
menu_wifi_settings(buttonQueue, pax_buffer, ili9341, framebuffer, &menu_action);
|
menu_wifi_settings(rp2040->queue, pax_buffer, ili9341, framebuffer, &menu_action);
|
||||||
if (menu_action == ACTION_WIFI_MANUAL) {
|
if (menu_action == ACTION_WIFI_MANUAL) {
|
||||||
nvs_handle_t handle;
|
nvs_handle_t handle;
|
||||||
nvs_open("system", NVS_READWRITE, &handle);
|
nvs_open("system", NVS_READWRITE, &handle);
|
||||||
|
@ -335,9 +348,9 @@ void app_main(void) {
|
||||||
if (res != ESP_OK) strcpy(password, "");
|
if (res != ESP_OK) strcpy(password, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool accepted = keyboard(buttonQueue, pax_buffer, ili9341, framebuffer, 30, 30, pax_buffer->width - 60, pax_buffer->height - 60, "WiFi SSID", "Press HOME to exit", ssid, sizeof(ssid));
|
bool accepted = keyboard(rp2040->queue, pax_buffer, ili9341, framebuffer, 30, 30, pax_buffer->width - 60, pax_buffer->height - 60, "WiFi SSID", "Press HOME to exit", ssid, sizeof(ssid));
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
accepted = keyboard(buttonQueue, pax_buffer, ili9341, framebuffer, 30, 30, pax_buffer->width - 60, pax_buffer->height - 60, "WiFi password", "Press HOME to exit", password, sizeof(password));
|
accepted = keyboard(rp2040->queue, pax_buffer, ili9341, framebuffer, 30, 30, pax_buffer->width - 60, pax_buffer->height - 60, "WiFi password", "Press HOME to exit", password, sizeof(password));
|
||||||
}
|
}
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
nvs_set_str(handle, "wifi.ssid", ssid);
|
nvs_set_str(handle, "wifi.ssid", ssid);
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "ili9341.h"
|
#include "ili9341.h"
|
||||||
#include "ice40.h"
|
#include "ice40.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
#include "button_wrapper.h"
|
|
||||||
|
|
||||||
static const char *TAG = "settings";
|
static const char *TAG = "settings";
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue