/* ================================================================== >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< ------------------------------------------------------------------ Copyright (c) 2019-2023 by Lattice Semiconductor Corporation ALL RIGHTS RESERVED ------------------------------------------------------------------ IMPORTANT: THIS FILE IS USED BY OR GENERATED BY the LATTICE PROPELâ„¢ DEVELOPMENT SUITE, WHICH INCLUDES PROPEL BUILDER AND PROPEL SDK. Lattice grants permission to use this code pursuant to the terms of the Lattice Propel License Agreement. DISCLAIMER: LATTICE MAKES NO WARRANTIES ON THIS FILE OR ITS CONTENTS, WHETHER EXPRESSED, IMPLIED, STATUTORY, OR IN ANY PROVISION OF THE LATTICE PROPEL LICENSE AGREEMENT OR COMMUNICATION WITH LICENSEE, AND LATTICE SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. LATTICE DOES NOT WARRANT THAT THE FUNCTIONS CONTAINED HEREIN WILL MEET LICENSEE 'S REQUIREMENTS, OR THAT LICENSEE' S OPERATION OF ANY DEVICE, SOFTWARE OR SYSTEM USING THIS FILE OR ITS CONTENTS WILL BE UNINTERRUPTED OR ERROR FREE, OR THAT DEFECTS HEREIN WILL BE CORRECTED. LICENSEE ASSUMES RESPONSIBILITY FOR SELECTION OF MATERIALS TO ACHIEVE ITS INTENDED RESULTS, AND FOR THE PROPER INSTALLATION, USE, AND RESULTS OBTAINED THEREFROM. LICENSEE ASSUMES THE ENTIRE RISK OF THE FILE AND ITS CONTENTS PROVING DEFECTIVE OR FAILING TO PERFORM PROPERLY AND IN SUCH EVENT, LICENSEE SHALL ASSUME THE ENTIRE COST AND RISK OF ANY REPAIR, SERVICE, CORRECTION, OR ANY OTHER LIABILITIES OR DAMAGES CAUSED BY OR ASSOCIATED WITH THE SOFTWARE.IN NO EVENT SHALL LATTICE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS FILE OR ITS CONTENTS, EVEN IF LATTICE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. LATTICE 'S SOLE LIABILITY, AND LICENSEE' S SOLE REMEDY, IS SET FORTH ABOVE. LATTICE DOES NOT WARRANT OR REPRESENT THAT THIS FILE, ITS CONTENTS OR USE THEREOF DOES NOT INFRINGE ON THIRD PARTIES' INTELLECTUAL PROPERTY RIGHTS, INCLUDING ANY PATENT. IT IS THE USER' S RESPONSIBILITY TO VERIFY THE USER SOFTWARE DESIGN FOR CONSISTENCY AND FUNCTIONALITY THROUGH THE USE OF FORMAL SOFTWARE VALIDATION METHODS. ------------------------------------------------------------------ ================================================================== */ #include "qspi_flash_cntl.h" static volatile qspi_flash_cntl_reg_t *flash_cntl; /** * @brief Initializes the QSPI flash controller instance with the provided base address and status. * * This function initializes the QSPI flash controller instance pointed by 'this_qspi_flash_cntl' * with the given 'base_addr'. It also sets the status of the flash controller * to 'IDLE'. * * @param this_qspi_flash_cntl Pointer to the QSPI flash controller instance. * @param base_addr The base address of the QSPI flash controller registers. * @return Returns 'SUCCESS' (0) on successful initialization, or 'FAILURE' (1) if 'this_qspi_flash_cntl' is NULL. */ unsigned int qspi_flash_cntl_init(struct qspi_flash_cntl_instance_t *this_qspi_flash_cntl, unsigned int base_addr) { if(this_qspi_flash_cntl == IS_NULL) { return RET_FAILURE; } this_qspi_flash_cntl->base_address = base_addr; flash_cntl = (volatile qspi_flash_cntl_reg_t *)this_qspi_flash_cntl->base_address; flash_cntl->REG_QSPI_CONFIG_0 = this_qspi_flash_cntl->config_0; flash_cntl->REG_QSPI_CONFIG_1 = this_qspi_flash_cntl->config_1; this_qspi_flash_cntl->status = IDLE; return RET_SUCCESS; } /** * @brief Reads the value from the specified register. * * This function reads the value from the QSPI flash controller registers * specified by 'index' and stores the result in the 'reg_data' pointer. * * @param this_qspi_flash_cntl Pointer to the QSPI flash controller instance. * @param index The index of the QSPI configuration register to read. * @param reg_data Pointer to a variable where the read register value will be stored. * @return Returns 'SUCCESS' (0) on successful read, or 'FAILURE' (1) if 'this_qspi_flash_cntl' is NULL. */ unsigned int qspi_flash_cntl_read(struct qspi_flash_cntl_instance_t *this_qspi_flash_cntl, qspi_reg_type_t index, unsigned int *reg_data) { if(this_qspi_flash_cntl == IS_NULL) { return RET_FAILURE; } volatile unsigned int base_addr = (unsigned int)(this_qspi_flash_cntl->base_address); volatile unsigned int *read_reg = (unsigned int *)(base_addr + (index<base_address); volatile unsigned int *write_reg = (unsigned int *)(base_addr + (index<REG_INT_ENABLE = INT_EN_VAL; // enable interrupt qspi_flash_cntl_set_tx_fifo(this_qspi_fifo); while (count_wr_fifo < ((this_qspi_fifo->params_ext_t.buff_length)>>REG_GAP)) { flash_cntl->REG_TX_FIFO_MAP = buffer[count_wr_fifo++]; // write the data } flash_cntl->REG_START_TRANS = START_TRANS_VAL; // start transaction while ((irq_sts & CHECK_ONE) == IRQ_WR_FIFO_EN) // check interrupt { irq_sts = flash_cntl->REG_INT_STATUS; } flash_cntl->REG_START_TRANS = CLR_START_TRANS; return RET_SUCCESS; } /** * @brief Reads data from RX FIFO with QSPI flash controller with FIFO enable. * * This function is used to read the data from the flash memory using RX FIFO. * * @param buffer Pointer to the buffer to store the read data. * @param this_qspi_fifo Pointer to the structure qspi_params_t. */ void qspi_flash_cntl_read_fifo_en(qspi_params_t *this_qspi_fifo ,unsigned int *buffer) { unsigned int count_read_fifo = 0; qspi_flash_cntl_set_tx_fifo(this_qspi_fifo); flash_cntl->REG_START_TRANS = START_TRANS_VAL; // start transaction while(((flash_cntl->REG_INT_STATUS>>SHIFT_FOUR) & CHECK_ONE) == IRQ_RD_FIFO_EN); flash_cntl->REG_INT_STATUS = CLR_INTERRUPT; // clear interrupt while(count_read_fifo < ((this_qspi_fifo->params_ext_t.buff_length)>>REG_GAP)) { buffer[count_read_fifo++] = flash_cntl->REG_RX_FIFO_MAP; // read the data } flash_cntl->REG_START_TRANS = CLR_START_TRANS; } /** * @brief Writes/erase the data to the flash memory with QSPI flash controller when FIFO is disable. * * This function is used to write/erase the data to the flash memory using Data Packet registers when fifo is disable. * * @param buffer Pointer to the buffer containing data to be written. * @param this_qspi_pkt Pointer to the structure qspi_params_t. * @return Returns 'SUCCESS' (0) on successful write, or 'FAILURE' (1) if 'buffer' is NULL. */ unsigned int qspi_flash_cntl_write_erase_fifo_dis(qspi_params_t *this_qspi_pkt, unsigned int *buffer) { unsigned int irq_sts = 0; unsigned int trans_sts = 1; unsigned int idx = 0; if (buffer == IS_NULL) { return RET_FAILURE; } flash_cntl->REG_INT_ENABLE = INT_EN_VAL; // interrupt enable // write packet headers qspi_flash_cntl_set_pkt_hdr(this_qspi_pkt); while (idx < ((this_qspi_pkt->params_ext_t.buff_length)>>REG_GAP)) { flash_cntl->REG_PACKET_DATA_0 = buffer[idx]; // write the data flash_cntl->REG_PACKET_DATA_1 = buffer[idx+INCREMENT_ONE]; while ((irq_sts & CHECK_ONE) == IRQ_WR_FIFO_DIS) { irq_sts = flash_cntl->REG_INT_STATUS; } irq_sts = CLR_IRQ_STS_VAR; flash_cntl->REG_INT_STATUS = CLR_INTERRUPT; // clear interrupt idx+=IDX_TWO; } while ((trans_sts & CHECK_ONE) == TRANS_STS) // transaction status { trans_sts = flash_cntl->REG_TRANS_STATUS; } return RET_SUCCESS; } /** * @brief Reads data from the flash memory with QSPI flash controller when FIFO is disabled. * * This function is used to read the data from the flash memory using Data Packet register when fifo is disable. * *@param this_qspi_pkt Pointer to the structure qspi_params_t. * @param buffer Pointer to the buffer to store the read data. * */ void qspi_flash_cntl_read_fifo_dis(qspi_params_t *this_qspi_pkt, unsigned int *buffer) { unsigned int len = 0; // write packet headers qspi_flash_cntl_set_pkt_hdr(this_qspi_pkt); flash_cntl->REG_INT_ENABLE = INT_EN_VAL; // interrupt enable flash_cntl->REG_START_TRANS = START_TRANS_VAL; // start transaction for (len = IDX_ZERO; len < ((this_qspi_pkt->params_ext_t.buff_length)>>REG_GAP); len++) { while (((flash_cntl->REG_INT_STATUS >> SHIFT_FOUR) & CHECK_ONE) == IRQ_RD_FIFO_DIS); // check the interrupt flash_cntl->REG_INT_STATUS = CLR_INTERRUPT; // clear the interrupt *(buffer+len) = flash_cntl->REG_PACKET_DATA_0; // read the data packet } flash_cntl->REG_START_TRANS = CLR_START_TRANS; } /** * @brief Set Packet Header for QSPI Flash Controller Transaction. * * This function set the packet header registers based on the provided parameters. * * @param this_pkt_hdr Pointer to the structure qspi_params_t containing the desired variables. * */ void qspi_flash_cntl_set_pkt_hdr(qspi_params_t *this_pkt_hdr) { flash_cntl->REG_PACKET_HDR_0 = this_pkt_hdr->params_reg_t.packet_header0; flash_cntl->REG_PACKET_HDR_1 = this_pkt_hdr->params_reg_t.packet_header1; flash_cntl->REG_PACKET_HDR_2 = this_pkt_hdr->params_reg_t.packet_header2; flash_cntl->REG_PACKET_HDR_3 = this_pkt_hdr->params_reg_t.packet_header3; } /** * @brief - Set up and transmit data to the QSPI flash controller TX FIFO. * * This Function configure the TX FIFO for the write/erase and read apis when fifo is enabled. * * @param this_tx_fifo Pointer to the structure qspi_params_t containing the desired variables. */ void qspi_flash_cntl_set_tx_fifo(qspi_params_t *this_tx_fifo) { flash_cntl->REG_TX_FIFO_MAP = this_tx_fifo->params_reg_t.packet_header0; flash_cntl->REG_TX_FIFO_MAP = this_tx_fifo->params_reg_t.packet_header1; flash_cntl->REG_TX_FIFO_MAP = this_tx_fifo->params_reg_t.packet_header2; } /** * enable_quad_mode - Enable Quad Mode for the QSPI flash controller. * * @brief - This function sets up the necessary registers to enable Quad Mode for the QSPI flash controller. * */ void enable_quad_mode() { flash_cntl->REG_QSPI_FLASH_CMD_CODE_7 = FLASH_CMD_CODE_7_REG_CMD_QUAD_EN; flash_cntl->REG_PACKET_HDR_0 = PKT_HDR_0_CMD_QUAD_EN; flash_cntl->REG_PACKET_HDR_1 = PKT_HDR_1_CMD_QUAD_EN; flash_cntl->REG_START_TRANS = START_TRANS_VAL; flash_cntl->REG_INT_STATUS = CLR_INTERRUPT; flash_cntl->REG_START_TRANS = CLR_START_TRANS; } /** * RESET_quad_mode - Reset Quad Mode for the QSPI flash controller. * * @brief - This function sets up the necessary registers to Reset Quad Mode for the QSPI flash controller. * */ void reset_quad_mode() { flash_cntl->REG_QSPI_FLASH_CMD_CODE_7 = FLASH_CMD_CODE_7_REG_CMD_QUAD_RST; flash_cntl->REG_PACKET_HDR_0 = PKT_HDR_0_CMD_QUAD_RST; flash_cntl->REG_PACKET_HDR_1 = PKT_HDR_1_CMD_QUAD_RST; flash_cntl->REG_START_TRANS = START_TRANS_VAL; flash_cntl->REG_INT_STATUS = CLR_INTERRUPT; flash_cntl->REG_START_TRANS = CLR_START_TRANS; }