tr-spidriver.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include "spidriver.h"
  2. class GDTransport {
  3. SPIDriver sd;
  4. uint16_t space, wp;
  5. uint8_t buf[64];
  6. size_t nbuf;
  7. public:
  8. void begin0(void) {
  9. spi_connect(&sd, "/dev/ttyUSB0");
  10. hostcmd(0x42); // SLEEP
  11. hostcmd(0x61); // CLKSEL default
  12. hostcmd(0x00); // ACTIVE
  13. hostcmd(0x48); // CLKINT
  14. hostcmd(0x49); // PD_ROMS all up
  15. hostcmd(0x68); // RST_PULSE
  16. ft8xx_model = 1;
  17. }
  18. void begin1(void) {
  19. while ((__rd16(0xc0000UL) & 0xff) != 0x08)
  20. ;
  21. wp = 0;
  22. stream();
  23. }
  24. void ios(void) {}
  25. void external_crystal() {
  26. __end();
  27. hostcmd(0x44);
  28. }
  29. void cmdbyte(char x) {
  30. if (nbuf == 64)
  31. flush();
  32. buf[nbuf++] = x;
  33. }
  34. void cmd32(uint32_t x) {
  35. if (nbuf == 64)
  36. flush();
  37. *(uint32_t*)&buf[nbuf] = x;
  38. nbuf += 4;
  39. }
  40. void cmd_n(byte *s, size_t n) {
  41. flush();
  42. getspace(n);
  43. spi_write(&sd, n, (char*)s);
  44. wp += n;
  45. }
  46. void hostcmd(uint8_t a)
  47. {
  48. char buf[3] = {a, 0, 0};
  49. spi_sel(&sd);
  50. spi_write(&sd, 3, buf);
  51. spi_unsel(&sd);
  52. }
  53. uint16_t rd16(uint32_t a) {
  54. __end();
  55. uint16_t r = __rd16(a);
  56. stream();
  57. return r;
  58. }
  59. void wr16(uint32_t a, uint16_t v) {
  60. __end();
  61. __wr16(a, v);
  62. stream();
  63. }
  64. uint8_t rd(uint32_t a) {
  65. return rd16(a);
  66. }
  67. void wr(uint32_t a, byte v)
  68. {
  69. __end();
  70. char buf[4] = {(a >> 16) | 0x80, a >> 8, a, v};
  71. spi_sel(&sd);
  72. spi_write(&sd, sizeof(buf), buf);
  73. spi_unsel(&sd);
  74. stream();
  75. }
  76. void __end() {
  77. spi_unsel(&sd);
  78. }
  79. void stream(void) {
  80. space = __rd16(REG_CMDB_SPACE);
  81. assert((space & 3) == 0);
  82. __wstart(REG_CMDB_WRITE);
  83. }
  84. void resume(void) {
  85. stream();
  86. }
  87. void getspace(uint16_t n) {
  88. while (space < n) {
  89. __end();
  90. stream();
  91. }
  92. space -= n;
  93. }
  94. uint32_t getwp(void) {
  95. flush();
  96. return RAM_CMD + (wp & 0xffc);
  97. }
  98. uint32_t rd32(uint32_t a) {
  99. uint32_t r;
  100. rd_n((byte*)&r, a, 4);
  101. return r;
  102. }
  103. void rd_n(byte *dst, uint32_t a, uint16_t n) {
  104. __end();
  105. char buf[4] = {a >> 16, a >> 8, a, 0xff};
  106. spi_sel(&sd);
  107. spi_write(&sd, sizeof(buf), buf);
  108. spi_read(&sd, n, (char*)dst);
  109. spi_unsel(&sd);
  110. stream();
  111. }
  112. void wr32(uint32_t a, uint32_t v) {
  113. }
  114. void flush() {
  115. if (nbuf) {
  116. getspace(nbuf);
  117. spi_write(&sd, nbuf, (char*)buf);
  118. wp += nbuf;
  119. nbuf = 0;
  120. }
  121. }
  122. void finish() {
  123. flush();
  124. while (space < 4092) {
  125. __end();
  126. stream();
  127. }
  128. }
  129. void bulk(uint32_t addr) {}
  130. unsigned int __wstart(uint32_t a) {
  131. char buf[3] = {0x80 | (a >> 16), a >> 8, a};
  132. spi_sel(&sd);
  133. spi_write(&sd, sizeof(buf), buf);
  134. }
  135. unsigned int __rd16(uint32_t a) {
  136. char buf[6] = {a >> 16, a >> 8, a, 0xff, 0xff, 0xff};
  137. spi_sel(&sd);
  138. spi_writeread(&sd, sizeof(buf), buf);
  139. spi_unsel(&sd);
  140. return *(uint16_t*)&buf[4];
  141. }
  142. void __wr16(uint32_t a, unsigned int v) {
  143. char buf[5] = {(a >> 16) | 0x80, a >> 8, a, v, v >> 8};
  144. spi_sel(&sd);
  145. spi_write(&sd, sizeof(buf), buf);
  146. spi_unsel(&sd);
  147. }
  148. void stop() {} // end the SPI transaction
  149. void wr_n(uint32_t addr, byte *src, uint16_t n) {
  150. assert(0);
  151. }
  152. };