如何使用微控制器对 Lattice iCE40 ultra 进行编程

How to program Lattice iCE40 ultra with a microcontroller

我正在尝试使用 stm32F4 微控制器对 iCE40 ultra FPGA 进行编程,我正在尝试弄清楚如何将配置文件加载到微控制器上,以便它可以通过 SPI 发送到 FPGA 进行编程。应用笔记说这是可以做到的,并且有一些伪代码,但它似乎是用于计算机而不是微控制器。微型和 FPGA 都在我设计的 PCB 上,它们之间有一个 SPI 通道。这将在编程后用于两者之间的通信。

配置文件是.bin 文件或.hex 文件,我不确定如何将这些文件之一加载到stm32 并将其发送到FPGA。我正在尝试这样做,因为我希望不必购买编程电缆并在我的 PCB 上包含闪存来存储程序,因为我已经需要微型和 FPGA 之间的 SPI 通信来实现我希望制作的应用程序事情对我自己来说更容易,而且可能做了相反的事情......

这是我编写的用于发送文件的函数。我知道我需要以某种方式打开文件并将其发送出去。所有其他时序均来自 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 打开文件的帮助都会很有帮助。

如果您使用 GCC 和 binutils 作为 compiler/linker 系统,您可以使用 objcopy 从任何二进制文件生成可链接模块。然后可以将其链接到控制器的只读数据 space 并从您的程序访问。

stm32F4镜像需要包含ice40镜像。至少有两种可能性。

  • 正如其他答案中所建议的那样。让链接器完成这项工作。 GCC 链接器可以包含任意二进制数据,概述了几种方法 here。这需要使用 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 运行)。在我看来,iceStorm 项目中的 'icecmpr' 是一个非常好的实用程序,请参阅 https://github.com/cliffordwolf/icestorm/tree/master/icecompr