#ifndef FPGAFLASHOPERATION_H #define FPGAFLASHOPERATION_H #include #include #include "fpgaflashengine.h" #include "fpgaflashconfig.h" /* * Resetting the core: 1. Reset the core issuing the keycode @ the the SRR address 2. Wait @ least 10 usec Using the core: 1. Set the MODER register. 2. Set the CMDR register. 3. Set the ADDRR register (this register setting depends by the command set into CMDR. Refer to Table 6-2 to know if this setting is requested or not). 4. Set the NBR register (this register setting depends by the command set into CMDR. Refer to Table 6-2 to know if this setting is requested or not). 5. Set the "SPI request" bit into the SPICR register 6. Wait until "SPI core Acknowledge" bit into the SPISR is raised by the core. 7. Check "SPI Core Error" bit is not raised (core error can be raised if currently requested command is not supported). 8. In case currently requested command requires to fill the TX FIFO (refers to Table 6-2), fill the trasmission buffer by writing data @ the SPIDTR register 9. Set the "SPI start" bit into the SPICR register (maintaining the "SPI request" bit set) 10. Wait until "SPI busy" into the SPISR is set 11. Reset "SPI start" bit 12. Wait until "SPI busy" into the SPISR is reset 13. Check "SPI Core Error" bit is not raised (core error can be raised if currently requested command generates an underflow or overflow error). 14. In case a read command has been requested, readout read data @ SPIDRR 15. De-assert "SPI request" bit. 16. Wait until "SPI core Acknowledge" bit into the SPISR is de-asserted by the core */ /*0x02C MODER RW 0x0 Mode Register 0x030 CMDR RW 0x0 Command Register 0x034 ADDRR RW 0x0 Address Register 0x038 NBR RW 0x0 Number of bytes Register 0x040 SRR RW 0x0 Software Reset Register 0x060 SPICR RW 0x0 SPI Control Register 0x400 SPIDTR RW 0x0 SPI Transmit FIFO Register 0x864 SPISR RO 0x0 SPI Status Register 0x874 TXFIFOOCY RO 0x0 TX FIFO Occupancy Register 0x878 RXFIFOOCY RO 0x0 RX FIFO Occupancy Register 0xC00 SPIRR RO 0x0 SPI Receive FIFO Register Interrupt Control Grouping 0x01C GIER RW 0x0 Global Interrupt Enable Register 0x020 ICSR RW 0x0 Interrupt Clear Status Register 0x028 IER RW 0x0 Interrupt Enable Register 0x820 ISR */ #define FLASH_ID_SIZE 4 #define FLASH_ID_NUMBER_OF_BYTES 20 // 5.5 Register Space, AXI_QSPIFlash_IF_PG Rev. A, pag 16 #define R32_(x_) ((x_)/4) enum reg_offset_t { //RW -> read write //RO -> read only r_base =R32_(0), r_moder =R32_(0x02C), //RW Mode Register r_cmdr =R32_(0x030), //RW Command Register r_addrr =R32_(0x034), //RW Address Register r_nbr =R32_(0x038), //RW Number of bytes Register r_srr =R32_(0x040), //RW Software Reset Register r_spicr =R32_(0x060), //RW SPI Control Register r_spidtr =R32_(0x400), //RW SPI Transmit FIFO Register r_spi_status_base =R32_(0x800), //RO SPI Status base r_spisr =R32_(0x864), //RO SPI Status Register r_txfifoocy =R32_(0x874), //RO TX FIFO Occupancy Register r_rxfifoocy =R32_(0x878), //RO RX FIFO Occupancy Register r_spirr =R32_(0xC00), //RO SPI Receive FIFO Register r_gier =R32_(0x01C), //RW Global Interrupt Enable Register r_icsr =R32_(0x020), //RW Interrupt Clear Status Register r_ier =R32_(0x028), //RW Interrupt Enable Register r_isr =R32_(0x820), //RO Interrupt Status Register adr_fifo=r_base+r_spidtr }; // 5.5.1.1 Mode Register (MODER) enum reg_moder_spimode_t //SPI Mode { moder_spimode_x1mode = 0, //normal SPI, x1 mode moder_spimode_x2mode = 1, //x2 mode moder_spimode_x4mode = 2 //x4 mode }; //5.5.1.2 Command Register (CMDR) //APPENDIX 1. MICRON FLASH SUPPORTED INSTRUCTIONS enum reg_cmdr_command_t { //software reset operations, cmdr_reset_enable =0x66, //reset enable cmdr_reset_mem =0x99, //reset mem //read id operations, cmdr_read_id =0x9e, //read id cmdr_multi_io_read_id=0xaf, //multiple I/O read id cmdr_read_serial =0x05a, //read serial flash discovery parameter //read memory operations, cmdr_mem_read =0x03, //read memory cmdr_mem_fast_read =0x0b, //fast read memory cmdr_mem_dual_read =0x3b, //dual output fast read cmdr_mem_quad_read =0x6b, //quad output fast read //write operations, cmdr_write_enable =0x06, //write enable cmdr_write_disable =0x04, //write disable //read register operation, cmdr_read_st_reg =0x05, //read status register cmdr_read_flag_st =0x70, //read flag status register cmdr_read_non_vol =0xb5, //read non-volatile config register cmdr_read_vol =0x85, //read volatile config register cmdr_read_enhan =0x65, //read enhanced volatile config register cmdr_read_gen_purp =0x96, //read general purpose read register //write register operation, cmdr_write_st_reg =0x01, //write status register cmdr_write_non_vol =0xb1, //write non-volatile configuration register cmdr_write_vol =0x81, //write volatile configuration register cmdr_write_enhan =0x61, //write enhanced volatile configuration register cmdr_write_ext =0xc5, //write extended address register cmdr_clear_st_reg =0x50, //clear flag status register //program operation, cmdr_prog_page =0x02, //page program cmdr_prog_dual_inp =0xa2, //dual input fast program cmdr_prog_ext_dual =0xd2, //extended dual input fast program cmdr_prog_quad_inp =0x32, //quad input fast program cmdr_prog_ext_quad =0x38, //extended quad input fast program //erase operation, cmdr_erase_32kb =0x52, //32 kb subsector erase cmdr_erase_4kb =0x20, //4kb subsector erase cmdr_erase_sector =0xd8, //sector erase cmdr_erase_bulk =0xc7, //bulk erase //4-byte address mode operations cmdr_4b_add_enter =0xb7, //enter 4b address mode cmdr_4b_add_exit =0xe9, //exit 4b address mode //quad protocol operations cmdr_quad_io_enter =0x35, //enter quad io mode cmdr_quad_io_exit =0xf5, //exit quad io mode //power down cmdr_pwr_enter =0xb9, //enter deep power down cmdr_pwr_release =0xab, //release deep power down //advanced sector protection cmdr_sect_read =0x2d, //read sector protection cmdr_sect_progr =0x2c, //program sector protection cmdr_sect_read_vol =0xe8, //read volatile lock bits cmdr_sect_write_vol =0xe5, //write volatile lock bits cmdr_sect_read_non_vol=0xe2, //read nonvolatile lock bits cmdr_sect_write_non_vol=0xe3, //write nonvolatile lock bits cmdr_sect_erase_non_vol=0xe4, //erase nonvolatile lock bits cmdr_sect_read_freez=0xa7, //read global freeze bit cmdr_sect_write_freez=0xa6, //write global freeze bit cmdr_sect_red_pwd =0x27, //read password cmdr_sect_write_pwd =0x28, //write password cmdr_sect_unlock_pwd=0x29, //unlock password //advanced function interface cmdr_int_activation =0x9b //interface activation }; enum type_cmd_t { cmd_nc, //cmd without read and write cmd_read, //cmd with read //cmd_read_flashID, //cmd with read cmd_write, //cmd with write }; //5.5.1.6 SPI Control Register (SPICR) enum reg_spicr_req_t //SPI request { spicr_req_no =0, //no request begin transaction spicr_req_begin_trans =1 //It requires to the IP to begin with a transaction }; enum reg_spicr_start_t //SPI start { spicr_start_no =0, //no start previous transaction spicr_start_prev_trans =1 //It starts a previously required transaction }; class FlashOperation { public: reg_moder_spimode_t moder_spimode; reg_moder_byteaddress_t moder_byteaddress; reg_moder_qspiport_t moder_qspiport; //struct contain data buffer and control command struct cx_t { uint32_t buffer[256/4]; //data buffer (256byte) //uint32_t ctrl[256/4]; //control command uint32_t ctrl[256/4]; //R32_(0xC00)]; //control command, max register address/4 }; cx_t cx; //struct contain status register information read from spi struct status_register_spisr_t { bool rx_fifo_valid; //bit 0, This bit flags that data present into SPIRR is valid bool rx_fifo_overrun; //bit 1, This bit flags that an overrun error occurred during data reception into the RX FIFO. bool tx_fifo_almost_full; //bit 4, This bit flags that an almost full condition occurred loading the TX FIFO. In particular this condition is activated when the number of bytes into the FIFO differs from respect the FIFO size. bool tx_fifo_overrun; //bit 5, This bit flags that an overrun error occurred loading data into the TX FIFO. bool tx_fifo_underrun; //bit 6, This bit flags that an underrun error occurred into the TX FIFO during data transmission. bool spi_core_error; //bit 10, The SPI Core error flags an error condition during transaction. This condition can be activated: - when an overrun or underrun is detected (on both "TX FIFO" or "RX FIFO") - when the required command is not implemented bool spi_core_ack; //bit 11, This bit is activated when a previously required transaction required with the "SPI request" on the SPICR register has been accepted bool spi_core_busy; //bit 12, This bit is activated when the core is executing the current transaction after that it has been run with the "SPI start" bit on the SPICR register. }; status_register_spisr_t status_register_spisr; FpgaFlashProfile profile; FpgaFlashInterface* fif; FpgaFlashEngine* engine; bool enabledMsgBlk; //enable message block bool getEnableMsgBlk(); void setEnableMsgBlk(bool _enable); uint32_t FLASH_ID[FLASH_ID_SIZE]; // INITIALIZE operations, 2.4.1.1 Inizializzazione // Inizialize mode register, set engine void init(FpgaFlashEngine* engine_, reg_moder_spimode_t a_moder_spimode, reg_moder_byteaddress_t a_moder_byteaddress, reg_moder_qspiport_t a_moder_qspiport); // Initialize connection without set engine void init(reg_moder_spimode_t a_moder_spimode, reg_moder_byteaddress_t a_moder_byteaddress, reg_moder_qspiport_t a_moder_qspiport); // Core reset bool reset(); // Read FLASH ID bool readFlashID(reg_moder_qspiport_t spi_port); // Read FPGA FW IBC bool readFPGAFWIBC(void* data, const int _len); //Sets the FPGA FLASH addressing mode bool setByteAddress(reg_moder_qspiport_t spi_port,reg_moder_byteaddress_t byteaddress); //2.4.1.4 Read (singolo data chunk di 256 byte) void readDataChunk(int size,void* data); bool program(const void* data, unsigned int size); //SPISR - SPI Status register info bool getRxFifoValid(); bool getRxFifoOverrun(); bool getTxFifoFull(); bool getTxFifoOverrun(); bool getTxFifoUnderrun(); bool getSpiCoreBusy(); bool getSpiCoreError(); bool getSpiCoreAck(); //Questo comando legge lo stato del registro di stato della Flash al fine di aspettare //l'avvenuta scrittura del pacchetto dati tramite il bit di "Write In Progress" bool getWriteInProgress(); // Erase from profile.BaseOffset for size bool eraseForSize(unsigned int size); // Read status register SPISR and put info into cmdr_read_st_reg struct bool readStatusRegisterSPISR(); //terminazione bool terminateDigitalCtrl(); bool terminateOtherFPGA(); private: bool setQuadSpiMode(bool _flag); void decodeSPIRError(unsigned int _spisr); bool confirmFlashOperation(); void printDebugFlashConfig(); bool sendCommand(unsigned int cmd, void *data=0, unsigned int len=256, type_cmd_t type_cmd=cmd_nc); // WRITE OPERATIONS, enable/disable bool writeEnable(bool enable); bool fpgaWrite(uint32_t address, const void* data, unsigned int len=256, const char* mess=""); bool fpgaRead(uint32_t address, void* data, unsigned int len=256, const char* mess=""); bool fpgaReadFPGAFWIBC(uint32_t address, void* data, unsigned int len=256, const char* mess=""); //2.4.1.3 Write (singolo data chunk di 256 byte) bool writeBlock(unsigned int address, const char* data, unsigned int len); //***************************************** // operation with the transaction void resetTransaction(); void prepareTransaction(); void startTransaction(); void endTransaction(); //ERASE OPERATION, erase sector bool eraseSector(unsigned long sector_address); //return stirng description for cmd char* retCommand(unsigned int cmd); }; #endif // FPGAFLASHOPERATION_H