Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load FPGA Bitfiles to Flash #30

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 78 additions & 5 deletions src/esp32/mcu_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
mcu_hw.c - MiSTeryNano FPGA companion hardware driver for esp32 s2/s3
*/

#include <stdio.h>
#include <inttypes.h>

#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/semphr.h>
Expand All @@ -14,6 +17,9 @@
#include "../hid.h"
#include "../config.h"

#include "../sysctrl.h"



//#define USB_ERROR_CHECK(a) ESP_ERROR_CHECK(a)
#define USB_ERROR_CHECK(a) (a)
Expand Down Expand Up @@ -346,12 +352,20 @@ static void usb_init(void) {

#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "esp_flash.h"
#include "esp_flash_spi_init.h"

#define SPI_HOST_ID SPI3_HOST
#define PIN_NUM_MISO 13
#define PIN_NUM_MOSI 11
#define PIN_NUM_CLK 12
#define PIN_NUM_CS 10
#define PIN_NUM_IRQ 14
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you moving this away from pin 14?

#define PIN_NUM_IRQ 9
#define PIN_NUM_RECONFIG_N 8 // To reconfigure the FPGA after a new bitstream has been written to the flash
// #define PIN_NUM_IRQ 14
#define PIN_NUM_FLASH_CS 7

esp_flash_t* ext_flash;

extern TaskHandle_t com_task_handle;
static spi_device_handle_t spi;
Expand Down Expand Up @@ -385,10 +399,11 @@ void mcu_hw_spi_init(void) {
.sclk_io_num = PIN_NUM_CLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.intr_flags = ESP_INTR_FLAG_LOWMED, // Needed to fix "No free interrupt inputs for USB interrupt (flags 0x802)" errors
.max_transfer_sz = 32
};

spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO);
spi_bus_initialize(SPI_HOST_ID, &buscfg, SPI_DMA_CH_AUTO);

spi_device_interface_config_t devcfg = {
.clock_speed_hz = 20 * 1000 * 1000, // 20 MHz
Expand All @@ -400,7 +415,7 @@ void mcu_hw_spi_init(void) {
.queue_size = 7, // We want to be able to queue 7 transactions at a time
};

spi_bus_add_device(SPI2_HOST, &devcfg, &spi);
spi_bus_add_device(SPI_HOST_ID, &devcfg, &spi);

// Chip select is active-low, so we'll initialise it to a driven-high state
debugf(" CSn = GPIO%d", PIN_NUM_CS);
Expand All @@ -412,9 +427,48 @@ void mcu_hw_spi_init(void) {
debugf(" IRQn = GPIO%d", PIN_NUM_IRQ);
gpio_set_pull_mode(PIN_NUM_IRQ, GPIO_PULLUP_ONLY);
gpio_set_direction(PIN_NUM_IRQ, GPIO_MODE_INPUT);
gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1);
gpio_install_isr_service(ESP_INTR_FLAG_LEVEL2);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And what is this change for?

gpio_isr_handler_add(PIN_NUM_IRQ, irq_handler, NULL);
gpio_set_intr_type(PIN_NUM_IRQ, GPIO_INTR_LOW_LEVEL);

sys_wait4fpga();

// Setup SPI Flash
const esp_flash_spi_device_config_t device_config = {
.host_id = SPI_HOST_ID,
.cs_id = 0,
.cs_io_num = PIN_NUM_FLASH_CS,
// .io_mode = SPI_FLASH_FASTRD,
.io_mode = SPI_FLASH_SLOWRD,
.freq_mhz = ESP_FLASH_20MHZ
};

ESP_ERROR_CHECK(spi_bus_add_flash_device(&ext_flash, &device_config));

// Probe the Flash chip and initialize it
esp_err_t err = esp_flash_init(ext_flash);
if (err != ESP_OK) {
debugf("Failed to initialize external Flash: %s (0x%x)", esp_err_to_name(err), err);
}

// Print out the ID and size
uint32_t id;
ESP_ERROR_CHECK(esp_flash_read_id(ext_flash, &id));
debugf("Initialized external Flash, size=%" PRIu32 " KB, ID=0x%" PRIx32, ext_flash->size / 1024, id);


}

void mcu_hw_erase_flash_region(uint32_t addr, uint32_t size) {
esp_flash_erase_region(ext_flash, addr, size);
}

void mcu_hw_write_flash(uint32_t addr, uint8_t *data, uint32_t size) {
esp_flash_write(ext_flash, data, addr, size);
}

void mcu_hw_read_flash(uint32_t addr, uint8_t *data, uint32_t size) {
esp_flash_read(ext_flash, data, addr, size);
}

void mcu_hw_irq_ack(void) {
Expand All @@ -432,6 +486,14 @@ void mcu_hw_spi_end() {
xSemaphoreGive(sem);
}

void mcu_hw_spi_flash_begin() {
xSemaphoreTake(sem, 0xffffffffUL); // wait forever
}

void mcu_hw_spi_flash_end() {
xSemaphoreGive(sem);
}

unsigned char mcu_hw_spi_tx_u08(unsigned char b) {
unsigned char retval = 0;

Expand All @@ -451,15 +513,26 @@ unsigned char mcu_hw_spi_tx_u08(unsigned char b) {
return retval;
}

void mcu_hw_fpga_reset(void) {
debugf("FPGA RESET");
gpio_set_level(PIN_NUM_RECONFIG_N, 0);
vTaskDelay(pdMS_TO_TICKS(100));
gpio_set_level(PIN_NUM_RECONFIG_N, 1);
}

void mcu_hw_reset(void) {
debugf("RESET");
debugf("MCU RESET");
esp_restart();
for(;;);
}

void mcu_hw_init(void) {
printf("\r\n\r\n" LOGO " FPGA Companion for ESP32-S2/S3\r\n\r\n");

debugf(" FPGA Reconfig = GPIO%d", PIN_NUM_RECONFIG_N);
gpio_set_direction(PIN_NUM_RECONFIG_N, GPIO_MODE_OUTPUT);
gpio_set_level(PIN_NUM_RECONFIG_N, 1);

mcu_hw_spi_init();
usb_init();
}
Expand Down
11 changes: 11 additions & 0 deletions src/mcu_hw.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#ifndef MCU_HW_H
#define MCU_HW_H

#include <stdio.h>
#include <inttypes.h>

#define LOGO "\033[1;33m"\
" __ __ _ ___ _____ _ _ \r\n"\
" | \\/ (_) __|_ _|__ _ _ _ _| \\| |__ _ _ _ ___ \r\n"\
Expand All @@ -13,6 +16,14 @@ void mcu_hw_main_loop(void);

void mcu_hw_irq_ack(void);
void mcu_hw_reset(void);
#ifdef ESP_PLATFORM
void mcu_hw_fpga_reset(void);
void mcu_hw_erase_flash_region(uint32_t addr, uint32_t size);
void mcu_hw_write_flash(uint32_t addr, uint8_t *data, uint32_t size);
void mcu_hw_read_flash(uint32_t addr, uint8_t *data, uint32_t size);
void mcu_hw_spi_flash_begin(void);
void mcu_hw_spi_flash_end(void);
#endif

// HW SPI interface
void mcu_hw_spi_begin(void);
Expand Down
20 changes: 19 additions & 1 deletion src/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include "sysctrl.h"
#include "debug.h"

#include "mcu_hw.h"

// this is the u8g2_font_helvR08_te with any trailing
// spaces removed
#include "font_helvR08_te.c"
Expand Down Expand Up @@ -1179,9 +1181,25 @@ static void menu_fileselector_select(sdc_dir_entry_t *entry) {
}
}
} else {
#ifdef ESP_PLATFORM
if(strcmp(sdc_get_cwd(drive), "/cores") == 0) {
debugf("loading core %s", entry->name);
menu_draw_dialog("Loading Core", "This could take up to 30 seconds.");
sdc_load_core(strcat("/cores/",entry->name));
menu_draw_dialog("Core loaded", "Restarting FPGA.");
vTaskDelay(pdMS_TO_TICKS(3000)); // give user time to read message
mcu_hw_fpga_reset();
} else {
// request insertion of this image
debugf("loading image %s", entry->name);
sdc_image_open(drive, entry->name);
}
#else
// request insertion of this image
debugf("loading image %s", entry->name);
sdc_image_open(drive, entry->name);

#endif

// return to parent form
menu_pop();
}
Expand Down
40 changes: 40 additions & 0 deletions src/sdc.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,46 @@ static int sdc_image_inserted(char drive, unsigned long size, char *ext) {
return 0;
}

#ifdef ESP_PLATFORM

void sdc_load_core(char *fname) {
uint8_t corebuf[256];
FIL f;

sdc_lock();
// mcu_hw_spi_flash_begin(); // This is not working... Need to figure out why

if (f_open(&f, fname, FA_READ) != FR_OK) {
debugf("Cannot open core file");
return;
}
int addr = 0x100000; // Second bit file location in SPI Flash - 1MB - First bit file needs multiboot enabled with SPI Location of 100000. Trigger reconfig_n to jump to this location.
unsigned int cnt = 0;
debugf("Starting Erase\n");
mcu_hw_erase_flash_region(addr, 0x100000); // Bit file size for Tang Primer 20k is 1MB
debugf("Starting Flashing\n");
while (!f_eof(&f)) {
f_read(&f, corebuf, 256, &cnt);
mcu_hw_write_flash(addr, corebuf, cnt);
addr += cnt;
cnt = 0;
}
// write remaining data in buffer
if (cnt > 0) {
mcu_hw_write_flash(addr, corebuf, cnt);
addr += cnt;
}
f_close(&f);

// mcu_hw_spi_flash_end();
sdc_unlock();

debugf("Core ready. Please reboot");

}

#endif

int sdc_image_open(int drive, char *name) {
// tell core that the "disk" has been removed
sdc_image_inserted(drive, 0, NULL);
Expand Down
3 changes: 3 additions & 0 deletions src/sdc.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,8 @@ char *sdc_get_image_name(int drive);
char *sdc_get_cwd(int drive);
void sdc_set_default(int drive, const char *name);
void sdc_mount_defaults(void);
#ifdef ESP_PLATFORM
void sdc_load_core(char *fname);
#endif

#endif // SDC_H