123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- /*
- * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /******************************************************************************
- * @file ck_eflash.c
- * @brief CSI Source File for Embedded Flash Driver
- * @version V1.0
- * @date 02. June 2017
- ******************************************************************************/
- #include <stdio.h>
- #include "drv_eflash.h"
- #include "ck_eflash.h"
- #define ERR_EFLASH(errno) (CSI_DRV_ERRNO_EFLASH_BASE | errno)
- #define EFLASH_NULL_PARAM_CHK(para) \
- do { \
- if (para == NULL) { \
- return ERR_EFLASH(EDRV_PARAMETER); \
- } \
- } while (0)
- typedef struct {
- uint32_t base;
- eflash_info eflashinfo;
- eflash_event_cb_t cb;
- eflash_status_t status;
- } ck_eflash_priv_t;
- static ck_eflash_priv_t eflash_handle[CONFIG_EFLASH_NUM];
- /* Driver Capabilities */
- static const eflash_capabilities_t driver_capabilities = {
- .event_ready = 1, /* event_ready */
- .data_width = 2, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
- .erase_chip = 0 /* erase_chip */
- };
- //
- // Functions
- //
- static int32_t eflash_program_word(eflash_handle_t handle, uint32_t dstaddr, uint32_t *srcbuf, uint32_t len)
- {
- ck_eflash_priv_t *eflash_priv = handle;
- uint32_t fbase = eflash_priv->base;
- uint32_t i;
- for (i = 0; i < len; i++) {
- *(volatile uint32_t *)(fbase + 0x04) = dstaddr;
- *(volatile uint32_t *)(fbase + 0x1c) = *srcbuf;
- *(volatile uint32_t *)(fbase + 0x18) = 1;
- srcbuf++;
- dstaddr += 4;
- }
- return (i << 2);
- }
- int32_t __attribute__((weak)) target_get_eflash_count(void)
- {
- return 0;
- }
- int32_t __attribute__((weak)) target_get_eflash(int32_t idx, uint32_t *base, eflash_info *info)
- {
- return NULL;
- }
- /**
- \brief get eflash handle count.
- \return eflash handle count
- */
- int32_t csi_eflash_get_instance_count(void)
- {
- return target_get_eflash_count();
- }
- /**
- \brief Initialize EFLASH Interface. 1. Initializes the resources needed for the EFLASH interface 2.registers event callback function
- \param[in] idx must not exceed return value of csi_eflash_get_instance_count()
- \param[in] cb_event Pointer to \ref eflash_event_cb_t
- \return pointer to eflash handle
- */
- eflash_handle_t csi_eflash_initialize(int32_t idx, eflash_event_cb_t cb_event)
- {
- if (idx < 0 || idx >= CONFIG_EFLASH_NUM) {
- return NULL;
- }
- /* obtain the eflash information */
- uint32_t base = 0u;
- eflash_info info;
- int32_t real_idx = target_get_eflash(idx, &base, &info);
- if (real_idx != idx) {
- return NULL;
- }
- ck_eflash_priv_t *eflash_priv = &eflash_handle[idx];
- eflash_priv->base = base;
- eflash_priv->eflashinfo.start = info.start;
- eflash_priv->eflashinfo.end = info.end;
- eflash_priv->eflashinfo.sector_count = info.sector_count;
- /* initialize the eflash context */
- eflash_priv->cb = cb_event;
- eflash_priv->status.busy = 0;
- eflash_priv->status.error = 0U;
- eflash_priv->eflashinfo.sector_size = EFLASH_SECTOR_SIZE;
- eflash_priv->eflashinfo.page_size = EFLASH_PAGE_SIZE;
- eflash_priv->eflashinfo.program_unit = EFLASH_PROGRAM_UINT;
- eflash_priv->eflashinfo.erased_value = EFLASH_ERASED_VALUE;
- return (eflash_handle_t)eflash_priv;
- }
- /**
- \brief De-initialize EFLASH Interface. stops operation and releases the software resources used by the interface
- \param[in] handle eflash handle to operate.
- \return error code
- */
- int32_t csi_eflash_uninitialize(eflash_handle_t handle)
- {
- EFLASH_NULL_PARAM_CHK(handle);
- ck_eflash_priv_t *eflash_priv = handle;
- eflash_priv->cb = NULL;
- return 0;
- }
- /**
- \brief Get driver capabilities.
- \param[in] eflash handle to operate.
- \return \ref eflash_capabilities_t
- */
- eflash_capabilities_t csi_eflash_get_capabilities(eflash_handle_t handle)
- {
- return driver_capabilities;
- }
- /**
- \brief Read data from Flash.
- \param[in] handle eflash handle to operate.
- \param[in] addr Data address.
- \param[out] data Pointer to a buffer storing the data read from Flash.
- \param[in] cnt Number of data items to read.
- \return number of data items read or error code
- */
- int32_t csi_eflash_read(eflash_handle_t handle, uint32_t addr, void *data, uint32_t cnt)
- {
- EFLASH_NULL_PARAM_CHK(handle);
- EFLASH_NULL_PARAM_CHK(data);
- EFLASH_NULL_PARAM_CHK(cnt);
- if (!IS_EFLASH_ADDR(addr) || !(IS_EFLASH_ADDR(addr + cnt -1))) {
- return ERR_EFLASH(EDRV_PARAMETER);
- }
- volatile uint8_t *src_addr = (uint8_t *)addr;
- ck_eflash_priv_t *eflash_priv = handle;
- if (eflash_priv->status.busy) {
- return ERR_EFLASH(EDRV_BUSY);
- }
- eflash_priv->status.error = 0U;
- int i;
- for (i = 0; i < cnt; i++) {
- *((uint8_t *)data + i) = *(src_addr + i);
- }
- return i;
- }
- /**
- \brief Program data to Flash.
- \param[in] handle eflash handle to operate.
- \param[in] addr Data address.
- \param[in] data Pointer to a buffer containing the data to be programmed to Flash..
- \param[in] cnt Number of data items to program.
- \return number of data items programmed or error code
- */
- int32_t csi_eflash_program(eflash_handle_t handle, uint32_t addr, const void *data, uint32_t cnt)
- {
- EFLASH_NULL_PARAM_CHK(handle);
- EFLASH_NULL_PARAM_CHK(data);
- EFLASH_NULL_PARAM_CHK(cnt);
- if (!IS_EFLASH_ADDR(addr) || !(IS_EFLASH_ADDR(addr + cnt -1))) {
- return ERR_EFLASH(EDRV_PARAMETER);
- }
- ck_eflash_priv_t *eflash_priv = handle;
- if ((addr & 0x3) || ((uint32_t)data & 0x3) || (cnt & 0x3)) {
- return ERR_EFLASH(EDRV_PARAMETER);
- }
- if (eflash_priv->status.busy) {
- return ERR_EFLASH(EDRV_BUSY);
- }
- eflash_priv->status.busy = 1U;
- eflash_priv->status.error = 0U;
- uint32_t ret = eflash_program_word(handle, addr, (uint32_t *)data, cnt >> 2);
- eflash_priv->status.busy = 0U;
- return ret;
- }
- /**
- \brief Erase Flash Sector.
- \param[in] handle eflash handle to operate.
- \param[in] addr Sector address
- \return error code
- */
- int32_t csi_eflash_erase_sector(eflash_handle_t handle, uint32_t addr)
- {
- EFLASH_NULL_PARAM_CHK(handle);
- if (!IS_EFLASH_ADDR(addr)) {
- return ERR_EFLASH(EDRV_PARAMETER);
- }
- addr = addr & ~(EFLASH_SECTOR_SIZE - 1);
- ck_eflash_priv_t *eflash_priv = handle;
- uint32_t fbase = eflash_priv->base;
- if (eflash_priv->status.busy) {
- return ERR_EFLASH(EDRV_BUSY);
- }
- eflash_priv->status.busy = 1U;
- eflash_priv->status.error = 0U;
- *(volatile uint32_t *)(fbase + 0x4) = addr;
- *(volatile uint32_t *)(fbase + 0x10) = 0x1;
- eflash_priv->status.busy = 0U;
- return 0;
- }
- /**
- \brief Erase complete Flash.
- \param[in] handle eflash handle to operate.
- \return error code
- */
- int32_t csi_eflash_erase_chip(eflash_handle_t handle)
- {
- EFLASH_NULL_PARAM_CHK(handle);
- return ERR_EFLASH(EDRV_UNSUPPORTED);
- }
- /**
- \brief Get Flash information.
- \param[in] handle eflash handle to operate.
- \return Pointer to Flash information \ref eflash_info
- */
- eflash_info *csi_eflash_get_info(eflash_handle_t handle)
- {
- ck_eflash_priv_t *eflash_priv = handle;
- eflash_info *eflash_info = &(eflash_priv->eflashinfo);
- return eflash_info;
- }
- /**
- \brief Get EFLASH status.
- \param[in] handle eflash handle to operate.
- \return EFLASH status \ref eflash_status_t
- */
- eflash_status_t csi_eflash_get_status(eflash_handle_t handle)
- {
- ck_eflash_priv_t *eflash_priv = handle;
- return eflash_priv->status;
- }
|