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"
|
||||
"bus-i2c"
|
||||
"i2c-bno055"
|
||||
"i2c-pca9555"
|
||||
"pax-graphics"
|
||||
"renze-graphics"
|
||||
"sdcard"
|
||||
|
|
|
@ -8,42 +8,45 @@
|
|||
|
||||
static const char *TAG = "hardware";
|
||||
|
||||
static PCA9555 dev_pca9555 = {0};
|
||||
static BNO055 dev_bno055 = {0};
|
||||
static ILI9341 dev_ili9341 = {0};
|
||||
static ICE40 dev_ice40 = {0};
|
||||
static RP2040 dev_rp2040 = {0};
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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() {
|
||||
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);
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Initializing system I2C bus failed");
|
||||
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_config_t busConfiguration = {0};
|
||||
busConfiguration.mosi_io_num = GPIO_SPI_MOSI;
|
||||
|
@ -63,7 +66,8 @@ static esp_err_t _bus_init() {
|
|||
|
||||
// Board init
|
||||
|
||||
esp_err_t board_init() {
|
||||
esp_err_t board_init(bool* aLcdReady) {
|
||||
if (aLcdReady != NULL) *aLcdReady = false;
|
||||
esp_err_t res;
|
||||
|
||||
// Interrupts
|
||||
|
@ -77,10 +81,36 @@ esp_err_t board_init() {
|
|||
res = _bus_init();
|
||||
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
|
||||
dev_rp2040.i2c_bus = I2C_BUS_SYS;
|
||||
dev_rp2040.i2c_address = RP2040_ADDR;
|
||||
dev_rp2040.pin_interrupt = GPIO_INT_RP2040;
|
||||
dev_rp2040.queue = xQueueCreate(8, sizeof(rp2040_input_message_t));
|
||||
|
||||
res = rp2040_init(&dev_rp2040);
|
||||
if (res != ESP_OK) {
|
||||
|
@ -88,45 +118,13 @@ esp_err_t board_init() {
|
|||
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
|
||||
dev_ice40.spi_bus = SPI_BUS;
|
||||
dev_ice40.pin_cs = GPIO_SPI_CS_FPGA;
|
||||
dev_ice40.pin_done = -1;
|
||||
dev_ice40.pin_reset = -1;
|
||||
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.get_done = ice40_get_done_wrapper;
|
||||
dev_ice40.set_reset = ice40_set_reset_wrapper;
|
||||
|
@ -137,23 +135,6 @@ esp_err_t board_init() {
|
|||
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
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
PCA9555* get_pca9555() {
|
||||
return &dev_pca9555;
|
||||
}
|
||||
|
||||
BNO055* get_bno055() {
|
||||
return &dev_bno055;
|
||||
}
|
||||
|
|
|
@ -3,52 +3,35 @@
|
|||
#include <sdkconfig.h>
|
||||
#include <esp_err.h>
|
||||
#include <driver/spi_master.h>
|
||||
#include "pca9555.h"
|
||||
#include "bno055.h"
|
||||
#include "ili9341.h"
|
||||
#include "ice40.h"
|
||||
#include "rp2040.h"
|
||||
|
||||
// Interrupts
|
||||
#define GPIO_INT_RP2040 0
|
||||
#define GPIO_INT_PCA9555 34
|
||||
#define GPIO_INT_RP2040 34
|
||||
#define GPIO_INT_BNO055 36
|
||||
#define GPIO_INT_FPGA 39
|
||||
|
||||
// SD card
|
||||
#define SD_PWR 5
|
||||
#define SD_PWR 19 // Also LED power
|
||||
#define SD_D0 2
|
||||
#define SD_CLK 14
|
||||
#define SD_CMD 15
|
||||
|
||||
// LEDs
|
||||
#define GPIO_LED_DATA 5
|
||||
|
||||
// I2S audio
|
||||
#define GPIO_I2S_CLK 14
|
||||
#define GPIO_I2S_DATA 13
|
||||
#define GPIO_I2S_LR 4
|
||||
|
||||
// System I2C bus
|
||||
// I2C bus
|
||||
#define GPIO_I2C_SYS_SCL 21
|
||||
#define GPIO_I2C_SYS_SDA 22
|
||||
#define I2C_BUS_SYS 0
|
||||
#define I2C_SPEED_SYS 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
|
||||
#define I2C_SPEED_SYS 8000 // 8 kHz //20000 // 20 kHz
|
||||
|
||||
// RP2040 co-processor
|
||||
#define RP2040_ADDR 0x17
|
||||
|
@ -56,27 +39,24 @@
|
|||
// BNO055 sensor
|
||||
#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
|
||||
#define GPIO_SPI_CLK 18
|
||||
#define GPIO_SPI_MOSI 23
|
||||
#define GPIO_SPI_MISO 35
|
||||
#define GPIO_SPI_CS_RP2040 19
|
||||
#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_MAX_TRANSFER_SIZE 4094
|
||||
#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();
|
||||
ILI9341* get_ili9341();
|
||||
ICE40* get_ice40();
|
||||
|
|
|
@ -11,12 +11,52 @@
|
|||
|
||||
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 res;
|
||||
|
||||
uint8_t 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) {
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
esp_err_t rp2040_get_led_mode(RP2040* device, bool* enabled, bool* automatic_flush) {
|
||||
uint8_t value;
|
||||
esp_err_t res = i2c_read_reg(device->i2c_bus, device->i2c_address, RP2040_REG_LED_MODE, &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_fpga(RP2040* device, bool enabled) {
|
||||
uint8_t value = enabled ? 0x01 : 0x00;
|
||||
return i2c_write_reg_n(device->i2c_bus, device->i2c_address, RP2040_REG_FPGA, &value, 1);
|
||||
}
|
||||
|
||||
esp_err_t rp2040_set_led_mode(RP2040* device, bool enabled, bool automatic_flush) {
|
||||
uint8_t value = enabled | (automatic_flush << 1);
|
||||
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);
|
||||
esp_err_t rp2040_read_buttons(RP2040* device, uint16_t* value) {
|
||||
return i2c_read_reg(device->i2c_bus, device->i2c_address, RP2040_REG_INPUT1, (uint8_t*) value, 2);
|
||||
}
|
||||
|
|
|
@ -6,36 +6,106 @@
|
|||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/semphr.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/queue.h>
|
||||
|
||||
enum {
|
||||
RP2040_REG_FW_VER = 0,
|
||||
RP2040_REG_GPIO_DIR,
|
||||
RP2040_REG_GPIO_IN,
|
||||
RP2040_REG_GPIO_OUT,
|
||||
RP2040_REG_LCD_MODE,
|
||||
RP2040_REG_LCD_BACKLIGHT,
|
||||
RP2040_REG_LED_MODE,
|
||||
RP2040_REG_LED_R0,
|
||||
RP2040_REG_LED_G0,
|
||||
RP2040_REG_LED_B0,
|
||||
RP2040_REG_LED_R1,
|
||||
RP2040_REG_LED_G1,
|
||||
RP2040_REG_LED_B1,
|
||||
RP2040_REG_LED_R2,
|
||||
RP2040_REG_LED_G2,
|
||||
RP2040_REG_LED_B2,
|
||||
RP2040_REG_LED_R3,
|
||||
RP2040_REG_LED_G3,
|
||||
RP2040_REG_LED_B3,
|
||||
RP2040_REG_LED_R4,
|
||||
RP2040_REG_LED_G4,
|
||||
RP2040_REG_LED_B4,
|
||||
RP2040_REG_FPGA,
|
||||
RP2040_REG_INPUT1,
|
||||
RP2040_REG_INPUT2,
|
||||
RP2040_REG_INTERRUPT1,
|
||||
RP2040_REG_INTERRUPT2,
|
||||
RP2040_REG_ADC_TRIGGER,
|
||||
RP2040_REG_ADC_VALUE_VUSB1,
|
||||
RP2040_REG_ADC_VALUE_VUSB2,
|
||||
RP2040_REG_ADC_VALUE_VBAT1,
|
||||
RP2040_REG_ADC_VALUE_VBAT2,
|
||||
RP2040_REG_USB,
|
||||
RP2040_REG_SCRATCH0, // Used by the ESP32 to store boot parameters, can also be read and written to from WebUSB
|
||||
RP2040_REG_SCRATCH1,
|
||||
RP2040_REG_SCRATCH2,
|
||||
RP2040_REG_SCRATCH3,
|
||||
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 {
|
||||
LCD_MODE_SPI = 0,
|
||||
LCD_MODE_PARALLEL = 1
|
||||
} lcd_mode_t;
|
||||
enum {
|
||||
RP2040_INPUT_BUTTON_HOME = 0,
|
||||
RP2040_INPUT_BUTTON_MENU,
|
||||
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)();
|
||||
|
||||
|
@ -43,14 +113,19 @@ typedef struct {
|
|||
int i2c_bus;
|
||||
int i2c_address;
|
||||
int pin_interrupt;
|
||||
xQueueHandle queue;
|
||||
rp2040_intr_t _intr_handler;
|
||||
TaskHandle_t _intr_task_handle;
|
||||
xSemaphoreHandle _intr_trigger;
|
||||
xSemaphoreHandle _mux;
|
||||
uint8_t _gpio_direction;
|
||||
uint8_t _gpio_value;
|
||||
} 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_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_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_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_led_mode(RP2040* device, bool enabled, bool automatic_flush);
|
||||
esp_err_t rp2040_set_fpga(RP2040* device, bool enabled);
|
||||
|
||||
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_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)
|
||||
esp_err_t rp2040_read_buttons(RP2040* device, uint16_t* value);
|
||||
|
|
|
@ -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(
|
||||
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"
|
||||
)
|
||||
|
|
|
@ -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 "ili9341.h"
|
||||
#include "ice40.h"
|
||||
#include "rp2040.h"
|
||||
#include "hardware.h"
|
||||
#include "button_wrapper.h"
|
||||
|
||||
static const char *TAG = "fpga_test";
|
||||
|
||||
|
@ -139,12 +139,12 @@ void fpga_test(ILI9341* ili9341, ICE40* ice40, xQueueHandle buttonQueue) {
|
|||
|
||||
bool waitForChoice = true;
|
||||
while (waitForChoice) {
|
||||
button_message_t buttonMessage = {0};
|
||||
rp2040_input_message_t buttonMessage = {0};
|
||||
printf("Waiting for button press...\n");
|
||||
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) {
|
||||
switch(buttonMessage.button) {
|
||||
/*switch(buttonMessage.button) {
|
||||
case PCA9555_PIN_BTN_HOME:
|
||||
case PCA9555_PIN_BTN_MENU:
|
||||
case PCA9555_PIN_BTN_BACK:
|
||||
|
@ -156,7 +156,7 @@ void fpga_test(ILI9341* ili9341, ICE40* ice40, xQueueHandle buttonQueue) {
|
|||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "graphics_wrapper.h"
|
||||
#include "hardware.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) {
|
||||
pax_col_t fgColor = 0xFFFF0000;
|
||||
|
@ -70,68 +70,68 @@ bool keyboard(xQueueHandle buttonQueue, pax_buf_t* aBuffer, ILI9341* ili9341, ui
|
|||
|
||||
bool running = true;
|
||||
while (running) {
|
||||
button_message_t buttonMessage = {0};
|
||||
rp2040_input_message_t buttonMessage = {0};
|
||||
if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) {
|
||||
uint8_t pin = buttonMessage.button;
|
||||
uint8_t pin = buttonMessage.input;
|
||||
bool value = buttonMessage.state;
|
||||
switch(pin) {
|
||||
case PCA9555_PIN_BTN_JOY_DOWN:
|
||||
case RP2040_INPUT_JOYSTICK_DOWN:
|
||||
if (value) {
|
||||
pkb_press(&kb_ctx, PKB_DOWN);
|
||||
} else {
|
||||
pkb_release(&kb_ctx, PKB_DOWN);
|
||||
}
|
||||
break;
|
||||
case PCA9555_PIN_BTN_JOY_UP:
|
||||
case RP2040_INPUT_JOYSTICK_UP:
|
||||
if (value) {
|
||||
pkb_press(&kb_ctx, PKB_UP);
|
||||
} else {
|
||||
pkb_release(&kb_ctx, PKB_UP);
|
||||
}
|
||||
break;
|
||||
case PCA9555_PIN_BTN_JOY_LEFT:
|
||||
case RP2040_INPUT_JOYSTICK_LEFT:
|
||||
if (value) {
|
||||
pkb_press(&kb_ctx, PKB_LEFT);
|
||||
} else {
|
||||
pkb_release(&kb_ctx, PKB_LEFT);
|
||||
}
|
||||
break;
|
||||
case PCA9555_PIN_BTN_JOY_RIGHT:
|
||||
case RP2040_INPUT_JOYSTICK_RIGHT:
|
||||
if (value) {
|
||||
pkb_press(&kb_ctx, PKB_RIGHT);
|
||||
} else {
|
||||
pkb_release(&kb_ctx, PKB_RIGHT);
|
||||
}
|
||||
break;
|
||||
case PCA9555_PIN_BTN_JOY_PRESS:
|
||||
case RP2040_INPUT_JOYSTICK_PRESS:
|
||||
if (value) {
|
||||
pkb_press(&kb_ctx, PKB_SHIFT);
|
||||
} else {
|
||||
pkb_release(&kb_ctx, PKB_SHIFT);
|
||||
}
|
||||
break;
|
||||
case PCA9555_PIN_BTN_ACCEPT:
|
||||
case RP2040_INPUT_BUTTON_ACCEPT:
|
||||
if (value) {
|
||||
pkb_press(&kb_ctx, PKB_CHARSELECT);
|
||||
} else {
|
||||
pkb_release(&kb_ctx, PKB_CHARSELECT);
|
||||
}
|
||||
break;
|
||||
case PCA9555_PIN_BTN_BACK:
|
||||
case RP2040_INPUT_BUTTON_BACK:
|
||||
if (value) {
|
||||
pkb_press(&kb_ctx, PKB_DELETE_BEFORE);
|
||||
} else {
|
||||
pkb_release(&kb_ctx, PKB_DELETE_BEFORE);
|
||||
}
|
||||
break;
|
||||
case PCA9555_PIN_BTN_SELECT:
|
||||
case RP2040_INPUT_BUTTON_SELECT:
|
||||
if (value) {
|
||||
pkb_press(&kb_ctx, PKB_MODESELECT);
|
||||
} else {
|
||||
pkb_release(&kb_ctx, PKB_MODESELECT);
|
||||
}
|
||||
break;
|
||||
case PCA9555_PIN_BTN_HOME:
|
||||
case RP2040_INPUT_BUTTON_HOME:
|
||||
if (value) {
|
||||
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 "menu.h"
|
||||
#include "button_wrapper.h"
|
||||
#include "system_wrapper.h"
|
||||
#include "graphics_wrapper.h"
|
||||
#include "appfs_wrapper.h"
|
||||
#include "settings.h"
|
||||
#include "wifi_connection.h"
|
||||
|
||||
#include "ws2812.h"
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
typedef enum action {
|
||||
|
@ -85,24 +86,24 @@ void menu_launcher(xQueueHandle buttonQueue, pax_buf_t* pax_buffer, ILI9341* ili
|
|||
menu_args_t* menuArgs = NULL;
|
||||
|
||||
while (1) {
|
||||
button_message_t buttonMessage = {0};
|
||||
rp2040_input_message_t buttonMessage = {0};
|
||||
if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) {
|
||||
uint8_t pin = buttonMessage.button;
|
||||
uint8_t pin = buttonMessage.input;
|
||||
bool value = buttonMessage.state;
|
||||
switch(pin) {
|
||||
case PCA9555_PIN_BTN_JOY_DOWN:
|
||||
case RP2040_INPUT_JOYSTICK_DOWN:
|
||||
if (value) {
|
||||
menu_navigate_next(menu);
|
||||
render = true;
|
||||
}
|
||||
break;
|
||||
case PCA9555_PIN_BTN_JOY_UP:
|
||||
case RP2040_INPUT_JOYSTICK_UP:
|
||||
if (value) {
|
||||
menu_navigate_previous(menu);
|
||||
render = true;
|
||||
}
|
||||
break;
|
||||
case PCA9555_PIN_BTN_ACCEPT:
|
||||
case RP2040_INPUT_BUTTON_ACCEPT:
|
||||
if (value) {
|
||||
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;
|
||||
|
||||
while (1) {
|
||||
button_message_t buttonMessage = {0};
|
||||
rp2040_input_message_t buttonMessage = {0};
|
||||
if (xQueueReceive(buttonQueue, &buttonMessage, 16 / portTICK_PERIOD_MS) == pdTRUE) {
|
||||
uint8_t pin = buttonMessage.button;
|
||||
uint8_t pin = buttonMessage.input;
|
||||
bool value = buttonMessage.state;
|
||||
switch(pin) {
|
||||
case PCA9555_PIN_BTN_JOY_DOWN:
|
||||
case RP2040_INPUT_JOYSTICK_DOWN:
|
||||
if (value) {
|
||||
menu_navigate_next(menu);
|
||||
render = true;
|
||||
}
|
||||
break;
|
||||
case PCA9555_PIN_BTN_JOY_UP:
|
||||
case RP2040_INPUT_JOYSTICK_UP:
|
||||
if (value) {
|
||||
menu_navigate_previous(menu);
|
||||
render = true;
|
||||
}
|
||||
break;
|
||||
case PCA9555_PIN_BTN_ACCEPT:
|
||||
case RP2040_INPUT_BUTTON_ACCEPT:
|
||||
if (value) {
|
||||
menuArgs = menu_get_callback_args(menu, menu_get_position(menu));
|
||||
}
|
||||
|
@ -204,15 +205,6 @@ void app_main(void) {
|
|||
esp_err_t res;
|
||||
|
||||
/* 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);
|
||||
if (framebuffer == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to allocate framebuffer");
|
||||
|
@ -232,9 +224,14 @@ void app_main(void) {
|
|||
|
||||
/* Initialize hardware */
|
||||
|
||||
res = board_init();
|
||||
bool lcdReady = false;
|
||||
res = board_init(&lcdReady);
|
||||
|
||||
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");
|
||||
restart();
|
||||
}
|
||||
|
@ -243,12 +240,6 @@ void app_main(void) {
|
|||
ICE40* ice40 = get_ice40();
|
||||
BNO055* bno055 = get_bno055();
|
||||
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...");
|
||||
res = appfs_init();
|
||||
|
@ -276,15 +267,37 @@ void app_main(void) {
|
|||
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) {
|
||||
menu_action_t menu_action;
|
||||
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) {
|
||||
appfs_boot_app(appfs_fd);
|
||||
} else if (menu_action == ACTION_FPGA) {
|
||||
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) {
|
||||
graphics_task(pax_buffer, ili9341, framebuffer, NULL, "INSTALLER");
|
||||
//appfs_store_app();
|
||||
|
@ -313,7 +326,7 @@ void app_main(void) {
|
|||
graphics_task(pax_buffer, ili9341, framebuffer, NULL, "Firmware update...");
|
||||
} else if (menu_action == ACTION_SETTINGS) {
|
||||
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) {
|
||||
nvs_handle_t handle;
|
||||
nvs_open("system", NVS_READWRITE, &handle);
|
||||
|
@ -335,9 +348,9 @@ void app_main(void) {
|
|||
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) {
|
||||
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) {
|
||||
nvs_set_str(handle, "wifi.ssid", ssid);
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "ili9341.h"
|
||||
#include "ice40.h"
|
||||
#include "hardware.h"
|
||||
#include "button_wrapper.h"
|
||||
|
||||
static const char *TAG = "settings";
|
||||
|
||||
|
|
Loading…
Reference in a new issue