chen
2024-11-08 cc432b761c884a0bd8e9d83db0a4e26109fc08b1
keil/include/drivers/mk_flash.h
对比新文件
@@ -0,0 +1,256 @@
/*
 * 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_ */