344 lines
14 KiB
C++
344 lines
14 KiB
C++
#ifndef FPGAFLASHOPERATION_H
|
|
#define FPGAFLASHOPERATION_H
|
|
|
|
#include <string.h>
|
|
#include <map>
|
|
|
|
#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[DIM_DATA_BUFFER/4]; //data buffer (256byte)
|
|
//uint32_t ctrl[DIM_DATA_BUFFER/4]; //control command
|
|
uint32_t ctrl[DIM_DATA_BUFFER/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=DIM_DATA_BUFFER, 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=DIM_DATA_BUFFER, const char* mess="");
|
|
|
|
bool fpgaRead(uint32_t address, void* data, unsigned int len=DIM_DATA_BUFFER, const char* mess="");
|
|
|
|
bool fpgaReadFPGAFWIBC(uint32_t address, void* data, unsigned int len=DIM_DATA_BUFFER, 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);
|
|
|
|
unsigned int counterRepeat;
|
|
|
|
void incrCounterRepeat();
|
|
|
|
bool setProtectionSector(bool testLock=false);
|
|
|
|
bool setVolatileLockBits(bool testLock=false);
|
|
|
|
bool readStatusFlagRegister();
|
|
|
|
|
|
};
|
|
|
|
#endif // FPGAFLASHOPERATION_H
|