Library(Beta) for Gameduino 2
GD2.cpp
- Committer:
- aluqard
- Date:
- 2014-04-11
- Revision:
- 0:9c211972beb2
File content as of revision 0:9c211972beb2:
#include "stdarg.h" #include "GD2.h" #include "Utils.h" //AnalogIn accel[3] = {P0_23, P0_24, P0_25}; byte touch_transform0[] = { 0xEA, 0x81, 0x00, 0x00, 0xAE, 0xFE, 0xFF, 0xFF, 0x49, 0xCC, 0xEC, 0xFF, 0x28, 0x00, 0x00, 0x00, 0x09, 0xB3, 0xFF, 0xFF, 0x42, 0x5D, 0x18, 0x01 }; byte touch_transform1[] = { 0xAB, 0x7E, 0xFF, 0xFF, 0x0F, 0x01, 0x00, 0x00, 0x97, 0x22, 0xEE, 0x01, 0xA3, 0x00, 0x00, 0x00, 0xB3, 0x4B, 0x00, 0x00, 0xE9, 0xC9, 0xF6, 0xFF }; GDClass::GDClass(PinName mosi, PinName miso, PinName sclk, PinName graphic_cs, PinName sdcard_cs) : GDTR(mosi, miso, sclk, graphic_cs) { _sdcard_cs = sdcard_cs; accel[0] = new AnalogIn(P0_23); accel[1] = new AnalogIn(P0_24); accel[2] = new AnalogIn(P0_25); } void GDClass::begin(uint8_t options) { GDTR.begin(); // Generate a blank screen cmd_dlstart(); Clear(); swap(); finish(); GDTR.wr(REG_PCLK_POL, 1); GDTR.wr(REG_PCLK, 5); #if PROTO == 1 GDTR.wr(REG_ROTATE, 0); GDTR.wr(REG_SWIZZLE, 3); #endif GDTR.wr(REG_GPIO_DIR, 0x83); GDTR.wr(REG_GPIO, 0x80); for (int i = 0; i < sizeof(touch_transform0); i++) { if(GDTR.rd(REG_ROTATE) == 0) GDTR.wr(REG_TOUCH_TRANSFORM_A + i, touch_transform0[i]); else GDTR.wr(REG_TOUCH_TRANSFORM_A + i, touch_transform1[i]); } if (options & GD_CALIBRATE) { #if CALIBRATION self_calibrate(); for (int i = 0; i < 24; i++) std::printf("0x%02X, ", GDTR.rd(REG_TOUCH_TRANSFORM_A + i)); /* if (EEPROM.read(0) != 0x7c) { self_calibrate(); for (int i = 0; i < 24; i++) DEBUGOUT(GDTR.rd(REG_TOUCH_TRANSFORM_A + i), HEX); for (int i = 0; i < 24; i++) EEPROM.write(1 + i, GDTR.rd(REG_TOUCH_TRANSFORM_A + i)); EEPROM.write(0, 0x7c); // is written! } else { for (int i = 0; i < 24; i++) GDTR.wr(REG_TOUCH_TRANSFORM_A + i, EEPROM.read(1 + i)); } */ #endif } GDTR.wr16(REG_TOUCH_RZTHRESH, 1200); lfsr = 0x5555; lcg = 0; SD = new sdcard(GDTR.SPI(), _sdcard_cs); #if STORAGE if (options & GD_STORAGE) { storage(); } #endif if (options & GD_TRIM) { tune(); DEBUGOUT("tune()\r\n"); } } void GDClass::flush(void) { GDTR.flush(); } void GDClass::swap(void) { Display(); cmd_swap(); cmd_loadidentity(); cmd_dlstart(); GDTR.flush(); } uint32_t GDClass::measure_freq(void) { unsigned long t0 = GDTR.rd32(REG_CLOCK); delayMicroseconds(15625); unsigned long t1 = GDTR.rd32(REG_CLOCK); return (t1 - t0) << 6; } void GDClass::tune(void) { uint32_t f; for (byte i = 0; (i < 31) && ((f = measure_freq()) < LOW_FREQ_BOUND); i++) GDTR.wr(REG_TRIM, i); GDTR.wr32(REG_FREQUENCY, f); } void GDClass::storage(void) { GDTR.__end(); SD->begin(); GDTR.resume(); } void GDClass::self_calibrate(void) { cmd_dlstart(); Clear(); cmd_text(240, 100, 30, OPT_CENTERX, "please tap on the dot"); cmd_calibrate(); finish(); cmd_loadidentity(); cmd_dlstart(); GDTR.flush(); } void GDClass::seed(uint16_t n) { lfsr = n | 1; lcg = n ^ 0x7921; } uint16_t GDClass::random() { lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xB400u); lcg = (lcg * 47) + 60497; return (lcg ^ lfsr); } uint16_t GDClass::random(uint16_t n) { return GDClass::random() % n; } // >>> [int(65535*math.sin(math.pi * 2 * i / 1024)) for i in range(257)] static PROGMEM int sintab[257] = { 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 }; int16_t GDClass::rsin(int16_t r, uint16_t th) { th >>= 6; // angle 0-123 // return int(r * sin((2 * M_PI) * th / 1024.)); int th4 = th & 511; if (th4 & 256) th4 = 512 - th4; // 256->256 257->255, etc uint16_t s = pgm_read_word_near(sintab + th4); int16_t p = ((uint32_t)s * r) >> 16; if (th & 512) p = -p; return p; } int16_t GDClass::rcos(int16_t r, uint16_t th) { return rsin(r, th + 0x4000); } void GDClass::polar(int &x, int &y, int16_t r, uint16_t th) { x = (int)(-rsin(r, th)); y = (int)( rcos(r, th)); } // >>> [int(round(1024 * math.atan(i / 256.) / math.pi)) for i in range(256)] static PROGMEM unsigned char atan8[] = { 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 }; uint16_t GDClass::atan2(int16_t y, int16_t x) { uint16_t a; uint16_t xx = 0; if ((x <= 0) ^ (y > 0)) { int16_t t; t = x; x = y; y = t; xx ^= 0x4000; } if (x <= 0) { x = -x; } else { xx ^= 0x8000; } y = abs(y); if (x > y) { int16_t t; t = x; x = y; y = t; xx ^= 0x3fff; } while ((x | y) & 0xff80) { x >>= 1; y >>= 1; } if (y == 0) { a = 0; } else if (x == y) { a = 0x2000; } else { // assert(x <= y); int r = ((x << 8) / y); // assert(0 <= r); // assert(r < 256); a = pgm_read_byte(atan8 + r) << 5; } a ^= xx; return a; } void GDClass::align(byte n) { while ((n++) & 3) GDTR.cmdbyte(0); } void GDClass::cH(uint16_t v) { GDTR.cmdbyte(v & 0xff); GDTR.cmdbyte((v >> 8) & 0xff); } void GDClass::ch(int16_t v) { cH((uint16_t)v); } void GDClass::cI(uint32_t v) { GDTR.cmd32(v); } void GDClass::cFFFFFF(byte v) { union { uint32_t c; uint8_t b[4]; }; b[0] = v; b[1] = 0xff; b[2] = 0xff; b[3] = 0xff; GDTR.cmd32(c); } void GDClass::ci(int32_t v) { cI((uint32_t) v); } void GDClass::cs(const char *s) { while (*s) { char c = *s++; GDTR.cmdbyte(c); } GDTR.cmdbyte(0); } void GDClass::copy(const unsigned char *src, int count) { byte a = count & 3; while (count--) { GDTR.cmdbyte(pgm_read_byte_near(src)); src++; } align(a); } void GDClass::copyram(byte *src, int count) { byte a = count & 3; GDTR.cmd_n(src, count); align(a); } void GDClass::AlphaFunc(byte func, byte ref) { cI((9UL << 24) | ((func & 7L) << 8) | ((ref & 255L) << 0)); } void GDClass::Begin(byte prim) { cI((31UL << 24) | prim); } void GDClass::BitmapHandle(byte handle) { cI((5UL << 24) | handle); } void GDClass::BitmapLayout(byte format, uint16_t linestride, uint16_t height) { // cI((7UL << 24) | ((format & 31L) << 19) | ((linestride & 1023L) << 9) | ((height & 511L) << 0)); union { uint32_t c; uint8_t b[4]; }; b[0] = height; b[1] = (1 & (height >> 8)) | (linestride << 1); b[2] = (7 & (linestride >> 7)) | (format << 3); b[3] = 7; cI(c); } void GDClass::BitmapSize(byte filter, byte wrapx, byte wrapy, uint16_t width, uint16_t height) { byte fxy = (filter << 2) | (wrapx << 1) | (wrapy); // cI((8UL << 24) | ((uint32_t)fxy << 18) | ((width & 511L) << 9) | ((height & 511L) << 0)); union { uint32_t c; uint8_t b[4]; }; b[0] = height; b[1] = (1 & (height >> 8)) | (width << 1); b[2] = (3 & (width >> 7)) | (fxy << 2); b[3] = 8; cI(c); } void GDClass::BitmapSource(uint32_t addr) { cI((1UL << 24) | ((addr & 1048575L) << 0)); } void GDClass::BitmapTransformA(int32_t a) { cI((21UL << 24) | ((a & 131071L) << 0)); } void GDClass::BitmapTransformB(int32_t b) { cI((22UL << 24) | ((b & 131071L) << 0)); } void GDClass::BitmapTransformC(int32_t c) { cI((23UL << 24) | ((c & 16777215L) << 0)); } void GDClass::BitmapTransformD(int32_t d) { cI((24UL << 24) | ((d & 131071L) << 0)); } void GDClass::BitmapTransformE(int32_t e) { cI((25UL << 24) | ((e & 131071L) << 0)); } void GDClass::BitmapTransformF(int32_t f) { cI((26UL << 24) | ((f & 16777215L) << 0)); } void GDClass::BlendFunc(byte src, byte dst) { cI((11UL << 24) | ((src & 7L) << 3) | ((dst & 7L) << 0)); } void GDClass::Call(uint16_t dest) { cI((29UL << 24) | ((dest & 2047L) << 0)); } void GDClass::Cell(byte cell) { cI((6UL << 24) | ((cell & 127L) << 0)); } void GDClass::ClearColorA(byte alpha) { cI((15UL << 24) | ((alpha & 255L) << 0)); } void GDClass::ClearColorRGB(byte red, byte green, byte blue) { cI((2UL << 24) | ((red & 255L) << 16) | ((green & 255L) << 8) | ((blue & 255L) << 0)); } void GDClass::ClearColorRGB(uint32_t rgb) { cI((2UL << 24) | (rgb & 0xffffffL)); } void GDClass::Clear(byte c, byte s, byte t) { byte m = (c << 2) | (s << 1) | t; cI((38UL << 24) | m); } void GDClass::Clear(void) { cI((38UL << 24) | 7); } void GDClass::ClearStencil(byte s) { cI((17UL << 24) | ((s & 255L) << 0)); } void GDClass::ClearTag(byte s) { cI((18UL << 24) | ((s & 255L) << 0)); } void GDClass::ColorA(byte alpha) { cI((16UL << 24) | ((alpha & 255L) << 0)); } void GDClass::ColorMask(byte r, byte g, byte b, byte a) { cI((32UL << 24) | ((r & 1L) << 3) | ((g & 1L) << 2) | ((b & 1L) << 1) | ((a & 1L) << 0)); } void GDClass::ColorRGB(byte red, byte green, byte blue) { // cI((4UL << 24) | ((red & 255L) << 16) | ((green & 255L) << 8) | ((blue & 255L) << 0)); union { uint32_t c; uint8_t b[4]; }; b[0] = blue; b[1] = green; b[2] = red; b[3] = 4; cI(c); } void GDClass::ColorRGB(uint32_t rgb) { cI((4UL << 24) | (rgb & 0xffffffL)); } void GDClass::Display(void) { cI((0UL << 24)); } void GDClass::End(void) { cI((33UL << 24)); } void GDClass::Jump(uint16_t dest) { cI((30UL << 24) | ((dest & 2047L) << 0)); } void GDClass::LineWidth(uint16_t width) { cI((14UL << 24) | ((width & 4095L) << 0)); } void GDClass::Macro(byte m) { cI((37UL << 24) | ((m & 1L) << 0)); } void GDClass::PointSize(uint16_t size) { cI((13UL << 24) | ((size & 8191L) << 0)); } void GDClass::RestoreContext(void) { cI((35UL << 24)); } void GDClass::Return(void) { cI((36UL << 24)); } void GDClass::SaveContext(void) { cI((34UL << 24)); } void GDClass::ScissorSize(uint16_t width, uint16_t height) { cI((28UL << 24) | ((width & 1023L) << 10) | ((height & 1023L) << 0)); } void GDClass::ScissorXY(uint16_t x, uint16_t y) { cI((27UL << 24) | ((x & 511L) << 9) | ((y & 511L) << 0)); } void GDClass::StencilFunc(byte func, byte ref, byte mask) { cI((10UL << 24) | ((func & 7L) << 16) | ((ref & 255L) << 8) | ((mask & 255L) << 0)); } void GDClass::StencilMask(byte mask) { cI((19UL << 24) | ((mask & 255L) << 0)); } void GDClass::StencilOp(byte sfail, byte spass) { cI((12UL << 24) | ((sfail & 7L) << 3) | ((spass & 7L) << 0)); } void GDClass::TagMask(byte mask) { cI((20UL << 24) | ((mask & 1L) << 0)); } void GDClass::Tag(byte s) { cI((3UL << 24) | ((s & 255L) << 0)); } void GDClass::Vertex2f(int16_t x, int16_t y) { // x = int(16 * x); // y = int(16 * y); cI((1UL << 30) | ((x & 32767L) << 15) | ((y & 32767L) << 0)); } void GDClass::Vertex2ii(uint16_t x, uint16_t y, byte handle, byte cell) { // cI((2UL << 30) | ((x & 511L) << 21) | ((y & 511L) << 12) | ((handle & 31L) << 7) | ((cell & 127L) << 0)); union { uint32_t c; uint8_t b[4]; }; b[0] = cell | ((handle & 1) << 7); b[1] = (handle >> 1) | (y << 4); b[2] = (y >> 4) | (x << 5); b[3] = (2 << 6) | (x >> 3); cI(c); } void GDClass::fmtcmd(const char *fmt, ...) { va_list ap; va_start(ap, fmt); byte sz = 0; // Only the low 2 bits matter const char *s; while (*fmt) switch (*fmt++) { case 'i': case 'I': cI(va_arg(ap, uint32_t)); break; case 'h': case 'H': cH(va_arg(ap, unsigned int)); sz += 2; break; case 's': s = va_arg(ap, const char*); cs(s); sz += strlen(s) + 1; break; } align(sz); } void GDClass::cmd_append(uint32_t ptr, uint32_t num) { cFFFFFF(0x1e); cI(ptr); cI(num); } void GDClass::cmd_bgcolor(uint32_t c) { fmtcmd("II", 0xffffff09UL, c); } void GDClass::cmd_button(int16_t x, int16_t y, uint16_t w, uint16_t h, byte font, uint16_t options, const char *s) { fmtcmd("IhhhhhHs", 0xffffff0dUL, x, y, w, h, font, options, s); } void GDClass::cmd_calibrate(void) { cFFFFFF(0x15); cFFFFFF(0xff); } 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) { fmtcmd("IhhhHHHHH", 0xffffff14UL, x, y, r, options, h, m, s, ms); } void GDClass::cmd_coldstart(void) { cFFFFFF(0x32); } void GDClass::cmd_dial(int16_t x, int16_t y, int16_t r, uint16_t options, uint16_t val) { fmtcmd("IhhhHH", 0xffffff2dUL, x, y, r, options, val); } void GDClass::cmd_dlstart(void) { cFFFFFF(0x00); } void GDClass::cmd_fgcolor(uint32_t c) { fmtcmd("II", 0xffffff0aUL, c); } 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) { fmtcmd("IhhhHHHHH", 0xffffff13UL, x, y, r, options, major, minor, val, range); } void GDClass::cmd_getmatrix(void) { fmtcmd("Iiiiiii", 0xffffff33UL, 0, 0, 0, 0, 0, 0); } void GDClass::cmd_getprops(uint32_t &ptr, uint32_t &w, uint32_t &h) { cFFFFFF(0x25); ptr = GDTR.getwp(); cI(0); w = GDTR.getwp(); cI(0); h = GDTR.getwp(); cI(0); } void GDClass::cmd_getptr(void) { fmtcmd("II", 0xffffff23UL, 0); } void GDClass::cmd_gradcolor(uint32_t c) { fmtcmd("II", 0xffffff34UL, c); } void GDClass::cmd_gradient(int16_t x0, int16_t y0, uint32_t rgb0, int16_t x1, int16_t y1, uint32_t rgb1) { fmtcmd("IhhIhhI", 0xffffff0bUL, x0, y0, rgb0, x1, y1, rgb1); } void GDClass::cmd_inflate(uint32_t ptr) { cFFFFFF(0x22); cI(ptr); } void GDClass::cmd_interrupt(uint32_t ms) { fmtcmd("II", 0xffffff02UL, ms); } void GDClass::cmd_keys(int16_t x, int16_t y, int16_t w, int16_t h, byte font, uint16_t options, const char*s) { fmtcmd("IhhhhhHs", 0xffffff0eUL, x, y, w, h, font, options, s); } void GDClass::cmd_loadidentity(void) { cFFFFFF(0x26); } void GDClass::cmd_loadimage(uint32_t ptr, int32_t options) { fmtcmd("III", 0xffffff24UL, ptr, options); } void GDClass::cmd_memcpy(uint32_t dest, uint32_t src, uint32_t num) { fmtcmd("IIII", 0xffffff1dUL, dest, src, num); } void GDClass::cmd_memset(uint32_t ptr, byte value, uint32_t num) { cFFFFFF(0x1b); cI(ptr); cI((uint32_t)value); cI(num); } uint32_t GDClass::cmd_memcrc(uint32_t ptr, uint32_t num) { cFFFFFF(0x18); cI(ptr); cI(num); uint32_t r = GDTR.getwp(); cI(0xFFFFFFFF); return r; } void GDClass::cmd_memwrite(uint32_t ptr, uint32_t num) { fmtcmd("III", 0xffffff1aUL, ptr, num); } void GDClass::cmd_regwrite(uint32_t ptr, uint32_t val) { cFFFFFF(0x1a); cI(ptr); cI(4UL); cI(val); } void GDClass::cmd_number(int16_t x, int16_t y, byte font, uint16_t options, uint32_t n) { // fmtcmd("IhhhHi", 0xffffff2eUL, x, y, font, options, n); cFFFFFF(0x2e); ch(x); ch(y); ch(font); cH(options); ci(n); } 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) { fmtcmd("IhhhhHHH", 0xffffff0fUL, x, y, w, h, options, val, range); } void GDClass::cmd_regread(uint32_t ptr) { fmtcmd("III", 0xffffff19UL, ptr, 0); } void GDClass::cmd_rotate(int32_t a) { cFFFFFF(0x29); ci(a); } void GDClass::cmd_scale(int32_t sx, int32_t sy) { cFFFFFF(0x28); ci(sx); ci(sy); } void GDClass::cmd_screensaver(void) { cFFFFFF(0x2f); } 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) { fmtcmd("IhhhhHHHH", 0xffffff11UL, x, y, w, h, options, val, size, range); } void GDClass::cmd_setfont(byte font, uint32_t ptr) { fmtcmd("III", 0xffffff2bUL, font, ptr); } void GDClass::cmd_setmatrix(void) { cFFFFFF(0x2a); } void GDClass::cmd_sketch(int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t ptr, uint16_t format) { cFFFFFF(0x30); ch(x); ch(y); cH(w); cH(h); cI(ptr); cI(format); } 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) { fmtcmd("IhhhhHHH", 0xffffff10UL, x, y, w, h, options, val, range); } void GDClass::cmd_snapshot(uint32_t ptr) { fmtcmd("II", 0xffffff1fUL, ptr); } void GDClass::cmd_spinner(int16_t x, int16_t y, byte style, byte scale) { cFFFFFF(0x16); ch(x); ch(y); cH(style); cH(scale); } void GDClass::cmd_stop(void) { cFFFFFF(0x17); } void GDClass::cmd_swap(void) { cFFFFFF(0x01); } void GDClass::cmd_text(int16_t x, int16_t y, byte font, uint16_t options, const char *s) { // fmtcmd("IhhhHs", 0xffffff0cUL, x, y, font, options, s); cFFFFFF(0x0c); ch(x); ch(y); ch(font); cH(options); cs(s); align(strlen(s) + 1); } void GDClass::cmd_toggle(int16_t x, int16_t y, int16_t w, byte font, uint16_t options, uint16_t state, const char *s) { fmtcmd("IhhhhHHs", 0xffffff12UL, x, y, w, font, options, state, s); } void GDClass::cmd_track(int16_t x, int16_t y, uint16_t w, uint16_t h, byte tag) { fmtcmd("Ihhhhh", 0xffffff2cUL, x, y, w, h, tag); } void GDClass::cmd_translate(int32_t tx, int32_t ty) { cFFFFFF(0x27); ci(tx); ci(ty); } byte GDClass::rd(uint32_t addr) { return GDTR.rd(addr); } void GDClass::wr(uint32_t addr, uint8_t v) { GDTR.wr(addr, v); } uint16_t GDClass::rd16(uint32_t addr) { return GDTR.rd16(addr); } void GDClass::wr16(uint32_t addr, uint16_t v) { GDTR.wr16(addr, v); } uint32_t GDClass::rd32(uint32_t addr) { return GDTR.rd32(addr); } void GDClass::wr32(uint32_t addr, uint32_t v) { GDTR.wr32(addr, v); } void GDClass::wr_n(uint32_t addr, byte *src, uint32_t n) { GDTR.wr_n(addr, src, n); } void GDClass::cmdbyte(uint8_t b) { GDTR.cmdbyte(b); } void GDClass::cmd32(uint32_t b) { GDTR.cmd32(b); } void GDClass::finish(void) { GDTR.finish(); } void GDClass::get_accel(int &x, int &y, int &z) { static float f[3]; for (byte i = 0; i < 3; i++) { float a = accel[i]->read() * 1000; // Serial.print(a, DEC); Serial.print(" "); int s = (-160 * ((int)(a - 376)) >> 6); f[i] = (((int)(3 * f[i])) >> 2) + (s >> 2); } // DEBUGOUT(); x = f[2]; y = f[1]; z = f[0]; } void GDClass::get_inputs(void) { GDTR.finish(); byte *bi = (byte*)&inputs; GDTR.rd_n(bi, REG_TRACKER, 4); GDTR.rd_n(bi + 4, REG_TOUCH_RZ, 13); GDTR.rd_n(bi + 17, REG_TAG, 1); #if DUMP_INPUTS for (size_t i = 0; i < sizeof(inputs); i++) { DEBUGOUT("%x", bi[i]); DEBUGOUT(" "); } #endif } void GDClass::bulkrd(uint32_t a) { GDTR.bulk(a); } void GDClass::resume(void) { GDTR.resume(); } void GDClass::__end(void) { GDTR.__end(); } void GDClass::play(uint8_t instrument, uint8_t note) { wr16(REG_SOUND, (note << 8) | instrument); wr(REG_PLAY, 1); } void GDClass::sample(uint32_t start, uint32_t len, uint16_t freq, uint16_t format, int loop) { wr32(REG_PLAYBACK_START, start); wr32(REG_PLAYBACK_LENGTH, len); wr16(REG_PLAYBACK_FREQ, freq); wr(REG_PLAYBACK_FORMAT, format); wr(REG_PLAYBACK_LOOP, loop); wr(REG_PLAYBACK_PLAY, 1); } void GDClass::reset() { GDTR.__end(); GDTR.wr(REG_CPURESET, 1); GDTR.wr(REG_CPURESET, 0); GDTR.resume(); } // Load named file from storage // returns 0 on failure (e.g. file not found), 1 on success byte GDClass::load(const char *filename, void (*progress)(long, long)) { #if defined(RASPBERRY_PI) FILE *f = fopen(filename, "rb"); if (!f) { perror(filename); exit(1); } byte buf[512]; int n; while ((n = fread(buf, 1, 512, f)) > 0) { GDTR.cmd_n(buf, (n + 3) & ~3); } fclose(f); return 1; #else __end(); Reader* r = new Reader(GDTR.SPI(), SD); if (r->openfile(filename)) { byte buf[512]; while (r->offset < r->size) { uint16_t n = min(512, r->size - r->offset); n = (n + 3) & ~3; // force 32-bit alignment r->readsector(buf); resume(); if (progress) (*progress)(r->offset, r->size); copyram(buf, n); GDTR.stop(); } resume(); delete r; return 1; } resume(); delete r; return 0; #endif } // Generated by mk_bsod.py. Blue screen with 'ERROR' text static const unsigned char __bsod[31] = { 0, 255, 255, 255, 255, 0, 0, 2, 7, 0, 0, 38, 12, 255, 255, 255, 240, 0, 120, 0, 28, 0, 0, 6, 69, 82, 82, 79, 82, 33, 0 }; // "Cannot open file" text static const unsigned char __bsod_badfile[31] = { 12, 255, 255, 255, 240, 0, 148, 0, 28, 0, 0, 6, 67, 97, 110, 110, 111, 116, 32, 111, 112, 101, 110, 32, 102, 105, 108, 101, 0, 0, 0 }; void GDClass::safeload(const char *filename) { if (!load(filename)) { copy(__bsod, sizeof(__bsod)); copy(__bsod_badfile, sizeof(__bsod_badfile)); cmd_text(240, 176, 28, OPT_CENTER, filename); swap(); for (;;) ; } }