wiring.h 5.8 KB

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