#include "fpga.h" #include "fpga_bin.h" #include "string.h" uint8_t fsmc_dat; uint16_t fsmc_add; // A public method to flash iCE40 FPGA on Humpback void flash_fpga() { // Data buffer setup uint8_t dummy_bytes[13]; memset(dummy_bytes, 0, 13); // Drive CRESET_B low HAL_GPIO_WritePin(FPGA_CRESET_GPIO_Port, FPGA_CRESET_Pin, GPIO_PIN_RESET); // Drive SPI_SS_B low HAL_GPIO_WritePin(SPI_FPGA_CS_GPIO_Port, SPI_FPGA_CS_Pin, GPIO_PIN_RESET); // Wait at least 200ns HAL_Delay(5); // Drive CRESET_B high HAL_GPIO_WritePin(FPGA_CRESET_GPIO_Port, FPGA_CRESET_Pin, GPIO_PIN_SET); // Wait at least another 1200us to clear internal config memory HAL_Delay(5); // Before data transmission starts, check if C_DONE is truly low // If C_DONE is high, the FPGA reset procedure is unsuccessful while (HAL_GPIO_ReadPin(FPGA_CDONE_GPIO_Port, FPGA_CDONE_Pin) == GPIO_PIN_SET); // Set SPI_SS_B high HAL_GPIO_WritePin(SPI_FPGA_CS_GPIO_Port, SPI_FPGA_CS_Pin, GPIO_PIN_SET); // Send 8 dummy clock, effectively 1 byte of 0x00 HAL_SPI_Transmit(&hspi1, dummy_bytes, 1, 1000); // Drive SPI_SS_B low HAL_GPIO_WritePin(SPI_FPGA_CS_GPIO_Port, SPI_FPGA_CS_Pin, GPIO_PIN_RESET); // Send the whole image without interruption for (uint16_t i = 0; i < 1351U; i++) { HAL_SPI_Transmit(&hspi1, (uint8_t *)blinky_bin+100*i, 100, HAL_MAX_DELAY-1); } // HAL_SPI_Transmit(&hspi1, (uint8_t *)blinky_bin, 65535U, HAL_MAX_DELAY-1); // HAL_SPI_Transmit(&hspi1, (uint8_t *)&blinky_bin[65535U], 65535U, HAL_MAX_DELAY-1); // HAL_SPI_Transmit(&hspi1, (uint8_t *)&blinky_bin[131070UL], 4030U, HAL_MAX_DELAY-1); // Drive SPI_SS_B high HAL_GPIO_WritePin(SPI_FPGA_CS_GPIO_Port, SPI_FPGA_CS_Pin, GPIO_PIN_SET); // Send at another 100 dummy clocks (choosing 13 bytes) HAL_SPI_Transmit(&hspi1, dummy_bytes, 13, 1000); // Check the CDONE output from FPGA // CDONE needs to be high while (HAL_GPIO_ReadPin(FPGA_CDONE_GPIO_Port, FPGA_CDONE_Pin) == GPIO_PIN_RESET); // Send at least another 49 clock cycles to activate IO pins (choosing same 13 bytes) HAL_SPI_Transmit(&hspi1, dummy_bytes, 13, 1000); } void read_fsmc() { HAL_SRAM_Read_8b(&hsram1, (uint32_t*)&fsmc_add, &fsmc_dat, 1); }