ECP5 FPGA Driver ================ The ECP5FPGA driver is a device driver within the HotRIO system designed to manage the boot sequence and status of the ECP5 FPGA. This driver encapsulates the functionality to control the FPGA's behavior using three dedicated control pins: DONE, INITn, and PROGRAMM. These pins are used to manage the FPGA's initialization, program loading, and completion signals, ensuring the proper operation of the FPGA during the boot process. In addition to managing the boot sequence and status of the FPGA, the ECP5FPGA driver also provides functionality for interacting with the FPGA's internal registers. The driver supports the following operations: - **Reading Registers**: The driver can read values from various registers within the FPGA, enabling it to retrieve status information or configuration data. This is essential for monitoring the FPGA's internal state and making any necessary adjustments. - **Writing Registers**: The driver can write data to specific registers within the FPGA, allowing for configuration or control of the FPGA's operation. These operations are necessary for controlling the FPGA's functionality, depending on the specific program loaded onto the device. The ability to read and write registers from the FPGA allows the driver to fully manage the FPGA's behavior, ensuring that the system can interact with the FPGA effectively and dynamically. Control Pins ------------ The ECP5FPGA driver uses the following control pins to interface with the FPGA: - The **DONE** pin is a bi-directional open-drain pin with a weak pull-up, used to signal that the FPGA has entered user mode and is ready for operation. The DONE pin can only indicate entry into user mode once an internal DONE bit is asserted, marking the beginning of the FPGA Wake-Up state. Key features of the DONE pin: - User Mode Indication: The DONE pin goes high to signal that the FPGA has successfully completed configuration and is now in user mode. This happens only after the internal DONE bit is set, signaling that the FPGA is awake and operational. - Tandem with INITN: The DONE pin is driven low alongside the INITn pin when the FPGA is in initialization mode. This occurs when power is applied, the PROGRAMN pin is asserted, or an IEEE 1532 Refresh command is received via a configuration port. - **INITn** pin is a bi-directional open-drain control pin with several key functions during the FPGA configuration process: - Erasing SRAM: Upon power application, PROGRAMN assertion, or a REFRESH command, the INITn pin goes low to signal that the SRAM configuration memory is being erased. The low duration is specified by the tINTIL parameter. - Ready for Configuration: After the INITn pin has been low for the specified time, it is deasserted (active high), indicating that the FPGA is ready to load its configuration data from an external SPI Flash. - Error Signaling: If INITn is asserted again before DONE becomes active high, it signals that the FPGA has detected an error during the configuration process. - **PROGRAMM** pin is an input used to configure the FPGA and is low-level sensitive with an internal weak pull-up. When asserted low, it causes the FPGA to exit user mode and enter the initialization phase. The pin must remain low for a minimum period, as specified in the ECP5 datasheet, for the FPGA to recognize it. *Key considerations for using PROGRAMN:* - If the FPGA is being programmed via JTAG, the PROGRAMN pin is ignored until the JTAG programming is complete. - Toggling PROGRAMN during configuration restarts the process. - PROGRAMN should not be asserted low before the power rails stabilize. This can be ensured by using an external pull-up resistor or relying on the FPGA's internal pull-up. - PROGRAMN should not transition low during the initialization phase, and it must stay low for a minimum time (tPRGMRJ) to avoid device malfunction, which could require a power cycle to recover. Error Conditions for INITN and Device Configuration Failure ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If an error occurs while reading the FPGA bitstream, The INITn pin will transition to low while the DONE pin remains low, indicating that the FPGA did not successfully complete its configuration. Possible causes of a FPGA wakeup error: - Bitstream CRC Error: A mismatch in the bitstream’s CRC (Cyclic Redundancy Check) indicates corruption or invalid data in the configuration bitstream. - Timeout Error During Bitstream Load: A timeout occurs when loading configuration data from the external SPI Flash, especially if the FPGA is in MSPI (Multispi) configuration mode, and the SPI Flash has not been properly programmed. - The SPI bus the microcontroller uses to communicate with the ECP5 and the ECP5 uses to retrieve the configuration is not released. Since during the configuration pahse of the FPGA, both the FPGA and the microcontroller are SPI bus masters, the microcontroller must release the bus by disabling the SPI peripheral while the FPGA boots. If the microcontroller fails to do that, the bus lines may remain asserted by the microcontroller while the FPGA tries to retrieve the configuration from the EEPROM. FPGA State Machine ~~~~~~~~~~~~~~~~~~ The state machine in the ECP5 driver manages the operational flow of the FPGA and its states, including initialization, booting, running, error handling, and halting. The state machine works by monitoring specific signals from the FPGA and taking actions based on the current state and those signals. This ensures smooth transitions between different phases of the FPGA's lifecycle. The state machine in this context uses a series of states, and each state represents a specific point in the FPGA's lifecycle. The transitions between these states are triggered by changes in GPIO pin states (such as the INITn or DONE pins) which are sensed via interrupts. **States Overview:** - **FPGA_RESET**: This is the default state of the state machine, where FPGA is stopped after a power-on. The FPGA is completely inactive in this state. Actions: Prepare the FPGA for initialization. - **FPGA_INITIALISATION**: This state occurs when the FPGA is being initialized. It is the phase just before FPGA configuration starts. The FPGA is powered on and the PROGRAMM pin is configured to signal a reset or boot sequence. Actions: Prepare the FPGA for configuration by setting up the communication interface (SPI, GPIOs), enabling the clock, and performing any hardware setup. - **FPGA_CONFIGURATION**: In this state, the FPGA is receiving its configuration bitstream, usually through the SPI interface. This is the stage where the FPGA is being loaded with its firmware or configuration data. Actions: Write the bitstream to the FPGA's memory. The system will continually check for the DONE signal to indicate when the FPGA has successfully completed configuration. - **FPGA_RUNNING**: After the FPGA has been successfully configured, it enters this state, where it begins running its programmed logic. The FPGA starts performing its tasks based on the configuration loaded in the previous state. Upon entering on this stage, the SPI peripheral can be enabled again to communicate with the FPGA, EEPROM or any other device sharing the bus. Actions: The FPGA is now active and performing its designated tasks. The driver might continue to monitor the status and interact with the FPGA's memory. - **FPGA_DISABLED_OFF and FPGA_DISABLED_ON**: These states represent when the FPGA is not being forced to any state or monitored, meaning that the developer is free to debug the FPGA without the micro forcing any state - **FPGA_HALT**: This is the state when the FPGA is being instructed not to boot by forcing the PROGRAMM pin to a low state and not releasing it. The FPGA enters a "halted" state where it does not perform any further actions until a reset or recovery operation is performed. //TODO Virtual file system interfaces ------------------------------ The driver exposes two interfaces to the microcontroller’s virtual file system under the **DEV** folder: **FPGA** and **BITSTREAM**. These interfaces allow interaction with the FPGA and its configuration in a seamless, file-like manner. - **FPGA File**: The **FPGA** file facilitates access to the FPGA's register map. It allows read and write operations on the FPGA's registers over the SPI bus in a format defined by the FPGA's register tree and interface documentation. This file serves as a direct interface to manipulate FPGA registers, enabling users to write and read register values at any time. Additionally, this file provides functionality for uploading configuration data to the FPGA, where users can copy a binary configuration file to this virtual file, triggering the FPGA to load the new configuration. - **BITSTREAM File**: The **BITSTREAM** file serves as the entry point for writing and recovering the FPGA's bitstream during its boot sequence. This file has its own specialized driver that allows writing to a dedicated memory region, which is separate from the **FatFS** file system. The memory region used for the bitstream is not part of the **FatFS** system because **FatFS** would typically segment the file across different memory areas. Instead, this file allows the loading and retrieval of the bitstream to/from the **EEPROM**, providing access to the specific bitstream data required to configure the FPGA during boot. These two virtual files provide a straightforward interface for FPGA configuration and management, abstracting low-level hardware access and making FPGA operations more accessible within the virtual file system framework.