ck_eflash.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*
  2. * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /******************************************************************************
  17. * @file ck_eflash.c
  18. * @brief CSI Source File for Embedded Flash Driver
  19. * @version V1.0
  20. * @date 02. June 2017
  21. ******************************************************************************/
  22. #include <stdio.h>
  23. #include "drv_eflash.h"
  24. #include "ck_eflash.h"
  25. #define ERR_EFLASH(errno) (CSI_DRV_ERRNO_EFLASH_BASE | errno)
  26. #define EFLASH_NULL_PARAM_CHK(para) \
  27. do { \
  28. if (para == NULL) { \
  29. return ERR_EFLASH(EDRV_PARAMETER); \
  30. } \
  31. } while (0)
  32. typedef struct {
  33. uint32_t base;
  34. eflash_info eflashinfo;
  35. eflash_event_cb_t cb;
  36. eflash_status_t status;
  37. } ck_eflash_priv_t;
  38. static ck_eflash_priv_t eflash_handle[CONFIG_EFLASH_NUM];
  39. /* Driver Capabilities */
  40. static const eflash_capabilities_t driver_capabilities = {
  41. .event_ready = 1, /* event_ready */
  42. .data_width = 2, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
  43. .erase_chip = 0 /* erase_chip */
  44. };
  45. //
  46. // Functions
  47. //
  48. static int32_t eflash_program_word(eflash_handle_t handle, uint32_t dstaddr, uint32_t *srcbuf, uint32_t len)
  49. {
  50. ck_eflash_priv_t *eflash_priv = handle;
  51. uint32_t fbase = eflash_priv->base;
  52. uint32_t i;
  53. for (i = 0; i < len; i++) {
  54. *(volatile uint32_t *)(fbase + 0x04) = dstaddr;
  55. *(volatile uint32_t *)(fbase + 0x1c) = *srcbuf;
  56. *(volatile uint32_t *)(fbase + 0x18) = 1;
  57. srcbuf++;
  58. dstaddr += 4;
  59. }
  60. return (i << 2);
  61. }
  62. int32_t __attribute__((weak)) target_get_eflash_count(void)
  63. {
  64. return 0;
  65. }
  66. int32_t __attribute__((weak)) target_get_eflash(int32_t idx, uint32_t *base, eflash_info *info)
  67. {
  68. return NULL;
  69. }
  70. /**
  71. \brief get eflash handle count.
  72. \return eflash handle count
  73. */
  74. int32_t csi_eflash_get_instance_count(void)
  75. {
  76. return target_get_eflash_count();
  77. }
  78. /**
  79. \brief Initialize EFLASH Interface. 1. Initializes the resources needed for the EFLASH interface 2.registers event callback function
  80. \param[in] idx must not exceed return value of csi_eflash_get_instance_count()
  81. \param[in] cb_event Pointer to \ref eflash_event_cb_t
  82. \return pointer to eflash handle
  83. */
  84. eflash_handle_t csi_eflash_initialize(int32_t idx, eflash_event_cb_t cb_event)
  85. {
  86. if (idx < 0 || idx >= CONFIG_EFLASH_NUM) {
  87. return NULL;
  88. }
  89. /* obtain the eflash information */
  90. uint32_t base = 0u;
  91. eflash_info info;
  92. int32_t real_idx = target_get_eflash(idx, &base, &info);
  93. if (real_idx != idx) {
  94. return NULL;
  95. }
  96. ck_eflash_priv_t *eflash_priv = &eflash_handle[idx];
  97. eflash_priv->base = base;
  98. eflash_priv->eflashinfo.start = info.start;
  99. eflash_priv->eflashinfo.end = info.end;
  100. eflash_priv->eflashinfo.sector_count = info.sector_count;
  101. /* initialize the eflash context */
  102. eflash_priv->cb = cb_event;
  103. eflash_priv->status.busy = 0;
  104. eflash_priv->status.error = 0U;
  105. eflash_priv->eflashinfo.sector_size = EFLASH_SECTOR_SIZE;
  106. eflash_priv->eflashinfo.page_size = EFLASH_PAGE_SIZE;
  107. eflash_priv->eflashinfo.program_unit = EFLASH_PROGRAM_UINT;
  108. eflash_priv->eflashinfo.erased_value = EFLASH_ERASED_VALUE;
  109. return (eflash_handle_t)eflash_priv;
  110. }
  111. /**
  112. \brief De-initialize EFLASH Interface. stops operation and releases the software resources used by the interface
  113. \param[in] handle eflash handle to operate.
  114. \return error code
  115. */
  116. int32_t csi_eflash_uninitialize(eflash_handle_t handle)
  117. {
  118. EFLASH_NULL_PARAM_CHK(handle);
  119. ck_eflash_priv_t *eflash_priv = handle;
  120. eflash_priv->cb = NULL;
  121. return 0;
  122. }
  123. /**
  124. \brief Get driver capabilities.
  125. \param[in] eflash handle to operate.
  126. \return \ref eflash_capabilities_t
  127. */
  128. eflash_capabilities_t csi_eflash_get_capabilities(eflash_handle_t handle)
  129. {
  130. return driver_capabilities;
  131. }
  132. /**
  133. \brief Read data from Flash.
  134. \param[in] handle eflash handle to operate.
  135. \param[in] addr Data address.
  136. \param[out] data Pointer to a buffer storing the data read from Flash.
  137. \param[in] cnt Number of data items to read.
  138. \return number of data items read or error code
  139. */
  140. int32_t csi_eflash_read(eflash_handle_t handle, uint32_t addr, void *data, uint32_t cnt)
  141. {
  142. EFLASH_NULL_PARAM_CHK(handle);
  143. EFLASH_NULL_PARAM_CHK(data);
  144. EFLASH_NULL_PARAM_CHK(cnt);
  145. if (!IS_EFLASH_ADDR(addr) || !(IS_EFLASH_ADDR(addr + cnt -1))) {
  146. return ERR_EFLASH(EDRV_PARAMETER);
  147. }
  148. volatile uint8_t *src_addr = (uint8_t *)addr;
  149. ck_eflash_priv_t *eflash_priv = handle;
  150. if (eflash_priv->status.busy) {
  151. return ERR_EFLASH(EDRV_BUSY);
  152. }
  153. eflash_priv->status.error = 0U;
  154. int i;
  155. for (i = 0; i < cnt; i++) {
  156. *((uint8_t *)data + i) = *(src_addr + i);
  157. }
  158. return i;
  159. }
  160. /**
  161. \brief Program data to Flash.
  162. \param[in] handle eflash handle to operate.
  163. \param[in] addr Data address.
  164. \param[in] data Pointer to a buffer containing the data to be programmed to Flash..
  165. \param[in] cnt Number of data items to program.
  166. \return number of data items programmed or error code
  167. */
  168. int32_t csi_eflash_program(eflash_handle_t handle, uint32_t addr, const void *data, uint32_t cnt)
  169. {
  170. EFLASH_NULL_PARAM_CHK(handle);
  171. EFLASH_NULL_PARAM_CHK(data);
  172. EFLASH_NULL_PARAM_CHK(cnt);
  173. if (!IS_EFLASH_ADDR(addr) || !(IS_EFLASH_ADDR(addr + cnt -1))) {
  174. return ERR_EFLASH(EDRV_PARAMETER);
  175. }
  176. ck_eflash_priv_t *eflash_priv = handle;
  177. if ((addr & 0x3) || ((uint32_t)data & 0x3) || (cnt & 0x3)) {
  178. return ERR_EFLASH(EDRV_PARAMETER);
  179. }
  180. if (eflash_priv->status.busy) {
  181. return ERR_EFLASH(EDRV_BUSY);
  182. }
  183. eflash_priv->status.busy = 1U;
  184. eflash_priv->status.error = 0U;
  185. uint32_t ret = eflash_program_word(handle, addr, (uint32_t *)data, cnt >> 2);
  186. eflash_priv->status.busy = 0U;
  187. return ret;
  188. }
  189. /**
  190. \brief Erase Flash Sector.
  191. \param[in] handle eflash handle to operate.
  192. \param[in] addr Sector address
  193. \return error code
  194. */
  195. int32_t csi_eflash_erase_sector(eflash_handle_t handle, uint32_t addr)
  196. {
  197. EFLASH_NULL_PARAM_CHK(handle);
  198. if (!IS_EFLASH_ADDR(addr)) {
  199. return ERR_EFLASH(EDRV_PARAMETER);
  200. }
  201. addr = addr & ~(EFLASH_SECTOR_SIZE - 1);
  202. ck_eflash_priv_t *eflash_priv = handle;
  203. uint32_t fbase = eflash_priv->base;
  204. if (eflash_priv->status.busy) {
  205. return ERR_EFLASH(EDRV_BUSY);
  206. }
  207. eflash_priv->status.busy = 1U;
  208. eflash_priv->status.error = 0U;
  209. *(volatile uint32_t *)(fbase + 0x4) = addr;
  210. *(volatile uint32_t *)(fbase + 0x10) = 0x1;
  211. eflash_priv->status.busy = 0U;
  212. return 0;
  213. }
  214. /**
  215. \brief Erase complete Flash.
  216. \param[in] handle eflash handle to operate.
  217. \return error code
  218. */
  219. int32_t csi_eflash_erase_chip(eflash_handle_t handle)
  220. {
  221. EFLASH_NULL_PARAM_CHK(handle);
  222. return ERR_EFLASH(EDRV_UNSUPPORTED);
  223. }
  224. /**
  225. \brief Get Flash information.
  226. \param[in] handle eflash handle to operate.
  227. \return Pointer to Flash information \ref eflash_info
  228. */
  229. eflash_info *csi_eflash_get_info(eflash_handle_t handle)
  230. {
  231. ck_eflash_priv_t *eflash_priv = handle;
  232. eflash_info *eflash_info = &(eflash_priv->eflashinfo);
  233. return eflash_info;
  234. }
  235. /**
  236. \brief Get EFLASH status.
  237. \param[in] handle eflash handle to operate.
  238. \return EFLASH status \ref eflash_status_t
  239. */
  240. eflash_status_t csi_eflash_get_status(eflash_handle_t handle)
  241. {
  242. ck_eflash_priv_t *eflash_priv = handle;
  243. return eflash_priv->status;
  244. }