2021-08-31 17:38:28 +08:00
|
|
|
#include "fpga.h"
|
|
|
|
#include "fpga_bin.h"
|
|
|
|
#include "string.h"
|
|
|
|
|
|
|
|
// 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++)
|
|
|
|
{
|
2021-12-26 16:53:27 +08:00
|
|
|
HAL_SPI_Transmit(&hspi1, (uint8_t *)__build_syrostan_fpga_bin+100*i, 100, HAL_MAX_DELAY-1);
|
2021-08-31 17:38:28 +08:00
|
|
|
}
|
2021-12-26 16:53:27 +08:00
|
|
|
// HAL_SPI_Transmit(&hspi1, (uint8_t *)__build_syrostan_fpga_bin, 65535U, HAL_MAX_DELAY-1);
|
|
|
|
// HAL_SPI_Transmit(&hspi1, (uint8_t *)&__build_syrostan_fpga_bin[65535U], 65535U, HAL_MAX_DELAY-1);
|
|
|
|
// HAL_SPI_Transmit(&hspi1, (uint8_t *)&__build_syrostan_fpga_bin[131070UL], 4030U, HAL_MAX_DELAY-1);
|
2021-08-31 17:38:28 +08:00
|
|
|
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
2021-12-31 10:57:11 +08:00
|
|
|
void fsmc_read(uint16_t address, uint8_t *dat)
|
2021-08-31 17:38:28 +08:00
|
|
|
{
|
2021-12-31 10:57:11 +08:00
|
|
|
uint32_t fsmc_add = 0x60000000 | (address << 8);
|
2021-12-26 16:53:27 +08:00
|
|
|
|
2021-12-31 10:57:11 +08:00
|
|
|
*dat = (*(__IO uint8_t *)(fsmc_add));
|
|
|
|
// HAL_GPIO_WritePin(FSMC_NRE_GPIO_Port, FSMC_NRE_Pin, GPIO_PIN_RESET);
|
|
|
|
// HAL_GPIO_WritePin(FSMC_NRE_GPIO_Port, FSMC_NRE_Pin, GPIO_PIN_SET);
|
|
|
|
// HAL_SRAM_Read_8b(&hsram1, (uint32_t*)&fsmc_add, dat, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void fsmc_write(uint16_t address, uint8_t dat)
|
|
|
|
{
|
|
|
|
// HAL_GPIO_WritePin(FSMC_NWE_GPIO_Port, FSMC_NWE_Pin, GPIO_PIN_RESET);
|
|
|
|
uint32_t fsmc_add = 0x60000000 | (address << 8);
|
|
|
|
// HAL_GPIO_WritePin(FSMC_NWE_GPIO_Port, FSMC_NWE_Pin, GPIO_PIN_SET);
|
|
|
|
|
|
|
|
(*(__IO uint8_t *)(fsmc_add)) = dat;
|
2021-12-26 16:53:27 +08:00
|
|
|
}
|