flash.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // This file is part of parrocchetto.
  2. // parrocchetto is free software: you can redistribute it and/or modify
  3. // it under the terms of the GNU General Public License as published by
  4. // the Free Software Foundation, either version 3 of the License, or
  5. // (at your option) any later version.
  6. // parrocchetto is distributed in the hope that it will be useful,
  7. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. // GNU General Public License for more details.
  10. // You should have received a copy of the GNU General Public License
  11. // along with parrocchetto. If not, see <http://www.gnu.org/licenses/>.
  12. #include "flash.h"
  13. #include "spi1.h"
  14. #include <xc.h>
  15. #include <stdint.h>
  16. inline void flash_AT45DB041D_init()
  17. {
  18. spi1_init();
  19. }
  20. uint8_t flash_AT45DB041D_identify(void)
  21. {
  22. uint8_t buf[4];
  23. spi1_begin();
  24. spi1_write(0x9F); // Device identification
  25. spi1_readbuf(buf, 4);
  26. spi1_end();
  27. return (buf[0] == 0x1F && buf[1] == 0x24 && buf[2] == 0 && buf[3] == 0);
  28. }
  29. uint8_t flash_AT45DB041D_getstatus(void)
  30. {
  31. uint8_t status;
  32. spi1_begin();
  33. spi1_write(0xD7); // Device identification
  34. status = spi1_read();
  35. spi1_end();
  36. return status;
  37. }
  38. void flash_AT45DB041D_erase()
  39. {
  40. uint8_t buf[] = { 0xC7, 0x94, 0x80, 0x9A };
  41. spi1_begin();
  42. spi1_writebuf(buf, 4); // Erase all
  43. spi1_end();
  44. }
  45. void flash_AT45DB041D_pageread(uint16_t addr, uint8_t* page)
  46. {
  47. uint8_t buf[] = { 0xD2, addr >> 8, addr, 0, 0, 0, 0, 0 };
  48. //while(!(flash_AT45DB041D_getstatus() & 0x80));
  49. spi1_begin();
  50. spi1_writebuf(buf, 8); // Read page + 24 bit address
  51. spi1_readbuf(page, 256);
  52. spi1_end();
  53. }
  54. void flash_AT45DB041D_pagewrite(uint16_t addr, const uint8_t* page)
  55. {
  56. uint8_t buf[] = { 0x82, addr >> 8, addr, 0 };
  57. spi1_begin();
  58. spi1_writebuf(buf, 4); // Load buffer 1 + 24 bit address
  59. spi1_writebuf(page, 256);
  60. spi1_end();
  61. }
  62. inline void flash_W25Q32JV_enable_write(void)
  63. {
  64. spi1_begin();
  65. spi1_write(0x06); // Write enable
  66. spi1_end();
  67. }
  68. inline void flash_W25Q32JV_init()
  69. {
  70. spi1_init();
  71. PORTBbits.RB4 = 1; // ~RST/~HOLD
  72. }
  73. uint8_t flash_W25Q32JV_identify(void)
  74. {
  75. uint8_t buf[3];
  76. spi1_begin();
  77. spi1_write(0x9F); // Device identification
  78. spi1_readbuf(buf, 3);
  79. spi1_end();
  80. return (buf[0] == 0xEF && buf[1] == 0x40 && buf[2] == 0x16);
  81. }
  82. uint8_t flash_W25Q32JV_getstatus1(void)
  83. {
  84. uint8_t status;
  85. spi1_begin();
  86. spi1_write(0x05); // Read status register 1
  87. status = spi1_read();
  88. spi1_end();
  89. return status;
  90. }
  91. inline uint8_t flash_W25Q32JV_isbusy(void)
  92. {
  93. return (flash_W25Q32JV_getstatus1() & 0x1);
  94. }
  95. void flash_W25Q32JV_busywait(void)
  96. {
  97. uint8_t status;
  98. spi1_begin();
  99. spi1_write(0x05); // Read status register 1
  100. do {
  101. status = spi1_read();
  102. } while(status & 0x1);
  103. spi1_end();
  104. }
  105. void flash_W25Q32JV_read(uint16_t page_addr, uint8_t byte_addr, uint8_t* buf, uint8_t size)
  106. {
  107. uint8_t cmd[] = { 0x03, page_addr >> 8, page_addr, byte_addr };
  108. spi1_begin();
  109. spi1_writebuf(cmd, 4); // Read page + 24 bit address
  110. spi1_readbuf(buf, size);
  111. spi1_end();
  112. }
  113. void flash_W25Q32JV_pageread(uint16_t addr, uint8_t* page)
  114. {
  115. uint8_t buf[] = { 0x03, addr >> 8, addr, 0 };
  116. spi1_begin();
  117. spi1_writebuf(buf, 4); // Read page + 24 bit address
  118. spi1_readbuf(page, 256);
  119. spi1_end();
  120. }
  121. void flash_W25Q32JV_pagewrite(uint16_t addr, const uint8_t* page)
  122. {
  123. uint8_t buf[] = { 0x02, addr >> 8, addr, 0 };
  124. flash_W25Q32JV_enable_write();
  125. spi1_begin();
  126. spi1_writebuf(buf, 4); // Load buffer 1 + 24 bit address
  127. spi1_writebuf(page, 256);
  128. spi1_end();
  129. }
  130. void flash_W25Q32JV_sectorerase(uint16_t addr)
  131. {
  132. uint8_t buf[] = { 0x20, addr >> 8, addr, 0 };
  133. flash_W25Q32JV_enable_write();
  134. spi1_begin();
  135. spi1_writebuf(buf, 4); // Sector erase
  136. spi1_end();
  137. }
  138. void flash_W25Q32JV_erase()
  139. {
  140. flash_W25Q32JV_enable_write();
  141. spi1_begin();
  142. spi1_write(0xC7); // Chip erase
  143. spi1_end();
  144. flash_W25Q32JV_busywait();
  145. }