xflash.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. //xflash.c
  2. #include "xflash.h"
  3. #include <avr/io.h>
  4. #include <avr/pgmspace.h>
  5. #include "spi.h"
  6. #include "fastio.h"
  7. #define _MFRID_W25X20CL 0xEF
  8. #define _DEVID_W25X20CL 0x11
  9. #define _MFRID_GD25Q20C 0xEF
  10. #define _DEVID_GD25Q20C 0x11
  11. #define _CMD_ENABLE_WR 0x06
  12. #define _CMD_ENABLE_WR_VSR 0x50
  13. #define _CMD_DISABLE_WR 0x04
  14. #define _CMD_RD_STATUS_REG 0x05
  15. #define _CMD_WR_STATUS_REG 0x01
  16. #define _CMD_RD_DATA 0x03
  17. #define _CMD_RD_FAST 0x0b
  18. #define _CMD_RD_FAST_D_O 0x3b
  19. #define _CMD_RD_FAST_D_IO 0xbb
  20. #define _CMD_PAGE_PROGRAM 0x02
  21. #define _CMD_SECTOR_ERASE 0x20
  22. #define _CMD_BLOCK32_ERASE 0x52
  23. #define _CMD_BLOCK64_ERASE 0xd8
  24. #define _CMD_CHIP_ERASE 0xc7
  25. #define _CMD_CHIP_ERASE2 0x60
  26. #define _CMD_PWR_DOWN 0xb9
  27. #define _CMD_PWR_DOWN_REL 0xab
  28. #define _CMD_MFRID_DEVID 0x90
  29. #define _CMD_MFRID_DEVID_D 0x92
  30. #define _CMD_JEDEC_ID 0x9f
  31. #define _CMD_RD_UID 0x4b
  32. #define _CS_LOW() WRITE(XFLASH_PIN_CS, 0)
  33. #define _CS_HIGH() WRITE(XFLASH_PIN_CS, 1)
  34. //#define _SPI_TX swspi_tx
  35. //#define _SPI_RX swspi_rx
  36. #define _SPI_TX(b) spi_txrx(b)
  37. #define _SPI_RX() spi_txrx(0xff)
  38. int xflash_mfrid_devid(void);
  39. int8_t xflash_init(void)
  40. {
  41. _CS_HIGH();
  42. SET_OUTPUT(XFLASH_PIN_CS);
  43. XFLASH_SPI_ENTER();
  44. if (!xflash_mfrid_devid()) return 0;
  45. return 1;
  46. }
  47. void xflash_enable_wr(void)
  48. {
  49. _CS_LOW();
  50. _SPI_TX(_CMD_ENABLE_WR); // send command 0x06
  51. _CS_HIGH();
  52. }
  53. void xflash_disable_wr(void)
  54. {
  55. _CS_LOW();
  56. _SPI_TX(_CMD_DISABLE_WR); // send command 0x04
  57. _CS_HIGH();
  58. }
  59. uint8_t xflash_rd_status_reg(void)
  60. {
  61. _CS_LOW();
  62. _SPI_TX(_CMD_RD_STATUS_REG); // send command 0x90
  63. uint8_t val = _SPI_RX(); // receive value
  64. _CS_HIGH();
  65. return val;
  66. }
  67. #if 0
  68. void w25x20cl_wr_status_reg(uint8_t val)
  69. {
  70. _CS_LOW();
  71. _SPI_TX(_CMD_WR_STATUS_REG); // send command 0x90
  72. _SPI_TX(val); // send value
  73. _CS_HIGH();
  74. }
  75. #endif
  76. void xflash_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt)
  77. {
  78. _CS_LOW();
  79. _SPI_TX(_CMD_RD_DATA); // send command 0x03
  80. _SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23
  81. _SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15
  82. _SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7
  83. while (cnt--) // receive data
  84. *(data++) = _SPI_RX();
  85. _CS_HIGH();
  86. }
  87. void xflash_page_program(uint32_t addr, uint8_t* data, uint16_t cnt)
  88. {
  89. _CS_LOW();
  90. _SPI_TX(_CMD_PAGE_PROGRAM); // send command 0x02
  91. _SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23
  92. _SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15
  93. _SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7
  94. while (cnt--) // send data
  95. _SPI_TX(*(data++));
  96. _CS_HIGH();
  97. }
  98. void xflash_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt)
  99. {
  100. _CS_LOW();
  101. _SPI_TX(_CMD_PAGE_PROGRAM); // send command 0x02
  102. _SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23
  103. _SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15
  104. _SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7
  105. while (cnt--) // send data
  106. _SPI_TX(pgm_read_byte(data++));
  107. _CS_HIGH();
  108. }
  109. void xflash_erase(uint8_t cmd, uint32_t addr)
  110. {
  111. _CS_LOW();
  112. _SPI_TX(cmd); // send command 0x20
  113. _SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23
  114. _SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15
  115. _SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7
  116. _CS_HIGH();
  117. }
  118. void xflash_sector_erase(uint32_t addr)
  119. {
  120. return xflash_erase(_CMD_SECTOR_ERASE, addr);
  121. }
  122. void xflash_block32_erase(uint32_t addr)
  123. {
  124. return xflash_erase(_CMD_BLOCK32_ERASE, addr);
  125. }
  126. void xflash_block64_erase(uint32_t addr)
  127. {
  128. return xflash_erase(_CMD_BLOCK64_ERASE, addr);
  129. }
  130. void xflash_chip_erase(void)
  131. {
  132. _CS_LOW();
  133. _SPI_TX(_CMD_CHIP_ERASE); // send command 0xc7
  134. _CS_HIGH();
  135. }
  136. void xflash_rd_uid(uint8_t* uid)
  137. {
  138. _CS_LOW();
  139. _SPI_TX(_CMD_RD_UID); // send command 0x4b
  140. uint8_t cnt = 4; // 4 dummy bytes
  141. while (cnt--) // transmit dummy bytes
  142. _SPI_TX(0x00);
  143. cnt = 8; // 8 bytes UID
  144. while (cnt--) // receive UID
  145. uid[7 - cnt] = _SPI_RX();
  146. _CS_HIGH();
  147. }
  148. int xflash_mfrid_devid(void)
  149. {
  150. _CS_LOW();
  151. _SPI_TX(_CMD_MFRID_DEVID); // send command 0x90
  152. uint8_t cnt = 3; // 3 address bytes
  153. while (cnt--) // send address bytes
  154. _SPI_TX(0x00);
  155. uint8_t xflash_mfrid = _SPI_RX(); // receive mfrid
  156. uint8_t xflash_devid = _SPI_RX(); // receive devid
  157. _CS_HIGH();
  158. return
  159. ((xflash_mfrid == _MFRID_W25X20CL) && (xflash_devid == _DEVID_W25X20CL)) ||
  160. ((xflash_mfrid == _MFRID_GD25Q20C) && (xflash_devid == _DEVID_GD25Q20C));
  161. }
  162. void xflash_wait_busy(void)
  163. {
  164. while (xflash_rd_status_reg() & XFLASH_STATUS_BUSY) ;
  165. }