SWM341_sfc.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /******************************************************************************************************************************************
  2. * 文件名称: SWM341_sfc.c
  3. * 功能说明: SWM341单片机的SFC(Serial Flash Controller)模块驱动库
  4. * 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
  5. * 注意事项:
  6. * 版本日期: V1.1.0 2017年10月25日
  7. * 升级记录:
  8. *
  9. *
  10. *******************************************************************************************************************************************
  11. * @attention
  12. *
  13. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
  14. * REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
  15. * FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
  16. * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
  17. * -ECTION WITH THEIR PRODUCTS.
  18. *
  19. * COPYRIGHT 2012 Synwit Technology
  20. *******************************************************************************************************************************************/
  21. #include "SWM341.h"
  22. #include "SWM341_sfc.h"
  23. /******************************************************************************************************************************************
  24. * 函数名称: SFC_Init()
  25. * 功能说明: SFC(Serial Flash Controller)初始化
  26. * 输 入: SFC_InitStructure * initStruct SFC初始化配置值
  27. * 输 出: 无
  28. * 注意事项: 无
  29. ******************************************************************************************************************************************/
  30. void SFC_Init(SFC_InitStructure * initStruct)
  31. {
  32. SYS->CLKEN1 |= (1 << SYS_CLKEN1_SFC_Pos);
  33. *((__IO uint32_t *)((uint32_t )&SFC->CFG + 0x3F4)) = 7;
  34. SFC->CFG &= ~(SFC_CFG_CLKDIV_Msk | SFC_CFG_DATA4L_RD_Msk | SFC_CFG_DATA4L_PP_Msk);
  35. SFC->CFG |= (initStruct->ClkDiv << SFC_CFG_CLKDIV_Pos) |
  36. (initStruct->Width_Read << SFC_CFG_DATA4L_RD_Pos) |
  37. (initStruct->Width_PageProgram << SFC_CFG_DATA4L_PP_Pos);
  38. SFC->CFG |= (1 << SFC_CFG_CMDWREN_Pos);
  39. SFC->CMDAHB &= ~(SFC_CMDAHB_READ_Msk | SFC_CMDAHB_PP_Msk);
  40. SFC->CMDAHB |= (initStruct->Cmd_Read << SFC_CMDAHB_READ_Pos) |
  41. (initStruct->Cmd_PageProgram << SFC_CMDAHB_PP_Pos);
  42. SFC->CFG &= ~(1 << SFC_CFG_CMDWREN_Pos);
  43. SFC->TIM &= ~(SFC_TIM_WIP_CHK_ITV_Msk | SFC_TIM_WIP_CHK_LMT_Msk);
  44. SFC->TIM |= ((CyclesPerUs / 10) << SFC_TIM_WIP_CHK_ITV_Pos) | //2048 * (CyclesPerUs / 10) / CyclesPerUs us = 0.2 ms
  45. (255 << SFC_TIM_WIP_CHK_LMT_Pos);
  46. }
  47. /******************************************************************************************************************************************
  48. * 函数名称: SFC_ReadJEDEC()
  49. * 功能说明: 读取 JEDEC ID
  50. * 输 入: 无
  51. * 输 出: uint32_t JEDEC ID
  52. * 注意事项: 无
  53. ******************************************************************************************************************************************/
  54. uint32_t SFC_ReadJEDEC(void)
  55. {
  56. SFC->CFG &= ~SFC_CFG_CMDTYPE_Msk;
  57. SFC->CFG |= (1 << SFC_CFG_CMDWREN_Pos) |
  58. (2 << SFC_CFG_CMDTYPE_Pos);
  59. SFC->CMD = SFC_CMD_READ_JEDEC;
  60. SFC->GO = 1;
  61. while(SFC->GO);
  62. return SFC->DATA;
  63. }
  64. /******************************************************************************************************************************************
  65. * 函数名称: SFC_Erase()
  66. * 功能说明: SPI Flash扇区擦除,每个扇区4K字节
  67. * 输 入: uint32_t addr 要擦除扇区的地址,必须4K对齐,即addr%4096 == 0
  68. * uint8_t wait 1 等待 Flash 完成擦除操作后再返回 0 发出擦除命令后立即返回
  69. * 输 出: 无
  70. * 注意事项: 无
  71. ******************************************************************************************************************************************/
  72. void SFC_Erase(uint32_t addr, uint8_t wait)
  73. {
  74. SFC_EraseEx(addr, SFC_CMD_ERASE_SECTOR, wait);
  75. }
  76. /******************************************************************************************************************************************
  77. * 函数名称: SFC_EraseEx()
  78. * 功能说明: SPI Flash擦除,通过提供不同的命令码支持片擦、块擦、扇区擦
  79. * 输 入: uint32_t addr 要擦除的块的地址,当 addr == 0xFFFFFFFF 时,执行片擦
  80. * uint8_t cmd 擦除命令码,有些SPI Flash支持多种大小的块的擦除,不同块大大小使用不同命令码
  81. * uint8_t wait 1 等待 Flash 完成擦除操作后再返回 0 发出擦除命令后立即返回
  82. * 输 出: 无
  83. * 注意事项: 无
  84. ******************************************************************************************************************************************/
  85. void SFC_EraseEx(uint32_t addr, uint8_t cmd, uint8_t wait)
  86. {
  87. uint8_t type = (addr == 0xFFFFFFFF) ? 5 : 7;
  88. SFC->ADDR = addr;
  89. SFC->CFG &= ~SFC_CFG_CMDTYPE_Msk;
  90. SFC->CFG |= (1 << SFC_CFG_WREN_Pos) |
  91. (1 << SFC_CFG_CMDWREN_Pos) |
  92. (type << SFC_CFG_CMDTYPE_Pos);
  93. SFC->CMD = cmd;
  94. SFC->GO = 1;
  95. for(int i = 0; i < CyclesPerUs; i++) __NOP(); //等待命令发出
  96. SFC->CFG &= ~SFC_CFG_WREN_Msk;
  97. if(wait)
  98. while(SFC_FlashBusy()) __NOP();
  99. }
  100. /******************************************************************************************************************************************
  101. * 函数名称: SFC_Write()
  102. * 功能说明: SPI Flash数据写入
  103. * 输 入: uint32_t addr 数据要写入到Flash中的地址,字对齐
  104. * uint32_t buff[] 要写入Flash中的数据
  105. * uint32_t cnt 要写的数据的个数,以字为单位,最大64
  106. * 输 出: 无
  107. * 注意事项: 要写入的数据必须全部在同一页内,即addr/256 == (addr+(cnt-1)*4)/256
  108. * 当 cnt > 4 时,LCD_DCLK 输出可能出现间断(|__| ̄|__| ̄|__| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|__| ̄|__| ̄|__|),这种情况下有些屏幕会显示异常,遇
  109. * 到这种情况,可通过以 cnt = 4 多次调用 SFC_Write() 解决
  110. ******************************************************************************************************************************************/
  111. void SFC_Write(uint32_t addr, uint32_t buff[], uint32_t cnt)
  112. {
  113. SFC->CFG |= (1 << SFC_CFG_WREN_Pos);
  114. for(int i = 0; i < cnt; i++)
  115. *((volatile unsigned int *)(0x70000000+addr+i*4)) = buff[i];
  116. while(SFC->SR & SFC_SR_BUSY_Msk) __NOP();
  117. SFC->CFG &= ~SFC_CFG_WREN_Msk;
  118. }
  119. /******************************************************************************************************************************************
  120. * 函数名称: SFC_Read()
  121. * 功能说明: SPI Flash数据读取
  122. * 输 入: uint32_t addr 要读取的数据在Flash中的地址,字对齐
  123. * uint32_t buff[] 读取到的数据存入buff指向的内存
  124. * uint32_t cnt 要读取的数据的个数,以字为单位
  125. * 输 出: 无
  126. * 注意事项: 无
  127. ******************************************************************************************************************************************/
  128. void SFC_Read(uint32_t addr, uint32_t buff[], uint32_t cnt)
  129. {
  130. for(int i = 0; i < cnt; i++)
  131. buff[i] = *((volatile unsigned int *)(0x70000000+addr+i*4));
  132. }
  133. /******************************************************************************************************************************************
  134. * 函数名称: SFC_ReadStatusReg()
  135. * 功能说明: SPI Flash读取状态寄存器
  136. * 输 入: uint8_t cmd 读取使用的命令码
  137. * 输 出: uint8_t 读到的状态寄存器值
  138. * 注意事项: 无
  139. ******************************************************************************************************************************************/
  140. uint8_t SFC_ReadStatusReg(uint8_t cmd)
  141. {
  142. SFC->CFG &= ~SFC_CFG_CMDTYPE_Msk;
  143. SFC->CFG |= (1 << SFC_CFG_CMDWREN_Pos) |
  144. (1 << SFC_CFG_CMDTYPE_Pos);
  145. SFC->CMD = cmd;
  146. SFC->GO = 1;
  147. while(SFC->GO);
  148. return SFC->DATA;
  149. }
  150. /******************************************************************************************************************************************
  151. * 函数名称: SFC_WriteStatusReg()
  152. * 功能说明: SPI Flash写入状态寄存器
  153. * 输 入: uint8_t cmd 写入使用的命令码
  154. * uint16_t reg 要写入的状态寄存器值
  155. * 输 出: 无
  156. * 注意事项: 无
  157. ******************************************************************************************************************************************/
  158. void SFC_WriteStatusReg(uint8_t cmd, uint16_t reg)
  159. {
  160. SFC->CFG &= ~SFC_CFG_CMDTYPE_Msk;
  161. SFC->CFG |= (1 << SFC_CFG_WREN_Pos) |
  162. (1 << SFC_CFG_CMDWREN_Pos) |
  163. (6 << SFC_CFG_CMDTYPE_Pos);
  164. SFC->CMD = cmd;
  165. SFC->DATA = reg;
  166. SFC->GO = 1;
  167. while(SFC->GO);
  168. }
  169. /******************************************************************************************************************************************
  170. * 函数名称: SFC_QuadSwitch()
  171. * 功能说明: SPI Flash Quad模式开关
  172. * 输 入: uint8_t on 1 开启 Quad 模式 0 关闭 Quad 模式
  173. * 输 出: 无
  174. * 注意事项: 无
  175. ******************************************************************************************************************************************/
  176. void SFC_QuadSwitch(uint8_t on)
  177. {
  178. uint16_t reg = (SFC_ReadStatusReg(SFC_CMD_READ_STATUS_REG2) << 8) |
  179. (SFC_ReadStatusReg(SFC_CMD_READ_STATUS_REG1) << 0);
  180. if(on)
  181. reg |= (1 << SFC_STATUS_REG_QUAD_Pos);
  182. else
  183. reg &=~(1 << SFC_STATUS_REG_QUAD_Pos);
  184. SFC_WriteStatusReg(SFC_CMD_WRITE_STATUS_REG1, reg);
  185. }
  186. /******************************************************************************************************************************************
  187. * 函数名称: SFC_QuadState()
  188. * 功能说明: SPI Flash Quad模式开关状态查询
  189. * 输 入: 无
  190. * 输 出: 1 Quad 模式开启 0 Quad 模式关闭
  191. * 注意事项: 无
  192. ******************************************************************************************************************************************/
  193. uint8_t SFC_QuadState(void)
  194. {
  195. uint8_t reg = SFC_ReadStatusReg(SFC_CMD_READ_STATUS_REG2);
  196. if(reg & (1 << (SFC_STATUS_REG_QUAD_Pos - 8)))
  197. return 1;
  198. else
  199. return 0;
  200. }
  201. /******************************************************************************************************************************************
  202. * 函数名称: SFC_FlashBusy()
  203. * 功能说明: SPI Flash Page Program、Sector Erase、Block Erase、Chip Erase 忙查询
  204. * 输 入: 无
  205. * 输 出: 1 Flash 正在执行 Erase/Write 操作 0 Flash 已完成 Erase/Write 操作
  206. * 注意事项: 无
  207. ******************************************************************************************************************************************/
  208. uint8_t SFC_FlashBusy(void)
  209. {
  210. uint8_t reg = SFC_ReadStatusReg(SFC_CMD_READ_STATUS_REG1);
  211. if(reg & (1 << SFC_STATUS_REG_BUSY_Pos))
  212. return 1;
  213. else
  214. return 0;
  215. }