xflash.c 4.8 KB

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