wiring.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. #ifndef CS
  2. #if defined(ESP8266)
  3. #define CS D8
  4. #else
  5. #define CS 8
  6. #endif
  7. #endif
  8. #if defined(ESP8266)
  9. #define YIELD() yield()
  10. #else
  11. #define YIELD()
  12. #endif
  13. class GDTransport {
  14. private:
  15. byte model;
  16. public:
  17. void ios() {
  18. pinMode(CS, OUTPUT);
  19. digitalWrite(CS, HIGH);
  20. pinMode(SD_PIN, OUTPUT);
  21. digitalWrite(SD_PIN, HIGH);
  22. }
  23. void begin0() {
  24. ios();
  25. SPI.begin();
  26. #if defined(TEENSYDUINO) || defined(ARDUINO_ARCH_STM32L4)
  27. SPI.beginTransaction(SPISettings(3000000, MSBFIRST, SPI_MODE0));
  28. #else
  29. #if !defined(__DUE__) && !defined(ESP8266)
  30. SPI.setClockDivider(SPI_CLOCK_DIV2);
  31. SPSR = (1 << SPI2X);
  32. #endif
  33. #endif
  34. hostcmd(0x42); // SLEEP
  35. hostcmd(0x61); // CLKSEL default
  36. hostcmd(0x00); // ACTIVE
  37. #if (BOARD != BOARD_GAMEDUINO23)
  38. hostcmd(0x44); // CLKEXT
  39. #else
  40. hostcmd(0x48); // CLKINT
  41. #endif
  42. hostcmd(0x49); // PD_ROMS all up
  43. hostcmd(0x68); // RST_PULSE
  44. }
  45. void begin1() {
  46. #if 0
  47. delay(120);
  48. #else
  49. while ((__rd16(0xc0000UL) & 0xff) != 0x08)
  50. ;
  51. #endif
  52. // Test point: saturate SPI
  53. while (0) {
  54. digitalWrite(CS, LOW);
  55. SPI.transfer(0x55);
  56. digitalWrite(CS, HIGH);
  57. }
  58. #if 0
  59. // Test point: attempt to wake up FT8xx every 2 seconds
  60. while (0) {
  61. hostcmd(0x00);
  62. delay(120);
  63. hostcmd(0x68);
  64. delay(120);
  65. digitalWrite(CS, LOW);
  66. Serial.println(SPI.transfer(0x10), HEX);
  67. Serial.println(SPI.transfer(0x24), HEX);
  68. Serial.println(SPI.transfer(0x00), HEX);
  69. Serial.println(SPI.transfer(0xff), HEX);
  70. Serial.println(SPI.transfer(0x00), HEX);
  71. Serial.println(SPI.transfer(0x00), HEX);
  72. Serial.println();
  73. digitalWrite(CS, HIGH);
  74. delay(2000);
  75. }
  76. #endif
  77. // So that FT800,801 FT81x
  78. // model 0 1
  79. ft8xx_model = __rd16(0x0c0000) >> 12;
  80. wp = 0;
  81. freespace = 4096 - 4;
  82. stream();
  83. }
  84. void cmd32(uint32_t x) {
  85. if (freespace < 4) {
  86. getfree(4);
  87. }
  88. wp += 4;
  89. freespace -= 4;
  90. #if defined(ESP8266)
  91. // SPI.writeBytes((uint8_t*)&x, 4);
  92. SPI.write32(x, 0);
  93. #else
  94. union {
  95. uint32_t c;
  96. uint8_t b[4];
  97. };
  98. c = x;
  99. SPI.transfer(b[0]);
  100. SPI.transfer(b[1]);
  101. SPI.transfer(b[2]);
  102. SPI.transfer(b[3]);
  103. #endif
  104. }
  105. void cmdbyte(byte x) {
  106. if (freespace == 0) {
  107. getfree(1);
  108. }
  109. wp++;
  110. freespace--;
  111. SPI.transfer(x);
  112. }
  113. void cmd_n(byte *s, uint16_t n) {
  114. if (freespace < n) {
  115. getfree(n);
  116. }
  117. wp += n;
  118. freespace -= n;
  119. while (n > 8) {
  120. n -= 8;
  121. SPI.transfer(*s++);
  122. SPI.transfer(*s++);
  123. SPI.transfer(*s++);
  124. SPI.transfer(*s++);
  125. SPI.transfer(*s++);
  126. SPI.transfer(*s++);
  127. SPI.transfer(*s++);
  128. SPI.transfer(*s++);
  129. }
  130. while (n--)
  131. SPI.transfer(*s++);
  132. }
  133. void flush() {
  134. YIELD();
  135. getfree(0);
  136. }
  137. uint16_t rp() {
  138. uint16_t r = __rd16(REG_CMD_READ);
  139. if (r == 0xfff) {
  140. GD.alert("COPROCESSOR EXCEPTION");
  141. }
  142. return r;
  143. }
  144. void finish() {
  145. wp &= 0xffc;
  146. __end();
  147. __wr16(REG_CMD_WRITE, wp);
  148. while (rp() != wp)
  149. YIELD();
  150. stream();
  151. }
  152. byte rd(uint32_t addr)
  153. {
  154. __end(); // stop streaming
  155. __start(addr);
  156. SPI.transfer(0); // dummy
  157. byte r = SPI.transfer(0);
  158. stream();
  159. return r;
  160. }
  161. void wr(uint32_t addr, byte v)
  162. {
  163. __end(); // stop streaming
  164. __wstart(addr);
  165. SPI.transfer(v);
  166. stream();
  167. }
  168. uint16_t rd16(uint32_t addr)
  169. {
  170. uint16_t r = 0;
  171. __end(); // stop streaming
  172. __start(addr);
  173. SPI.transfer(0);
  174. r = SPI.transfer(0);
  175. r |= (SPI.transfer(0) << 8);
  176. stream();
  177. return r;
  178. }
  179. void wr16(uint32_t addr, uint32_t v)
  180. {
  181. __end(); // stop streaming
  182. __wstart(addr);
  183. SPI.transfer(v);
  184. SPI.transfer(v >> 8);
  185. stream();
  186. }
  187. uint32_t rd32(uint32_t addr)
  188. {
  189. __end(); // stop streaming
  190. __start(addr);
  191. SPI.transfer(0);
  192. union {
  193. uint32_t c;
  194. uint8_t b[4];
  195. };
  196. b[0] = SPI.transfer(0);
  197. b[1] = SPI.transfer(0);
  198. b[2] = SPI.transfer(0);
  199. b[3] = SPI.transfer(0);
  200. stream();
  201. return c;
  202. }
  203. void rd_n(byte *dst, uint32_t addr, uint16_t n)
  204. {
  205. __end(); // stop streaming
  206. __start(addr);
  207. SPI.transfer(0);
  208. while (n--)
  209. *dst++ = SPI.transfer(0);
  210. stream();
  211. }
  212. #if defined(ARDUINO) && !defined(__DUE__) && !defined(ESP8266) && !defined(ARDUINO_ARCH_STM32L4)
  213. void wr_n(uint32_t addr, byte *src, uint16_t n)
  214. {
  215. __end(); // stop streaming
  216. __wstart(addr);
  217. while (n--) {
  218. SPDR = *src++;
  219. asm volatile("nop");
  220. asm volatile("nop");
  221. asm volatile("nop");
  222. asm volatile("nop");
  223. asm volatile("nop");
  224. asm volatile("nop");
  225. asm volatile("nop");
  226. asm volatile("nop");
  227. asm volatile("nop");
  228. asm volatile("nop");
  229. }
  230. while (!(SPSR & _BV(SPIF))) ;
  231. stream();
  232. }
  233. #else
  234. void wr_n(uint32_t addr, byte *src, uint16_t n)
  235. {
  236. __end(); // stop streaming
  237. __wstart(addr);
  238. #if defined(ESP8266)
  239. SPI.writeBytes(src, n);
  240. #else
  241. while (n--)
  242. SPI.transfer(*src++);
  243. #endif
  244. stream();
  245. }
  246. #endif
  247. void wr32(uint32_t addr, unsigned long v)
  248. {
  249. __end(); // stop streaming
  250. __wstart(addr);
  251. SPI.transfer(v);
  252. SPI.transfer(v >> 8);
  253. SPI.transfer(v >> 16);
  254. SPI.transfer(v >> 24);
  255. stream();
  256. }
  257. uint32_t getwp(void) {
  258. return RAM_CMD + (wp & 0xffc);
  259. }
  260. void bulk(uint32_t addr) {
  261. __end(); // stop streaming
  262. __start(addr);
  263. }
  264. void resume(void) {
  265. stream();
  266. }
  267. static void __start(uint32_t addr) // start an SPI transaction to addr
  268. {
  269. digitalWrite(CS, LOW);
  270. SPI.transfer(addr >> 16);
  271. SPI.transfer(highByte(addr));
  272. SPI.transfer(lowByte(addr));
  273. }
  274. static void __wstart(uint32_t addr) // start an SPI write transaction to addr
  275. {
  276. digitalWrite(CS, LOW);
  277. SPI.transfer(0x80 | (addr >> 16));
  278. SPI.transfer(highByte(addr));
  279. SPI.transfer(lowByte(addr));
  280. }
  281. static void __end() // end the SPI transaction
  282. {
  283. digitalWrite(CS, HIGH);
  284. }
  285. void stop() // end the SPI transaction
  286. {
  287. wp &= 0xffc;
  288. __end();
  289. __wr16(REG_CMD_WRITE, wp);
  290. // while (__rd16(REG_CMD_READ) != wp) ;
  291. }
  292. void stream(void) {
  293. __end();
  294. __wstart(RAM_CMD + (wp & 0xfff));
  295. }
  296. static unsigned int __rd16(uint32_t addr)
  297. {
  298. unsigned int r;
  299. __start(addr);
  300. SPI.transfer(0); // dummy
  301. r = SPI.transfer(0);
  302. r |= (SPI.transfer(0) << 8);
  303. __end();
  304. return r;
  305. }
  306. static void __wr16(uint32_t addr, unsigned int v)
  307. {
  308. __wstart(addr);
  309. SPI.transfer(lowByte(v));
  310. SPI.transfer(highByte(v));
  311. __end();
  312. }
  313. static void hostcmd(byte a)
  314. {
  315. digitalWrite(CS, LOW);
  316. SPI.transfer(a);
  317. SPI.transfer(0x00);
  318. SPI.transfer(0x00);
  319. digitalWrite(CS, HIGH);
  320. }
  321. void getfree(uint16_t n)
  322. {
  323. wp &= 0xfff;
  324. __end();
  325. __wr16(REG_CMD_WRITE, wp & 0xffc);
  326. do {
  327. uint16_t fullness = (wp - rp()) & 4095;
  328. freespace = (4096 - 4) - fullness;
  329. } while (freespace < n);
  330. stream();
  331. }
  332. byte streaming;
  333. uint16_t wp;
  334. uint16_t freespace;
  335. };