aboutsummaryrefslogtreecommitdiff
path: root/stm-ice40mkm.c
diff options
context:
space:
mode:
Diffstat (limited to 'stm-ice40mkm.c')
-rw-r--r--stm-ice40mkm.c52
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();