diff options
author | Pavel V. Shatov (Meister) <meisterpaul1@yandex.ru> | 2021-12-20 12:52:23 +0300 |
---|---|---|
committer | Pavel V. Shatov (Meister) <meisterpaul1@yandex.ru> | 2021-12-20 12:52:23 +0300 |
commit | 200a616758fa9c7aa83737e9620fb6a927d0c45a (patch) | |
tree | f6d998e5f03edf130f10838d2c7d4982c631bd47 /stm-ice40mkm.c | |
parent | e3a5752a303dff144dec71f909b5721cf2ffdb64 (diff) |
Reworked the way iCE40-based MKM is configured. The bitmap is now stored rightice40mkm
after the main FPGA's bitstream (was placed at the very end of the
configuration memory previously). This makes it possible to flash two devices
at the same time, but needs a somewhat smarter supporting routine. Instead of
just looking at the very last sector of the config memy we now to need to swipe
through all the sectors looking for the Lattice magic bitmap marker to
determine where the MKM firmware starts.
Diffstat (limited to 'stm-ice40mkm.c')
-rw-r--r-- | stm-ice40mkm.c | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/stm-ice40mkm.c b/stm-ice40mkm.c index 5a03525..a7eb9a9 100644 --- a/stm-ice40mkm.c +++ b/stm-ice40mkm.c @@ -92,10 +92,10 @@ int ice40mkm_configure(void) size_t c; uint8_t prom_buf[N25Q128_PAGE_SIZE]; uint8_t prom_marker[] = ICE40_MAGIC_MARKER; - int prom_marker_bad = 0, cdone_state; + int prom_marker_bad = 1, cdone_state; - uint32_t prom_addr, prom_offset = N25Q128_SECTOR_SIZE * - (N25Q128_NUM_SECTORS - ICE40_BITSTREAM_SECTORS); + + uint32_t prom_addr, prom_sector_index; uint32_t page, num_pages = ICE40_BITSTREAM_SECTORS * (N25Q128_SECTOR_SIZE / N25Q128_PAGE_SIZE); @@ -124,8 +124,8 @@ int ice40mkm_configure(void) /* * device is now ready to receive the bitstream * - * the bitstream is stored in the last two sectors of the main - * FPGA configuration memory + * the mkm bitmap is stored right after the main bitstream and is aligned + * on sector boundary * * the very first page of the bitstream starts with a magic marker, * which can be used to detect whether the bitstream is present @@ -135,26 +135,44 @@ int ice40mkm_configure(void) fpgacfg_access_control(ALLOW_ARM); /* - * read the bitstream page-by-page and send it over SPI3 + * first read the very first page of each sector to find the offset of + * the mkm bitmap, skip the very first sector (there's no + * sane way for the mkm bitmap may start there) + * + * then read the bitstream page-by-page and send it over SPI3 + * * note, that bitstream is slightly smaller than two sectors, so we're * sending some 0xFF's after the binary image, which is harmless * (just some dummy clock cycles) */ - prom_addr = prom_offset; - for (page=0; page<num_pages; page++) + for (prom_sector_index = 1; prom_sector_index < N25Q128_NUM_SECTORS; prom_sector_index += 1) { /* read next page */ + prom_addr = prom_sector_index * N25Q128_SECTOR_SIZE; prom_ok = fpgacfg_read_data(prom_addr, prom_buf, N25Q128_PAGE_SIZE); if (prom_ok != HAL_OK) break; /* check magic marker */ - if (page == 0) { - for (c=0; c<sizeof prom_marker; c++) - if (prom_buf[c] != prom_marker[c]) { - prom_marker_bad = 1; - break; - } - } + prom_marker_bad = 0; + for (c=0; c<sizeof prom_marker; c++) + if (prom_buf[c] != prom_marker[c]) { + prom_marker_bad = 1; + break; + } + + /* mkm bitmap found! */ + if (!prom_marker_bad) break; + } + + /* check, that magic marker was correct */ + if (prom_marker_bad) return 2; + + /* send the mkm bitmap */ + for (page=0; page<num_pages; page++) + { + /* read next page */ + prom_ok = fpgacfg_read_data(prom_addr, prom_buf, N25Q128_PAGE_SIZE); + if (prom_ok != HAL_OK) break; /* send page to iCE40 */ prom_ok = HAL_SPI_Transmit(&hspi_ice40mkm, prom_buf, N25Q128_PAGE_SIZE, N25Q128_SPI_TIMEOUT); @@ -167,10 +185,8 @@ int ice40mkm_configure(void) /* relinquish access to FPGA config storage */ fpgacfg_access_control(ALLOW_FPGA); - /* check, that magic marker was correct */ /* check, that all the pages were written */ - if (prom_marker_bad) return 2; - else if (page != num_pages) return 1; + if (page != num_pages) return 1; /* clear chip-select */ _ice40mkm_chip_deselect(); |