GD2.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335
  1. #include <Arduino.h>
  2. #include "SPI.h"
  3. #if !defined(__SAM3X8E__)
  4. #include "EEPROM.h"
  5. #endif
  6. #define VERBOSE 0
  7. #include <GD2.h>
  8. #define SD_PIN 9 // pin used for the microSD enable signal
  9. #define BOARD_FTDI_80x 0
  10. #define BOARD_GAMEDUINO23 1
  11. #define BOARD_EVITA_0 2
  12. #define BOARD BOARD_GAMEDUINO23 // board, from above
  13. #define STORAGE 1 // Want SD storage?
  14. #define CALIBRATION 1 // Want touchscreen?
  15. // EVITA_0 has no storage or calibration
  16. #if (BOARD == BOARD_EVITA_0)
  17. // #undef STORAGE
  18. // #define STORAGE 0
  19. #undef CALIBRATION
  20. #define CALIBRATION 0
  21. #endif
  22. // FTDI boards do not have storage
  23. #if (BOARD == BOARD_FTDI_80x)
  24. #undef STORAGE
  25. #define STORAGE 0
  26. #endif
  27. #ifdef DUMPDEV
  28. #include <assert.h>
  29. #include "transports/dump.h"
  30. #endif
  31. #ifdef RASPBERRY_PI
  32. #include <stdio.h>
  33. #include <fcntl.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #include <unistd.h>
  37. #include <stdint.h>
  38. #include <sys/ioctl.h>
  39. #include <linux/types.h>
  40. #include <linux/spi/spidev.h>
  41. #include "transports/spidev.h"
  42. #endif
  43. byte ft8xx_model;
  44. #if defined(ARDUINO)
  45. #include "transports/wiring.h"
  46. #endif
  47. static GDTransport GDTR;
  48. GDClass GD;
  49. // The GD3 has a tiny configuration EEPROM - AT24C01D
  50. // It is programmed at manufacturing time with the setup
  51. // commands for the connected panel. The SCL,SDA lines
  52. // are connected to thye FT81x GPIO0, GPIO1 signals.
  53. // This is a read-only driver for it. A single method
  54. // 'read()' initializes the RAM and reads all 128 bytes
  55. // into an array.
  56. class ConfigRam {
  57. private:
  58. uint8_t gpio, gpio_dir, sda;
  59. void set_SDA(byte n)
  60. {
  61. if (sda != n) {
  62. GDTR.__wr16(REG_GPIO_DIR, gpio_dir | (0x03 - n)); // Drive SCL, SDA low
  63. sda = n;
  64. }
  65. }
  66. void set_SCL(byte n)
  67. {
  68. GDTR.__wr16(REG_GPIO, gpio | (n << 1));
  69. }
  70. int get_SDA(void)
  71. {
  72. return GDTR.__rd16(REG_GPIO) & 1;
  73. }
  74. void i2c_start(void)
  75. {
  76. set_SDA(1);
  77. set_SCL(1);
  78. set_SDA(0);
  79. set_SCL(0);
  80. }
  81. void i2c_stop(void)
  82. {
  83. set_SDA(0);
  84. set_SCL(1);
  85. set_SDA(1);
  86. set_SCL(1);
  87. }
  88. int i2c_rx1()
  89. {
  90. set_SDA(1);
  91. set_SCL(1);
  92. byte r = get_SDA();
  93. set_SCL(0);
  94. return r;
  95. }
  96. void i2c_tx1(byte b)
  97. {
  98. set_SDA(b);
  99. set_SCL(1);
  100. set_SCL(0);
  101. }
  102. int i2c_tx(byte x)
  103. {
  104. for (byte i = 0; i < 8; i++, x <<= 1)
  105. i2c_tx1(x >> 7);
  106. return i2c_rx1();
  107. }
  108. int i2c_rx(int nak)
  109. {
  110. byte r = 0;
  111. for (byte i = 0; i < 8; i++)
  112. r = (r << 1) | i2c_rx1();
  113. i2c_tx1(nak);
  114. return r;
  115. }
  116. public:
  117. void read(byte *v)
  118. {
  119. GDTR.__end();
  120. gpio = GDTR.__rd16(REG_GPIO) & ~3;
  121. gpio_dir = GDTR.__rd16(REG_GPIO_DIR) & ~3;
  122. sda = 2;
  123. // 2-wire software reset
  124. i2c_start();
  125. i2c_rx(1);
  126. i2c_start();
  127. i2c_stop();
  128. int ADDR = 0xa0;
  129. i2c_start();
  130. if (i2c_tx(ADDR))
  131. return;
  132. if (i2c_tx(0))
  133. return;
  134. i2c_start();
  135. if (i2c_tx(ADDR | 1))
  136. return;
  137. for (int i = 0; i < 128; i++) {
  138. *v++ = i2c_rx(i == 127);
  139. // Serial.println(v[-1], DEC);
  140. }
  141. i2c_stop();
  142. GDTR.resume();
  143. }
  144. };
  145. void GDClass::flush(void)
  146. {
  147. GDTR.flush();
  148. }
  149. void GDClass::swap(void) {
  150. Display();
  151. cmd_swap();
  152. cmd_loadidentity();
  153. cmd_dlstart();
  154. GDTR.flush();
  155. #ifdef DUMPDEV
  156. GDTR.swap();
  157. #endif
  158. }
  159. uint32_t GDClass::measure_freq(void)
  160. {
  161. unsigned long t0 = GDTR.rd32(REG_CLOCK);
  162. delayMicroseconds(15625);
  163. unsigned long t1 = GDTR.rd32(REG_CLOCK);
  164. // Serial.println((t1 - t0) << 6);
  165. return (t1 - t0) << 6;
  166. }
  167. #define LOW_FREQ_BOUND 47040000UL
  168. // #define LOW_FREQ_BOUND 32040000UL
  169. void GDClass::tune(void)
  170. {
  171. uint32_t f;
  172. for (byte i = 0; (i < 31) && ((f = measure_freq()) < LOW_FREQ_BOUND); i++) {
  173. GDTR.wr(REG_TRIM, i);
  174. }
  175. GDTR.wr32(REG_FREQUENCY, f);
  176. }
  177. void GDClass::begin(uint8_t options) {
  178. #if STORAGE && defined(ARDUINO)
  179. GDTR.begin0();
  180. if (options & GD_STORAGE) {
  181. GDTR.ios();
  182. SD.begin(SD_PIN);
  183. }
  184. #endif
  185. GDTR.begin1();
  186. #if 0
  187. Serial.println("ID REGISTER:");
  188. Serial.println(GDTR.rd(REG_ID), HEX);
  189. #endif
  190. #if (BOARD == BOARD_FTDI_80x)
  191. GDTR.wr(REG_PCLK_POL, 1);
  192. GDTR.wr(REG_PCLK, 5);
  193. #endif
  194. GDTR.wr(REG_PWM_DUTY, 0);
  195. GDTR.wr(REG_GPIO_DIR, 0x83);
  196. GDTR.wr(REG_GPIO, GDTR.rd(REG_GPIO) | 0x80);
  197. #if (BOARD == BOARD_GAMEDUINO23)
  198. ConfigRam cr;
  199. byte v8[128] = {0};
  200. cr.read(v8);
  201. if ((v8[1] == 0xff) && (v8[2] == 0x01)) {
  202. options &= ~(GD_TRIM | GD_CALIBRATE);
  203. if (v8[3] & 2) {
  204. GDTR.__end();
  205. GDTR.hostcmd(0x44); // switch to external crystal
  206. GDTR.resume();
  207. }
  208. copyram(v8 + 4, 124);
  209. finish();
  210. } else {
  211. GDTR.wr(REG_PCLK_POL, 1);
  212. GDTR.wr(REG_PCLK, 5);
  213. GDTR.wr(REG_ROTATE, 1);
  214. GDTR.wr(REG_SWIZZLE, 3);
  215. }
  216. #endif
  217. if (0) {
  218. GDTR.wr16(REG_HCYCLE, 928);
  219. GDTR.wr16(REG_HOFFSET, 88);
  220. GDTR.wr16(REG_HSIZE, 800);
  221. GDTR.wr16(REG_HSYNC0, 0);
  222. GDTR.wr16(REG_HSYNC1, 48);
  223. GDTR.wr16(REG_VCYCLE, 525);
  224. GDTR.wr16(REG_VOFFSET, 32);
  225. GDTR.wr16(REG_VSIZE, 480);
  226. GDTR.wr16(REG_VSYNC0, 0);
  227. GDTR.wr16(REG_VSYNC1, 3);
  228. GDTR.wr16(REG_CSPREAD, 0);
  229. GDTR.wr16(REG_DITHER, 1);
  230. GDTR.wr16(REG_PCLK_POL, 1);
  231. GDTR.wr16(REG_PCLK, 2);
  232. }
  233. #if (BOARD == BOARD_EVITA_0)
  234. GDTR.wr16(REG_HCYCLE, 1344);
  235. GDTR.wr16(REG_HSIZE, 1024);
  236. GDTR.wr16(REG_HSYNC0, 0 );
  237. GDTR.wr16(REG_HSYNC1, 136 );
  238. GDTR.wr16(REG_HOFFSET, 136+160);
  239. GDTR.wr16(REG_VCYCLE, 806 );
  240. GDTR.wr16(REG_VSIZE, 768 );
  241. GDTR.wr16(REG_VSYNC0, 0 );
  242. GDTR.wr16(REG_VSYNC1, 6 );
  243. GDTR.wr16(REG_VOFFSET, 6+29 );
  244. GDTR.wr16(REG_CSPREAD, 0 );
  245. GDTR.wr16(REG_PCLK_POL,0 );
  246. GDTR.wr16(REG_PCLK, 1 );
  247. GDTR.wr(REG_GPIO, GDTR.rd(REG_GPIO) | 0x10);
  248. #endif
  249. w = GDTR.rd16(REG_HSIZE);
  250. h = GDTR.rd16(REG_VSIZE);
  251. // w = 480, h = 272;
  252. Clear(); swap();
  253. Clear(); swap();
  254. Clear(); swap();
  255. cmd_regwrite(REG_PWM_DUTY, 128);
  256. GD.flush();
  257. // Serial.println("STOP"); for(;;);
  258. if (CALIBRATION & (options & GD_CALIBRATE)) {
  259. #if defined(ARDUINO) && !defined(__DUE__)
  260. if ((EEPROM.read(0) != 0x7c)) {
  261. self_calibrate();
  262. // for (int i = 0; i < 24; i++) Serial.println(GDTR.rd(REG_TOUCH_TRANSFORM_A + i), HEX);
  263. for (int i = 0; i < 24; i++)
  264. EEPROM.write(1 + i, GDTR.rd(REG_TOUCH_TRANSFORM_A + i));
  265. EEPROM.write(0, 0x7c); // is written!
  266. } else {
  267. for (int i = 0; i < 24; i++)
  268. GDTR.wr(REG_TOUCH_TRANSFORM_A + i, EEPROM.read(1 + i));
  269. }
  270. #endif
  271. #ifdef __DUE__
  272. // The Due has no persistent storage. So instead use a "canned"
  273. // calibration.
  274. // self_calibrate();
  275. // for (int i = 0; i < 24; i++)
  276. // Serial.println(GDTR.rd(REG_TOUCH_TRANSFORM_A + i), HEX);
  277. static const byte canned_calibration[24] = {
  278. 0xCC, 0x7C, 0xFF, 0xFF, 0x57, 0xFE, 0xFF, 0xFF,
  279. 0xA1, 0x04, 0xF9, 0x01, 0x93, 0x00, 0x00, 0x00,
  280. 0x5E, 0x4B, 0x00, 0x00, 0x08, 0x8B, 0xF1, 0xFF };
  281. for (int i = 0; i < 24; i++)
  282. GDTR.wr(REG_TOUCH_TRANSFORM_A + i, canned_calibration[i]);
  283. #endif
  284. #if defined(RASPBERRY_PI)
  285. {
  286. uint8_t cal[24];
  287. FILE *calfile = fopen(".calibration", "r");
  288. if (calfile == NULL) {
  289. calfile = fopen(".calibration", "w");
  290. if (calfile != NULL) {
  291. self_calibrate();
  292. for (int i = 0; i < 24; i++)
  293. cal[i] = GDTR.rd(REG_TOUCH_TRANSFORM_A + i);
  294. fwrite(cal, 1, sizeof(cal), calfile);
  295. fclose(calfile);
  296. }
  297. } else {
  298. fread(cal, 1, sizeof(cal), calfile);
  299. for (int i = 0; i < 24; i++)
  300. GDTR.wr(REG_TOUCH_TRANSFORM_A + i, cal[i]);
  301. fclose(calfile);
  302. }
  303. }
  304. #endif
  305. }
  306. GDTR.wr16(REG_TOUCH_RZTHRESH, 1200);
  307. rseed = 0x77777777;
  308. if ((BOARD == BOARD_GAMEDUINO23) && (options & GD_TRIM)) {
  309. tune();
  310. }
  311. }
  312. void GDClass::storage(void) {
  313. GDTR.__end();
  314. SD.begin(SD_PIN);
  315. GDTR.resume();
  316. }
  317. void GDClass::self_calibrate(void) {
  318. cmd_dlstart();
  319. Clear();
  320. cmd_text(240, 100, 30, OPT_CENTERX, "please tap on the dot");
  321. cmd_calibrate();
  322. finish();
  323. cmd_loadidentity();
  324. cmd_dlstart();
  325. GDTR.flush();
  326. }
  327. void GDClass::seed(uint16_t n) {
  328. rseed = n ? n : 7;
  329. }
  330. uint16_t GDClass::random() {
  331. rseed ^= rseed << 13;
  332. rseed ^= rseed >> 17;
  333. rseed ^= rseed << 5;
  334. return rseed;
  335. }
  336. uint16_t GDClass::random(uint16_t n) {
  337. uint32_t p = random();
  338. return (p * n) >> 16;
  339. }
  340. // >>> [int(65535*math.sin(math.pi * 2 * i / 1024)) for i in range(257)]
  341. static const PROGMEM uint16_t sintab[257] = {
  342. 0, 402, 804, 1206, 1608, 2010, 2412, 2813, 3215, 3617, 4018, 4419, 4821, 5221, 5622, 6023, 6423, 6823, 7223, 7622, 8022, 8421, 8819, 9218, 9615, 10013, 10410, 10807, 11203, 11599, 11995, 12390, 12785, 13179, 13573, 13966, 14358, 14750, 15142, 15533, 15923, 16313, 16702, 17091, 17479, 17866, 18252, 18638, 19023, 19408, 19791, 20174, 20557, 20938, 21319, 21699, 22078, 22456, 22833, 23210, 23585, 23960, 24334, 24707, 25079, 25450, 25820, 26189, 26557, 26924, 27290, 27655, 28019, 28382, 28744, 29105, 29465, 29823, 30181, 30537, 30892, 31247, 31599, 31951, 32302, 32651, 32999, 33346, 33691, 34035, 34378, 34720, 35061, 35400, 35737, 36074, 36409, 36742, 37075, 37406, 37735, 38063, 38390, 38715, 39039, 39361, 39682, 40001, 40319, 40635, 40950, 41263, 41574, 41885, 42193, 42500, 42805, 43109, 43411, 43711, 44010, 44307, 44603, 44896, 45189, 45479, 45768, 46055, 46340, 46623, 46905, 47185, 47463, 47739, 48014, 48287, 48558, 48827, 49094, 49360, 49623, 49885, 50145, 50403, 50659, 50913, 51165, 51415, 51664, 51910, 52155, 52397, 52638, 52876, 53113, 53347, 53580, 53810, 54039, 54265, 54490, 54712, 54933, 55151, 55367, 55581, 55793, 56003, 56211, 56416, 56620, 56821, 57021, 57218, 57413, 57606, 57796, 57985, 58171, 58355, 58537, 58717, 58894, 59069, 59242, 59413, 59582, 59748, 59912, 60074, 60234, 60391, 60546, 60699, 60849, 60997, 61143, 61287, 61428, 61567, 61704, 61838, 61970, 62100, 62227, 62352, 62474, 62595, 62713, 62828, 62941, 63052, 63161, 63267, 63370, 63472, 63570, 63667, 63761, 63853, 63942, 64029, 64114, 64196, 64275, 64353, 64427, 64500, 64570, 64637, 64702, 64765, 64825, 64883, 64938, 64991, 65042, 65090, 65135, 65178, 65219, 65257, 65293, 65326, 65357, 65385, 65411, 65435, 65456, 65474, 65490, 65504, 65515, 65523, 65530, 65533, 65535
  343. };
  344. int16_t GDClass::rsin(int16_t r, uint16_t th) {
  345. th >>= 6; // angle 0-123
  346. // return int(r * sin((2 * M_PI) * th / 1024.));
  347. int th4 = th & 511;
  348. if (th4 & 256)
  349. th4 = 512 - th4; // 256->256 257->255, etc
  350. uint16_t s = pgm_read_word_near(sintab + th4);
  351. int16_t p = ((uint32_t)s * r) >> 16;
  352. if (th & 512)
  353. p = -p;
  354. return p;
  355. }
  356. int16_t GDClass::rcos(int16_t r, uint16_t th) {
  357. return rsin(r, th + 0x4000);
  358. }
  359. void GDClass::polar(int &x, int &y, int16_t r, uint16_t th) {
  360. x = (int)(-GD.rsin(r, th));
  361. y = (int)( GD.rcos(r, th));
  362. }
  363. // >>> [int(round(1024 * math.atan(i / 256.) / math.pi)) for i in range(256)]
  364. static const PROGMEM uint8_t atan8[] = {
  365. 0,1,3,4,5,6,8,9,10,11,13,14,15,17,18,19,20,22,23,24,25,27,28,29,30,32,33,34,36,37,38,39,41,42,43,44,46,47,48,49,51,52,53,54,55,57,58,59,60,62,63,64,65,67,68,69,70,71,73,74,75,76,77,79,80,81,82,83,85,86,87,88,89,91,92,93,94,95,96,98,99,100,101,102,103,104,106,107,108,109,110,111,112,114,115,116,117,118,119,120,121,122,124,125,126,127,128,129,130,131,132,133,134,135,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,177,178,179,180,181,182,183,184,185,186,187,188,188,189,190,191,192,193,194,195,195,196,197,198,199,200,201,201,202,203,204,205,206,206,207,208,209,210,211,211,212,213,214,215,215,216,217,218,219,219,220,221,222,222,223,224,225,225,226,227,228,228,229,230,231,231,232,233,234,234,235,236,236,237,238,239,239,240,241,241,242,243,243,244,245,245,246,247,248,248,249,250,250,251,251,252,253,253,254,255,255
  366. };
  367. uint16_t GDClass::atan2(int16_t y, int16_t x)
  368. {
  369. uint16_t a;
  370. uint16_t xx = 0;
  371. /* These values are tricky. So pretend they are not */
  372. if (x == -32768)
  373. x++;
  374. if (y == -32768)
  375. y++;
  376. if ((x <= 0) ^ (y > 0)) {
  377. int16_t t; t = x; x = y; y = t;
  378. xx ^= 0x4000;
  379. }
  380. if (x <= 0) {
  381. x = -x;
  382. } else {
  383. xx ^= 0x8000;
  384. }
  385. y = abs(y);
  386. if (x > y) {
  387. int16_t t; t = x; x = y; y = t;
  388. xx ^= 0x3fff;
  389. }
  390. while ((x | y) & 0xff80) {
  391. x >>= 1;
  392. y >>= 1;
  393. }
  394. if (y == 0) {
  395. a = 0;
  396. } else if (x == y) {
  397. a = 0x2000;
  398. } else {
  399. // assert(x <= y);
  400. int r = ((x << 8) / y);
  401. // assert(0 <= r);
  402. // assert(r < 256);
  403. a = pgm_read_byte(atan8 + r) << 5;
  404. }
  405. a ^= xx;
  406. return a;
  407. }
  408. void GDClass::align(byte n) {
  409. while ((n++) & 3)
  410. GDTR.cmdbyte(0);
  411. }
  412. void GDClass::cH(uint16_t v) {
  413. GDTR.cmdbyte(v & 0xff);
  414. GDTR.cmdbyte((v >> 8) & 0xff);
  415. }
  416. void GDClass::ch(int16_t v) {
  417. cH((uint16_t)v);
  418. }
  419. void GDClass::cI(uint32_t v) {
  420. GDTR.cmd32(v);
  421. }
  422. void GDClass::cFFFFFF(byte v) {
  423. union {
  424. uint32_t c;
  425. uint8_t b[4];
  426. };
  427. b[0] = v;
  428. b[1] = 0xff;
  429. b[2] = 0xff;
  430. b[3] = 0xff;
  431. GDTR.cmd32(c);
  432. }
  433. void GDClass::ci(int32_t v) {
  434. cI((uint32_t) v);
  435. }
  436. void GDClass::cs(const char *s) {
  437. int count = 0;
  438. while (*s) {
  439. char c = *s++;
  440. GDTR.cmdbyte(c);
  441. count++;
  442. }
  443. GDTR.cmdbyte(0);
  444. align(count + 1);
  445. }
  446. void GDClass::copy(const PROGMEM uint8_t *src, int count) {
  447. byte a = count & 3;
  448. while (count--) {
  449. GDTR.cmdbyte(pgm_read_byte_near(src));
  450. src++;
  451. }
  452. align(a);
  453. }
  454. void GDClass::copyram(byte *src, int count) {
  455. byte a = count & 3;
  456. GDTR.cmd_n(src, count);
  457. align(a);
  458. }
  459. void GDClass::AlphaFunc(byte func, byte ref) {
  460. cI((9UL << 24) | ((func & 7L) << 8) | ((ref & 255L) << 0));
  461. }
  462. void GDClass::Begin(byte prim) {
  463. cI((31UL << 24) | prim);
  464. }
  465. void GDClass::BitmapHandle(byte handle) {
  466. cI((5UL << 24) | handle);
  467. }
  468. void GDClass::BitmapLayout(byte format, uint16_t linestride, uint16_t height) {
  469. // cI((7UL << 24) | ((format & 31L) << 19) | ((linestride & 1023L) << 9) | ((height & 511L) << 0));
  470. union {
  471. uint32_t c;
  472. uint8_t b[4];
  473. };
  474. b[0] = height;
  475. b[1] = (1 & (height >> 8)) | (linestride << 1);
  476. b[2] = (7 & (linestride >> 7)) | (format << 3);
  477. b[3] = 7;
  478. cI(c);
  479. }
  480. void GDClass::BitmapSize(byte filter, byte wrapx, byte wrapy, uint16_t width, uint16_t height) {
  481. byte fxy = (filter << 2) | (wrapx << 1) | (wrapy);
  482. // cI((8UL << 24) | ((uint32_t)fxy << 18) | ((width & 511L) << 9) | ((height & 511L) << 0));
  483. union {
  484. uint32_t c;
  485. uint8_t b[4];
  486. };
  487. b[0] = height;
  488. b[1] = (1 & (height >> 8)) | (width << 1);
  489. b[2] = (3 & (width >> 7)) | (fxy << 2);
  490. b[3] = 8;
  491. cI(c);
  492. if (ft8xx_model) {
  493. b[0] = ((width >> 9) << 2) | (3 & (height >> 9));
  494. b[3] = 0x29;
  495. cI(c);
  496. }
  497. }
  498. void GDClass::BitmapSource(uint32_t addr) {
  499. cI((1UL << 24) | ((addr & 1048575L) << 0));
  500. }
  501. void GDClass::BitmapTransformA(int32_t a) {
  502. cI((21UL << 24) | ((a & 131071L) << 0));
  503. }
  504. void GDClass::BitmapTransformB(int32_t b) {
  505. cI((22UL << 24) | ((b & 131071L) << 0));
  506. }
  507. void GDClass::BitmapTransformC(int32_t c) {
  508. cI((23UL << 24) | ((c & 16777215L) << 0));
  509. }
  510. void GDClass::BitmapTransformD(int32_t d) {
  511. cI((24UL << 24) | ((d & 131071L) << 0));
  512. }
  513. void GDClass::BitmapTransformE(int32_t e) {
  514. cI((25UL << 24) | ((e & 131071L) << 0));
  515. }
  516. void GDClass::BitmapTransformF(int32_t f) {
  517. cI((26UL << 24) | ((f & 16777215L) << 0));
  518. }
  519. void GDClass::BlendFunc(byte src, byte dst) {
  520. cI((11UL << 24) | ((src & 7L) << 3) | ((dst & 7L) << 0));
  521. }
  522. void GDClass::Call(uint16_t dest) {
  523. cI((29UL << 24) | ((dest & 2047L) << 0));
  524. }
  525. void GDClass::Cell(byte cell) {
  526. cI((6UL << 24) | ((cell & 127L) << 0));
  527. }
  528. void GDClass::ClearColorA(byte alpha) {
  529. cI((15UL << 24) | ((alpha & 255L) << 0));
  530. }
  531. void GDClass::ClearColorRGB(byte red, byte green, byte blue) {
  532. cI((2UL << 24) | ((red & 255L) << 16) | ((green & 255L) << 8) | ((blue & 255L) << 0));
  533. }
  534. void GDClass::ClearColorRGB(uint32_t rgb) {
  535. cI((2UL << 24) | (rgb & 0xffffffL));
  536. }
  537. void GDClass::Clear(byte c, byte s, byte t) {
  538. byte m = (c << 2) | (s << 1) | t;
  539. cI((38UL << 24) | m);
  540. }
  541. void GDClass::Clear(void) {
  542. cI((38UL << 24) | 7);
  543. }
  544. void GDClass::ClearStencil(byte s) {
  545. cI((17UL << 24) | ((s & 255L) << 0));
  546. }
  547. void GDClass::ClearTag(byte s) {
  548. cI((18UL << 24) | ((s & 255L) << 0));
  549. }
  550. void GDClass::ColorA(byte alpha) {
  551. cI((16UL << 24) | ((alpha & 255L) << 0));
  552. }
  553. void GDClass::ColorMask(byte r, byte g, byte b, byte a) {
  554. cI((32UL << 24) | ((r & 1L) << 3) | ((g & 1L) << 2) | ((b & 1L) << 1) | ((a & 1L) << 0));
  555. }
  556. void GDClass::ColorRGB(byte red, byte green, byte blue) {
  557. // cI((4UL << 24) | ((red & 255L) << 16) | ((green & 255L) << 8) | ((blue & 255L) << 0));
  558. union {
  559. uint32_t c;
  560. uint8_t b[4];
  561. };
  562. b[0] = blue;
  563. b[1] = green;
  564. b[2] = red;
  565. b[3] = 4;
  566. cI(c);
  567. }
  568. void GDClass::ColorRGB(uint32_t rgb) {
  569. cI((4UL << 24) | (rgb & 0xffffffL));
  570. }
  571. void GDClass::Display(void) {
  572. cI((0UL << 24));
  573. }
  574. void GDClass::End(void) {
  575. cI((33UL << 24));
  576. }
  577. void GDClass::Jump(uint16_t dest) {
  578. cI((30UL << 24) | ((dest & 2047L) << 0));
  579. }
  580. void GDClass::LineWidth(uint16_t width) {
  581. cI((14UL << 24) | ((width & 4095L) << 0));
  582. }
  583. void GDClass::Macro(byte m) {
  584. cI((37UL << 24) | ((m & 1L) << 0));
  585. }
  586. void GDClass::PointSize(uint16_t size) {
  587. cI((13UL << 24) | ((size & 8191L) << 0));
  588. }
  589. void GDClass::RestoreContext(void) {
  590. cI((35UL << 24));
  591. }
  592. void GDClass::Return(void) {
  593. cI((36UL << 24));
  594. }
  595. void GDClass::SaveContext(void) {
  596. cI((34UL << 24));
  597. }
  598. void GDClass::ScissorSize(uint16_t width, uint16_t height) {
  599. if (ft8xx_model == 0)
  600. cI((28UL << 24) | ((width & 1023L) << 10) | ((height & 1023L) << 0));
  601. else
  602. cI((28UL << 24) | ((width & 4095L) << 12) | ((height & 4095L) << 0));
  603. }
  604. void GDClass::ScissorXY(uint16_t x, uint16_t y) {
  605. if (ft8xx_model == 0)
  606. cI((27UL << 24) | ((x & 511L) << 9) | ((y & 511L) << 0));
  607. else
  608. cI((27UL << 24) | ((x & 2047L) << 11) | ((y & 2047L) << 0));
  609. }
  610. void GDClass::StencilFunc(byte func, byte ref, byte mask) {
  611. cI((10UL << 24) | ((func & 7L) << 16) | ((ref & 255L) << 8) | ((mask & 255L) << 0));
  612. }
  613. void GDClass::StencilMask(byte mask) {
  614. cI((19UL << 24) | ((mask & 255L) << 0));
  615. }
  616. void GDClass::StencilOp(byte sfail, byte spass) {
  617. cI((12UL << 24) | ((sfail & 7L) << 3) | ((spass & 7L) << 0));
  618. }
  619. void GDClass::TagMask(byte mask) {
  620. cI((20UL << 24) | ((mask & 1L) << 0));
  621. }
  622. void GDClass::Tag(byte s) {
  623. cI((3UL << 24) | ((s & 255L) << 0));
  624. }
  625. void GDClass::Vertex2f(int16_t x, int16_t y) {
  626. // x = int(16 * x);
  627. // y = int(16 * y);
  628. cI((1UL << 30) | ((x & 32767L) << 15) | ((y & 32767L) << 0));
  629. }
  630. void GDClass::Vertex2ii(uint16_t x, uint16_t y, byte handle, byte cell) {
  631. // cI((2UL << 30) | ((x & 511L) << 21) | ((y & 511L) << 12) | ((handle & 31L) << 7) | ((cell & 127L) << 0));
  632. union {
  633. uint32_t c;
  634. uint8_t b[4];
  635. };
  636. b[0] = cell | ((handle & 1) << 7);
  637. b[1] = (handle >> 1) | (y << 4);
  638. b[2] = (y >> 4) | (x << 5);
  639. b[3] = (2 << 6) | (x >> 3);
  640. cI(c);
  641. }
  642. void GDClass::VertexFormat(byte frac) {
  643. cI((39UL << 24) | (((frac) & 7) << 0));
  644. }
  645. void GDClass::BitmapLayoutH(byte linestride, byte height) {
  646. cI((40 << 24) | (((linestride) & 3) << 2) | (((height) & 3) << 0));
  647. }
  648. void GDClass::BitmapSizeH(byte width, byte height) {
  649. cI((41UL << 24) | (((width) & 3) << 2) | (((height) & 3) << 0));
  650. }
  651. void GDClass::PaletteSource(uint32_t addr) {
  652. cI((42UL << 24) | (((addr) & 4194303UL) << 0));
  653. }
  654. void GDClass::VertexTranslateX(uint32_t x) {
  655. cI((43UL << 24) | (((x) & 131071UL) << 0));
  656. }
  657. void GDClass::VertexTranslateY(uint32_t y) {
  658. cI((44UL << 24) | (((y) & 131071UL) << 0));
  659. }
  660. void GDClass::Nop(void) {
  661. cI((45UL << 24));
  662. }
  663. void GDClass::cmd_append(uint32_t ptr, uint32_t num) {
  664. cFFFFFF(0x1e);
  665. cI(ptr);
  666. cI(num);
  667. }
  668. void GDClass::cmd_bgcolor(uint32_t c) {
  669. cFFFFFF(0x09);
  670. cI(c);
  671. }
  672. void GDClass::cmd_button(int16_t x, int16_t y, uint16_t w, uint16_t h, byte font, uint16_t options, const char *s) {
  673. cFFFFFF(0x0d);
  674. ch(x);
  675. ch(y);
  676. ch(w);
  677. ch(h);
  678. ch(font);
  679. cH(options);
  680. cs(s);
  681. }
  682. void GDClass::cmd_calibrate(void) {
  683. cFFFFFF(0x15);
  684. cFFFFFF(0xff);
  685. }
  686. void GDClass::cmd_clock(int16_t x, int16_t y, int16_t r, uint16_t options, uint16_t h, uint16_t m, uint16_t s, uint16_t ms) {
  687. cFFFFFF(0x14);
  688. ch(x);
  689. ch(y);
  690. ch(r);
  691. cH(options);
  692. cH(h);
  693. cH(m);
  694. cH(s);
  695. cH(ms);
  696. }
  697. void GDClass::cmd_coldstart(void) {
  698. cFFFFFF(0x32);
  699. }
  700. void GDClass::cmd_dial(int16_t x, int16_t y, int16_t r, uint16_t options, uint16_t val) {
  701. cFFFFFF(0x2d);
  702. ch(x);
  703. ch(y);
  704. ch(r);
  705. cH(options);
  706. cH(val);
  707. cH(0);
  708. }
  709. void GDClass::cmd_dlstart(void) {
  710. cFFFFFF(0x00);
  711. }
  712. void GDClass::cmd_fgcolor(uint32_t c) {
  713. cFFFFFF(0x0a);
  714. cI(c);
  715. }
  716. void GDClass::cmd_gauge(int16_t x, int16_t y, int16_t r, uint16_t options, uint16_t major, uint16_t minor, uint16_t val, uint16_t range) {
  717. cFFFFFF(0x13);
  718. ch(x);
  719. ch(y);
  720. ch(r);
  721. cH(options);
  722. cH(major);
  723. cH(minor);
  724. cH(val);
  725. cH(range);
  726. }
  727. void GDClass::cmd_getmatrix(void) {
  728. cFFFFFF(0x33);
  729. ci(0);
  730. ci(0);
  731. ci(0);
  732. ci(0);
  733. ci(0);
  734. ci(0);
  735. }
  736. void GDClass::cmd_getprops(uint32_t &ptr, uint32_t &w, uint32_t &h) {
  737. cFFFFFF(0x25);
  738. ptr = GDTR.getwp();
  739. cI(0);
  740. w = GDTR.getwp();
  741. cI(0);
  742. h = GDTR.getwp();
  743. cI(0);
  744. }
  745. void GDClass::cmd_getptr(void) {
  746. cFFFFFF(0x23);
  747. cI(0);
  748. }
  749. void GDClass::cmd_gradcolor(uint32_t c) {
  750. cFFFFFF(0x34);
  751. cI(c);
  752. }
  753. void GDClass::cmd_gradient(int16_t x0, int16_t y0, uint32_t rgb0, int16_t x1, int16_t y1, uint32_t rgb1) {
  754. cFFFFFF(0x0b);
  755. ch(x0);
  756. ch(y0);
  757. cI(rgb0);
  758. ch(x1);
  759. ch(y1);
  760. cI(rgb1);
  761. }
  762. void GDClass::cmd_inflate(uint32_t ptr) {
  763. cFFFFFF(0x22);
  764. cI(ptr);
  765. }
  766. void GDClass::cmd_interrupt(uint32_t ms) {
  767. cFFFFFF(0x02);
  768. cI(ms);
  769. }
  770. void GDClass::cmd_keys(int16_t x, int16_t y, int16_t w, int16_t h, byte font, uint16_t options, const char*s) {
  771. cFFFFFF(0x0e);
  772. ch(x);
  773. ch(y);
  774. ch(w);
  775. ch(h);
  776. ch(font);
  777. cH(options);
  778. cs(s);
  779. }
  780. void GDClass::cmd_loadidentity(void) {
  781. cFFFFFF(0x26);
  782. }
  783. void GDClass::cmd_loadimage(uint32_t ptr, int32_t options) {
  784. cFFFFFF(0x24);
  785. cI(ptr);
  786. cI(options);
  787. }
  788. void GDClass::cmd_memcpy(uint32_t dest, uint32_t src, uint32_t num) {
  789. cFFFFFF(0x1d);
  790. cI(dest);
  791. cI(src);
  792. cI(num);
  793. }
  794. void GDClass::cmd_memset(uint32_t ptr, byte value, uint32_t num) {
  795. cFFFFFF(0x1b);
  796. cI(ptr);
  797. cI((uint32_t)value);
  798. cI(num);
  799. }
  800. uint32_t GDClass::cmd_memcrc(uint32_t ptr, uint32_t num) {
  801. cFFFFFF(0x18);
  802. cI(ptr);
  803. cI(num);
  804. uint32_t r = GDTR.getwp();
  805. cI(0xFFFFFFFF);
  806. return r;
  807. }
  808. void GDClass::cmd_memwrite(uint32_t ptr, uint32_t num) {
  809. cFFFFFF(0x1a);
  810. cI(ptr);
  811. cI(num);
  812. }
  813. void GDClass::cmd_regwrite(uint32_t ptr, uint32_t val) {
  814. cFFFFFF(0x1a);
  815. cI(ptr);
  816. cI(4UL);
  817. cI(val);
  818. }
  819. void GDClass::cmd_number(int16_t x, int16_t y, byte font, uint16_t options, uint32_t n) {
  820. cFFFFFF(0x2e);
  821. ch(x);
  822. ch(y);
  823. ch(font);
  824. cH(options);
  825. ci(n);
  826. }
  827. void GDClass::cmd_progress(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range) {
  828. cFFFFFF(0x0f);
  829. ch(x);
  830. ch(y);
  831. ch(w);
  832. ch(h);
  833. cH(options);
  834. cH(val);
  835. cH(range);
  836. cH(0);
  837. }
  838. void GDClass::cmd_regread(uint32_t ptr) {
  839. cFFFFFF(0x19);
  840. cI(ptr);
  841. cI(0);
  842. }
  843. void GDClass::cmd_rotate(int32_t a) {
  844. cFFFFFF(0x29);
  845. ci(a);
  846. }
  847. void GDClass::cmd_scale(int32_t sx, int32_t sy) {
  848. cFFFFFF(0x28);
  849. ci(sx);
  850. ci(sy);
  851. }
  852. void GDClass::cmd_screensaver(void) {
  853. cFFFFFF(0x2f);
  854. }
  855. void GDClass::cmd_scrollbar(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t size, uint16_t range) {
  856. cFFFFFF(0x11);
  857. ch(x);
  858. ch(y);
  859. ch(w);
  860. ch(h);
  861. cH(options);
  862. cH(val);
  863. cH(size);
  864. cH(range);
  865. }
  866. void GDClass::cmd_setfont(byte font, uint32_t ptr) {
  867. cFFFFFF(0x2b);
  868. cI(font);
  869. cI(ptr);
  870. }
  871. void GDClass::cmd_setmatrix(void) {
  872. cFFFFFF(0x2a);
  873. }
  874. void GDClass::cmd_sketch(int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t ptr, uint16_t format) {
  875. cFFFFFF(0x30);
  876. ch(x);
  877. ch(y);
  878. cH(w);
  879. cH(h);
  880. cI(ptr);
  881. cI(format);
  882. }
  883. void GDClass::cmd_slider(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t options, uint16_t val, uint16_t range) {
  884. cFFFFFF(0x10);
  885. ch(x);
  886. ch(y);
  887. ch(w);
  888. ch(h);
  889. cH(options);
  890. cH(val);
  891. cH(range);
  892. cH(0);
  893. }
  894. void GDClass::cmd_snapshot(uint32_t ptr) {
  895. cFFFFFF(0x1f);
  896. cI(ptr);
  897. }
  898. void GDClass::cmd_spinner(int16_t x, int16_t y, byte style, byte scale) {
  899. cFFFFFF(0x16);
  900. ch(x);
  901. ch(y);
  902. cH(style);
  903. cH(scale);
  904. }
  905. void GDClass::cmd_stop(void) {
  906. cFFFFFF(0x17);
  907. }
  908. void GDClass::cmd_swap(void) {
  909. cFFFFFF(0x01);
  910. }
  911. void GDClass::cmd_text(int16_t x, int16_t y, byte font, uint16_t options, const char *s) {
  912. cFFFFFF(0x0c);
  913. ch(x);
  914. ch(y);
  915. ch(font);
  916. cH(options);
  917. cs(s);
  918. }
  919. void GDClass::cmd_toggle(int16_t x, int16_t y, int16_t w, byte font, uint16_t options, uint16_t state, const char *s) {
  920. cFFFFFF(0x12);
  921. ch(x);
  922. ch(y);
  923. ch(w);
  924. ch(font);
  925. cH(options);
  926. cH(state);
  927. cs(s);
  928. }
  929. void GDClass::cmd_track(int16_t x, int16_t y, uint16_t w, uint16_t h, byte tag) {
  930. cFFFFFF(0x2c);
  931. ch(x);
  932. ch(y);
  933. ch(w);
  934. ch(h);
  935. ch(tag);
  936. ch(0);
  937. }
  938. void GDClass::cmd_translate(int32_t tx, int32_t ty) {
  939. cFFFFFF(0x27);
  940. ci(tx);
  941. ci(ty);
  942. }
  943. void GDClass::cmd_playvideo(int32_t options) {
  944. cFFFFFF(0x3a);
  945. cI(options);
  946. }
  947. void GDClass::cmd_romfont(uint32_t font, uint32_t romslot) {
  948. cFFFFFF(0x3f);
  949. cI(font);
  950. cI(romslot);
  951. }
  952. void GDClass::cmd_mediafifo(uint32_t ptr, uint32_t size) {
  953. cFFFFFF(0x39);
  954. cI(ptr);
  955. cI(size);
  956. }
  957. void GDClass::cmd_setbase(uint32_t b) {
  958. cFFFFFF(0x38);
  959. cI(b);
  960. }
  961. void GDClass::cmd_videoframe(uint32_t dst, uint32_t ptr) {
  962. cFFFFFF(0x41);
  963. cI(dst);
  964. cI(ptr);
  965. }
  966. void GDClass::cmd_snapshot2(uint32_t fmt, uint32_t ptr, int16_t x, int16_t y, int16_t w, int16_t h) {
  967. cFFFFFF(0x37);
  968. cI(fmt);
  969. cI(ptr);
  970. ch(x);
  971. ch(y);
  972. ch(w);
  973. ch(h);
  974. }
  975. void GDClass::cmd_setfont2(uint32_t font, uint32_t ptr, uint32_t firstchar) {
  976. cFFFFFF(0x3b);
  977. cI(font);
  978. cI(ptr);
  979. cI(firstchar);
  980. }
  981. void GDClass::cmd_setbitmap(uint32_t source, uint16_t fmt, uint16_t w, uint16_t h) {
  982. cFFFFFF(0x43);
  983. cI(source);
  984. ch(fmt);
  985. ch(w);
  986. ch(h);
  987. ch(0);
  988. }
  989. void GDClass::cmd_setrotate(uint32_t r) {
  990. cFFFFFF(0x36);
  991. cI(r);
  992. }
  993. void GDClass::cmd_videostart() {
  994. cFFFFFF(0x40);
  995. }
  996. byte GDClass::rd(uint32_t addr) {
  997. return GDTR.rd(addr);
  998. }
  999. void GDClass::wr(uint32_t addr, uint8_t v) {
  1000. GDTR.wr(addr, v);
  1001. }
  1002. uint16_t GDClass::rd16(uint32_t addr) {
  1003. return GDTR.rd16(addr);
  1004. }
  1005. void GDClass::wr16(uint32_t addr, uint16_t v) {
  1006. GDTR.wr16(addr, v);
  1007. }
  1008. uint32_t GDClass::rd32(uint32_t addr) {
  1009. return GDTR.rd32(addr);
  1010. }
  1011. void GDClass::wr32(uint32_t addr, uint32_t v) {
  1012. GDTR.wr32(addr, v);
  1013. }
  1014. void GDClass::wr_n(uint32_t addr, byte *src, uint32_t n) {
  1015. GDTR.wr_n(addr, src, n);
  1016. }
  1017. void GDClass::cmdbyte(uint8_t b) {
  1018. GDTR.cmdbyte(b);
  1019. }
  1020. void GDClass::cmd32(uint32_t b) {
  1021. GDTR.cmd32(b);
  1022. }
  1023. void GDClass::finish(void) {
  1024. GDTR.finish();
  1025. }
  1026. void GDClass::get_accel(int &x, int &y, int &z) {
  1027. static int f[3];
  1028. for (byte i = 0; i < 3; i++) {
  1029. int a = analogRead(A0 + i);
  1030. int s = (-160 * (a - 376)) >> 6;
  1031. f[i] = ((3 * f[i]) >> 2) + (s >> 2);
  1032. }
  1033. x = f[2];
  1034. y = f[1];
  1035. z = f[0];
  1036. }
  1037. void GDClass::get_inputs(void) {
  1038. GDTR.finish();
  1039. byte *bi = (byte*)&inputs;
  1040. #if defined(DUMPDEV)
  1041. extern FILE* stimfile;
  1042. if (stimfile) {
  1043. byte tag;
  1044. fscanf(stimfile, "%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx",
  1045. &bi[0],
  1046. &bi[1],
  1047. &bi[2],
  1048. &bi[3],
  1049. &bi[4],
  1050. &bi[5],
  1051. &bi[6],
  1052. &bi[7],
  1053. &bi[8],
  1054. &bi[9],
  1055. &bi[10],
  1056. &bi[11],
  1057. &bi[12],
  1058. &bi[13],
  1059. &bi[14],
  1060. &bi[15],
  1061. &bi[16],
  1062. &bi[17]);
  1063. GDTR.wr(REG_TAG, tag);
  1064. } else {
  1065. inputs.x = inputs.y = -32768;
  1066. }
  1067. #else
  1068. GDTR.rd_n(bi, REG_TRACKER, 4);
  1069. GDTR.rd_n(bi + 4, REG_TOUCH_RZ, 13);
  1070. GDTR.rd_n(bi + 17, REG_TAG, 1);
  1071. #ifdef DUMP_INPUTS
  1072. for (size_t i = 0; i < sizeof(inputs); i++) {
  1073. Serial.print(bi[i], HEX);
  1074. Serial.print(" ");
  1075. }
  1076. Serial.println();
  1077. #endif
  1078. #endif
  1079. }
  1080. void GDClass::bulkrd(uint32_t a) {
  1081. GDTR.bulk(a);
  1082. }
  1083. void GDClass::resume(void) {
  1084. GDTR.resume();
  1085. }
  1086. void GDClass::__end(void) {
  1087. #if !defined(DUMPDEV) && !defined(RASPBERRY_PI)
  1088. GDTR.__end();
  1089. #endif
  1090. }
  1091. void GDClass::play(uint8_t instrument, uint8_t note) {
  1092. wr16(REG_SOUND, (note << 8) | instrument);
  1093. wr(REG_PLAY, 1);
  1094. }
  1095. void GDClass::sample(uint32_t start, uint32_t len, uint16_t freq, uint16_t format, int loop) {
  1096. GD.wr32(REG_PLAYBACK_START, start);
  1097. GD.wr32(REG_PLAYBACK_LENGTH, len);
  1098. GD.wr16(REG_PLAYBACK_FREQ, freq);
  1099. GD.wr(REG_PLAYBACK_FORMAT, format);
  1100. GD.wr(REG_PLAYBACK_LOOP, loop);
  1101. GD.wr(REG_PLAYBACK_PLAY, 1);
  1102. }
  1103. void GDClass::reset() {
  1104. GDTR.__end();
  1105. GDTR.wr(REG_CPURESET, 1);
  1106. GDTR.wr(REG_CPURESET, 0);
  1107. GDTR.resume();
  1108. }
  1109. // Load named file from storage
  1110. // returns 0 on failure (e.g. file not found), 1 on success
  1111. byte GDClass::load(const char *filename, void (*progress)(long, long))
  1112. {
  1113. #if defined(RASPBERRY_PI) || defined(DUMPDEV)
  1114. char full_name[2048] = "sdcard/";
  1115. strcat(full_name, filename);
  1116. FILE *f = fopen(full_name, "rb");
  1117. if (!f) {
  1118. perror(full_name);
  1119. exit(1);
  1120. }
  1121. byte buf[512];
  1122. int n;
  1123. while ((n = fread(buf, 1, 512, f)) > 0) {
  1124. GDTR.cmd_n(buf, (n + 3) & ~3);
  1125. }
  1126. fclose(f);
  1127. return 1;
  1128. #else
  1129. GD.__end();
  1130. Reader r;
  1131. if (r.openfile(filename)) {
  1132. byte buf[512];
  1133. while (r.offset < r.size) {
  1134. uint16_t n = min(512U, r.size - r.offset);
  1135. n = (n + 3) & ~3; // force 32-bit alignment
  1136. r.readsector(buf);
  1137. GD.resume();
  1138. if (progress)
  1139. (*progress)(r.offset, r.size);
  1140. GD.copyram(buf, n);
  1141. GDTR.stop();
  1142. }
  1143. GD.resume();
  1144. return 1;
  1145. }
  1146. GD.resume();
  1147. return 0;
  1148. #endif
  1149. }
  1150. // Generated by mk_bsod.py. Blue screen with 'ERROR' text
  1151. static const PROGMEM uint8_t __bsod[32] = {
  1152. 0, 255, 255, 255, 96, 0, 0, 2, 7, 0, 0, 38, 12, 255, 255, 255, 240, 0,
  1153. 90, 0, 31, 0, 0, 6, 69, 82, 82, 79, 82, 0, 0, 0
  1154. };
  1155. static const PROGMEM uint8_t __bsod_badfile[32] = {
  1156. 12, 255, 255, 255, 240, 0, 148, 0, 29, 0, 0, 6, 67, 97, 110, 110, 111,
  1157. 116, 32, 111, 112, 101, 110, 32, 102, 105, 108, 101, 58, 0, 0, 0
  1158. };
  1159. // Fatal error alert.
  1160. // Show a blue screen with message.
  1161. // This method never returns.
  1162. void GDClass::alert(const char *message)
  1163. {
  1164. begin(0);
  1165. copy(__bsod, sizeof(__bsod));
  1166. cmd_text(240, 176, 29, OPT_CENTER, message);
  1167. swap();
  1168. GD.finish();
  1169. for (;;)
  1170. ;
  1171. }
  1172. void GDClass::safeload(const char *filename)
  1173. {
  1174. if (!load(filename)) {
  1175. copy(__bsod, sizeof(__bsod));
  1176. copy(__bsod_badfile, sizeof(__bsod_badfile));
  1177. cmd_text(240, 190, 29, OPT_CENTER, filename);
  1178. swap();
  1179. for (;;)
  1180. ;
  1181. }
  1182. }
  1183. #define REG_SCREENSHOT_EN (ft8xx_model ? 0x302010UL : 0x102410UL) // Set to enable screenshot mode
  1184. #define REG_SCREENSHOT_Y (ft8xx_model ? 0x302014UL : 0x102414UL) // Y line register
  1185. #define REG_SCREENSHOT_START (ft8xx_model ? 0x302018UL : 0x102418UL) // Screenshot start trigger
  1186. #define REG_SCREENSHOT_BUSY (ft8xx_model ? 0x3020e8UL : 0x1024d8UL) // Screenshot ready flags
  1187. #define REG_SCREENSHOT_READ (ft8xx_model ? 0x302174UL : 0x102554UL) // Set to enable readout
  1188. #define RAM_SCREENSHOT (ft8xx_model ? 0x3c2000UL : 0x1C2000UL) // Screenshot readout buffer
  1189. #if 0 // ndef DUMPDEV
  1190. void GDClass::dumpscreen(void)
  1191. {
  1192. {
  1193. finish();
  1194. wr(REG_SCREENSHOT_EN, 1);
  1195. Serial.write(0xa5);
  1196. Serial.write(GD.w & 0xff);
  1197. Serial.write((GD.w >> 8) & 0xff);
  1198. Serial.write(GD.h & 0xff);
  1199. Serial.write((GD.h >> 8) & 0xff);
  1200. for (int ly = 0; ly < GD.h; ly++) {
  1201. wr16(REG_SCREENSHOT_Y, ly);
  1202. wr(REG_SCREENSHOT_START, 1);
  1203. delay(2);
  1204. while (rd32(REG_SCREENSHOT_BUSY) | rd32(REG_SCREENSHOT_BUSY + 4))
  1205. ;
  1206. wr(REG_SCREENSHOT_READ, 1);
  1207. bulkrd(RAM_SCREENSHOT);
  1208. SPI.transfer(0xff);
  1209. for (int x = 0; x < GD.w; x += 8) {
  1210. union {
  1211. uint32_t v;
  1212. struct {
  1213. uint8_t b, g, r, a;
  1214. };
  1215. } block[8];
  1216. for (int i = 0; i < 8; i++) {
  1217. block[i].b = SPI.transfer(0xff);
  1218. block[i].g = SPI.transfer(0xff);
  1219. block[i].r = SPI.transfer(0xff);
  1220. block[i].a = SPI.transfer(0xff);
  1221. }
  1222. // if (x == 0) block[0].r = 0xff;
  1223. byte difference = 1;
  1224. for (int i = 1, mask = 2; i < 8; i++, mask <<= 1)
  1225. if (block[i].v != block[i-1].v)
  1226. difference |= mask;
  1227. Serial.write(difference);
  1228. for (int i = 0; i < 8; i++)
  1229. if (1 & (difference >> i)) {
  1230. Serial.write(block[i].b);
  1231. Serial.write(block[i].g);
  1232. Serial.write(block[i].r);
  1233. }
  1234. }
  1235. resume();
  1236. wr(REG_SCREENSHOT_READ, 0);
  1237. }
  1238. wr16(REG_SCREENSHOT_EN, 0);
  1239. }
  1240. }
  1241. #endif