1
0

dev_sflash.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. /******************************************************************//**
  2. * @file dev_sflash.c
  3. * @brief SPI Flash driver of RT-Thread RTOS for using EFM32 USART module.
  4. * This driver is tested by using the M25PX16 device on the EFM32 development kit.
  5. * COPYRIGHT (C) 2011, RT-Thread Development Team
  6. * @author onelife
  7. * @version 0.4 beta
  8. **********************************************************************
  9. * @section License
  10. * The license and distribution terms for this file may be found in the file LICENSE in this
  11. * distribution or at http://www.rt-thread.org/license/LICENSE
  12. **********************************************************************
  13. * @section Change Logs
  14. * Date Author Notes
  15. * 2010-05-06 onelife Initial creation for using EFM32 USART module
  16. *********************************************************************/
  17. /******************************************************************//**
  18. * @addtogroup efm32_dk
  19. * @{
  20. *********************************************************************/
  21. /* Includes -------------------------------------------------------------------*/
  22. #include "board.h"
  23. #include "dev_sflash.h"
  24. #if defined(EFM32_USING_SFLASH)
  25. /* Private typedef -------------------------------------------------------------*/
  26. typedef struct
  27. {
  28. rt_uint8_t code;
  29. rt_uint32_t address:24;
  30. rt_uint32_t dummy:8;
  31. } sflash_instruction;
  32. /* Private define --------------------------------------------------------------*/
  33. /* Private macro --------------------------------------------------------------*/
  34. #ifdef EFM32_SFLASH_DEBUG
  35. #define sflash_debug(format,args...) rt_kprintf(format, ##args)
  36. #else
  37. #define sflash_debug(format,args...)
  38. #endif
  39. /* Private constants -----------------------------------------------------------*/
  40. static rt_uint8_t sflash_inst_code_tbl[] =
  41. {
  42. /* Instruction only */
  43. SFLASH_INST_CODE_WREN,
  44. SFLASH_INST_CODE_WRDI,
  45. SFLASH_INST_CODE_RDID_L,
  46. SFLASH_INST_CODE_RDID_S,
  47. SFLASH_INST_CODE_RDSR,
  48. SFLASH_INST_CODE_WRSR,
  49. SFLASH_INST_CODE_BE,
  50. SFLASH_INST_CODE_DP,
  51. SFLASH_INST_CODE_RDP,
  52. /* Instruction and address */
  53. SFLASH_INST_CODE_WRLR,
  54. SFLASH_INST_CODE_RDLR,
  55. SFLASH_INST_CODE_READ,
  56. SFLASH_INST_CODE_POTP,
  57. SFLASH_INST_CODE_PP,
  58. SFLASH_INST_CODE_DIFP,
  59. SFLASH_INST_CODE_SSE,
  60. SFLASH_INST_CODE_SE,
  61. /* Instruction, address and dummy read */
  62. SFLASH_INST_CODE_READ_F,
  63. SFLASH_INST_CODE_DOFR,
  64. SFLASH_INST_CODE_ROTP
  65. };
  66. static rt_uint16_t sflash_data_len_tbl[] =
  67. {
  68. /* Instruction only */
  69. SFLASH_REPLY_LEN_WREN,
  70. SFLASH_REPLY_LEN_WRDI,
  71. SFLASH_REPLY_LEN_RDID_L,
  72. SFLASH_REPLY_LEN_RDID_S,
  73. SFLASH_REPLY_LEN_RDSR,
  74. SFLASH_REPLY_LEN_WRSR,
  75. SFLASH_REPLY_LEN_BE,
  76. SFLASH_REPLY_LEN_DP,
  77. SFLASH_REPLY_LEN_RDP,
  78. /* Instruction and address */
  79. SFLASH_REPLY_LEN_WRLR,
  80. SFLASH_REPLY_LEN_RDLR,
  81. SFLASH_REPLY_LEN_READ,
  82. SFLASH_REPLY_LEN_POTP,
  83. SFLASH_REPLY_LEN_PP,
  84. SFLASH_REPLY_LEN_DIFP,
  85. SFLASH_REPLY_LEN_SSE,
  86. SFLASH_REPLY_LEN_SE,
  87. /* Instruction, address and dummy read */
  88. SFLASH_REPLY_LEN_READ_F,
  89. SFLASH_REPLY_LEN_DOFR,
  90. SFLASH_REPLY_LEN_ROTP
  91. };
  92. static rt_bool_t sflash_read_inst_tbl[] =
  93. {
  94. /* Instruction only */
  95. false,
  96. false,
  97. true,
  98. true,
  99. true,
  100. false,
  101. false,
  102. false,
  103. false,
  104. /* Instruction and address */
  105. false,
  106. true,
  107. true,
  108. false,
  109. false,
  110. false,
  111. false,
  112. false,
  113. /* Instruction, address and dummy read */
  114. true,
  115. true,
  116. true
  117. };
  118. /* Private variables ------------------------------------------------------------*/
  119. static rt_device_t sflash = RT_NULL;
  120. /* Private function prototypes ---------------------------------------------------*/
  121. /* Private functions ------------------------------------------------------------*/
  122. /******************************************************************//**
  123. * @brief
  124. * Initialize the SPI Flash
  125. *
  126. * @details
  127. *
  128. * @note
  129. *
  130. * @return
  131. * Error code
  132. *********************************************************************/
  133. rt_err_t efm_spiFash_init(void)
  134. {
  135. /* Find SPI device */
  136. sflash = rt_device_find(SFLASH_USING_DEVICE_NAME);
  137. do
  138. {
  139. if (sflash == RT_NULL)
  140. {
  141. sflash_debug("SFLASH: Can't find device %s!\n",
  142. SFLASH_USING_DEVICE_NAME);
  143. break;
  144. }
  145. sflash_debug("SFLASH: Find device %s\n", SFLASH_USING_DEVICE_NAME);
  146. /* Open SPI device */
  147. if (sflash->open(sflash, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
  148. {
  149. break;
  150. }
  151. return RT_EOK;
  152. } while(0);
  153. sflash_debug("SFLASH: Init failed!\n");
  154. return -RT_ERROR;
  155. }
  156. /******************************************************************//**
  157. * @brief
  158. * De-initialize the SPI Flash
  159. *
  160. * @details
  161. *
  162. * @note
  163. *
  164. * @return
  165. * Error code
  166. *********************************************************************/
  167. rt_err_t efm_spiFash_deinit(void)
  168. {
  169. do
  170. {
  171. if (sflash == RT_NULL)
  172. {
  173. sflash_debug("SFLASH: Already deinit!\n");
  174. break;
  175. }
  176. /* Close SPI device */
  177. if (sflash->close(sflash) != RT_EOK)
  178. {
  179. break;
  180. }
  181. sflash = RT_NULL;
  182. sflash_debug("SFLASH: Close device %s\n", SFLASH_USING_DEVICE_NAME);
  183. return RT_EOK;
  184. } while(0);
  185. sflash_debug("SFLASH: Deinit failed!\n");
  186. return -RT_ERROR;
  187. }
  188. /******************************************************************//**
  189. * @brief
  190. * Execute a command
  191. *
  192. * @details
  193. *
  194. * @note
  195. *
  196. * @param[in] command
  197. * SPI Flash instruction
  198. *
  199. * @param[in] address
  200. * Memory address
  201. *
  202. * @param[in] buffer
  203. * Poniter to the read/write buffer
  204. *
  205. * @param[in] size
  206. * Buffer size in byte
  207. *
  208. * @return
  209. * Number of read/written bytes
  210. *********************************************************************/
  211. rt_uint32_t efm_spiFash_cmd(
  212. enum sflash_inst_type_t command,
  213. rt_uint32_t address,
  214. rt_uint8_t *buffer,
  215. rt_uint32_t size)
  216. {
  217. RT_ASSERT(sflash != RT_NULL);
  218. sflash_instruction *inst;
  219. rt_uint8_t *inst_buf;
  220. rt_uint8_t inst_len, head_len;
  221. rt_uint32_t data_len;
  222. sflash_debug("SFLASH: Inst %x\n", sflash_inst_code_tbl[command]);
  223. if (sflash_data_len_tbl[command] && !size)
  224. {
  225. sflash_debug("SFLASH: No data!\n");
  226. return 0x00;
  227. }
  228. data_len = (sflash_data_len_tbl[command] < size)? \
  229. sflash_data_len_tbl[command] : size;
  230. if (data_len && (buffer == RT_NULL))
  231. {
  232. sflash_debug("SFLASH: No buffer specified!\n");
  233. return 0x00;
  234. }
  235. /* Allocate memory for write buffer */
  236. if (sflash_read_inst_tbl[command])
  237. {
  238. inst_buf = rt_malloc(6 + 4);
  239. inst = (sflash_instruction *)(inst_buf + 1);
  240. head_len = 1;
  241. }
  242. else
  243. {
  244. inst_buf = rt_malloc(5 + data_len);
  245. inst = (sflash_instruction *)inst_buf;
  246. head_len = 0;
  247. }
  248. /* Fill in instruction */
  249. inst->code = sflash_inst_code_tbl[command];
  250. if (command >= sflash_inst_wrlr)
  251. {
  252. /* MSB first */
  253. inst->address = ((address & 0x000000FF) << 16) | \
  254. (address & 0x0000FF00) | \
  255. ((address & 0x00FF0000) >> 16);
  256. if (command >= sflash_inst_read_f)
  257. {
  258. inst->dummy = 0x00;
  259. inst_len = 5;
  260. }
  261. else
  262. {
  263. inst_len = 4;
  264. }
  265. }
  266. else
  267. {
  268. inst_len = 1;
  269. }
  270. head_len += inst_len;
  271. /* Fill in data and send the buffer */
  272. if (sflash_read_inst_tbl[command])
  273. {
  274. inst_buf[0] = inst_len;
  275. *(rt_uint8_t **)(inst_buf + head_len) = buffer;
  276. if (sflash->read(sflash, EFM32_NO_DATA, inst_buf, \
  277. (data_len == size)? data_len - 1 : data_len) == 0)
  278. {
  279. sflash_debug("SFLASH: Read failed!\n");
  280. return 0x00;
  281. }
  282. buffer[data_len] = 0x00;
  283. sflash_debug("SFLASH: Read %d bytes data to 0x%x\n", data_len, buffer);
  284. }
  285. else
  286. {
  287. if (data_len)
  288. {
  289. rt_memcpy((inst_buf + head_len), buffer, data_len);
  290. }
  291. if (sflash->write(sflash, EFM32_NO_DATA, inst_buf, \
  292. head_len + data_len) == 0)
  293. {
  294. sflash_debug("SFLASH: Write failed!\n");
  295. return 0x00;
  296. }
  297. sflash_debug("SFLASH: Write %d/%d bytes data\n", data_len, \
  298. head_len + data_len);
  299. }
  300. /* Free the buffer */
  301. rt_free(inst_buf);
  302. return data_len;
  303. }
  304. /*********************************************************************
  305. * Export to FINSH
  306. *********************************************************************/
  307. #ifdef RT_USING_FINSH
  308. #include <finsh.h>
  309. void list_sflash(void)
  310. {
  311. rt_uint8_t buf[4];
  312. efm_spiFash_cmd(sflash_inst_rdid_s, EFM32_NO_DATA, buf, sizeof(buf));
  313. rt_kprintf(" spi flash on %s\n", SFLASH_USING_DEVICE_NAME);
  314. rt_kprintf(" manufacturer id: \t%x\n", buf[0]);
  315. rt_kprintf(" memory type: \t\t%x\n", buf[1]);
  316. rt_kprintf(" memory capacity: \t%x\n", buf[2]);
  317. }
  318. FINSH_FUNCTION_EXPORT(list_sflash, list the SPI Flash.)
  319. #endif
  320. #endif /* defined(EFM32_USING_SFLASH) */
  321. /******************************************************************//**
  322. * @}
  323. *********************************************************************/