spi_flash.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. #include <stm32f10x.h>
  2. #include "board.h"
  3. #include "spi_flash.h"
  4. #include "rtthread.h"
  5. /*
  6. * WARNING: !!! ENABLING DMA MODE MAY DESTROY YOUR DATA IN THE SPI FLASH !!!
  7. * Don't set SPI_FLASH_USE_DMA to 1 unless you know what you're doing!
  8. * However, readonly access is just fine. :)
  9. */
  10. #define SPI_FLASH_USE_DMA 0
  11. #define SECTOR_SIZE 512
  12. extern uint8_t SPI_WriteByte(unsigned char data);
  13. #if SPI_FLASH_USE_DMA
  14. static uint8_t dummy = 0;
  15. static uint8_t _spi_flash_buffer[SECTOR_SIZE];
  16. #endif
  17. /********************** hardware *************************************/
  18. /* SPI_FLASH_CS PA4 */
  19. /* SPI_FLASH_RST PA3 */
  20. #define FLASH_RST_0() GPIO_ResetBits(GPIOA,GPIO_Pin_3)
  21. #define FLASH_RST_1() GPIO_SetBits(GPIOA,GPIO_Pin_3)
  22. #define FLASH_CS_0() GPIO_ResetBits(GPIOA,GPIO_Pin_4)
  23. #define FLASH_CS_1() GPIO_SetBits(GPIOA,GPIO_Pin_4)
  24. /********************** hardware *************************************/
  25. static void GPIO_Configuration(void)
  26. {
  27. GPIO_InitTypeDef GPIO_InitStructure;
  28. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  29. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_3;
  30. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  31. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  32. GPIO_Init(GPIOA, &GPIO_InitStructure);
  33. FLASH_RST_0(); // RESET
  34. FLASH_CS_1();
  35. FLASH_RST_1();
  36. }
  37. #if SPI_FLASH_USE_DMA
  38. static void DMA_RxConfiguration(rt_uint32_t addr, rt_size_t size)
  39. {
  40. DMA_InitTypeDef DMA_InitStructure;
  41. DMA_ClearFlag(DMA1_FLAG_TC2 | DMA1_FLAG_TE2 | DMA1_FLAG_TC3 | DMA1_FLAG_TE3);
  42. dummy = 0;
  43. /* DMA Channel configuration ----------------------------------------------*/
  44. DMA_Cmd(DMA1_Channel2, DISABLE);
  45. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(SPI1->DR));
  46. DMA_InitStructure.DMA_MemoryBaseAddr = (u32) addr;
  47. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  48. DMA_InitStructure.DMA_BufferSize = size;
  49. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  50. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  51. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  52. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  53. DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  54. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  55. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  56. DMA_Init(DMA1_Channel2, &DMA_InitStructure);
  57. DMA_Cmd(DMA1_Channel2, ENABLE);
  58. /* Dummy TX channel configuration */
  59. DMA_Cmd(DMA1_Channel3, DISABLE);
  60. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(SPI1->DR));
  61. DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(&dummy);
  62. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  63. DMA_InitStructure.DMA_BufferSize = size;
  64. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  65. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  66. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  67. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  68. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  69. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  70. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  71. DMA_Init(DMA1_Channel3, &DMA_InitStructure);
  72. DMA_Cmd(DMA1_Channel3, ENABLE);
  73. }
  74. static void DMA_TxConfiguration(rt_uint32_t addr, rt_size_t size)
  75. {
  76. DMA_InitTypeDef DMA_InitStructure;
  77. DMA_ClearFlag(DMA1_FLAG_TC2 | DMA1_FLAG_TE2 | DMA1_FLAG_TC3 | DMA1_FLAG_TE3);
  78. /* DMA Channel configuration ----------------------------------------------*/
  79. DMA_Cmd(DMA1_Channel2, DISABLE);
  80. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(SPI1->DR));
  81. DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(&dummy);
  82. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  83. DMA_InitStructure.DMA_BufferSize = size;
  84. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  85. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  86. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  87. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  88. DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  89. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  90. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  91. DMA_Init(DMA1_Channel2, &DMA_InitStructure);
  92. /* DMA Channel configuration ----------------------------------------------*/
  93. DMA_Cmd(DMA1_Channel3, DISABLE);
  94. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(SPI1->DR));
  95. DMA_InitStructure.DMA_MemoryBaseAddr = (u32) addr;
  96. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  97. DMA_InitStructure.DMA_BufferSize = size;
  98. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  99. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  100. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  101. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  102. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  103. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  104. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  105. DMA_Init(DMA1_Channel3, &DMA_InitStructure);
  106. DMA_Cmd(DMA1_Channel3, ENABLE);
  107. }
  108. #endif
  109. static uint8_t SPI_HostReadByte(void)
  110. {
  111. //return SPI_WriteByte(0x00);
  112. //Wait until the transmit buffer is empty
  113. //while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
  114. while( (SPI1->SR & SPI_I2S_FLAG_TXE) == RESET);
  115. // Send the byte
  116. SPI_I2S_SendData(SPI1, 0);
  117. //Wait until a data is received
  118. //while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
  119. while( (SPI1->SR & SPI_I2S_FLAG_RXNE) == RESET);
  120. // Get the received data
  121. return SPI_I2S_ReceiveData(SPI1);
  122. }
  123. static void SPI_HostWriteByte(uint8_t wByte)
  124. {
  125. SPI_WriteByte(wByte);
  126. }
  127. /*****************************************************************************/
  128. /*Status Register Format: */
  129. /* ------------------------------------------------------------------------- */
  130. /* | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | */
  131. /* |--------|--------|--------|--------|--------|--------|--------|--------| */
  132. /* |RDY/BUSY| COMP | device density | X | X | */
  133. /* ------------------------------------------------------------------------- */
  134. /* 0:busy | | AT45DB041:0111 | protect|page size */
  135. /* 1:ready | | AT45DB161:1011 | */
  136. /* --------------------------------------------------------------------------*/
  137. /*****************************************************************************/
  138. static uint8_t AT45DB_StatusRegisterRead(void)
  139. {
  140. uint8_t i;
  141. FLASH_CS_0();
  142. SPI_HostWriteByte(AT45DB_READ_STATE_REGISTER);
  143. i = SPI_HostReadByte();
  144. FLASH_CS_1();
  145. return i;
  146. }
  147. static void wait_busy(void)
  148. {
  149. uint16_t i = 0;
  150. while (i++ < 10000)
  151. {
  152. if (AT45DB_StatusRegisterRead() & 0x80)
  153. {
  154. return;
  155. }
  156. }
  157. rt_kprintf("\r\nSPI_FLASH timeout!!!\r\n");
  158. }
  159. static void read_page(uint32_t page, uint8_t *pHeader)
  160. {
  161. #if SPI_FLASH_USE_DMA
  162. rt_sem_take(&spi1_lock, RT_WAITING_FOREVER);
  163. DMA_RxConfiguration((rt_uint32_t) pHeader, SECTOR_SIZE);
  164. FLASH_CS_0();
  165. SPI_HostWriteByte(AT45DB_MM_PAGE_READ);
  166. SPI_HostWriteByte((uint8_t)(page >> 6));
  167. SPI_HostWriteByte((uint8_t)(page << 2));
  168. SPI_HostWriteByte(0x00);
  169. // 4 don't care bytes
  170. SPI_HostWriteByte(0x00);
  171. SPI_HostWriteByte(0x00);
  172. SPI_HostWriteByte(0x00);
  173. SPI_HostWriteByte(0x00);
  174. SPI_I2S_ClearFlag(SPI1, SPI_I2S_FLAG_RXNE);
  175. SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, ENABLE);
  176. while (DMA_GetFlagStatus(DMA1_FLAG_TC2) == RESET);
  177. FLASH_CS_1();
  178. SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, DISABLE);
  179. rt_sem_release(&spi1_lock);
  180. #else
  181. uint16_t i;
  182. rt_sem_take(&spi1_lock, RT_WAITING_FOREVER);
  183. FLASH_CS_0();
  184. SPI_HostWriteByte(AT45DB_MM_PAGE_READ);
  185. SPI_HostWriteByte((uint8_t)(page >> 6));
  186. SPI_HostWriteByte((uint8_t)(page << 2));
  187. SPI_HostWriteByte(0x00);
  188. // 4 don't care bytes
  189. SPI_HostWriteByte(0x00);
  190. SPI_HostWriteByte(0x00);
  191. SPI_HostWriteByte(0x00);
  192. SPI_HostWriteByte(0x00);
  193. for (i = 0; i < SECTOR_SIZE; i++)
  194. {
  195. *pHeader++ = SPI_HostReadByte();
  196. }
  197. FLASH_CS_1();
  198. rt_sem_release(&spi1_lock);
  199. #endif
  200. }
  201. static void write_page(uint32_t page, uint8_t *pHeader)
  202. {
  203. #if SPI_FLASH_USE_DMA
  204. rt_sem_take(&spi1_lock, RT_WAITING_FOREVER);
  205. DMA_TxConfiguration((rt_uint32_t) pHeader, SECTOR_SIZE);
  206. FLASH_CS_0();
  207. SPI_HostWriteByte(AT45DB_MM_PAGE_PROG_THRU_BUFFER1);
  208. SPI_HostWriteByte((uint8_t) (page >> 6));
  209. SPI_HostWriteByte((uint8_t) (page << 2));
  210. SPI_HostWriteByte(0x00);
  211. SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
  212. while (DMA_GetFlagStatus(DMA1_FLAG_TC3) == RESET);
  213. FLASH_CS_1();
  214. SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, DISABLE);
  215. wait_busy();
  216. rt_sem_release(&spi1_lock);
  217. #else
  218. uint16_t i;
  219. rt_sem_take(&spi1_lock, RT_WAITING_FOREVER);
  220. FLASH_CS_0();
  221. SPI_HostWriteByte(AT45DB_MM_PAGE_PROG_THRU_BUFFER1);
  222. SPI_HostWriteByte((uint8_t) (page >> 6));
  223. SPI_HostWriteByte((uint8_t) (page << 2));
  224. SPI_HostWriteByte(0x00);
  225. for (i = 0; i < SECTOR_SIZE; i++)
  226. {
  227. SPI_HostWriteByte(*pHeader++);
  228. }
  229. FLASH_CS_1();
  230. wait_busy();
  231. rt_sem_release(&spi1_lock);
  232. #endif
  233. }
  234. #include <rtthread.h>
  235. /* SPI DEVICE */
  236. static struct rt_device spi_flash_device;
  237. /* RT-Thread Device Driver Interface */
  238. static rt_err_t rt_spi_flash_init(rt_device_t dev)
  239. {
  240. return RT_EOK;
  241. }
  242. static rt_err_t rt_spi_flash_open(rt_device_t dev, rt_uint16_t oflag)
  243. {
  244. return RT_EOK;
  245. }
  246. static rt_err_t rt_spi_flash_close(rt_device_t dev)
  247. {
  248. return RT_EOK;
  249. }
  250. static rt_err_t rt_spi_flash_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  251. {
  252. return RT_EOK;
  253. }
  254. static rt_size_t rt_spi_flash_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  255. {
  256. rt_uint32_t index, nr;
  257. nr = size / SECTOR_SIZE;
  258. for (index = 0; index < nr; index++)
  259. {
  260. /* only supply single block read: block size 512Byte */
  261. #if SPI_FLASH_USE_DMA
  262. read_page((pos / SECTOR_SIZE + index), _spi_flash_buffer);
  263. rt_memcpy(((rt_uint8_t *) buffer + index * SECTOR_SIZE), _spi_flash_buffer, SECTOR_SIZE);
  264. #else
  265. read_page((pos / SECTOR_SIZE + index), ((rt_uint8_t *) buffer + index * SECTOR_SIZE));
  266. #endif
  267. }
  268. return nr * SECTOR_SIZE;
  269. }
  270. static rt_size_t rt_spi_flash_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  271. {
  272. rt_uint32_t index, nr;
  273. nr = size / SECTOR_SIZE;
  274. for (index = 0; index < nr; index++)
  275. {
  276. /* only supply single block write: block size 512Byte */
  277. #if SPI_FLASH_USE_DMA
  278. rt_memcpy(_spi_flash_buffer, ((rt_uint8_t *) buffer + index * SECTOR_SIZE), SECTOR_SIZE);
  279. write_page((pos / SECTOR_SIZE + index), _spi_flash_buffer);
  280. #else
  281. write_page((pos / SECTOR_SIZE + index), ((rt_uint8_t *) buffer + index * SECTOR_SIZE));
  282. #endif
  283. }
  284. return nr * SECTOR_SIZE;
  285. }
  286. void rt_hw_spi_flash_init(void)
  287. {
  288. GPIO_Configuration();
  289. #if SPI_FLASH_USE_DMA
  290. /* Enable the DMA1 Clock */
  291. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  292. #endif
  293. /* register spi_flash device */
  294. spi_flash_device.type = RT_Device_Class_Block;
  295. spi_flash_device.init = rt_spi_flash_init;
  296. spi_flash_device.open = rt_spi_flash_open;
  297. spi_flash_device.close = rt_spi_flash_close;
  298. spi_flash_device.read = rt_spi_flash_read;
  299. spi_flash_device.write = rt_spi_flash_write;
  300. spi_flash_device.control = rt_spi_flash_control;
  301. /* no private */
  302. spi_flash_device.private = RT_NULL;
  303. rt_device_register(&spi_flash_device, "spi0",
  304. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
  305. }