/*
|
* Copyright (c) 2019-2023 Beijing Hanwei Innovation Technology Ltd. Co. and
|
* its subsidiaries and affiliates (collectly called MKSEMI).
|
*
|
* All rights reserved.
|
*
|
* Redistribution and use in source and binary forms, with or without
|
* modification, are permitted provided that the following conditions are met:
|
*
|
* 1. Redistributions of source code must retain the above copyright notice,
|
* this list of conditions and the following disclaimer.
|
*
|
* 2. Redistributions in binary form, except as embedded into an MKSEMI
|
* integrated circuit in a product or a software update for such product,
|
* must reproduce the above copyright notice, this list of conditions and
|
* the following disclaimer in the documentation and/or other materials
|
* provided with the distribution.
|
*
|
* 3. Neither the name of MKSEMI nor the names of its contributors may be used
|
* to endorse or promote products derived from this software without
|
* specific prior written permission.
|
*
|
* 4. This software, with or without modification, must only be used with a
|
* MKSEMI integrated circuit.
|
*
|
* 5. Any software provided in binary form under this license must not be
|
* reverse engineered, decompiled, modified and/or disassembled.
|
*
|
* THIS SOFTWARE IS PROVIDED BY MKSEMI "AS IS" AND ANY EXPRESS OR IMPLIED
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* DISCLAIMED. IN NO EVENT SHALL MKSEMI OR CONTRIBUTORS BE LIABLE FOR ANY
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
*/
|
|
#ifndef MK_FLASH_H_
|
#define MK_FLASH_H_
|
|
#include "mk_common.h"
|
#include "mk_dma.h"
|
#include "mk_misc.h"
|
|
#ifndef FLASH_INT_MODE_EN
|
#define FLASH_INT_MODE_EN (1)
|
#endif
|
|
#ifndef FLASH_DMA_MODE_EN
|
#define FLASH_DMA_MODE_EN (1)
|
#endif
|
|
#ifndef FLASH_WRITE_EN
|
#define FLASH_WRITE_EN (1)
|
#endif
|
|
/**
|
* @addtogroup MK8000_Flash
|
* @{
|
*/
|
|
#define FLASH_PAGE_SIZE 0x100U
|
#define FLASH_SECTOR_SIZE 0x1000U
|
#define FLASH_BLOCK_SIZE 0x10000U
|
|
#define FLASH_OP_ERASE 1
|
#define FLASH_OP_WRITE 2
|
#define FLASH_OP_READ 3
|
|
// Flash status check timeout
|
#define FLASH_OP_ERASE_SECTOR_TIMEOUT __MS_TO_TICKS(600)
|
#define FLASH_OP_ERASE_BLOCK_TIMEOUT __MS_TO_TICKS(4000)
|
#define FLASH_OP_WRITE_PAGE_TIMEOUT __MS_TO_TICKS(6)
|
#define FLASH_OP_WRITE_STATUS_TIMEOUT __MS_TO_TICKS(40)
|
|
/** FLASH device instance */
|
enum FLASH_DEV_T
|
{
|
FLASH_ID0 = 0,
|
FLASH_MAX_NUM
|
};
|
|
/** FLASH operation code */
|
enum FLASH_OPCODE_T
|
{
|
FLASH_OPCODE_READ = 0,
|
FLASH_OPCODE_PROGRAM_PAGE,
|
FLASH_OPCODE_GET_STATUS,
|
FLASH_OPCODE_GET_STATUS1,
|
FLASH_OPCODE_ERASE_SECTOR,
|
FLASH_OPCODE_ERASE_BLOCK,
|
FLASH_OPCODE_WRITE_ENABLE,
|
FLASH_OPCODE_WRITE_REGISTER,
|
FLASH_OPCODE_RDID,
|
FLASH_OPCODE_POWER_DOWN,
|
FLASH_OPCODE_RELEASE_POWER_DOWN,
|
FLASH_OPCODE_NUM,
|
};
|
|
/** FLASH operation state */
|
enum FLASH_STATE_T
|
{
|
FLASH_STATE_RESET = 0,
|
FLASH_STATE_READY,
|
FLASH_STATE_BUSY_READ,
|
FLASH_STATE_BUSY_ERASE,
|
FLASH_STATE_BUSY_WRITE,
|
FLASH_STATE_TIMEOUT,
|
FLASH_STATE_ERROR
|
};
|
|
/*! @brief FLASH data direction */
|
enum FLASH_DATA_DIR_TYPE_T
|
{
|
FLASH_DATA_IN = 0x0U, /*!< Data input from serial flash. */
|
FLASH_DATA_OUT = 0x1U /*!< Data output to serial flash. */
|
};
|
|
/*! @brief FLASH command opcode format */
|
enum FLASH_CMD_FORMAT_T
|
{
|
FLASH_CMD_ALL_SERIAL = 0x0, /*!< All fields of command are serial. */
|
FLASH_CMD_DATA_QUAD_DUAL = 0x1U, /*!< Only data field is dual/quad, others are serial. */
|
FLASH_CMD_OP_SERIAL = 0x2U, /*!< Only opcode field is serial, others are quad/dual. */
|
FLASH_CMD_ALL_QUAD_DUAL = 0x3U /*!< All fields of command are dual/quad mode. */
|
};
|
|
/*! @brief FLASH command type */
|
enum FLASH_CMD_TYPE_T
|
{
|
FLASH_CMD_OP_ONLY = 0x1U, /*!< Command only have opcode, no address field */
|
FLASH_CMD_OP_ADDR_1B = 0x2U, /*!< Command have opcode and also one byte address field */
|
FLASH_CMD_OP_ADDR_2B = 0x3U, /*!< Command have opcode and also two bytes address field */
|
FLASH_CMD_OP_ADDR_3B = 0x4U, /*!< Command have opcode and also three bytes address field. */
|
FLASH_CMD_OP_ADDR_4B = 0x5U, /*!< Command have opcode and also four bytes address field */
|
FLASH_CMD_NO_OP_ADDR_3B = 0x6U, /*!< Command have no opcode and three bytes address field */
|
FLASH_CMD_NO_OP_ADDR_4B = 0x7U /*!< Command have no opcode and four bytes address field */
|
};
|
|
/*! @brief FLASH command structure */
|
struct FLASH_CMD_T
|
{
|
uint32_t polling_mode; /*!< For command need to read data from serial flash */
|
enum FLASH_DATA_DIR_TYPE_T data_dir; /*!< Data direction of this command. */
|
enum FLASH_CMD_FORMAT_T format; /*!< Command format */
|
enum FLASH_CMD_TYPE_T type; /*!< Command type */
|
uint16_t data_len; /*!< How many data bytes are needed in this command. */
|
uint8_t dummy_len; /*!< How many intermediate bytes needed */
|
uint8_t opcode; /*!< Command opcode value */
|
};
|
|
/*!
|
* @brief FLASH configuration structure.
|
*/
|
struct FLASH_CFG_T
|
{
|
uint16_t timeout; /*!< SPI transfer timeout, the unit is SCK cycles */
|
uint8_t cs_high_time; /*!< CS high time cycles */
|
bool dual_mode : 1; /*!< true: dual mode, false: quad mode */
|
bool prefetch_dis : 1; /*!< True means FLASH will not attempt a speculative prefetch */
|
bool cache_prefetch_dis : 1; /*!< Disable prefetch of cache line */
|
bool feedback_clk_sel : 1; /*!< Is data sample uses feedback clock */
|
bool spi_sck_high : 1; /*!< FLASH spi mode select */
|
bool spi_falling_edge_active : 1; /*!< If enable read full clock cycle. */
|
bool dma_en : 1;
|
bool int_en : 1;
|
uint32_t start_addr;
|
uint32_t total_size;
|
uint32_t block_size;
|
uint16_t sector_size;
|
uint16_t page_size;
|
};
|
|
struct FLASH_DMA_OP_CFG_T
|
{
|
uint32_t start_addr;
|
const uint8_t *buf;
|
uint32_t len;
|
uint32_t count;
|
};
|
|
struct FLASH_WRITE_NBYTES_CFG_T
|
{
|
const uint8_t *src_addr;
|
uint32_t write_start_addr;
|
uint32_t write_end_addr;
|
uint32_t offset_addr;
|
uint32_t page_start;
|
uint32_t page_end;
|
uint32_t page_count;
|
uint32_t write_num;
|
uint32_t write_count;
|
uint32_t start_page_inc_data_len;
|
uint32_t end_page_inc_data_len;
|
uint32_t src_buf_pos;
|
__IOM uint32_t dest_tmp_addr;
|
};
|
|
struct FLASH_HANDLE_T
|
{
|
FLASH_CTRL_TypeDef *const base;
|
const IRQn_Type irq;
|
enum DMA_CH_T dma_wr_ch;
|
enum DMA_CH_T dma_rd_ch;
|
enum FLASH_STATE_T state;
|
struct FLASH_CFG_T config;
|
struct FLASH_WRITE_NBYTES_CFG_T wr_nbyte_cfg;
|
struct FLASH_DMA_OP_CFG_T dma_op;
|
uint32_t code; // reserved | err_code | int_flag | op_code
|
drv_callback_t callback;
|
uint8_t flash_type;
|
uint8_t wrsr_type;
|
uint8_t work_mode;
|
uint8_t promote_fclk;
|
uint8_t is_open;
|
};
|
|
#ifdef __cplusplus
|
extern "C" {
|
#endif
|
|
extern struct FLASH_HANDLE_T flash_handle[FLASH_MAX_NUM];
|
|
int flash_open(enum FLASH_DEV_T id, struct FLASH_CFG_T *cfg);
|
int flash_close(enum FLASH_DEV_T id);
|
|
void RAM_FUNC flash_power_up(enum FLASH_DEV_T id);
|
void RAM_FUNC flash_power_down(enum FLASH_DEV_T id);
|
|
int flash_sector_erase(enum FLASH_DEV_T id, uint32_t sector);
|
int flash_block_erase(enum FLASH_DEV_T id, uint32_t block);
|
|
int flash_erase(enum FLASH_DEV_T id, uint32_t start_addr, uint32_t len);
|
|
int flash_write_nbytes(enum FLASH_DEV_T id, uint32_t start_addr, const uint8_t *buf, uint32_t len);
|
int flash_write(enum FLASH_DEV_T id, uint32_t start_addr, const uint8_t *buf, uint32_t len);
|
int flash_read(enum FLASH_DEV_T id, uint32_t start_addr, uint8_t *buf, uint32_t len);
|
|
void FLASH_CTRL_IRQHandler(void);
|
|
bool flash_check_busy(enum FLASH_DEV_T id);
|
|
int RAM_FUNC flash_open_for_xip(enum FLASH_DEV_T id);
|
|
#ifdef __cplusplus
|
}
|
#endif
|
|
/**
|
* @}
|
*/
|
|
#endif /* MK_FLASH_H_ */
|