Add ICE40 FPGA support
This commit is contained in:
parent
80a7369f89
commit
159e1b3a01
6 changed files with 8780 additions and 27 deletions
4
.gitmodules
vendored
4
.gitmodules
vendored
|
@ -18,3 +18,7 @@
|
||||||
path = factory_test/components/spi-ili9341
|
path = factory_test/components/spi-ili9341
|
||||||
url = git@github.com:Nicolai-Electronics/esp32-component-spi-ili9341.git
|
url = git@github.com:Nicolai-Electronics/esp32-component-spi-ili9341.git
|
||||||
branch = master
|
branch = master
|
||||||
|
[submodule "factory_test/components/spi-ice40"]
|
||||||
|
path = factory_test/components/spi-ice40
|
||||||
|
url = git@github.com:Nicolai-Electronics/esp32-component-spi-ice40.git
|
||||||
|
branch = master
|
||||||
|
|
1
factory_test/components/spi-ice40
Submodule
1
factory_test/components/spi-ice40
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 3c7ce5ba461f770d330c5a7a8a129b9f13568ed5
|
8683
factory_test/main/bitstream.h
Normal file
8683
factory_test/main/bitstream.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -10,6 +10,11 @@ static const char *TAG = "hardware";
|
||||||
PCA9555 dev_pca9555 = {0};
|
PCA9555 dev_pca9555 = {0};
|
||||||
BNO055 dev_bno055 = {0};
|
BNO055 dev_bno055 = {0};
|
||||||
ILI9341 dev_ili9341 = {0};
|
ILI9341 dev_ili9341 = {0};
|
||||||
|
ICE40 dev_ice40 = {0};
|
||||||
|
|
||||||
|
// Wrapper functions for linking the ICE40 component to the PCA9555 component
|
||||||
|
esp_err_t ice40_get_done_wrapper(bool* done) { return pca9555_get_gpio_value(&dev_pca9555, PCA9555_PIN_FPGA_CDONE, done); }
|
||||||
|
esp_err_t ice40_set_reset_wrapper(bool reset) { return pca9555_set_gpio_value(&dev_pca9555, PCA9555_PIN_FPGA_RESET, reset); }
|
||||||
|
|
||||||
esp_err_t hardware_init() {
|
esp_err_t hardware_init() {
|
||||||
esp_err_t res;
|
esp_err_t res;
|
||||||
|
@ -20,6 +25,20 @@ esp_err_t hardware_init() {
|
||||||
ESP_LOGE(TAG, "Initializing ISR service failed");
|
ESP_LOGE(TAG, "Initializing ISR service failed");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// System 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
|
||||||
spi_bus_config_t busConfiguration = {0};
|
spi_bus_config_t busConfiguration = {0};
|
||||||
|
@ -35,6 +54,42 @@ esp_err_t hardware_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 = 60000000; // 60MHz
|
||||||
|
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;
|
||||||
|
|
||||||
|
res = ice40_init(&dev_ice40);
|
||||||
|
if (res != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Initializing FPGA failed");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
// LCD display
|
// LCD display
|
||||||
dev_ili9341.spi_bus = SPI_BUS;
|
dev_ili9341.spi_bus = SPI_BUS;
|
||||||
dev_ili9341.pin_cs = GPIO_SPI_CS_LCD;
|
dev_ili9341.pin_cs = GPIO_SPI_CS_LCD;
|
||||||
|
@ -58,20 +113,6 @@ esp_err_t hardware_init() {
|
||||||
ESP_LOGE(TAG, "Failed to write logo to LCD");
|
ESP_LOGE(TAG, "Failed to write logo to LCD");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// System 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BNO055 sensor on system I2C bus
|
// BNO055 sensor on system I2C bus
|
||||||
|
|
||||||
|
@ -81,13 +122,6 @@ esp_err_t hardware_init() {
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,3 +136,7 @@ BNO055* get_bno055() {
|
||||||
ILI9341* get_ili9341() {
|
ILI9341* get_ili9341() {
|
||||||
return &dev_ili9341;
|
return &dev_ili9341;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ICE40* get_ice40() {
|
||||||
|
return &dev_ice40;
|
||||||
|
}
|
||||||
|
|
|
@ -6,11 +6,13 @@
|
||||||
#include "pca9555.h"
|
#include "pca9555.h"
|
||||||
#include "bno055.h"
|
#include "bno055.h"
|
||||||
#include "ili9341.h"
|
#include "ili9341.h"
|
||||||
|
#include "ice40.h"
|
||||||
|
|
||||||
esp_err_t hardware_init();
|
esp_err_t hardware_init();
|
||||||
PCA9555* get_pca9555();
|
PCA9555* get_pca9555();
|
||||||
BNO055* get_bno055();
|
BNO055* get_bno055();
|
||||||
ILI9341* get_ili9341();
|
ILI9341* get_ili9341();
|
||||||
|
ICE40* get_ice40();
|
||||||
|
|
||||||
// Interrupts
|
// Interrupts
|
||||||
#define GPIO_INT_STM32 0
|
#define GPIO_INT_STM32 0
|
||||||
|
@ -33,7 +35,7 @@ ILI9341* get_ili9341();
|
||||||
#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
|
#define I2C_SPEED_SYS 20000 // 20kHz
|
||||||
|
|
||||||
// PCA9555 IO expander
|
// PCA9555 IO expander
|
||||||
#define PCA9555_ADDR 0x26
|
#define PCA9555_ADDR 0x26
|
||||||
|
@ -60,7 +62,7 @@ ILI9341* get_ili9341();
|
||||||
#define GPIO_I2C_EXT_SCL 25
|
#define GPIO_I2C_EXT_SCL 25
|
||||||
#define GPIO_I2C_EXT_SDA 26
|
#define GPIO_I2C_EXT_SDA 26
|
||||||
#define I2C_BUS_EXT 1
|
#define I2C_BUS_EXT 1
|
||||||
#define I2C_SPEED_EXT 40000
|
#define I2C_SPEED_EXT 20000 // 20 kHz
|
||||||
|
|
||||||
// SPI bus
|
// SPI bus
|
||||||
#define GPIO_SPI_CLK 18
|
#define GPIO_SPI_CLK 18
|
||||||
|
|
|
@ -8,21 +8,42 @@
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
|
#include "bitstream.h"
|
||||||
|
|
||||||
static const char *TAG = "main";
|
static const char *TAG = "main";
|
||||||
|
|
||||||
bool calibrate = true;
|
bool calibrate = true;
|
||||||
|
bool display_bno_value = true;
|
||||||
ILI9341* ili9341 = NULL;
|
ILI9341* ili9341 = NULL;
|
||||||
|
ICE40* ice40 = NULL;
|
||||||
uint8_t* framebuffer = NULL;
|
uint8_t* framebuffer = NULL;
|
||||||
|
|
||||||
void button_handler(uint8_t pin, bool value) {
|
void button_handler(uint8_t pin, bool value) {
|
||||||
switch(pin) {
|
switch(pin) {
|
||||||
case PCA9555_PIN_BTN_START:
|
case PCA9555_PIN_BTN_START: {
|
||||||
printf("Start button %s\n", value ? "pressed" : "released");
|
printf("Start button %s\n", value ? "pressed" : "released");
|
||||||
|
if (value) {
|
||||||
|
esp_err_t res = ice40_load_bitstream(ice40, bitstream, bitstream_length);
|
||||||
|
if (res != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to program the FPGA (%d)", res);
|
||||||
|
} else {
|
||||||
|
printf("FPGA enabled\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_SELECT:
|
}
|
||||||
|
case PCA9555_PIN_BTN_SELECT: {
|
||||||
printf("Select button %s\n", value ? "pressed" : "released");
|
printf("Select button %s\n", value ? "pressed" : "released");
|
||||||
|
if (value) {
|
||||||
|
esp_err_t res = ice40_disable(ice40);
|
||||||
|
if (res != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to disable the FPGA (%d)", res);
|
||||||
|
} else {
|
||||||
|
printf("FPGA disabled\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PCA9555_PIN_BTN_MENU:
|
case PCA9555_PIN_BTN_MENU:
|
||||||
printf("Menu button %s\n", value ? "pressed" : "released");
|
printf("Menu button %s\n", value ? "pressed" : "released");
|
||||||
break;
|
break;
|
||||||
|
@ -46,9 +67,10 @@ void button_handler(uint8_t pin, bool value) {
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_BACK:
|
case PCA9555_PIN_BTN_BACK:
|
||||||
printf("Back button %s\n", value ? "pressed" : "released");
|
printf("Back button %s\n", value ? "pressed" : "released");
|
||||||
|
display_bno_value = value;
|
||||||
break;
|
break;
|
||||||
case PCA9555_PIN_BTN_ACCEPT:
|
case PCA9555_PIN_BTN_ACCEPT:
|
||||||
//printf("Accept button %s\n", value ? "pressed" : "released");
|
printf("Accept button %s\n", value ? "pressed" : "released");
|
||||||
if (value) calibrate = true;
|
if (value) calibrate = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -121,6 +143,7 @@ void app_main(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ili9341 = get_ili9341();
|
ili9341 = get_ili9341();
|
||||||
|
ice40 = get_ice40();
|
||||||
|
|
||||||
framebuffer = heap_caps_malloc(ILI9341_BUFFER_SIZE, MALLOC_CAP_8BIT);
|
framebuffer = heap_caps_malloc(ILI9341_BUFFER_SIZE, MALLOC_CAP_8BIT);
|
||||||
if (framebuffer == NULL) {
|
if (framebuffer == NULL) {
|
||||||
|
@ -224,7 +247,9 @@ void app_main(void) {
|
||||||
printf("Linear acceleration (m/s²) x = %5.8f y = %5.8f z = %5.8f\n", linear_acceleration.x, linear_acceleration.y, linear_acceleration.z);
|
printf("Linear acceleration (m/s²) x = %5.8f y = %5.8f z = %5.8f\n", linear_acceleration.x, linear_acceleration.y, linear_acceleration.z);
|
||||||
printf("Gravity (m/s²) x = %5.8f y = %5.8f z = %5.8f\n", gravity.x, gravity.y, gravity.z);*/
|
printf("Gravity (m/s²) x = %5.8f y = %5.8f z = %5.8f\n", gravity.x, gravity.y, gravity.z);*/
|
||||||
|
|
||||||
printf("Magnetic (uT) x: %5.4f y: %5.4f z: %5.4f Rotation (deg): x: %5.4f y: %5.4f z: %5.4f \n", magnetism.x, magnetism.y, magnetism.z, rotation.x, rotation.y, rotation.z);
|
if (display_bno_value) {
|
||||||
|
printf("Magnetic (uT) x: %5.4f y: %5.4f z: %5.4f Rotation (deg): x: %5.4f y: %5.4f z: %5.4f \n", magnetism.x, magnetism.y, magnetism.z, rotation.x, rotation.y, rotation.z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(framebuffer);
|
free(framebuffer);
|
||||||
|
|
Loading…
Reference in a new issue