Как запрограммировать Lattice iCE40 ultra с помощью микроконтроллера
Я пытаюсь запрограммировать iCE40 ultra FPGA с микроконтроллером stm32F4, и я пытаюсь выяснить, как загрузить файл конфигурации на микроконтроллер, чтобы его можно было отправить на FPGA с помощью SPI для его программирования. В примечании к приложению говорится, что это можно сделать, и есть некоторый псевдокод, но похоже, что он предназначен для использования с компьютером, а не с микроконтроллером. И микро, и FPGA находятся на разработанной мной печатной плате, и между ними есть канал SPI. Это будет использоваться после программирования для простого общения между ними.
Файл конфигурации - это файл.bin или.hex, и я не уверен, как загрузить один из этих файлов на stm32 и отправить его на FPGA. Я пытаюсь сделать это таким образом, потому что я надеялся, что мне не придется покупать программный кабель и включать флеш-память на моей печатной плате для хранения программы, поскольку мне уже нужна связь SPI между микро и FPGA для приложения, которое я надеялся сделать. мне было легче, и я мог сделать наоборот...
Вот функция, которую я написал для отправки файла. Я знаю, что мне нужно как-то открыть файл и отправить его. Все остальное время поступает от гильдии программистов для FPGA.
static void FPGA_Programming(void){
char FPGA_TimeOut = 0; // Error timeout
uint8_t dummyBits[7];
for(char i = 0; i < 7; i++){ // loads dummy bits to be transmitted
dummyBits[i] = 0b01010101;
}
/* Write FPGA config pin and SS to low for at least 200 ns to reset and start FPGA
* in SPI Slave Configuration
*/
HAL_GPIO_WritePin(FPGA_Config_GPIO_Port, FPGA_Config_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(FPGA_SS_GPIO_Port,FPGA_SS_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(FPGA_Config_GPIO_Port, FPGA_Config_Pin, GPIO_PIN_SET); // Set high to turn on FPGA THIS PIN SHOULD STAY HIGH!
HAL_Delay(2); // Wait for FPGA to clear sys memory
// SEND FPGA CONFIG FILE
while(!HAL_GPIO_ReadPin(FPGA_CDone_GPIO_Port, FPGA_CDone_Pin)){ // wait for CDone to go high when config is done and successfull
HAL_Delay(1);
if (FPGA_TimeOut == 5) { // if 5 milliseconds have passed and CDone has not gone low
// send to debug FPGA ERROR Programming
break;
}
FPGA_TimeOut++;
}
HAL_SPI_Transmit(&hspi1, dummyBits, 7, 10 ); // wait for FPGA to start
}
Любая помощь с загрузкой файла и открытием его с помощью micro была бы большой помощью.
2 ответа
Образ ice40 необходимо включить в образ stm32F4. Есть как минимум две возможности.
- Как предлагается в другом ответе. Пусть линкер сделает свою работу. Компоновщик GCC может включать произвольные двоичные данные, здесь описаны несколько способов сделать это. Это требует использования
objcopy
или модификации скрипта компоновщика. Сделайте небольшую утилиту для преобразования двоичного изображения ice40 в объект данных C, примерно так (предупреждение, код не очень хорошо протестирован):
#include <stdio.h> int main( void ) { int i=0,c; printf( "#include <stdint.h>\nconst uint8_t ice40image[] = {\n" ); while ( (c = getchar()) != EOF ) printf( "%#2.2x%s", c, (++i & 15) ? "," : ",\n" ); printf( "};\n#define ICE40IMAGE_LEN %d\n", i ); return 0; }
Бинарное изображение ice40 преобразуется в заголовочный файл:
./bin2uint8_t < ice40image.bin > ice40image.h
а также
ice40image.h
включен в вашу программу stm32F4. Я предпочитаю этот метод, он пригоден для более поздних усовершенствований, таких как сжатие образа FPGA (часто он имеет длинные прогоны 0x00). На мой взгляд, очень хорошая утилита для этого - icecmpr в проекте iceStorm, см. https://github.com/cliffordwolf/icestorm/tree/master/icecompr.
Если вы используете GCC и binutils в качестве системы компилятора / компоновщика, вы можете использовать objcopy
для создания связываемого модуля из любого двоичного файла. Затем его можно связать с пространством данных вашего контроллера, доступным только для чтения, и получить к нему доступ из вашей программы.