xflash.c 4.6 KB

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