GD2.h 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198
  1. /*
  2. * Copyright (C) 2013-2017 by James Bowman <jamesb@excamera.com>
  3. * Gameduino 2/3 library for Arduino, Arduino Due, Raspberry Pi,
  4. * Teensy 3.2 and ESP8266.
  5. *
  6. */
  7. #ifndef _GD2_H_INCLUDED
  8. #define _GD2_H_INCLUDED
  9. #if defined(RASPBERRY_PI) || defined(DUMPDEV)
  10. #include "wiring.h"
  11. #endif
  12. #include "Arduino.h"
  13. #include <stdarg.h>
  14. #define RGB(r, g, b) ((uint32_t)((((r) & 0xffL) << 16) | (((g) & 0xffL) << 8) | ((b) & 0xffL)))
  15. #define F8(x) (int((x) * 256L))
  16. #define F16(x) ((int32_t)((x) * 65536L))
  17. #define GD_CALIBRATE 1
  18. #define GD_TRIM 2
  19. #define GD_STORAGE 4
  20. #ifdef __SAM3X8E__
  21. #define __DUE__ 1
  22. #endif
  23. ////////////////////////////////////////////////////////////////////////
  24. // Decide if we want to compile in SDcard support
  25. //
  26. // For stock Arduino models: yes
  27. // Raspberry PI: no
  28. // Arduino Due: no
  29. //
  30. #if !defined(RASPBERRY_PI) && !defined(DUMPDEV)
  31. #define SDCARD 1
  32. #else
  33. #define SDCARD 0
  34. #endif
  35. #if defined(__DUE__)
  36. #define MOSI 11
  37. #define MISO 12
  38. #define SCK 13 // B.27
  39. class ASPI_t {
  40. public:
  41. void begin(void) {
  42. pinMode(MOSI, OUTPUT);
  43. pinMode(MISO, INPUT);
  44. pinMode(SCK, OUTPUT);
  45. digitalWrite(SCK, 0);
  46. // PIOB->PIO_PER = PIO_PB27;
  47. // PIOB->PIO_CODR = PIO_PB27;
  48. // PIOB->PIO_PUDR = PIO_PB27;
  49. }
  50. byte transfer(byte x ) {
  51. byte r = 0;
  52. for (byte i = 8; i; i--) {
  53. if (x & 0x80)
  54. PIOD->PIO_SODR = PIO_PD7;
  55. else
  56. PIOD->PIO_CODR = PIO_PD7;
  57. // digitalWrite(MOSI, (x >> 7) & 1);
  58. x <<= 1;
  59. // digitalWrite(SCK, 1);
  60. PIOB->PIO_SODR = PIO_PB27;
  61. r <<= 1;
  62. r |= digitalRead(MISO);
  63. // digitalWrite(SCK, 0);
  64. PIOB->PIO_CODR = PIO_PB27;
  65. }
  66. return r;
  67. }
  68. };
  69. static class ASPI_t ASPI;
  70. #define SPI ASPI
  71. #endif
  72. #if SDCARD
  73. #if defined(VERBOSE) && (VERBOSE > 0)
  74. #define INFO(X) Serial.println((X))
  75. #if defined(RASPBERRY_PI)
  76. #define REPORT(VAR) fprintf(stderr, #VAR "=%d\n", (VAR))
  77. #else
  78. #define REPORT(VAR) (Serial.print(#VAR "="), Serial.print(VAR, DEC), Serial.print(' '), Serial.println(VAR, HEX))
  79. #endif
  80. #else
  81. #define INFO(X)
  82. #define REPORT(X)
  83. #endif
  84. struct dirent {
  85. char name[8];
  86. char ext[3];
  87. byte attribute;
  88. byte reserved[8];
  89. uint16_t cluster_hi; // FAT32 only
  90. uint16_t time;
  91. uint16_t date;
  92. uint16_t cluster;
  93. uint32_t size;
  94. };
  95. // https://www.sdcard.org/downloads/pls/simplified_specs/Part_1_Physical_Layer_Simplified_Specification_Ver_3.01_Final_100518.pdf
  96. // page 22
  97. // http://mac6.ma.psu.edu/space2008/RockSat/microController/sdcard_appnote_foust.pdf
  98. // http://elm-chan.org/docs/mmc/mmc_e.html
  99. // http://www.pjrc.com/tech/8051/ide/fat32.html
  100. #define FAT16 0
  101. #define FAT32 1
  102. #define DD
  103. class sdcard {
  104. public:
  105. void sel() {
  106. digitalWrite(pin, LOW);
  107. delay(1);
  108. }
  109. void desel() {
  110. digitalWrite(pin, HIGH);
  111. SPI.transfer(0xff); // force DO release
  112. }
  113. void sd_delay(byte n) {
  114. while (n--) {
  115. DD SPI.transfer(0xff);
  116. }
  117. }
  118. void cmd(byte cmd, uint32_t lba = 0, uint8_t crc = 0x95) {
  119. #if VERBOSE > 1
  120. Serial.print("cmd ");
  121. Serial.print(cmd, DEC);
  122. Serial.print(" ");
  123. Serial.print(lba, HEX);
  124. Serial.println();
  125. #endif
  126. sel();
  127. // DD SPI.transfer(0xff);
  128. DD SPI.transfer(0x40 | cmd);
  129. DD SPI.transfer(0xff & (lba >> 24));
  130. DD SPI.transfer(0xff & (lba >> 16));
  131. DD SPI.transfer(0xff & (lba >> 8));
  132. DD SPI.transfer(0xff & (lba));
  133. DD SPI.transfer(crc);
  134. // DD SPI.transfer(0xff);
  135. }
  136. byte response() {
  137. byte r;
  138. DD
  139. r = SPI.transfer(0xff);
  140. while (r & 0x80) {
  141. DD
  142. r = SPI.transfer(0xff);
  143. }
  144. return r;
  145. }
  146. byte R1() { // read response R1
  147. byte r = response();
  148. desel();
  149. SPI.transfer(0xff); // trailing byte
  150. return r;
  151. }
  152. byte sdR3(uint32_t &ocr) { // read response R3
  153. byte r = response();
  154. for (byte i = 4; i; i--)
  155. ocr = (ocr << 8) | SPI.transfer(0xff);
  156. SPI.transfer(0xff); // trailing byte
  157. desel();
  158. return r;
  159. }
  160. byte sdR7() { // read response R3
  161. byte r = response();
  162. for (byte i = 4; i; i--)
  163. // Serial.println(SPI.transfer(0xff), HEX);
  164. SPI.transfer(0xff);
  165. desel();
  166. return r;
  167. }
  168. void appcmd(byte cc, uint32_t lba = 0) {
  169. cmd(55); R1();
  170. cmd(cc, lba);
  171. }
  172. void begin(byte p) {
  173. byte type_code;
  174. byte sdhc;
  175. pin = p;
  176. pinMode(pin, OUTPUT);
  177. #if !defined(__DUE__) && !defined(TEENSYDUINO)
  178. SPI.setClockDivider(SPI_CLOCK_DIV64);
  179. #endif
  180. desel();
  181. // for (;;) SPI.transfer(0xff);
  182. delay(50); // wait for boot
  183. sd_delay(10); // deselected, 80 pulses
  184. INFO("Attempting card reset... ");
  185. byte r1;
  186. static int attempts;
  187. attempts = 0;
  188. do { // reset, enter idle
  189. cmd(0);
  190. while ((r1 = SPI.transfer(0xff)) & 0x80)
  191. if (++attempts == 1000)
  192. goto finished;
  193. desel();
  194. SPI.transfer(0xff); // trailing byte
  195. REPORT(r1);
  196. } while (r1 != 1);
  197. INFO("reset ok\n");
  198. sdhc = 0;
  199. cmd(8, 0x1aa, 0x87);
  200. r1 = sdR7();
  201. sdhc = (r1 == 1);
  202. REPORT(sdhc);
  203. INFO("Sending card init command");
  204. attempts = 0;
  205. while (1) {
  206. appcmd(41, sdhc ? (1UL << 30) : 0); // card init
  207. r1 = R1();
  208. #if VERBOSE
  209. Serial.println(r1, HEX);
  210. #endif
  211. if ((r1 & 1) == 0)
  212. break;
  213. if (++attempts == 300)
  214. goto finished;
  215. delay(1);
  216. }
  217. INFO("OK");
  218. if (sdhc) {
  219. uint32_t OCR = 0;
  220. for (int i = 10; i; i--) {
  221. cmd(58);
  222. sdR3(OCR);
  223. REPORT(OCR);
  224. }
  225. ccs = 1UL & (OCR >> 30);
  226. } else {
  227. ccs = 0;
  228. }
  229. REPORT(ccs);
  230. // Test point: dump sector 0 to serial.
  231. // should see first 512 bytes of card, ending 55 AA.
  232. #if 0
  233. cmd17(0);
  234. for (int i = 0; i < 512; i++) {
  235. delay(10);
  236. byte b = SPI.transfer(0xff);
  237. Serial.print(b, HEX);
  238. Serial.print(' ');
  239. if ((i & 15) == 15)
  240. Serial.println();
  241. }
  242. desel();
  243. for (;;);
  244. #endif
  245. #if !defined(__DUE__) && !defined(ESP8266)
  246. SPI.setClockDivider(SPI_CLOCK_DIV2);
  247. SPSR = (1 << SPI2X);
  248. #endif
  249. #if defined(ESP8266)
  250. SPI.setFrequency(40000000L);
  251. #endif
  252. type_code = rd(0x1be + 0x4);
  253. switch (type_code) {
  254. default:
  255. type = FAT16;
  256. break;
  257. case 0x0b:
  258. case 0x0c:
  259. type = FAT32;
  260. break;
  261. }
  262. REPORT(type_code);
  263. o_partition = 512L * rd4(0x1be + 0x8);
  264. sectors_per_cluster = rd(o_partition + 0xd);
  265. reserved_sectors = rd2(o_partition + 0xe);
  266. cluster_size = 512L * sectors_per_cluster;
  267. REPORT(sectors_per_cluster);
  268. // Serial.println("Bytes per sector: %d\n", rd2(o_partition + 0xb));
  269. // Serial.println("Sectors per cluster: %d\n", sectors_per_cluster);
  270. if (type == FAT16) {
  271. max_root_dir_entries = rd2(o_partition + 0x11);
  272. sectors_per_fat = rd2(o_partition + 0x16);
  273. o_fat = o_partition + 512L * reserved_sectors;
  274. o_root = o_fat + (2 * 512L * sectors_per_fat);
  275. // data area starts with cluster 2, so offset it here
  276. o_data = o_root + (max_root_dir_entries * 32L) - (2L * cluster_size);
  277. } else {
  278. uint32_t sectors_per_fat = rd4(o_partition + 0x24);
  279. root_dir_first_cluster = rd4(o_partition + 0x2c);
  280. uint32_t fat_begin_lba = (o_partition >> 9) + reserved_sectors;
  281. uint32_t cluster_begin_lba = (o_partition >> 9) + reserved_sectors + (2 * sectors_per_fat);
  282. o_fat = 512L * fat_begin_lba;
  283. o_root = (512L * (cluster_begin_lba + (root_dir_first_cluster - 2) * sectors_per_cluster));
  284. o_data = (512L * (cluster_begin_lba - 2 * sectors_per_cluster));
  285. }
  286. finished:
  287. INFO("finished");
  288. ;
  289. }
  290. void cmd17(uint32_t off) {
  291. if (ccs)
  292. cmd(17, off >> 9);
  293. else
  294. cmd(17, off & ~511L);
  295. R1();
  296. sel();
  297. while (SPI.transfer(0xff) != 0xfe)
  298. ;
  299. }
  300. void rdn(byte *d, uint32_t off, uint16_t n) {
  301. cmd17(off);
  302. uint16_t i;
  303. uint16_t bo = (off & 511);
  304. for (i = 0; i < bo; i++)
  305. SPI.transfer(0xff);
  306. for (i = 0; i < n; i++)
  307. *d++ = SPI.transfer(0xff);
  308. for (i = 0; i < (514 - bo - n); i++)
  309. SPI.transfer(0xff);
  310. desel();
  311. }
  312. uint32_t rd4(uint32_t off) {
  313. uint32_t r;
  314. rdn((byte*)&r, off, sizeof(r));
  315. return r;
  316. }
  317. uint16_t rd2(uint32_t off) {
  318. uint16_t r;
  319. rdn((byte*)&r, off, sizeof(r));
  320. return r;
  321. }
  322. byte rd(uint32_t off) {
  323. byte r;
  324. rdn((byte*)&r, off, sizeof(r));
  325. return r;
  326. }
  327. byte pin;
  328. byte ccs;
  329. byte type;
  330. uint16_t sectors_per_cluster;
  331. uint16_t reserved_sectors;
  332. uint16_t max_root_dir_entries;
  333. uint16_t sectors_per_fat;
  334. uint16_t cluster_size;
  335. uint32_t root_dir_first_cluster;
  336. // These are all linear addresses, hence the o_ prefix
  337. uint32_t o_partition;
  338. uint32_t o_fat;
  339. uint32_t o_root;
  340. uint32_t o_data;
  341. };
  342. static void dos83(byte dst[11], const char *ps)
  343. {
  344. byte i = 0;
  345. while (*ps) {
  346. if (*ps != '.')
  347. dst[i++] = toupper(*ps);
  348. else {
  349. while (i < 8)
  350. dst[i++] = ' ';
  351. }
  352. ps++;
  353. }
  354. while (i < 11)
  355. dst[i++] = ' ';
  356. }
  357. #else
  358. class sdcard {
  359. public:
  360. void begin(int p) {};
  361. };
  362. #endif
  363. ////////////////////////////////////////////////////////////////////////
  364. class xy {
  365. public:
  366. int x, y;
  367. void set(int _x, int _y);
  368. void rmove(int distance, int angle);
  369. int angleto(class xy &other);
  370. void draw(byte offset = 0);
  371. void rotate(int angle);
  372. int onscreen(void);
  373. class xy operator<<=(int d);
  374. class xy operator+=(class xy &other);
  375. class xy operator-=(class xy &other);
  376. long operator*(class xy &other);
  377. class xy operator*=(int);
  378. int nearer_than(int distance, xy &other);
  379. };
  380. class Bitmap {
  381. public:
  382. xy size, center;
  383. uint32_t source;
  384. uint16_t format;
  385. int8_t handle;
  386. void fromtext(int font, const char* s);
  387. void fromfile(const char *filename);
  388. void bind(uint8_t handle);
  389. void draw(int x, int y, int16_t angle = 0);
  390. private:
  391. void defaults(uint8_t f);
  392. void setup(void);
  393. };
  394. ////////////////////////////////////////////////////////////////////////
  395. class GDClass {
  396. public:
  397. int w, h;
  398. uint32_t loadptr;
  399. void begin(uint8_t options = (GD_CALIBRATE | GD_TRIM | GD_STORAGE));
  400. uint16_t random();
  401. uint16_t random(uint16_t n);
  402. void seed(uint16_t n);
  403. int16_t rsin(int16_t r, uint16_t th);
  404. int16_t rcos(int16_t r, uint16_t th);
  405. void polar(int &x, int &y, int16_t r, uint16_t th);
  406. uint16_t atan2(int16_t y, int16_t x);
  407. #if !defined(ESP8266)
  408. void copy(const PROGMEM uint8_t *src, int count);
  409. #else
  410. void copy(const uint8_t *src, int count);
  411. #endif
  412. void copyram(byte *src, int count);
  413. void self_calibrate(void);
  414. void swap(void);
  415. void flush(void);
  416. void finish(void);
  417. void play(uint8_t instrument, uint8_t note = 0);
  418. void sample(uint32_t start, uint32_t len, uint16_t freq, uint16_t format, int loop = 0);
  419. void get_inputs(void);
  420. void get_accel(int &x, int &y, int &z);
  421. struct {
  422. uint16_t track_tag;
  423. uint16_t track_val;
  424. uint16_t rz;
  425. uint16_t __dummy_1;
  426. int16_t y;
  427. int16_t x;
  428. int16_t tag_y;
  429. int16_t tag_x;
  430. uint8_t tag;
  431. uint8_t ptag;
  432. uint8_t touching;
  433. xy xytouch;
  434. } inputs;
  435. void AlphaFunc(byte func, byte ref);
  436. void Begin(byte prim);
  437. void BitmapHandle(byte handle);
  438. void BitmapLayout(byte format, uint16_t linestride, uint16_t height);
  439. void BitmapSize(byte filter, byte wrapx, byte wrapy, uint16_t width, uint16_t height);
  440. void BitmapSource(uint32_t addr);
  441. void BitmapTransformA(int32_t a);
  442. void BitmapTransformB(int32_t b);
  443. void BitmapTransformC(int32_t c);
  444. void BitmapTransformD(int32_t d);
  445. void BitmapTransformE(int32_t e);
  446. void BitmapTransformF(int32_t f);
  447. void BlendFunc(byte src, byte dst);
  448. void Call(uint16_t dest);
  449. void Cell(byte cell);
  450. void ClearColorA(byte alpha);
  451. void ClearColorRGB(byte red, byte green, byte blue);
  452. void ClearColorRGB(uint32_t rgb);
  453. void Clear(byte c, byte s, byte t);
  454. void Clear(void);
  455. void ClearStencil(byte s);
  456. void ClearTag(byte s);
  457. void ColorA(byte alpha);
  458. void ColorMask(byte r, byte g, byte b, byte a);
  459. void ColorRGB(byte red, byte green, byte blue);
  460. void ColorRGB(uint32_t rgb);
  461. void Display(void);
  462. void End(void);
  463. void Jump(uint16_t dest);
  464. void LineWidth(uint16_t width);
  465. void Macro(byte m);
  466. void PointSize(uint16_t size);
  467. void RestoreContext(void);
  468. void Return(void);
  469. void SaveContext(void);
  470. void ScissorSize(uint16_t width, uint16_t height);
  471. void ScissorXY(uint16_t x, uint16_t y);
  472. void StencilFunc(byte func, byte ref, byte mask);
  473. void StencilMask(byte mask);
  474. void StencilOp(byte sfail, byte spass);
  475. void TagMask(byte mask);
  476. void Tag(byte s);
  477. void Vertex2f(int16_t x, int16_t y);
  478. void Vertex2ii(uint16_t x, uint16_t y, byte handle = 0, byte cell = 0);
  479. void VertexFormat(byte frac);
  480. void BitmapLayoutH(byte linestride, byte height);
  481. void BitmapSizeH(byte width, byte height);
  482. void PaletteSource(uint32_t addr);
  483. void VertexTranslateX(uint32_t x);
  484. void VertexTranslateY(uint32_t y);
  485. void Nop(void);
  486. // Higher-level graphics commands
  487. void cmd_append(uint32_t ptr, uint32_t num);
  488. void cmd_bgcolor(uint32_t c);
  489. void cmd_button(int16_t x, int16_t y, uint16_t w, uint16_t h, byte font, uint16_t options, const char *s);
  490. void cmd_calibrate(void);
  491. void 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);
  492. void cmd_coldstart(void);
  493. void cmd_dial(int16_t x, int16_t y, int16_t r, uint16_t options, uint16_t val);
  494. void cmd_dlstart(void);
  495. void cmd_fgcolor(uint32_t c);
  496. void 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);
  497. void cmd_getmatrix(void);
  498. void cmd_getprops(uint32_t &ptr, uint32_t &w, uint32_t &h);
  499. void cmd_getptr(void);
  500. void cmd_gradcolor(uint32_t c);
  501. void cmd_gradient(int16_t x0, int16_t y0, uint32_t rgb0, int16_t x1, int16_t y1, uint32_t rgb1);
  502. void cmd_inflate(uint32_t ptr);
  503. void cmd_interrupt(uint32_t ms);
  504. void cmd_keys(int16_t x, int16_t y, int16_t w, int16_t h, byte font, uint16_t options, const char*s);
  505. void cmd_loadidentity(void);
  506. void cmd_loadimage(uint32_t ptr, int32_t options);
  507. void cmd_memcpy(uint32_t dest, uint32_t src, uint32_t num);
  508. void cmd_memset(uint32_t ptr, byte value, uint32_t num);
  509. uint32_t cmd_memcrc(uint32_t ptr, uint32_t num);
  510. void cmd_memwrite(uint32_t ptr, uint32_t num);
  511. void cmd_regwrite(uint32_t ptr, uint32_t val);
  512. void cmd_number(int16_t x, int16_t y, byte font, uint16_t options, uint32_t n);
  513. void cmd_progress(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range);
  514. void cmd_regread(uint32_t ptr);
  515. void cmd_rotate(int32_t a);
  516. void cmd_scale(int32_t sx, int32_t sy);
  517. void cmd_screensaver(void);
  518. void 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);
  519. void cmd_setfont(byte font, uint32_t ptr);
  520. void cmd_setmatrix(void);
  521. void cmd_sketch(int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t ptr, uint16_t format);
  522. void cmd_slider(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t options, uint16_t val, uint16_t range);
  523. void cmd_snapshot(uint32_t ptr);
  524. void cmd_spinner(int16_t x, int16_t y, byte style, byte scale);
  525. void cmd_stop(void);
  526. void cmd_swap(void);
  527. void cmd_text(int16_t x, int16_t y, byte font, uint16_t options, const char *s);
  528. void cmd_toggle(int16_t x, int16_t y, int16_t w, byte font, uint16_t options, uint16_t state, const char *s);
  529. void cmd_track(int16_t x, int16_t y, uint16_t w, uint16_t h, byte tag);
  530. void cmd_translate(int32_t tx, int32_t ty);
  531. void cmd_playvideo(int32_t options);
  532. void cmd_romfont(uint32_t font, uint32_t romslot);
  533. void cmd_mediafifo(uint32_t ptr, uint32_t size);
  534. void cmd_setbase(uint32_t b);
  535. void cmd_videoframe(uint32_t dst, uint32_t ptr);
  536. void cmd_snapshot2(uint32_t fmt, uint32_t ptr, int16_t x, int16_t y, int16_t w, int16_t h);
  537. void cmd_setfont2(uint32_t font, uint32_t ptr, uint32_t firstchar);
  538. void cmd_setrotate(uint32_t r);
  539. void cmd_videostart();
  540. void cmd_setbitmap(uint32_t source, uint16_t fmt, uint16_t w, uint16_t h);
  541. byte rd(uint32_t addr);
  542. void wr(uint32_t addr, uint8_t v);
  543. uint16_t rd16(uint32_t addr);
  544. void wr16(uint32_t addr, uint16_t v);
  545. uint32_t rd32(uint32_t addr);
  546. void wr32(uint32_t addr, uint32_t v);
  547. void wr_n(uint32_t addr, byte *src, uint32_t n);
  548. void cmd32(uint32_t b);
  549. void bulkrd(uint32_t a);
  550. void resume(void);
  551. void __end(void);
  552. void reset(void);
  553. void dumpscreen(void);
  554. byte load(const char *filename, void (*progress)(long, long) = NULL);
  555. void safeload(const char *filename);
  556. void alert(const char *message);
  557. void textsize(int &w, int &h, int font, const char *s);
  558. sdcard SD;
  559. void storage(void);
  560. void tune(void);
  561. private:
  562. static void cFFFFFF(byte v);
  563. static void cI(uint32_t);
  564. static void ci(int32_t);
  565. static void cH(uint16_t);
  566. static void ch(int16_t);
  567. static void cs(const char *);
  568. static void fmtcmd(const char *fmt, ...);
  569. static void align(byte n);
  570. void cmdbyte(uint8_t b);
  571. uint32_t measure_freq(void);
  572. uint32_t rseed;
  573. };
  574. extern GDClass GD;
  575. extern byte ft8xx_model;
  576. #if SDCARD
  577. class Reader {
  578. public:
  579. int openfile(const char *filename) {
  580. int i = 0;
  581. byte dosname[11];
  582. dirent de;
  583. dos83(dosname, filename);
  584. do {
  585. GD.SD.rdn((byte*)&de, GD.SD.o_root + i * 32, sizeof(de));
  586. // Serial.println(de.name);
  587. if (0 == memcmp(de.name, dosname, 11)) {
  588. begin(de);
  589. return 1;
  590. }
  591. i++;
  592. } while (de.name[0]);
  593. return 0;
  594. }
  595. void begin(dirent &de) {
  596. nseq = 0;
  597. size = de.size;
  598. cluster0 = de.cluster;
  599. if (GD.SD.type == FAT32)
  600. cluster0 |= ((long)de.cluster_hi << 16);
  601. rewind();
  602. }
  603. void rewind(void) {
  604. cluster = cluster0;
  605. sector = 0;
  606. offset = 0;
  607. }
  608. void nextcluster() {
  609. if (GD.SD.type == FAT16)
  610. cluster = GD.SD.rd2(GD.SD.o_fat + 2 * cluster);
  611. else
  612. cluster = GD.SD.rd4(GD.SD.o_fat + 4 * cluster);
  613. #if VERBOSE
  614. Serial.print("nextcluster=");
  615. Serial.println(cluster, DEC);
  616. #endif
  617. }
  618. void fetch512(byte *dst) {
  619. #if defined(__DUE__) || defined(TEENSYDUINO) || defined(ESP8266)
  620. #if defined(ESP8266)
  621. SPI.transferBytes(NULL, dst, 512);
  622. #else
  623. for (int i = 0; i < 512; i++)
  624. *dst++ = SPI.transfer(0xff);
  625. #endif
  626. SPI.transfer(0xff); // consume CRC
  627. SPI.transfer(0xff);
  628. #else
  629. SPDR = 0xff;
  630. while (!(SPSR & _BV(SPIF))) ;
  631. for (int i = 0; i < 512; i++) {
  632. asm volatile("nop");
  633. asm volatile("nop");
  634. asm volatile("nop");
  635. asm volatile("nop");
  636. asm volatile("nop");
  637. asm volatile("nop");
  638. asm volatile("nop");
  639. asm volatile("nop");
  640. asm volatile("nop");
  641. asm volatile("nop");
  642. asm volatile("nop");
  643. *dst++ = SPDR;
  644. SPDR = 0xff;
  645. }
  646. while (!(SPSR & _BV(SPIF))) ;
  647. SPI.transfer(0xff);
  648. #endif
  649. GD.SD.desel();
  650. }
  651. void nextcluster2(byte *dst) {
  652. if (nseq) {
  653. nseq--;
  654. cluster++;
  655. return;
  656. }
  657. uint32_t off = GD.SD.o_fat + 4 * cluster;
  658. GD.SD.cmd17(off & ~511L);
  659. fetch512(dst);
  660. int i = off & 511;
  661. cluster = *(uint32_t*)&dst[i];
  662. uint32_t c = cluster;
  663. nseq = 0;
  664. for (uint32_t c = cluster;
  665. (i < 512) && *(uint32_t*)&dst[i] == c;
  666. i += 4, c++)
  667. nseq++;
  668. }
  669. void skipcluster() {
  670. nextcluster();
  671. offset += GD.SD.cluster_size;
  672. }
  673. void skipsector() {
  674. if (sector == GD.SD.sectors_per_cluster) {
  675. sector = 0;
  676. nextcluster();
  677. }
  678. sector++;
  679. offset += 512;
  680. }
  681. void seek(uint32_t o) {
  682. union {
  683. uint8_t buf[512];
  684. uint32_t fat32[128];
  685. uint16_t fat16[256];
  686. };
  687. uint32_t co = ~0;
  688. if (o < offset)
  689. rewind();
  690. while (offset < o) {
  691. if ((sector == GD.SD.sectors_per_cluster) && ((o - offset) > (long)GD.SD.cluster_size)) {
  692. uint32_t o;
  693. if (GD.SD.type == FAT16)
  694. o = (GD.SD.o_fat + 2 * cluster) & ~511;
  695. else
  696. o = (GD.SD.o_fat + 4 * cluster) & ~511;
  697. if (o != co) {
  698. GD.SD.rdn(buf, o, 512);
  699. co = o;
  700. }
  701. cluster = fat32[cluster & 127];
  702. offset += GD.SD.cluster_size;
  703. } else
  704. skipsector();
  705. }
  706. }
  707. void readsector(byte *dst) {
  708. if (sector == GD.SD.sectors_per_cluster) {
  709. sector = 0;
  710. nextcluster2(dst);
  711. }
  712. uint32_t off = GD.SD.o_data + ((long)GD.SD.cluster_size * cluster) + (512L * sector);
  713. GD.SD.cmd17(off & ~511L);
  714. sector++;
  715. offset += 512;
  716. fetch512(dst);
  717. }
  718. int eof(void) {
  719. return size <= offset;
  720. }
  721. uint32_t cluster, cluster0;
  722. uint32_t offset;
  723. uint32_t size;
  724. byte sector;
  725. byte nseq;
  726. };
  727. #endif
  728. typedef struct {
  729. byte handle;
  730. uint16_t w, h;
  731. uint16_t size;
  732. } shape_t;
  733. // convert integer pixels to subpixels
  734. #define PIXELS(x) int((x) * 16)
  735. // Convert degrees to Furmans
  736. #define DEGREES(n) ((65536L * (n)) / 360)
  737. #define NEVER 0
  738. #define LESS 1
  739. #define LEQUAL 2
  740. #define GREATER 3
  741. #define GEQUAL 4
  742. #define EQUAL 5
  743. #define NOTEQUAL 6
  744. #define ALWAYS 7
  745. #define ARGB1555 0
  746. #define L1 1
  747. #define L4 2
  748. #define L8 3
  749. #define RGB332 4
  750. #define ARGB2 5
  751. #define ARGB4 6
  752. #define RGB565 7
  753. #define PALETTED 8
  754. #define TEXT8X8 9
  755. #define TEXTVGA 10
  756. #define BARGRAPH 11
  757. #define L2 17
  758. #define NEAREST 0
  759. #define BILINEAR 1
  760. #define BORDER 0
  761. #define REPEAT 1
  762. #define KEEP 1
  763. #define REPLACE 2
  764. #define INCR 3
  765. #define DECR 4
  766. #define INVERT 5
  767. #define DLSWAP_DONE 0
  768. #define DLSWAP_LINE 1
  769. #define DLSWAP_FRAME 2
  770. #define INT_SWAP 1
  771. #define INT_TOUCH 2
  772. #define INT_TAG 4
  773. #define INT_SOUND 8
  774. #define INT_PLAYBACK 16
  775. #define INT_CMDEMPTY 32
  776. #define INT_CMDFLAG 64
  777. #define INT_CONVCOMPLETE 128
  778. #define TOUCHMODE_OFF 0
  779. #define TOUCHMODE_ONESHOT 1
  780. #define TOUCHMODE_FRAME 2
  781. #define TOUCHMODE_CONTINUOUS 3
  782. #define ZERO 0
  783. #define ONE 1
  784. #define SRC_ALPHA 2
  785. #define DST_ALPHA 3
  786. #define ONE_MINUS_SRC_ALPHA 4
  787. #define ONE_MINUS_DST_ALPHA 5
  788. #define BITMAPS 1
  789. #define POINTS 2
  790. #define LINES 3
  791. #define LINE_STRIP 4
  792. #define EDGE_STRIP_R 5
  793. #define EDGE_STRIP_L 6
  794. #define EDGE_STRIP_A 7
  795. #define EDGE_STRIP_B 8
  796. #define RECTS 9
  797. #define OPT_MONO 1
  798. #define OPT_NODL 2
  799. #define OPT_FLAT 256
  800. #define OPT_CENTERX 512
  801. #define OPT_CENTERY 1024
  802. #define OPT_CENTER (OPT_CENTERX | OPT_CENTERY)
  803. #define OPT_NOBACK 4096
  804. #define OPT_NOTICKS 8192
  805. #define OPT_NOHM 16384
  806. #define OPT_NOPOINTER 16384
  807. #define OPT_NOSECS 32768
  808. #define OPT_NOHANDS 49152
  809. #define OPT_RIGHTX 2048
  810. #define OPT_SIGNED 256
  811. #define OPT_NOTEAR 4
  812. #define OPT_FULLSCREEN 8
  813. #define OPT_MEDIAFIFO 16
  814. #define LINEAR_SAMPLES 0
  815. #define ULAW_SAMPLES 1
  816. #define ADPCM_SAMPLES 2
  817. // 'instrument' argument to GD.play()
  818. #define SILENCE 0x00
  819. #define SQUAREWAVE 0x01
  820. #define SINEWAVE 0x02
  821. #define SAWTOOTH 0x03
  822. #define TRIANGLE 0x04
  823. #define BEEPING 0x05
  824. #define ALARM 0x06
  825. #define WARBLE 0x07
  826. #define CAROUSEL 0x08
  827. #define PIPS(n) (0x0f + (n))
  828. #define HARP 0x40
  829. #define XYLOPHONE 0x41
  830. #define TUBA 0x42
  831. #define GLOCKENSPIEL 0x43
  832. #define ORGAN 0x44
  833. #define TRUMPET 0x45
  834. #define PIANO 0x46
  835. #define CHIMES 0x47
  836. #define MUSICBOX 0x48
  837. #define BELL 0x49
  838. #define CLICK 0x50
  839. #define SWITCH 0x51
  840. #define COWBELL 0x52
  841. #define NOTCH 0x53
  842. #define HIHAT 0x54
  843. #define KICKDRUM 0x55
  844. #define POP 0x56
  845. #define CLACK 0x57
  846. #define CHACK 0x58
  847. #define MUTE 0x60
  848. #define UNMUTE 0x61
  849. #define RAM_PAL 1056768UL
  850. #define RAM_CMD (ft8xx_model ? 0x308000UL : 0x108000UL)
  851. #define RAM_DL (ft8xx_model ? 0x300000UL : 0x100000UL)
  852. #define REG_CLOCK (ft8xx_model ? 0x302008UL : 0x102408UL)
  853. #define REG_CMD_DL (ft8xx_model ? 0x302100UL : 0x1024ecUL)
  854. #define REG_CMD_READ (ft8xx_model ? 0x3020f8UL : 0x1024e4UL)
  855. #define REG_CMD_WRITE (ft8xx_model ? 0x3020fcUL : 0x1024e8UL)
  856. #define REG_CPURESET (ft8xx_model ? 0x302020UL : 0x10241cUL)
  857. #define REG_CSPREAD (ft8xx_model ? 0x302068UL : 0x102464UL)
  858. #define REG_DITHER (ft8xx_model ? 0x302060UL : 0x10245cUL)
  859. #define REG_DLSWAP (ft8xx_model ? 0x302054UL : 0x102450UL)
  860. #define REG_FRAMES (ft8xx_model ? 0x302004UL : 0x102404UL)
  861. #define REG_FREQUENCY (ft8xx_model ? 0x30200cUL : 0x10240cUL)
  862. #define REG_GPIO (ft8xx_model ? 0x302094UL : 0x102490UL)
  863. #define REG_GPIO_DIR (ft8xx_model ? 0x302090UL : 0x10248cUL)
  864. #define REG_HCYCLE (ft8xx_model ? 0x30202cUL : 0x102428UL)
  865. #define REG_HOFFSET (ft8xx_model ? 0x302030UL : 0x10242cUL)
  866. #define REG_HSIZE (ft8xx_model ? 0x302034UL : 0x102430UL)
  867. #define REG_HSYNC0 (ft8xx_model ? 0x302038UL : 0x102434UL)
  868. #define REG_HSYNC1 (ft8xx_model ? 0x30203cUL : 0x102438UL)
  869. #define REG_ID (ft8xx_model ? 0x302000UL : 0x102400UL)
  870. #define REG_INT_EN (ft8xx_model ? 0x3020acUL : 0x10249cUL)
  871. #define REG_INT_FLAGS (ft8xx_model ? 0x3020a8UL : 0x102498UL)
  872. #define REG_INT_MASK (ft8xx_model ? 0x3020b0UL : 0x1024a0UL)
  873. #define REG_MACRO_0 (ft8xx_model ? 0x3020d8UL : 0x1024c8UL)
  874. #define REG_MACRO_1 (ft8xx_model ? 0x3020dcUL : 0x1024ccUL)
  875. #define REG_OUTBITS (ft8xx_model ? 0x30205cUL : 0x102458UL)
  876. #define REG_PCLK (ft8xx_model ? 0x302070UL : 0x10246cUL)
  877. #define REG_PCLK_POL (ft8xx_model ? 0x30206cUL : 0x102468UL)
  878. #define REG_PLAY (ft8xx_model ? 0x30208cUL : 0x102488UL)
  879. #define REG_PLAYBACK_FORMAT (ft8xx_model ? 0x3020c4UL : 0x1024b4UL)
  880. #define REG_PLAYBACK_FREQ (ft8xx_model ? 0x3020c0UL : 0x1024b0UL)
  881. #define REG_PLAYBACK_LENGTH (ft8xx_model ? 0x3020b8UL : 0x1024a8UL)
  882. #define REG_PLAYBACK_LOOP (ft8xx_model ? 0x3020c8UL : 0x1024b8UL)
  883. #define REG_PLAYBACK_PLAY (ft8xx_model ? 0x3020ccUL : 0x1024bcUL)
  884. #define REG_PLAYBACK_READPTR (ft8xx_model ? 0x3020bcUL : 0x1024acUL)
  885. #define REG_PLAYBACK_START (ft8xx_model ? 0x3020b4UL : 0x1024a4UL)
  886. #define REG_PWM_DUTY (ft8xx_model ? 0x3020d4UL : 0x1024c4UL)
  887. #define REG_PWM_HZ (ft8xx_model ? 0x3020d0UL : 0x1024c0UL)
  888. #define REG_ROTATE (ft8xx_model ? 0x302058UL : 0x102454UL)
  889. #define REG_SOUND (ft8xx_model ? 0x302088UL : 0x102484UL)
  890. #define REG_SWIZZLE (ft8xx_model ? 0x302064UL : 0x102460UL)
  891. #define REG_TAG (ft8xx_model ? 0x30207cUL : 0x102478UL)
  892. #define REG_TAG_X (ft8xx_model ? 0x302074UL : 0x102470UL)
  893. #define REG_TAG_Y (ft8xx_model ? 0x302078UL : 0x102474UL)
  894. #define REG_TOUCH_ADC_MODE (ft8xx_model ? 0x302108UL : 0x1024f4UL)
  895. #define REG_TOUCH_CHARGE (ft8xx_model ? 0x30210cUL : 0x1024f8UL)
  896. #define REG_TOUCH_DIRECT_XY (ft8xx_model ? 0x30218cUL : 0x102574UL)
  897. #define REG_TOUCH_DIRECT_Z1Z2 (ft8xx_model ? 0x302190UL : 0x102578UL)
  898. #define REG_TOUCH_MODE (ft8xx_model ? 0x302104UL : 0x1024f0UL)
  899. #define REG_TOUCH_OVERSAMPLE (ft8xx_model ? 0x302114UL : 0x102500UL)
  900. #define REG_TOUCH_RAW_XY (ft8xx_model ? 0x30211cUL : 0x102508UL)
  901. #define REG_TOUCH_RZ (ft8xx_model ? 0x302120UL : 0x10250cUL)
  902. #define REG_TOUCH_RZTHRESH (ft8xx_model ? 0x302118UL : 0x102504UL)
  903. #define REG_TOUCH_SCREEN_XY (ft8xx_model ? 0x302124UL : 0x102510UL)
  904. #define REG_TOUCH_SETTLE (ft8xx_model ? 0x302110UL : 0x1024fcUL)
  905. #define REG_TOUCH_TAG (ft8xx_model ? 0x30212cUL : 0x102518UL)
  906. #define REG_TOUCH_TAG_XY (ft8xx_model ? 0x302128UL : 0x102514UL)
  907. #define REG_TOUCH_TRANSFORM_A (ft8xx_model ? 0x302150UL : 0x10251cUL)
  908. #define REG_TOUCH_TRANSFORM_B (ft8xx_model ? 0x302154UL : 0x102520UL)
  909. #define REG_TOUCH_TRANSFORM_C (ft8xx_model ? 0x302158UL : 0x102524UL)
  910. #define REG_TOUCH_TRANSFORM_D (ft8xx_model ? 0x30215cUL : 0x102528UL)
  911. #define REG_TOUCH_TRANSFORM_E (ft8xx_model ? 0x302160UL : 0x10252cUL)
  912. #define REG_TOUCH_TRANSFORM_F (ft8xx_model ? 0x302164UL : 0x102530UL)
  913. #define REG_TRACKER (ft8xx_model ? 0x309000UL : 0x109000UL)
  914. #define REG_TRIM (ft8xx_model ? 0x302180UL : 0x10256cUL)
  915. #define REG_VCYCLE (ft8xx_model ? 0x302040UL : 0x10243cUL)
  916. #define REG_VOFFSET (ft8xx_model ? 0x302044UL : 0x102440UL)
  917. #define REG_VOL_PB (ft8xx_model ? 0x302080UL : 0x10247cUL)
  918. #define REG_VOL_SOUND (ft8xx_model ? 0x302084UL : 0x102480UL)
  919. #define REG_VSIZE (ft8xx_model ? 0x302048UL : 0x102444UL)
  920. #define REG_VSYNC0 (ft8xx_model ? 0x30204cUL : 0x102448UL)
  921. #define REG_VSYNC1 (ft8xx_model ? 0x302050UL : 0x10244cUL)
  922. #define FONT_ROOT (ft8xx_model ? 0x2ffffcUL : 0x0ffffcUL)
  923. #define REG_MEDIAFIFO_READ 0x309014
  924. #define REG_MEDIAFIFO_WRITE 0x309018
  925. #define VERTEX2II(x, y, handle, cell) \
  926. ((2UL << 30) | (((x) & 511UL) << 21) | (((y) & 511UL) << 12) | (((handle) & 31) << 7) | (((cell) & 127) << 0))
  927. #define ROM_PIXEL_FF 0xc0400UL
  928. class Poly {
  929. int x0, y0, x1, y1;
  930. int x[8], y[8];
  931. byte n;
  932. void restart() {
  933. n = 0;
  934. x0 = 16 * 480;
  935. x1 = 0;
  936. y0 = 16 * 272;
  937. y1 = 0;
  938. }
  939. void perim() {
  940. for (byte i = 0; i < n; i++)
  941. GD.Vertex2f(x[i], y[i]);
  942. GD.Vertex2f(x[0], y[0]);
  943. }
  944. public:
  945. void begin() {
  946. restart();
  947. GD.ColorMask(0,0,0,0);
  948. GD.StencilOp(KEEP, INVERT);
  949. GD.StencilFunc(ALWAYS, 255, 255);
  950. }
  951. void v(int _x, int _y) {
  952. x0 = min(x0, _x >> 4);
  953. x1 = max(x1, _x >> 4);
  954. y0 = min(y0, _y >> 4);
  955. y1 = max(y1, _y >> 4);
  956. x[n] = _x;
  957. y[n] = _y;
  958. n++;
  959. }
  960. void paint() {
  961. x0 = max(0, x0);
  962. y0 = max(0, y0);
  963. x1 = min(16 * 480, x1);
  964. y1 = min(16 * 272, y1);
  965. GD.ScissorXY(x0, y0);
  966. GD.ScissorSize(x1 - x0 + 1, y1 - y0 + 1);
  967. GD.Begin(EDGE_STRIP_B);
  968. perim();
  969. }
  970. void finish() {
  971. GD.ColorMask(1,1,1,1);
  972. GD.StencilFunc(EQUAL, 255, 255);
  973. GD.Begin(EDGE_STRIP_B);
  974. GD.Vertex2ii(0, 0);
  975. GD.Vertex2ii(511, 0);
  976. }
  977. void draw() {
  978. paint();
  979. finish();
  980. }
  981. void outline() {
  982. GD.Begin(LINE_STRIP);
  983. perim();
  984. }
  985. };
  986. #if SDCARD
  987. class Streamer {
  988. public:
  989. void begin(const char *rawsamples,
  990. uint16_t freq = 44100,
  991. byte format = ADPCM_SAMPLES,
  992. uint32_t _base = (0x40000UL - 8192), uint16_t size = 8192) {
  993. GD.__end();
  994. r.openfile(rawsamples);
  995. GD.resume();
  996. base = _base;
  997. mask = size - 1;
  998. wp = 0;
  999. for (byte i = 10; i; i--)
  1000. feed();
  1001. GD.sample(base, size, freq, format, 1);
  1002. }
  1003. int feed() {
  1004. uint16_t rp = GD.rd32(REG_PLAYBACK_READPTR) - base;
  1005. uint16_t freespace = mask & ((rp - 1) - wp);
  1006. if (freespace >= 512) {
  1007. // REPORT(base);
  1008. // REPORT(rp);
  1009. // REPORT(wp);
  1010. // REPORT(freespace);
  1011. // Serial.println();
  1012. byte buf[512];
  1013. // uint16_t n = min(512, r.size - r.offset);
  1014. // n = (n + 3) & ~3; // force 32-bit alignment
  1015. GD.__end();
  1016. r.readsector(buf);
  1017. GD.resume();
  1018. GD.cmd_memwrite(base + wp, 512);
  1019. GD.copyram(buf, 512);
  1020. wp = (wp + 512) & mask;
  1021. }
  1022. return r.offset < r.size;
  1023. }
  1024. void progress(uint16_t &val, uint16_t &range) {
  1025. uint32_t m = r.size;
  1026. uint32_t p = min(r.offset, m);
  1027. while (m > 0x10000) {
  1028. m >>= 1;
  1029. p >>= 1;
  1030. }
  1031. val = p;
  1032. range = m;
  1033. }
  1034. private:
  1035. Reader r;
  1036. uint32_t base;
  1037. uint16_t mask;
  1038. uint16_t wp;
  1039. };
  1040. #else
  1041. class Streamer {
  1042. public:
  1043. void begin(const char *rawsamples,
  1044. uint16_t freq = 44100,
  1045. byte format = ADPCM_SAMPLES,
  1046. uint32_t _base = (0x40000UL - 4096), uint16_t size = 4096) {}
  1047. int feed() {}
  1048. void progress(uint16_t &val, uint16_t &range) {}
  1049. };
  1050. #endif
  1051. /*
  1052. * PROGMEM declarations are currently not supported by the ESP8266
  1053. * comppiler. So redefine PROGMEM to nothing.
  1054. */
  1055. #if defined(ESP8266)
  1056. #undef PROGMEM
  1057. #define PROGMEM
  1058. #endif
  1059. #endif