PageRenderTime 43ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/firmware/ssd1963/spiflash.c

https://bitbucket.org/plumbum/ttgui
C | 251 lines | 198 code | 29 blank | 24 comment | 11 complexity | 97c7f8b74536002a6e753f03599747e9 MD5 | raw file
  1. /*
  2. * SST25VF016B SPI Flash access
  3. * (CC) 2011 Ivan A-R <ivan@tuxotronic.org>
  4. */
  5. #include "spiflash.h"
  6. #include "stm32f10x.h"
  7. #define USE_HW_SPI 1
  8. #define nCS (1<<4)
  9. #define grabCS() GPIOA->BRR = nCS
  10. #define releaseCS() GPIOA->BSRR = nCS
  11. void sfSpiCsGrab(void)
  12. {
  13. grabCS();
  14. }
  15. void sfSpiCsRelease(void)
  16. {
  17. releaseCS();
  18. }
  19. uint16_t sfSpiExchange(uint16_t data)
  20. {
  21. #if (USE_HW_SPI == 1)
  22. while((SPI1->SR & SPI_SR_TXE) == 0) ;
  23. SPI1->DR = data;
  24. while((SPI1->SR & SPI_SR_RXNE) == 0) ;
  25. return SPI1->DR;
  26. #else
  27. uint16_t d = 0;
  28. uint16_t mask = (1<<(BIT_SIZE-1));
  29. int i;
  30. for(i=0; i<BIT_SIZE; i++)
  31. {
  32. if(data & mask)
  33. GPIOA->BSRR = (1<<7);
  34. else
  35. GPIOA->BRR = (1<<7);
  36. data <<= 1;
  37. GPIOA->BSRR = (1<<5);
  38. d <<= 1;
  39. if(GPIOA->IDR & (1<<6))
  40. d |= 1;
  41. GPIOA->BRR = (1<<5);
  42. }
  43. return d;
  44. #endif
  45. }
  46. void sfInit(void)
  47. {
  48. #if (USE_HW_SPI == 1)
  49. GPIOA->CRL = (GPIOA->CRL & 0x0000FFFF) | 0xbbb30000;
  50. // GPIOD->CRH = (GPIOD->CRH & 0xFF0FFFFF) | 0x00300000;
  51. releaseCS();
  52. /*
  53. SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_SPE;
  54. SPI1->CR1 = 0;
  55. */
  56. RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
  57. SPI1->CR1 = 0;
  58. SPI1->CR1 = SPI_CR1_MSTR |
  59. // SPI_CR1_DFF |
  60. // SPI_CR1_CPHA |
  61. // SPI_CR1_CPOL |
  62. // SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_BR_2 | /* BR[2-0] = 000 - Fpclk/2 */
  63. 0;
  64. SPI1->CR2 = 0; // SPI_CR2_SSOE;
  65. SPI1->CR1 |= SPI_CR1_SPE; // Enable SPI
  66. //(void)(SPI1->DR);
  67. grabCS();
  68. sfSpiExchange(0);
  69. sfSpiExchange(0);
  70. sfSpiExchange(0);
  71. sfSpiExchange(0);
  72. releaseCS();
  73. #else
  74. GPIOA->BSRR = 0xE0;
  75. GPIOA->CRL = (GPIOA->CRL & 0x000FFFFF) | 0x38300000;
  76. GPIOD->CRH = (GPIOD->CRH & 0xFF0FFFFF) | 0x00300000;
  77. releaseCS();
  78. grabCS();
  79. int i;
  80. GPIOA->BRR = (1<<5);
  81. GPIOA->BSRR = (1<<7);
  82. for(i=0; i<32; i++)
  83. {
  84. GPIOA->BSRR = (1<<5);
  85. GPIOA->BRR = (1<<5);
  86. }
  87. releaseCS();
  88. #endif
  89. sfWriteDisable();
  90. grabCS();
  91. sfSpiExchange(0x80);
  92. releaseCS();
  93. }
  94. void sfSetDataWidth(uint8_t width)
  95. {
  96. if(width == 16)
  97. {
  98. SPI1->CR1 |= SPI_CR1_DFF;
  99. }
  100. else
  101. {
  102. SPI1->CR1 &= ~SPI_CR1_DFF;
  103. }
  104. }
  105. void sfWriteEnable(void)
  106. {
  107. grabCS();
  108. sfSpiExchange(0x06);
  109. releaseCS();
  110. }
  111. void sfWriteDisable(void)
  112. {
  113. grabCS();
  114. sfSpiExchange(0x04);
  115. releaseCS();
  116. }
  117. void sfWaitFlash(void)
  118. {
  119. uint8_t stat;
  120. grabCS();
  121. sfSpiExchange(0x05);
  122. do {
  123. stat = sfSpiExchange(0xFF);
  124. } while(stat & 1);
  125. releaseCS();
  126. }
  127. uint32_t sfReadJedecId(void)
  128. {
  129. uint32_t id;
  130. grabCS();
  131. sfSpiExchange(0x9F);
  132. id = sfSpiExchange(0xFF)<<16;
  133. id |= sfSpiExchange(0xFF)<<8;
  134. id |= sfSpiExchange(0xFF);
  135. releaseCS();
  136. return id;
  137. }
  138. void sfWriteStatus(uint8_t stat)
  139. {
  140. sfWaitFlash();
  141. sfWriteEnable();
  142. /*
  143. grabCS();
  144. sfSpiExchange(0x50);
  145. releaseCS();
  146. */
  147. grabCS();
  148. sfSpiExchange(0x01);
  149. sfSpiExchange(stat);
  150. releaseCS();
  151. }
  152. void sfEraseChip(void)
  153. {
  154. sfWaitFlash();
  155. sfWriteEnable();
  156. grabCS();
  157. sfSpiExchange(0x60);
  158. releaseCS();
  159. }
  160. void sfErase4k(uint32_t addr)
  161. {
  162. sfWaitFlash();
  163. sfWriteEnable();
  164. grabCS();
  165. sfSpiExchange(0x20);
  166. sfSpiExchange((addr >> 16) & 0xFF);
  167. sfSpiExchange((addr >> 8) & 0xFF);
  168. sfSpiExchange(addr & 0xFF);
  169. releaseCS();
  170. }
  171. void sfReadBlock(uint8_t* buf, int addr, int len)
  172. {
  173. sfWaitFlash();
  174. grabCS();
  175. sfSpiExchange(0x0B);
  176. sfSpiExchange((addr>>16) & 0xFF);
  177. sfSpiExchange((addr>>8) & 0xFF);
  178. sfSpiExchange((addr>>0) & 0xFF);
  179. sfSpiExchange(0xFF); // Dummy
  180. while(len--)
  181. {
  182. *buf++ = sfSpiExchange(0xFF);
  183. }
  184. releaseCS();
  185. }
  186. // char szBuf[32];
  187. void sfWriteBlock(uint8_t* buf, int addr, int len)
  188. {
  189. sfWaitFlash();
  190. len = (len+1)>>1;
  191. grabCS();
  192. sfSpiExchange(0x70); // Enable SO to output RY/BY# status during AAI programming
  193. releaseCS();
  194. sfWriteEnable();
  195. grabCS();
  196. sfSpiExchange(0xAD);
  197. sfSpiExchange((addr>>16) & 0xFF);
  198. sfSpiExchange((addr>>8) & 0xFF);
  199. sfSpiExchange((addr>>0) & 0xFF);
  200. sfSpiExchange(*buf++);
  201. sfSpiExchange(*buf++);
  202. releaseCS();
  203. while(--len)
  204. {
  205. /*
  206. uitox(len, szBuf, 8);
  207. fontString(fontList[0], 16, 80, szBuf, lcdNightBlue, lcdYellow);
  208. */
  209. grabCS();
  210. sfSpiExchange(0xAD);
  211. sfSpiExchange(*buf++);
  212. sfSpiExchange(*buf++);
  213. releaseCS();
  214. while((GPIOA->IDR & (1<<6)) == 0)
  215. ;
  216. }
  217. sfWriteDisable();
  218. sfWaitFlash();
  219. grabCS();
  220. sfSpiExchange(0x80); // Disable SO to output RY/BY# status during AAI programming
  221. releaseCS();
  222. }