From 8a856686f1022cc9da05554f8206b1bdc9aada26 Mon Sep 17 00:00:00 2001 From: Tomas Lubkowitz Date: Wed, 3 Jan 2018 22:19:27 +0100 Subject: [PATCH 1/6] Added Sino:bit board, including HT1632,AdaFruit GFX and Dave Astels Sinobit Library --- boards.txt | 47 + docs/package_nRF5_boards_index.json | 46 + variants/Sinobit/Adafruit_GFX.cpp | 1348 ++++++++++++++++++++++++++ variants/Sinobit/Adafruit_GFX.h | 211 ++++ variants/Sinobit/Adafruit_HT1632.cpp | 282 ++++++ variants/Sinobit/Adafruit_HT1632.h | 84 ++ variants/Sinobit/README.md | 3 + variants/Sinobit/gfxfont.h | 24 + variants/Sinobit/glcdfont.c | 276 ++++++ variants/Sinobit/license.txt | 24 + variants/Sinobit/pins_arduino.h | 17 + variants/Sinobit/scroll_support.cpp | 33 + variants/Sinobit/scroll_support.h | 82 ++ variants/Sinobit/sinobit.cpp | 252 +++++ variants/Sinobit/sinobit.h | 76 ++ variants/Sinobit/variant.cpp | 68 ++ variants/Sinobit/variant.h | 104 ++ 17 files changed, 2977 insertions(+) create mode 100644 variants/Sinobit/Adafruit_GFX.cpp create mode 100644 variants/Sinobit/Adafruit_GFX.h create mode 100644 variants/Sinobit/Adafruit_HT1632.cpp create mode 100644 variants/Sinobit/Adafruit_HT1632.h create mode 100644 variants/Sinobit/README.md create mode 100644 variants/Sinobit/gfxfont.h create mode 100644 variants/Sinobit/glcdfont.c create mode 100644 variants/Sinobit/license.txt create mode 100644 variants/Sinobit/pins_arduino.h create mode 100644 variants/Sinobit/scroll_support.cpp create mode 100644 variants/Sinobit/scroll_support.h create mode 100644 variants/Sinobit/sinobit.cpp create mode 100644 variants/Sinobit/sinobit.h create mode 100644 variants/Sinobit/variant.cpp create mode 100644 variants/Sinobit/variant.h diff --git a/boards.txt b/boards.txt index a185129d..6ce4a881 100644 --- a/boards.txt +++ b/boards.txt @@ -818,3 +818,50 @@ ng_beacon.menu.softdevice.s130.softdeviceversion=2.0.1 ng_beacon.menu.softdevice.s130.upload.maximum_size=151552 ng_beacon.menu.softdevice.s130.build.extra_flags=-DNRF51 -DS130 -DNRF51_S130 ng_beacon.menu.softdevice.s130.build.ldscript=armgcc_s130_nrf51822_xxaa.ld + + +Sinobit.name=Sino:bit + +Sinobit.vid.0=0x0d28 +Sinobit.pid.0=0x0204 + +Sinobit.upload.tool=sandeepmistry:openocd +Sinobit.upload.protocol=cmsis-dap +Sinobit.upload.target=nrf51 +Sinobit.upload.maximum_size=262144 +Sinobit.upload.setup_command=transport select swd; +Sinobit.upload.use_1200bps_touch=false +Sinobit.upload.wait_for_upload_port=false +Sinobit.upload.native_usb=false + +Sinobit.bootloader.tool=sandeepmistry:openocd + +Sinobit.build.mcu=cortex-m0 +Sinobit.build.f_cpu=16000000 +Sinobit.build.board=BBC_MICROBIT +Sinobit.build.core=nRF5 +Sinobit.build.variant=Sinobit +Sinobit.build.variant_system_lib= +Sinobit.build.extra_flags=-DNRF51 +Sinobit.build.float_flags= +Sinobit.build.ldscript=nrf51_xxaa.ld + +Sinobit.build.lfclk_flags=-DUSE_LFRC + +Sinobit.menu.softdevice.none=None +Sinobit.menu.softdevice.none.softdevice=none +Sinobit.menu.softdevice.none.softdeviceversion= + +Sinobit.menu.softdevice.s110=S110 +Sinobit.menu.softdevice.s110.softdevice=s110 +Sinobit.menu.softdevice.s110.softdeviceversion=8.0.0 +Sinobit.menu.softdevice.s110.upload.maximum_size=151552 +Sinobit.menu.softdevice.s110.build.extra_flags=-DNRF51 -DS110 -DNRF51_S110 +Sinobit.menu.softdevice.s110.build.ldscript=armgcc_s110_nrf51822_xxaa.ld + +Sinobit.menu.softdevice.s130=S130 +Sinobit.menu.softdevice.s130.softdevice=s130 +Sinobit.menu.softdevice.s130.softdeviceversion=2.0.1 +Sinobit.menu.softdevice.s130.upload.maximum_size=151552 +Sinobit.menu.softdevice.s130.build.extra_flags=-DNRF51 -DS130 -DNRF51_S130 +Sinobit.menu.softdevice.s130.build.ldscript=armgcc_s130_nrf51822_xxaa.ld diff --git a/docs/package_nRF5_boards_index.json b/docs/package_nRF5_boards_index.json index bb97deac..c02d6005 100644 --- a/docs/package_nRF5_boards_index.json +++ b/docs/package_nRF5_boards_index.json @@ -157,6 +157,52 @@ "version": "0.10.0-dev.nrf5" } ] + }, + { + "name": "Nordic Semiconductor nRF5 Boards", + "architecture": "nRF5", + "version": "0.5.0", + "category": "Contributed", + "help": { + "online": "https://github.com/sandeepmistry/arduino-nRF5/issues" + }, + "url": "https://github.com/sandeepmistry/arduino-nRF5/archive/0.4.0.tar.gz", + "archiveFileName": "arduino-nRF52-0.4.0.tar.gz", + "checksum": "MD5:E82DA39642AB48492A9FEDE8159871F5", + "size": "573440", + "boards": [ + {"name": "BBC micro:bit"}, + {"name": "Bluz DK"}, + {"name": "Electronut labs bluey"}, + {"name": "Generic nRF51822"}, + {"name": "Generic nRF52823"}, + {"name": "OSHChip"}, + {"name": "ng-beacon"}, + {"name": "nRF51 Dongle"}, + {"name": "nRF51822 Development Kit"}, + {"name": "nRF52 DK"}, + {"name": "Nordic Beacon Kit"}, + {"name": "RedBear BLE Nano 2"}, + {"name": "RedBear Blend 2"}, + {"name": "RedBearLab BLE Nano"}, + {"name": "RedBearLab nRF51822"}, + {"name": "Taida Century nRF52 mini board"}, + {"name": "TinyBLE"}, + {"name": "Waveshare BLE400"}, + {"name": "Sino:bit"} + ], + "toolsDependencies": [ + { + "packager": "sandeepmistry", + "name": "gcc-arm-none-eabi", + "version": "5_2-2015q4" + }, + { + "packager": "sandeepmistry", + "name": "openocd", + "version": "0.10.0-dev.nrf5" + } + ] } ], "tools":[ diff --git a/variants/Sinobit/Adafruit_GFX.cpp b/variants/Sinobit/Adafruit_GFX.cpp new file mode 100644 index 00000000..53c7ad35 --- /dev/null +++ b/variants/Sinobit/Adafruit_GFX.cpp @@ -0,0 +1,1348 @@ +/* +This is the core graphics library for all our displays, providing a common +set of graphics primitives (points, lines, circles, etc.). It needs to be +paired with a hardware-specific library for each display device we carry +(to handle the lower-level functions). + +Adafruit invests time and resources providing this open source code, please +support Adafruit & open-source hardware by purchasing products from Adafruit! + +Copyright (c) 2013 Adafruit Industries. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Adafruit_GFX.h" +#include "glcdfont.c" +#ifdef __AVR__ + #include +#elif defined(ESP8266) || defined(ESP32) + #include +#endif + +// Many (but maybe not all) non-AVR board installs define macros +// for compatibility with existing PROGMEM-reading AVR code. +// Do our own checks and defines here for good measure... + +#ifndef pgm_read_byte + #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#endif +#ifndef pgm_read_word + #define pgm_read_word(addr) (*(const unsigned short *)(addr)) +#endif +#ifndef pgm_read_dword + #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) +#endif + +// Pointers are a peculiar case...typically 16-bit on AVR boards, +// 32 bits elsewhere. Try to accommodate both... + +#if !defined(__INT_MAX__) || (__INT_MAX__ > 0xFFFF) + #define pgm_read_pointer(addr) ((void *)pgm_read_dword(addr)) +#else + #define pgm_read_pointer(addr) ((void *)pgm_read_word(addr)) +#endif + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef _swap_int16_t +#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; } +#endif + +Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h): +WIDTH(w), HEIGHT(h) +{ + _width = WIDTH; + _height = HEIGHT; + rotation = 0; + cursor_y = cursor_x = 0; + textsize = 1; + textcolor = textbgcolor = 0xFFFF; + wrap = true; + _cp437 = false; + gfxFont = NULL; +} + +// Bresenham's algorithm - thx wikpedia +void Adafruit_GFX::writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, + uint16_t color) { + int16_t steep = abs(y1 - y0) > abs(x1 - x0); + if (steep) { + _swap_int16_t(x0, y0); + _swap_int16_t(x1, y1); + } + + if (x0 > x1) { + _swap_int16_t(x0, x1); + _swap_int16_t(y0, y1); + } + + int16_t dx, dy; + dx = x1 - x0; + dy = abs(y1 - y0); + + int16_t err = dx / 2; + int16_t ystep; + + if (y0 < y1) { + ystep = 1; + } else { + ystep = -1; + } + + for (; x0<=x1; x0++) { + if (steep) { + writePixel(y0, x0, color); + } else { + writePixel(x0, y0, color); + } + err -= dy; + if (err < 0) { + y0 += ystep; + err += dx; + } + } +} + +void Adafruit_GFX::startWrite(){ + // Overwrite in subclasses if desired! +} + +void Adafruit_GFX::writePixel(int16_t x, int16_t y, uint16_t color){ + // Overwrite in subclasses if startWrite is defined! + drawPixel(x, y, color); +} + +// (x,y) is topmost point; if unsure, calling function +// should sort endpoints or call writeLine() instead +void Adafruit_GFX::writeFastVLine(int16_t x, int16_t y, + int16_t h, uint16_t color) { + // Overwrite in subclasses if startWrite is defined! + // Can be just writeLine(x, y, x, y+h-1, color); + // or writeFillRect(x, y, 1, h, color); + drawFastVLine(x, y, h, color); +} + +// (x,y) is leftmost point; if unsure, calling function +// should sort endpoints or call writeLine() instead +void Adafruit_GFX::writeFastHLine(int16_t x, int16_t y, + int16_t w, uint16_t color) { + // Overwrite in subclasses if startWrite is defined! + // Example: writeLine(x, y, x+w-1, y, color); + // or writeFillRect(x, y, w, 1, color); + drawFastHLine(x, y, w, color); +} + +void Adafruit_GFX::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, + uint16_t color) { + // Overwrite in subclasses if desired! + fillRect(x,y,w,h,color); +} + +void Adafruit_GFX::endWrite(){ + // Overwrite in subclasses if startWrite is defined! +} + +// (x,y) is topmost point; if unsure, calling function +// should sort endpoints or call drawLine() instead +void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, + int16_t h, uint16_t color) { + // Update in subclasses if desired! + startWrite(); + writeLine(x, y, x, y+h-1, color); + endWrite(); +} + +// (x,y) is leftmost point; if unsure, calling function +// should sort endpoints or call drawLine() instead +void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, + int16_t w, uint16_t color) { + // Update in subclasses if desired! + startWrite(); + writeLine(x, y, x+w-1, y, color); + endWrite(); +} + +void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, + uint16_t color) { + // Update in subclasses if desired! + startWrite(); + for (int16_t i=x; i y1) _swap_int16_t(y0, y1); + drawFastVLine(x0, y0, y1 - y0 + 1, color); + } else if(y0 == y1){ + if(x0 > x1) _swap_int16_t(x0, x1); + drawFastHLine(x0, y0, x1 - x0 + 1, color); + } else { + startWrite(); + writeLine(x0, y0, x1, y1, color); + endWrite(); + } +} + +// Draw a circle outline +void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r, + uint16_t color) { + int16_t f = 1 - r; + int16_t ddF_x = 1; + int16_t ddF_y = -2 * r; + int16_t x = 0; + int16_t y = r; + + startWrite(); + writePixel(x0 , y0+r, color); + writePixel(x0 , y0-r, color); + writePixel(x0+r, y0 , color); + writePixel(x0-r, y0 , color); + + while (x= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + + writePixel(x0 + x, y0 + y, color); + writePixel(x0 - x, y0 + y, color); + writePixel(x0 + x, y0 - y, color); + writePixel(x0 - x, y0 - y, color); + writePixel(x0 + y, y0 + x, color); + writePixel(x0 - y, y0 + x, color); + writePixel(x0 + y, y0 - x, color); + writePixel(x0 - y, y0 - x, color); + } + endWrite(); +} + +void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0, + int16_t r, uint8_t cornername, uint16_t color) { + int16_t f = 1 - r; + int16_t ddF_x = 1; + int16_t ddF_y = -2 * r; + int16_t x = 0; + int16_t y = r; + + while (x= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + if (cornername & 0x4) { + writePixel(x0 + x, y0 + y, color); + writePixel(x0 + y, y0 + x, color); + } + if (cornername & 0x2) { + writePixel(x0 + x, y0 - y, color); + writePixel(x0 + y, y0 - x, color); + } + if (cornername & 0x8) { + writePixel(x0 - y, y0 + x, color); + writePixel(x0 - x, y0 + y, color); + } + if (cornername & 0x1) { + writePixel(x0 - y, y0 - x, color); + writePixel(x0 - x, y0 - y, color); + } + } +} + +void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r, + uint16_t color) { + startWrite(); + writeFastVLine(x0, y0-r, 2*r+1, color); + fillCircleHelper(x0, y0, r, 3, 0, color); + endWrite(); +} + +// Used to do circles and roundrects +void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, + uint8_t cornername, int16_t delta, uint16_t color) { + + int16_t f = 1 - r; + int16_t ddF_x = 1; + int16_t ddF_y = -2 * r; + int16_t x = 0; + int16_t y = r; + + while (x= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + + if (cornername & 0x1) { + writeFastVLine(x0+x, y0-y, 2*y+1+delta, color); + writeFastVLine(x0+y, y0-x, 2*x+1+delta, color); + } + if (cornername & 0x2) { + writeFastVLine(x0-x, y0-y, 2*y+1+delta, color); + writeFastVLine(x0-y, y0-x, 2*x+1+delta, color); + } + } +} + +// Draw a rectangle +void Adafruit_GFX::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, + uint16_t color) { + startWrite(); + writeFastHLine(x, y, w, color); + writeFastHLine(x, y+h-1, w, color); + writeFastVLine(x, y, h, color); + writeFastVLine(x+w-1, y, h, color); + endWrite(); +} + +// Draw a rounded rectangle +void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w, + int16_t h, int16_t r, uint16_t color) { + // smarter version + startWrite(); + writeFastHLine(x+r , y , w-2*r, color); // Top + writeFastHLine(x+r , y+h-1, w-2*r, color); // Bottom + writeFastVLine(x , y+r , h-2*r, color); // Left + writeFastVLine(x+w-1, y+r , h-2*r, color); // Right + // draw four corners + drawCircleHelper(x+r , y+r , r, 1, color); + drawCircleHelper(x+w-r-1, y+r , r, 2, color); + drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color); + drawCircleHelper(x+r , y+h-r-1, r, 8, color); + endWrite(); +} + +// Fill a rounded rectangle +void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, + int16_t h, int16_t r, uint16_t color) { + // smarter version + startWrite(); + writeFillRect(x+r, y, w-2*r, h, color); + + // draw four corners + fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color); + fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color); + endWrite(); +} + +// Draw a triangle +void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0, + int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) { + drawLine(x0, y0, x1, y1, color); + drawLine(x1, y1, x2, y2, color); + drawLine(x2, y2, x0, y0, color); +} + +// Fill a triangle +void Adafruit_GFX::fillTriangle(int16_t x0, int16_t y0, + int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) { + + int16_t a, b, y, last; + + // Sort coordinates by Y order (y2 >= y1 >= y0) + if (y0 > y1) { + _swap_int16_t(y0, y1); _swap_int16_t(x0, x1); + } + if (y1 > y2) { + _swap_int16_t(y2, y1); _swap_int16_t(x2, x1); + } + if (y0 > y1) { + _swap_int16_t(y0, y1); _swap_int16_t(x0, x1); + } + + startWrite(); + if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing + a = b = x0; + if(x1 < a) a = x1; + else if(x1 > b) b = x1; + if(x2 < a) a = x2; + else if(x2 > b) b = x2; + writeFastHLine(a, y0, b-a+1, color); + endWrite(); + return; + } + + int16_t + dx01 = x1 - x0, + dy01 = y1 - y0, + dx02 = x2 - x0, + dy02 = y2 - y0, + dx12 = x2 - x1, + dy12 = y2 - y1; + int32_t + sa = 0, + sb = 0; + + // For upper part of triangle, find scanline crossings for segments + // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 + // is included here (and second loop will be skipped, avoiding a /0 + // error there), otherwise scanline y1 is skipped here and handled + // in the second loop...which also avoids a /0 error here if y0=y1 + // (flat-topped triangle). + if(y1 == y2) last = y1; // Include y1 scanline + else last = y1-1; // Skip it + + for(y=y0; y<=last; y++) { + a = x0 + sa / dy01; + b = x0 + sb / dy02; + sa += dx01; + sb += dx02; + /* longhand: + a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); + b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); + */ + if(a > b) _swap_int16_t(a,b); + writeFastHLine(a, y, b-a+1, color); + } + + // For lower part of triangle, find scanline crossings for segments + // 0-2 and 1-2. This loop is skipped if y1=y2. + sa = dx12 * (y - y1); + sb = dx02 * (y - y0); + for(; y<=y2; y++) { + a = x1 + sa / dy12; + b = x0 + sb / dy02; + sa += dx12; + sb += dx02; + /* longhand: + a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); + b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); + */ + if(a > b) _swap_int16_t(a,b); + writeFastHLine(a, y, b-a+1, color); + } + endWrite(); +} + +// BITMAP / XBITMAP / GRAYSCALE / RGB BITMAP FUNCTIONS --------------------- + +// Draw a PROGMEM-resident 1-bit image at the specified (x,y) position, +// using the specified foreground color (unset bits are transparent). +void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, + const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color) { + + int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte + uint8_t byte = 0; + + startWrite(); + for(int16_t j=0; j>= 1; + else byte = pgm_read_byte(&bitmap[j * byteWidth + i / 8]); + // Nearly identical to drawBitmap(), only the bit order + // is reversed here (left-to-right = LSB to MSB): + if(byte & 0x01) writePixel(x+i, y, color); + } + } + endWrite(); +} + +// Draw a PROGMEM-resident 8-bit image (grayscale) at the specified (x,y) +// pos. Specifically for 8-bit display devices such as IS31FL3731; +// no color reduction/expansion is performed. +void Adafruit_GFX::drawGrayscaleBitmap(int16_t x, int16_t y, + const uint8_t bitmap[], int16_t w, int16_t h) { + startWrite(); + for(int16_t j=0; j= _width) || // Clip right + (y >= _height) || // Clip bottom + ((x + 6 * size - 1) < 0) || // Clip left + ((y + 8 * size - 1) < 0)) // Clip top + return; + + if(!_cp437 && (c >= 176)) c++; // Handle 'classic' charset behavior + + startWrite(); + for(int8_t i=0; i<5; i++ ) { // Char bitmap = 5 columns + uint8_t line = pgm_read_byte(&font[c * 5 + i]); + for(int8_t j=0; j<8; j++, line >>= 1) { + if(line & 1) { + if(size == 1) + writePixel(x+i, y+j, color); + else + writeFillRect(x+i*size, y+j*size, size, size, color); + } else if(bg != color) { + if(size == 1) + writePixel(x+i, y+j, bg); + else + writeFillRect(x+i*size, y+j*size, size, size, bg); + } + } + } + if(bg != color) { // If opaque, draw vertical line for last column + if(size == 1) writeFastVLine(x+5, y, 8, bg); + else writeFillRect(x+5*size, y, size, 8*size, bg); + } + endWrite(); + + } else { // Custom font + + // Character is assumed previously filtered by write() to eliminate + // newlines, returns, non-printable characters, etc. Calling + // drawChar() directly with 'bad' characters of font may cause mayhem! + + c -= (uint8_t)pgm_read_byte(&gfxFont->first); + GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c]); + uint8_t *bitmap = (uint8_t *)pgm_read_pointer(&gfxFont->bitmap); + + uint16_t bo = pgm_read_word(&glyph->bitmapOffset); + uint8_t w = pgm_read_byte(&glyph->width), + h = pgm_read_byte(&glyph->height); + int8_t xo = pgm_read_byte(&glyph->xOffset), + yo = pgm_read_byte(&glyph->yOffset); + uint8_t xx, yy, bits = 0, bit = 0; + int16_t xo16 = 0, yo16 = 0; + + if(size > 1) { + xo16 = xo; + yo16 = yo; + } + + // Todo: Add character clipping here + + // NOTE: THERE IS NO 'BACKGROUND' COLOR OPTION ON CUSTOM FONTS. + // THIS IS ON PURPOSE AND BY DESIGN. The background color feature + // has typically been used with the 'classic' font to overwrite old + // screen contents with new data. This ONLY works because the + // characters are a uniform size; it's not a sensible thing to do with + // proportionally-spaced fonts with glyphs of varying sizes (and that + // may overlap). To replace previously-drawn text when using a custom + // font, use the getTextBounds() function to determine the smallest + // rectangle encompassing a string, erase the area with fillRect(), + // then draw new text. This WILL infortunately 'blink' the text, but + // is unavoidable. Drawing 'background' pixels will NOT fix this, + // only creates a new set of problems. Have an idea to work around + // this (a canvas object type for MCUs that can afford the RAM and + // displays supporting setAddrWindow() and pushColors()), but haven't + // implemented this yet. + + startWrite(); + for(yy=0; yy= 100 +size_t Adafruit_GFX::write(uint8_t c) { +#else +void Adafruit_GFX::write(uint8_t c) { +#endif + if(!gfxFont) { // 'Classic' built-in font + + if(c == '\n') { // Newline? + cursor_x = 0; // Reset x to zero, + cursor_y += textsize * 8; // advance y one line + } else if(c != '\r') { // Ignore carriage returns + if(wrap && ((cursor_x + textsize * 6) > _width)) { // Off right? + cursor_x = 0; // Reset x to zero, + cursor_y += textsize * 8; // advance y one line + } + drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize); + cursor_x += textsize * 6; // Advance x one char + } + + } else { // Custom font + + if(c == '\n') { + cursor_x = 0; + cursor_y += (int16_t)textsize * + (uint8_t)pgm_read_byte(&gfxFont->yAdvance); + } else if(c != '\r') { + uint8_t first = pgm_read_byte(&gfxFont->first); + if((c >= first) && (c <= (uint8_t)pgm_read_byte(&gfxFont->last))) { + GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer( + &gfxFont->glyph))[c - first]); + uint8_t w = pgm_read_byte(&glyph->width), + h = pgm_read_byte(&glyph->height); + if((w > 0) && (h > 0)) { // Is there an associated bitmap? + int16_t xo = (int8_t)pgm_read_byte(&glyph->xOffset); // sic + if(wrap && ((cursor_x + textsize * (xo + w)) > _width)) { + cursor_x = 0; + cursor_y += (int16_t)textsize * + (uint8_t)pgm_read_byte(&gfxFont->yAdvance); + } + drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize); + } + cursor_x += (uint8_t)pgm_read_byte(&glyph->xAdvance) * (int16_t)textsize; + } + } + + } +#if ARDUINO >= 100 + return 1; +#endif +} + +void Adafruit_GFX::setCursor(int16_t x, int16_t y) { + cursor_x = x; + cursor_y = y; +} + +int16_t Adafruit_GFX::getCursorX(void) const { + return cursor_x; +} + +int16_t Adafruit_GFX::getCursorY(void) const { + return cursor_y; +} + +void Adafruit_GFX::setTextSize(uint8_t s) { + textsize = (s > 0) ? s : 1; +} + +void Adafruit_GFX::setTextColor(uint16_t c) { + // For 'transparent' background, we'll set the bg + // to the same as fg instead of using a flag + textcolor = textbgcolor = c; +} + +void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) { + textcolor = c; + textbgcolor = b; +} + +void Adafruit_GFX::setTextWrap(boolean w) { + wrap = w; +} + +uint8_t Adafruit_GFX::getRotation(void) const { + return rotation; +} + +void Adafruit_GFX::setRotation(uint8_t x) { + rotation = (x & 3); + switch(rotation) { + case 0: + case 2: + _width = WIDTH; + _height = HEIGHT; + break; + case 1: + case 3: + _width = HEIGHT; + _height = WIDTH; + break; + } +} + +// Enable (or disable) Code Page 437-compatible charset. +// There was an error in glcdfont.c for the longest time -- one character +// (#176, the 'light shade' block) was missing -- this threw off the index +// of every character that followed it. But a TON of code has been written +// with the erroneous character indices. By default, the library uses the +// original 'wrong' behavior and old sketches will still work. Pass 'true' +// to this function to use correct CP437 character values in your code. +void Adafruit_GFX::cp437(boolean x) { + _cp437 = x; +} + +void Adafruit_GFX::setFont(const GFXfont *f) { + if(f) { // Font struct pointer passed in? + if(!gfxFont) { // And no current font struct? + // Switching from classic to new font behavior. + // Move cursor pos down 6 pixels so it's on baseline. + cursor_y += 6; + } + } else if(gfxFont) { // NULL passed. Current font struct defined? + // Switching from new to classic font behavior. + // Move cursor pos up 6 pixels so it's at top-left of char. + cursor_y -= 6; + } + gfxFont = (GFXfont *)f; +} + +// Broke this out as it's used by both the PROGMEM- and RAM-resident +// getTextBounds() functions. +void Adafruit_GFX::charBounds(char c, int16_t *x, int16_t *y, + int16_t *minx, int16_t *miny, int16_t *maxx, int16_t *maxy) { + + if(gfxFont) { + + if(c == '\n') { // Newline? + *x = 0; // Reset x to zero, advance y by one line + *y += textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance); + } else if(c != '\r') { // Not a carriage return; is normal char + uint8_t first = pgm_read_byte(&gfxFont->first), + last = pgm_read_byte(&gfxFont->last); + if((c >= first) && (c <= last)) { // Char present in this font? + GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer( + &gfxFont->glyph))[c - first]); + uint8_t gw = pgm_read_byte(&glyph->width), + gh = pgm_read_byte(&glyph->height), + xa = pgm_read_byte(&glyph->xAdvance); + int8_t xo = pgm_read_byte(&glyph->xOffset), + yo = pgm_read_byte(&glyph->yOffset); + if(wrap && ((*x+(((int16_t)xo+gw)*textsize)) > _width)) { + *x = 0; // Reset x to zero, advance y by one line + *y += textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance); + } + int16_t ts = (int16_t)textsize, + x1 = *x + xo * ts, + y1 = *y + yo * ts, + x2 = x1 + gw * ts - 1, + y2 = y1 + gh * ts - 1; + if(x1 < *minx) *minx = x1; + if(y1 < *miny) *miny = y1; + if(x2 > *maxx) *maxx = x2; + if(y2 > *maxy) *maxy = y2; + *x += xa * ts; + } + } + + } else { // Default font + + if(c == '\n') { // Newline? + *x = 0; // Reset x to zero, + *y += textsize * 8; // advance y one line + // min/max x/y unchaged -- that waits for next 'normal' character + } else if(c != '\r') { // Normal char; ignore carriage returns + if(wrap && ((*x + textsize * 6) > _width)) { // Off right? + *x = 0; // Reset x to zero, + *y += textsize * 8; // advance y one line + } + int x2 = *x + textsize * 6 - 1, // Lower-right pixel of char + y2 = *y + textsize * 8 - 1; + if(x2 > *maxx) *maxx = x2; // Track max x, y + if(y2 > *maxy) *maxy = y2; + if(*x < *minx) *minx = *x; // Track min x, y + if(*y < *miny) *miny = *y; + *x += textsize * 6; // Advance x one char + } + } +} + +// Pass string and a cursor position, returns UL corner and W,H. +void Adafruit_GFX::getTextBounds(char *str, int16_t x, int16_t y, + int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h) { + uint8_t c; // Current character + + *x1 = x; + *y1 = y; + *w = *h = 0; + + int16_t minx = _width, miny = _height, maxx = -1, maxy = -1; + + while((c = *str++)) + charBounds(c, &x, &y, &minx, &miny, &maxx, &maxy); + + if(maxx >= minx) { + *x1 = minx; + *w = maxx - minx + 1; + } + if(maxy >= miny) { + *y1 = miny; + *h = maxy - miny + 1; + } +} + +// Same as above, but for PROGMEM strings +void Adafruit_GFX::getTextBounds(const __FlashStringHelper *str, + int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h) { + uint8_t *s = (uint8_t *)str, c; + + *x1 = x; + *y1 = y; + *w = *h = 0; + + int16_t minx = _width, miny = _height, maxx = -1, maxy = -1; + + while((c = pgm_read_byte(s++))) + charBounds(c, &x, &y, &minx, &miny, &maxx, &maxy); + + if(maxx >= minx) { + *x1 = minx; + *w = maxx - minx + 1; + } + if(maxy >= miny) { + *y1 = miny; + *h = maxy - miny + 1; + } +} + +// Return the size of the display (per current rotation) +int16_t Adafruit_GFX::width(void) const { + return _width; +} + +int16_t Adafruit_GFX::height(void) const { + return _height; +} + +void Adafruit_GFX::invertDisplay(boolean i) { + // Do nothing, must be subclassed if supported by hardware +} + +/***************************************************************************/ +// code for the GFX button UI element + +Adafruit_GFX_Button::Adafruit_GFX_Button(void) { + _gfx = 0; +} + +// Classic initButton() function: pass center & size +void Adafruit_GFX_Button::initButton( + Adafruit_GFX *gfx, int16_t x, int16_t y, uint16_t w, uint16_t h, + uint16_t outline, uint16_t fill, uint16_t textcolor, + char *label, uint8_t textsize) +{ + // Tweak arguments and pass to the newer initButtonUL() function... + initButtonUL(gfx, x - (w / 2), y - (h / 2), w, h, outline, fill, + textcolor, label, textsize); +} + +// Newer function instead accepts upper-left corner & size +void Adafruit_GFX_Button::initButtonUL( + Adafruit_GFX *gfx, int16_t x1, int16_t y1, uint16_t w, uint16_t h, + uint16_t outline, uint16_t fill, uint16_t textcolor, + char *label, uint8_t textsize) +{ + _x1 = x1; + _y1 = y1; + _w = w; + _h = h; + _outlinecolor = outline; + _fillcolor = fill; + _textcolor = textcolor; + _textsize = textsize; + _gfx = gfx; + strncpy(_label, label, 9); +} + +void Adafruit_GFX_Button::drawButton(boolean inverted) { + uint16_t fill, outline, text; + + if(!inverted) { + fill = _fillcolor; + outline = _outlinecolor; + text = _textcolor; + } else { + fill = _textcolor; + outline = _outlinecolor; + text = _fillcolor; + } + + uint8_t r = min(_w, _h) / 4; // Corner radius + _gfx->fillRoundRect(_x1, _y1, _w, _h, r, fill); + _gfx->drawRoundRect(_x1, _y1, _w, _h, r, outline); + + _gfx->setCursor(_x1 + (_w/2) - (strlen(_label) * 3 * _textsize), + _y1 + (_h/2) - (4 * _textsize)); + _gfx->setTextColor(text); + _gfx->setTextSize(_textsize); + _gfx->print(_label); +} + +boolean Adafruit_GFX_Button::contains(int16_t x, int16_t y) { + return ((x >= _x1) && (x < (_x1 + _w)) && + (y >= _y1) && (y < (_y1 + _h))); +} + +void Adafruit_GFX_Button::press(boolean p) { + laststate = currstate; + currstate = p; +} + +boolean Adafruit_GFX_Button::isPressed() { return currstate; } +boolean Adafruit_GFX_Button::justPressed() { return (currstate && !laststate); } +boolean Adafruit_GFX_Button::justReleased() { return (!currstate && laststate); } + +// ------------------------------------------------------------------------- + +// GFXcanvas1, GFXcanvas8 and GFXcanvas16 (currently a WIP, don't get too +// comfy with the implementation) provide 1-, 8- and 16-bit offscreen +// canvases, the address of which can be passed to drawBitmap() or +// pushColors() (the latter appears only in a couple of GFX-subclassed TFT +// libraries at this time). This is here mostly to help with the recently- +// added proportionally-spaced fonts; adds a way to refresh a section of the +// screen without a massive flickering clear-and-redraw...but maybe you'll +// find other uses too. VERY RAM-intensive, since the buffer is in MCU +// memory and not the display driver...GXFcanvas1 might be minimally useful +// on an Uno-class board, but this and the others are much more likely to +// require at least a Mega or various recent ARM-type boards (recommended, +// as the text+bitmap draw can be pokey). GFXcanvas1 requires 1 bit per +// pixel (rounded up to nearest byte per scanline), GFXcanvas8 is 1 byte +// per pixel (no scanline pad), and GFXcanvas16 uses 2 bytes per pixel (no +// scanline pad). +// NOT EXTENSIVELY TESTED YET. MAY CONTAIN WORST BUGS KNOWN TO HUMANKIND. + +GFXcanvas1::GFXcanvas1(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) { + uint16_t bytes = ((w + 7) / 8) * h; + if((buffer = (uint8_t *)malloc(bytes))) { + memset(buffer, 0, bytes); + } +} + +GFXcanvas1::~GFXcanvas1(void) { + if(buffer) free(buffer); +} + +uint8_t* GFXcanvas1::getBuffer(void) { + return buffer; +} + +void GFXcanvas1::drawPixel(int16_t x, int16_t y, uint16_t color) { +#ifdef __AVR__ + // Bitmask tables of 0x80>>X and ~(0x80>>X), because X>>Y is slow on AVR + static const uint8_t PROGMEM + GFXsetBit[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, + GFXclrBit[] = { 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE }; +#endif + + if(buffer) { + if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return; + + int16_t t; + switch(rotation) { + case 1: + t = x; + x = WIDTH - 1 - y; + y = t; + break; + case 2: + x = WIDTH - 1 - x; + y = HEIGHT - 1 - y; + break; + case 3: + t = x; + x = y; + y = HEIGHT - 1 - t; + break; + } + + uint8_t *ptr = &buffer[(x / 8) + y * ((WIDTH + 7) / 8)]; +#ifdef __AVR__ + if(color) *ptr |= pgm_read_byte(&GFXsetBit[x & 7]); + else *ptr &= pgm_read_byte(&GFXclrBit[x & 7]); +#else + if(color) *ptr |= 0x80 >> (x & 7); + else *ptr &= ~(0x80 >> (x & 7)); +#endif + } +} + +void GFXcanvas1::fillScreen(uint16_t color) { + if(buffer) { + uint16_t bytes = ((WIDTH + 7) / 8) * HEIGHT; + memset(buffer, color ? 0xFF : 0x00, bytes); + } +} + +GFXcanvas8::GFXcanvas8(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) { + uint32_t bytes = w * h; + if((buffer = (uint8_t *)malloc(bytes))) { + memset(buffer, 0, bytes); + } +} + +GFXcanvas8::~GFXcanvas8(void) { + if(buffer) free(buffer); +} + +uint8_t* GFXcanvas8::getBuffer(void) { + return buffer; +} + +void GFXcanvas8::drawPixel(int16_t x, int16_t y, uint16_t color) { + if(buffer) { + if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return; + + int16_t t; + switch(rotation) { + case 1: + t = x; + x = WIDTH - 1 - y; + y = t; + break; + case 2: + x = WIDTH - 1 - x; + y = HEIGHT - 1 - y; + break; + case 3: + t = x; + x = y; + y = HEIGHT - 1 - t; + break; + } + + buffer[x + y * WIDTH] = color; + } +} + +void GFXcanvas8::fillScreen(uint16_t color) { + if(buffer) { + memset(buffer, color, WIDTH * HEIGHT); + } +} + +void GFXcanvas8::writeFastHLine(int16_t x, int16_t y, + int16_t w, uint16_t color) { + + if((x >= _width) || (y < 0) || (y >= _height)) return; + int16_t x2 = x + w - 1; + if(x2 < 0) return; + + // Clip left/right + if(x < 0) { + x = 0; + w = x2 + 1; + } + if(x2 >= _width) w = _width - x; + + int16_t t; + switch(rotation) { + case 1: + t = x; + x = WIDTH - 1 - y; + y = t; + break; + case 2: + x = WIDTH - 1 - x; + y = HEIGHT - 1 - y; + break; + case 3: + t = x; + x = y; + y = HEIGHT - 1 - t; + break; + } + + memset(buffer + y * WIDTH + x, color, w); +} + +GFXcanvas16::GFXcanvas16(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) { + uint32_t bytes = w * h * 2; + if((buffer = (uint16_t *)malloc(bytes))) { + memset(buffer, 0, bytes); + } +} + +GFXcanvas16::~GFXcanvas16(void) { + if(buffer) free(buffer); +} + +uint16_t* GFXcanvas16::getBuffer(void) { + return buffer; +} + +void GFXcanvas16::drawPixel(int16_t x, int16_t y, uint16_t color) { + if(buffer) { + if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return; + + int16_t t; + switch(rotation) { + case 1: + t = x; + x = WIDTH - 1 - y; + y = t; + break; + case 2: + x = WIDTH - 1 - x; + y = HEIGHT - 1 - y; + break; + case 3: + t = x; + x = y; + y = HEIGHT - 1 - t; + break; + } + + buffer[x + y * WIDTH] = color; + } +} + +void GFXcanvas16::fillScreen(uint16_t color) { + if(buffer) { + uint8_t hi = color >> 8, lo = color & 0xFF; + if(hi == lo) { + memset(buffer, lo, WIDTH * HEIGHT * 2); + } else { + uint32_t i, pixels = WIDTH * HEIGHT; + for(i=0; i= 100 + #include "Arduino.h" + #include "Print.h" +#else + #include "WProgram.h" +#endif +#include "gfxfont.h" + +class Adafruit_GFX : public Print { + + public: + + Adafruit_GFX(int16_t w, int16_t h); // Constructor + + // This MUST be defined by the subclass: + virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0; + + // TRANSACTION API / CORE DRAW API + // These MAY be overridden by the subclass to provide device-specific + // optimized code. Otherwise 'generic' versions are used. + virtual void startWrite(void); + virtual void writePixel(int16_t x, int16_t y, uint16_t color); + virtual void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); + virtual void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); + virtual void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); + virtual void writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color); + virtual void endWrite(void); + + // CONTROL API + // These MAY be overridden by the subclass to provide device-specific + // optimized code. Otherwise 'generic' versions are used. + virtual void setRotation(uint8_t r); + virtual void invertDisplay(boolean i); + + // BASIC DRAW API + // These MAY be overridden by the subclass to provide device-specific + // optimized code. Otherwise 'generic' versions are used. + virtual void + // It's good to implement those, even if using transaction API + drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color), + drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color), + fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color), + fillScreen(uint16_t color), + // Optional and probably not necessary to change + drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color), + drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); + + // These exist only with Adafruit_GFX (no subclass overrides) + void + drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color), + drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, + uint16_t color), + fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color), + fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, + int16_t delta, uint16_t color), + drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, + int16_t x2, int16_t y2, uint16_t color), + fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, + int16_t x2, int16_t y2, uint16_t color), + drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, + int16_t radius, uint16_t color), + fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, + int16_t radius, uint16_t color), + drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], + int16_t w, int16_t h, uint16_t color), + drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], + int16_t w, int16_t h, uint16_t color, uint16_t bg), + drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, + int16_t w, int16_t h, uint16_t color), + drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, + int16_t w, int16_t h, uint16_t color, uint16_t bg), + drawXBitmap(int16_t x, int16_t y, const uint8_t bitmap[], + int16_t w, int16_t h, uint16_t color), + drawGrayscaleBitmap(int16_t x, int16_t y, const uint8_t bitmap[], + int16_t w, int16_t h), + drawGrayscaleBitmap(int16_t x, int16_t y, uint8_t *bitmap, + int16_t w, int16_t h), + drawGrayscaleBitmap(int16_t x, int16_t y, + const uint8_t bitmap[], const uint8_t mask[], + int16_t w, int16_t h), + drawGrayscaleBitmap(int16_t x, int16_t y, + uint8_t *bitmap, uint8_t *mask, int16_t w, int16_t h), + drawRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[], + int16_t w, int16_t h), + drawRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, + int16_t w, int16_t h), + drawRGBBitmap(int16_t x, int16_t y, + const uint16_t bitmap[], const uint8_t mask[], + int16_t w, int16_t h), + drawRGBBitmap(int16_t x, int16_t y, + uint16_t *bitmap, uint8_t *mask, int16_t w, int16_t h), + drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, + uint16_t bg, uint8_t size), + setCursor(int16_t x, int16_t y), + setTextColor(uint16_t c), + setTextColor(uint16_t c, uint16_t bg), + setTextSize(uint8_t s), + setTextWrap(boolean w), + cp437(boolean x=true), + setFont(const GFXfont *f = NULL), + getTextBounds(char *string, int16_t x, int16_t y, + int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h), + getTextBounds(const __FlashStringHelper *s, int16_t x, int16_t y, + int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h); + +#if ARDUINO >= 100 + virtual size_t write(uint8_t); +#else + virtual void write(uint8_t); +#endif + + int16_t height(void) const; + int16_t width(void) const; + + uint8_t getRotation(void) const; + + // get current cursor position (get rotation safe maximum values, using: width() for x, height() for y) + int16_t getCursorX(void) const; + int16_t getCursorY(void) const; + + protected: + void + charBounds(char c, int16_t *x, int16_t *y, + int16_t *minx, int16_t *miny, int16_t *maxx, int16_t *maxy); + const int16_t + WIDTH, HEIGHT; // This is the 'raw' display w/h - never changes + int16_t + _width, _height, // Display w/h as modified by current rotation + cursor_x, cursor_y; + uint16_t + textcolor, textbgcolor; + uint8_t + textsize, + rotation; + boolean + wrap, // If set, 'wrap' text at right edge of display + _cp437; // If set, use correct CP437 charset (default is off) + GFXfont + *gfxFont; +}; + +class Adafruit_GFX_Button { + + public: + Adafruit_GFX_Button(void); + // "Classic" initButton() uses center & size + void initButton(Adafruit_GFX *gfx, int16_t x, int16_t y, + uint16_t w, uint16_t h, uint16_t outline, uint16_t fill, + uint16_t textcolor, char *label, uint8_t textsize); + // New/alt initButton() uses upper-left corner & size + void initButtonUL(Adafruit_GFX *gfx, int16_t x1, int16_t y1, + uint16_t w, uint16_t h, uint16_t outline, uint16_t fill, + uint16_t textcolor, char *label, uint8_t textsize); + void drawButton(boolean inverted = false); + boolean contains(int16_t x, int16_t y); + + void press(boolean p); + boolean isPressed(); + boolean justPressed(); + boolean justReleased(); + + private: + Adafruit_GFX *_gfx; + int16_t _x1, _y1; // Coordinates of top-left corner + uint16_t _w, _h; + uint8_t _textsize; + uint16_t _outlinecolor, _fillcolor, _textcolor; + char _label[10]; + + boolean currstate, laststate; +}; + +class GFXcanvas1 : public Adafruit_GFX { + public: + GFXcanvas1(uint16_t w, uint16_t h); + ~GFXcanvas1(void); + void drawPixel(int16_t x, int16_t y, uint16_t color), + fillScreen(uint16_t color); + uint8_t *getBuffer(void); + private: + uint8_t *buffer; +}; + +class GFXcanvas8 : public Adafruit_GFX { + public: + GFXcanvas8(uint16_t w, uint16_t h); + ~GFXcanvas8(void); + void drawPixel(int16_t x, int16_t y, uint16_t color), + fillScreen(uint16_t color), + writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); + + uint8_t *getBuffer(void); + private: + uint8_t *buffer; +}; + +class GFXcanvas16 : public Adafruit_GFX { + public: + GFXcanvas16(uint16_t w, uint16_t h); + ~GFXcanvas16(void); + void drawPixel(int16_t x, int16_t y, uint16_t color), + fillScreen(uint16_t color); + uint16_t *getBuffer(void); + private: + uint16_t *buffer; +}; + +#endif // _ADAFRUIT_GFX_H diff --git a/variants/Sinobit/Adafruit_HT1632.cpp b/variants/Sinobit/Adafruit_HT1632.cpp new file mode 100644 index 00000000..ebf173e7 --- /dev/null +++ b/variants/Sinobit/Adafruit_HT1632.cpp @@ -0,0 +1,282 @@ +#include "Adafruit_HT1632.h" + +#ifndef _swap_int16_t +#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; } +#endif + +// Constructor for single GFX matrix +Adafruit_HT1632LEDMatrix::Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, + uint8_t cs1) : Adafruit_GFX(24, 16), matrices(NULL), matrixNum(0) { + if((matrices = (Adafruit_HT1632 *)malloc(sizeof(Adafruit_HT1632)))) { + matrices[0] = Adafruit_HT1632(data, wr, cs1); + matrixNum = 1; + } +} + +// Constructor for two matrices, tiled side-by-side for GFX +Adafruit_HT1632LEDMatrix::Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, + uint8_t cs1, uint8_t cs2) : Adafruit_GFX(48, 16), matrices(NULL), + matrixNum(0) { + if((matrices = (Adafruit_HT1632 *)malloc(2 * sizeof(Adafruit_HT1632)))) { + matrices[0] = Adafruit_HT1632(data, wr, cs1); + matrices[1] = Adafruit_HT1632(data, wr, cs2); + matrixNum = 2; + } +} + +// Constructor for three matrices, tiled side-by-side for GFX +Adafruit_HT1632LEDMatrix::Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, + uint8_t cs1, uint8_t cs2, uint8_t cs3) : Adafruit_GFX(72, 16), + matrices(NULL), matrixNum(0) { + if((matrices = (Adafruit_HT1632 *)malloc(3 * sizeof(Adafruit_HT1632)))) { + matrices[0] = Adafruit_HT1632(data, wr, cs1); + matrices[1] = Adafruit_HT1632(data, wr, cs2); + matrices[2] = Adafruit_HT1632(data, wr, cs3); + matrixNum = 3; + } +} + +// Constructor for four matrices, tiled side-by-side for GFX +Adafruit_HT1632LEDMatrix::Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, + uint8_t cs1, uint8_t cs2, uint8_t cs3, uint8_t cs4) : Adafruit_GFX(96, 16), + matrices(NULL), matrixNum(0) { + if((matrices = (Adafruit_HT1632 *)malloc(4 * sizeof(Adafruit_HT1632)))) { + matrices[0] = Adafruit_HT1632(data, wr, cs1); + matrices[1] = Adafruit_HT1632(data, wr, cs2); + matrices[2] = Adafruit_HT1632(data, wr, cs3); + matrices[3] = Adafruit_HT1632(data, wr, cs4); + matrixNum = 4; + } +} + +void Adafruit_HT1632LEDMatrix::setPixel(uint8_t x, uint8_t y) { + drawPixel(x, y, 1); +} + +void Adafruit_HT1632LEDMatrix::clrPixel(uint8_t x, uint8_t y) { + drawPixel(x, y, 0); +} + +void Adafruit_HT1632LEDMatrix::drawPixel(int16_t x, int16_t y, uint16_t color) { + if((x < 0) || (x >= _width) || (y < 0) || (y >= _height)) return; + + switch(rotation) { // Rotate pixel into device-specific coordinates + case 1: + _swap_int16_t(x, y); + x = WIDTH - 1 - x; + break; + case 2: + x = WIDTH - 1 - x; + y = HEIGHT - 1 - y; + break; + case 3: + _swap_int16_t(x, y); + y = HEIGHT - 1 - y; + break; + } + + uint8_t m = x / 24; // Which matrix controller is pixel on? + x %= 24; // Which column in matrix? + + uint16_t i; + + if(x < 8) i = 7; + else if(x < 16) i = 128 + 7; + else i = 256 + 7; + i -= (x & 7); + + if(y < 8) y *= 2; + else y = (y-8) * 2 + 1; + i += y * 8; + + if(color) matrices[m].setPixel(i); + else matrices[m].clrPixel(i); +} + +boolean Adafruit_HT1632LEDMatrix::begin(uint8_t type) { + if(matrixNum) { // Did malloc() work OK? + for(uint8_t i=0; i= 0) { + pinMode(_rd, OUTPUT); + digitalWrite(_rd, HIGH); + } + +#ifdef __AVR__ + csport = portOutputRegister(digitalPinToPort(_cs)); + csmask = digitalPinToBitMask(_cs); + wrport = portOutputRegister(digitalPinToPort(_wr)); + wrmask = digitalPinToBitMask(_wr); + dataport = portOutputRegister(digitalPinToPort(_data)); + datadir = portModeRegister(digitalPinToPort(_data)); + datamask = digitalPinToBitMask(_data); +#endif + + sendcommand(ADA_HT1632_SYS_EN); + sendcommand(ADA_HT1632_LED_ON); + sendcommand(ADA_HT1632_BLINK_OFF); + sendcommand(ADA_HT1632_MASTER_MODE); + sendcommand(ADA_HT1632_INT_RC); + sendcommand(type); + sendcommand(ADA_HT1632_PWM_CONTROL | 0xF); +} + +void Adafruit_HT1632::setBrightness(uint8_t pwm) { + if(pwm > 15) pwm = 15; + sendcommand(ADA_HT1632_PWM_CONTROL | pwm); +} + +void Adafruit_HT1632::blink(boolean blinky) { + sendcommand(blinky ? ADA_HT1632_BLINK_ON : ADA_HT1632_BLINK_OFF); +} + +void Adafruit_HT1632::setPixel(uint16_t i) { + ledmatrix[i/8] |= (1 << (i & 7)); +} + +void Adafruit_HT1632::clrPixel(uint16_t i) { + ledmatrix[i/8] &= ~(1 << (i & 7)); +} + +void Adafruit_HT1632::dumpScreen() { + Serial.println(F("---------------------------------------")); + + for (uint16_t i=0; i>= 1) { + *wrport &= ~wrmask; + if(d & bit) *dataport |= datamask; + else *dataport &= ~datamask; + *wrport |= wrmask; + } +#else + pinMode(_data, OUTPUT); + for(uint16_t bit = 1<<(bits-1); bit; bit >>= 1) { + digitalWrite(_wr, LOW); + digitalWrite(_data, (d & bit) ? HIGH : LOW); + digitalWrite(_wr, HIGH); + } + pinMode(_data, INPUT); +#endif +} + +void Adafruit_HT1632::writeRAM(uint8_t addr, uint8_t data) { + //Serial.print("Writing 0x"); Serial.print(data&0xF, HEX); + //Serial.print(" to 0x"); Serial.println(addr & 0x7F, HEX); + + uint16_t d = ADA_HT1632_WRITE; + d <<= 7; + d |= addr & 0x7F; + d <<= 4; + d |= data & 0xF; + +#ifdef __AVR__ + *csport &= ~csmask; + writedata(d, 14); + *csport |= csmask; +#else + digitalWrite(_cs, LOW); + writedata(d, 14); + digitalWrite(_cs, HIGH); +#endif +} + +void Adafruit_HT1632::sendcommand(uint8_t cmd) { +#ifdef __AVR__ + *csport &= ~csmask; + *datadir |= datamask; // OUTPUT + writedata((((uint16_t)ADA_HT1632_COMMAND << 8) | cmd) << 1, 12); + *datadir &= ~datamask; // INPUT + *csport |= csmask; +#else + digitalWrite(_cs, LOW); + writedata((((uint16_t)ADA_HT1632_COMMAND << 8) | cmd) << 1, 12); + digitalWrite(_cs, HIGH); +#endif +} + +void Adafruit_HT1632::fillScreen() { + memset(ledmatrix, 0xFF, sizeof(ledmatrix)); + writeScreen(); +} diff --git a/variants/Sinobit/Adafruit_HT1632.h b/variants/Sinobit/Adafruit_HT1632.h new file mode 100644 index 00000000..f914bd87 --- /dev/null +++ b/variants/Sinobit/Adafruit_HT1632.h @@ -0,0 +1,84 @@ +#include "Adafruit_GFX.h" + +#ifndef ADA_HT1632_H_ +#define ADA_HT1632_H_ + +#if(ARDUINO >= 100) + #include +#else + #include +#endif + +#define ADA_HT1632_READ 0x06 +#define ADA_HT1632_WRITE 0x05 +#define ADA_HT1632_COMMAND 0x04 + +#define ADA_HT1632_SYS_DIS 0x00 +#define ADA_HT1632_SYS_EN 0x01 +#define ADA_HT1632_LED_OFF 0x02 +#define ADA_HT1632_LED_ON 0x03 +#define ADA_HT1632_BLINK_OFF 0x08 +#define ADA_HT1632_BLINK_ON 0x09 +#define ADA_HT1632_SLAVE_MODE 0x10 +#define ADA_HT1632_MASTER_MODE 0x14 +#define ADA_HT1632_INT_RC 0x18 +#define ADA_HT1632_EXT_CLK 0x1C +#define ADA_HT1632_PWM_CONTROL 0xA0 + +#define ADA_HT1632_COMMON_8NMOS 0x20 +#define ADA_HT1632_COMMON_16NMOS 0x24 +#define ADA_HT1632_COMMON_8PMOS 0x28 +#define ADA_HT1632_COMMON_16PMOS 0x2C + +class Adafruit_HT1632 { + + public: + Adafruit_HT1632(int8_t data, int8_t wr, int8_t cs, int8_t rd = -1); + + void begin(uint8_t type), + clrPixel(uint16_t i), + setPixel(uint16_t i), + blink(boolean state), + setBrightness(uint8_t pwm), + clearScreen(), + fillScreen(), + writeScreen(), + dumpScreen(); + + protected: + int8_t _data, _cs, _wr, _rd; + uint8_t ledmatrix[24 * 16 / 8]; + void sendcommand(uint8_t c), + writedata(uint16_t d, uint8_t bits), + writeRAM(uint8_t addr, uint8_t data); +#ifdef __AVR__ + volatile uint8_t *dataport, *csport, *wrport, *datadir; + uint8_t datamask, csmask, wrmask; +#endif +}; + +class Adafruit_HT1632LEDMatrix : public Adafruit_GFX { + public: + Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, uint8_t cs1); + Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, uint8_t cs1, uint8_t cs2); + Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, + uint8_t cs1, uint8_t cs, uint8_t cs3); + Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, + uint8_t cs1, uint8_t cs2, uint8_t cs3, uint8_t cs4); + + boolean begin(uint8_t type); + void clearScreen(void), + fillScreen(void), + blink(boolean b), + setBrightness(uint8_t brightness), + writeScreen(), + clrPixel(uint8_t x, uint8_t y), + setPixel(uint8_t x, uint8_t y), + drawPixel(int16_t x, int16_t y, uint16_t color); + + protected: + Adafruit_HT1632 *matrices; + uint8_t matrixNum; +}; + +#endif /* Adafruit HT1632_H_ */ diff --git a/variants/Sinobit/README.md b/variants/Sinobit/README.md new file mode 100644 index 00000000..cab3216a --- /dev/null +++ b/variants/Sinobit/README.md @@ -0,0 +1,3 @@ +# Sino:Bit support files for Arduino +sinobit.cpp, sinobit.h courtesy of Dave Astels (Twitter @DAstels) +Adafruit files from Adafruit GFX and Adafruit HT1632 Arduino Libraries. diff --git a/variants/Sinobit/gfxfont.h b/variants/Sinobit/gfxfont.h new file mode 100644 index 00000000..07381edd --- /dev/null +++ b/variants/Sinobit/gfxfont.h @@ -0,0 +1,24 @@ +// Font structures for newer Adafruit_GFX (1.1 and later). +// Example fonts are included in 'Fonts' directory. +// To use a font in your Arduino sketch, #include the corresponding .h +// file and pass address of GFXfont struct to setFont(). Pass NULL to +// revert to 'classic' fixed-space bitmap font. + +#ifndef _GFXFONT_H_ +#define _GFXFONT_H_ + +typedef struct { // Data stored PER GLYPH + uint16_t bitmapOffset; // Pointer into GFXfont->bitmap + uint8_t width, height; // Bitmap dimensions in pixels + uint8_t xAdvance; // Distance to advance cursor (x axis) + int8_t xOffset, yOffset; // Dist from cursor pos to UL corner +} GFXglyph; + +typedef struct { // Data stored for FONT AS A WHOLE: + uint8_t *bitmap; // Glyph bitmaps, concatenated + GFXglyph *glyph; // Glyph array + uint8_t first, last; // ASCII extents + uint8_t yAdvance; // Newline distance (y axis) +} GFXfont; + +#endif // _GFXFONT_H_ diff --git a/variants/Sinobit/glcdfont.c b/variants/Sinobit/glcdfont.c new file mode 100644 index 00000000..6f88bd23 --- /dev/null +++ b/variants/Sinobit/glcdfont.c @@ -0,0 +1,276 @@ +// This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0. +// See gfxfont.h for newer custom bitmap font info. + +#ifndef FONT5X7_H +#define FONT5X7_H + +#ifdef __AVR__ + #include + #include +#elif defined(ESP8266) + #include +#else + #define PROGMEM +#endif + +// Standard ASCII 5x7 font + +static const unsigned char font[] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, + 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, + 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, + 0x18, 0x3C, 0x7E, 0x3C, 0x18, + 0x1C, 0x57, 0x7D, 0x57, 0x1C, + 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, + 0x00, 0x18, 0x3C, 0x18, 0x00, + 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, + 0x00, 0x18, 0x24, 0x18, 0x00, + 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, + 0x30, 0x48, 0x3A, 0x06, 0x0E, + 0x26, 0x29, 0x79, 0x29, 0x26, + 0x40, 0x7F, 0x05, 0x05, 0x07, + 0x40, 0x7F, 0x05, 0x25, 0x3F, + 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, + 0x7F, 0x3E, 0x1C, 0x1C, 0x08, + 0x08, 0x1C, 0x1C, 0x3E, 0x7F, + 0x14, 0x22, 0x7F, 0x22, 0x14, + 0x5F, 0x5F, 0x00, 0x5F, 0x5F, + 0x06, 0x09, 0x7F, 0x01, 0x7F, + 0x00, 0x66, 0x89, 0x95, 0x6A, + 0x60, 0x60, 0x60, 0x60, 0x60, + 0x94, 0xA2, 0xFF, 0xA2, 0x94, + 0x08, 0x04, 0x7E, 0x04, 0x08, + 0x10, 0x20, 0x7E, 0x20, 0x10, + 0x08, 0x08, 0x2A, 0x1C, 0x08, + 0x08, 0x1C, 0x2A, 0x08, 0x08, + 0x1E, 0x10, 0x10, 0x10, 0x10, + 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, + 0x30, 0x38, 0x3E, 0x38, 0x30, + 0x06, 0x0E, 0x3E, 0x0E, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5F, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x07, 0x00, + 0x14, 0x7F, 0x14, 0x7F, 0x14, + 0x24, 0x2A, 0x7F, 0x2A, 0x12, + 0x23, 0x13, 0x08, 0x64, 0x62, + 0x36, 0x49, 0x56, 0x20, 0x50, + 0x00, 0x08, 0x07, 0x03, 0x00, + 0x00, 0x1C, 0x22, 0x41, 0x00, + 0x00, 0x41, 0x22, 0x1C, 0x00, + 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, + 0x08, 0x08, 0x3E, 0x08, 0x08, + 0x00, 0x80, 0x70, 0x30, 0x00, + 0x08, 0x08, 0x08, 0x08, 0x08, + 0x00, 0x00, 0x60, 0x60, 0x00, + 0x20, 0x10, 0x08, 0x04, 0x02, + 0x3E, 0x51, 0x49, 0x45, 0x3E, + 0x00, 0x42, 0x7F, 0x40, 0x00, + 0x72, 0x49, 0x49, 0x49, 0x46, + 0x21, 0x41, 0x49, 0x4D, 0x33, + 0x18, 0x14, 0x12, 0x7F, 0x10, + 0x27, 0x45, 0x45, 0x45, 0x39, + 0x3C, 0x4A, 0x49, 0x49, 0x31, + 0x41, 0x21, 0x11, 0x09, 0x07, + 0x36, 0x49, 0x49, 0x49, 0x36, + 0x46, 0x49, 0x49, 0x29, 0x1E, + 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x40, 0x34, 0x00, 0x00, + 0x00, 0x08, 0x14, 0x22, 0x41, + 0x14, 0x14, 0x14, 0x14, 0x14, + 0x00, 0x41, 0x22, 0x14, 0x08, + 0x02, 0x01, 0x59, 0x09, 0x06, + 0x3E, 0x41, 0x5D, 0x59, 0x4E, + 0x7C, 0x12, 0x11, 0x12, 0x7C, + 0x7F, 0x49, 0x49, 0x49, 0x36, + 0x3E, 0x41, 0x41, 0x41, 0x22, + 0x7F, 0x41, 0x41, 0x41, 0x3E, + 0x7F, 0x49, 0x49, 0x49, 0x41, + 0x7F, 0x09, 0x09, 0x09, 0x01, + 0x3E, 0x41, 0x41, 0x51, 0x73, + 0x7F, 0x08, 0x08, 0x08, 0x7F, + 0x00, 0x41, 0x7F, 0x41, 0x00, + 0x20, 0x40, 0x41, 0x3F, 0x01, + 0x7F, 0x08, 0x14, 0x22, 0x41, + 0x7F, 0x40, 0x40, 0x40, 0x40, + 0x7F, 0x02, 0x1C, 0x02, 0x7F, + 0x7F, 0x04, 0x08, 0x10, 0x7F, + 0x3E, 0x41, 0x41, 0x41, 0x3E, + 0x7F, 0x09, 0x09, 0x09, 0x06, + 0x3E, 0x41, 0x51, 0x21, 0x5E, + 0x7F, 0x09, 0x19, 0x29, 0x46, + 0x26, 0x49, 0x49, 0x49, 0x32, + 0x03, 0x01, 0x7F, 0x01, 0x03, + 0x3F, 0x40, 0x40, 0x40, 0x3F, + 0x1F, 0x20, 0x40, 0x20, 0x1F, + 0x3F, 0x40, 0x38, 0x40, 0x3F, + 0x63, 0x14, 0x08, 0x14, 0x63, + 0x03, 0x04, 0x78, 0x04, 0x03, + 0x61, 0x59, 0x49, 0x4D, 0x43, + 0x00, 0x7F, 0x41, 0x41, 0x41, + 0x02, 0x04, 0x08, 0x10, 0x20, + 0x00, 0x41, 0x41, 0x41, 0x7F, + 0x04, 0x02, 0x01, 0x02, 0x04, + 0x40, 0x40, 0x40, 0x40, 0x40, + 0x00, 0x03, 0x07, 0x08, 0x00, + 0x20, 0x54, 0x54, 0x78, 0x40, + 0x7F, 0x28, 0x44, 0x44, 0x38, + 0x38, 0x44, 0x44, 0x44, 0x28, + 0x38, 0x44, 0x44, 0x28, 0x7F, + 0x38, 0x54, 0x54, 0x54, 0x18, + 0x00, 0x08, 0x7E, 0x09, 0x02, + 0x18, 0xA4, 0xA4, 0x9C, 0x78, + 0x7F, 0x08, 0x04, 0x04, 0x78, + 0x00, 0x44, 0x7D, 0x40, 0x00, + 0x20, 0x40, 0x40, 0x3D, 0x00, + 0x7F, 0x10, 0x28, 0x44, 0x00, + 0x00, 0x41, 0x7F, 0x40, 0x00, + 0x7C, 0x04, 0x78, 0x04, 0x78, + 0x7C, 0x08, 0x04, 0x04, 0x78, + 0x38, 0x44, 0x44, 0x44, 0x38, + 0xFC, 0x18, 0x24, 0x24, 0x18, + 0x18, 0x24, 0x24, 0x18, 0xFC, + 0x7C, 0x08, 0x04, 0x04, 0x08, + 0x48, 0x54, 0x54, 0x54, 0x24, + 0x04, 0x04, 0x3F, 0x44, 0x24, + 0x3C, 0x40, 0x40, 0x20, 0x7C, + 0x1C, 0x20, 0x40, 0x20, 0x1C, + 0x3C, 0x40, 0x30, 0x40, 0x3C, + 0x44, 0x28, 0x10, 0x28, 0x44, + 0x4C, 0x90, 0x90, 0x90, 0x7C, + 0x44, 0x64, 0x54, 0x4C, 0x44, + 0x00, 0x08, 0x36, 0x41, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, + 0x00, 0x41, 0x36, 0x08, 0x00, + 0x02, 0x01, 0x02, 0x04, 0x02, + 0x3C, 0x26, 0x23, 0x26, 0x3C, + 0x1E, 0xA1, 0xA1, 0x61, 0x12, + 0x3A, 0x40, 0x40, 0x20, 0x7A, + 0x38, 0x54, 0x54, 0x55, 0x59, + 0x21, 0x55, 0x55, 0x79, 0x41, + 0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut + 0x21, 0x55, 0x54, 0x78, 0x40, + 0x20, 0x54, 0x55, 0x79, 0x40, + 0x0C, 0x1E, 0x52, 0x72, 0x12, + 0x39, 0x55, 0x55, 0x55, 0x59, + 0x39, 0x54, 0x54, 0x54, 0x59, + 0x39, 0x55, 0x54, 0x54, 0x58, + 0x00, 0x00, 0x45, 0x7C, 0x41, + 0x00, 0x02, 0x45, 0x7D, 0x42, + 0x00, 0x01, 0x45, 0x7C, 0x40, + 0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut + 0xF0, 0x28, 0x25, 0x28, 0xF0, + 0x7C, 0x54, 0x55, 0x45, 0x00, + 0x20, 0x54, 0x54, 0x7C, 0x54, + 0x7C, 0x0A, 0x09, 0x7F, 0x49, + 0x32, 0x49, 0x49, 0x49, 0x32, + 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut + 0x32, 0x4A, 0x48, 0x48, 0x30, + 0x3A, 0x41, 0x41, 0x21, 0x7A, + 0x3A, 0x42, 0x40, 0x20, 0x78, + 0x00, 0x9D, 0xA0, 0xA0, 0x7D, + 0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut + 0x3D, 0x40, 0x40, 0x40, 0x3D, + 0x3C, 0x24, 0xFF, 0x24, 0x24, + 0x48, 0x7E, 0x49, 0x43, 0x66, + 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, + 0xFF, 0x09, 0x29, 0xF6, 0x20, + 0xC0, 0x88, 0x7E, 0x09, 0x03, + 0x20, 0x54, 0x54, 0x79, 0x41, + 0x00, 0x00, 0x44, 0x7D, 0x41, + 0x30, 0x48, 0x48, 0x4A, 0x32, + 0x38, 0x40, 0x40, 0x22, 0x7A, + 0x00, 0x7A, 0x0A, 0x0A, 0x72, + 0x7D, 0x0D, 0x19, 0x31, 0x7D, + 0x26, 0x29, 0x29, 0x2F, 0x28, + 0x26, 0x29, 0x29, 0x29, 0x26, + 0x30, 0x48, 0x4D, 0x40, 0x20, + 0x38, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x38, + 0x2F, 0x10, 0xC8, 0xAC, 0xBA, + 0x2F, 0x10, 0x28, 0x34, 0xFA, + 0x00, 0x00, 0x7B, 0x00, 0x00, + 0x08, 0x14, 0x2A, 0x14, 0x22, + 0x22, 0x14, 0x2A, 0x14, 0x08, + 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code + 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block + 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block + 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x10, 0x10, 0x10, 0xFF, 0x00, + 0x14, 0x14, 0x14, 0xFF, 0x00, + 0x10, 0x10, 0xFF, 0x00, 0xFF, + 0x10, 0x10, 0xF0, 0x10, 0xF0, + 0x14, 0x14, 0x14, 0xFC, 0x00, + 0x14, 0x14, 0xF7, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0x14, 0x14, 0xF4, 0x04, 0xFC, + 0x14, 0x14, 0x17, 0x10, 0x1F, + 0x10, 0x10, 0x1F, 0x10, 0x1F, + 0x14, 0x14, 0x14, 0x1F, 0x00, + 0x10, 0x10, 0x10, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0x10, + 0x10, 0x10, 0x10, 0x1F, 0x10, + 0x10, 0x10, 0x10, 0xF0, 0x10, + 0x00, 0x00, 0x00, 0xFF, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0xFF, 0x10, + 0x00, 0x00, 0x00, 0xFF, 0x14, + 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0x00, 0x00, 0x1F, 0x10, 0x17, + 0x00, 0x00, 0xFC, 0x04, 0xF4, + 0x14, 0x14, 0x17, 0x10, 0x17, + 0x14, 0x14, 0xF4, 0x04, 0xF4, + 0x00, 0x00, 0xFF, 0x00, 0xF7, + 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0xF7, 0x00, 0xF7, + 0x14, 0x14, 0x14, 0x17, 0x14, + 0x10, 0x10, 0x1F, 0x10, 0x1F, + 0x14, 0x14, 0x14, 0xF4, 0x14, + 0x10, 0x10, 0xF0, 0x10, 0xF0, + 0x00, 0x00, 0x1F, 0x10, 0x1F, + 0x00, 0x00, 0x00, 0x1F, 0x14, + 0x00, 0x00, 0x00, 0xFC, 0x14, + 0x00, 0x00, 0xF0, 0x10, 0xF0, + 0x10, 0x10, 0xFF, 0x10, 0xFF, + 0x14, 0x14, 0x14, 0xFF, 0x14, + 0x10, 0x10, 0x10, 0x1F, 0x00, + 0x00, 0x00, 0x00, 0xF0, 0x10, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x38, 0x44, 0x44, 0x38, 0x44, + 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta + 0x7E, 0x02, 0x02, 0x06, 0x06, + 0x02, 0x7E, 0x02, 0x7E, 0x02, + 0x63, 0x55, 0x49, 0x41, 0x63, + 0x38, 0x44, 0x44, 0x3C, 0x04, + 0x40, 0x7E, 0x20, 0x1E, 0x20, + 0x06, 0x02, 0x7E, 0x02, 0x02, + 0x99, 0xA5, 0xE7, 0xA5, 0x99, + 0x1C, 0x2A, 0x49, 0x2A, 0x1C, + 0x4C, 0x72, 0x01, 0x72, 0x4C, + 0x30, 0x4A, 0x4D, 0x4D, 0x30, + 0x30, 0x48, 0x78, 0x48, 0x30, + 0xBC, 0x62, 0x5A, 0x46, 0x3D, + 0x3E, 0x49, 0x49, 0x49, 0x00, + 0x7E, 0x01, 0x01, 0x01, 0x7E, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x44, 0x44, 0x5F, 0x44, 0x44, + 0x40, 0x51, 0x4A, 0x44, 0x40, + 0x40, 0x44, 0x4A, 0x51, 0x40, + 0x00, 0x00, 0xFF, 0x01, 0x03, + 0xE0, 0x80, 0xFF, 0x00, 0x00, + 0x08, 0x08, 0x6B, 0x6B, 0x08, + 0x36, 0x12, 0x36, 0x24, 0x36, + 0x06, 0x0F, 0x09, 0x0F, 0x06, + 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x10, 0x10, 0x00, + 0x30, 0x40, 0xFF, 0x01, 0x01, + 0x00, 0x1F, 0x01, 0x01, 0x1E, + 0x00, 0x19, 0x1D, 0x17, 0x12, + 0x00, 0x3C, 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP +}; +#endif // FONT5X7_H diff --git a/variants/Sinobit/license.txt b/variants/Sinobit/license.txt new file mode 100644 index 00000000..7492e93a --- /dev/null +++ b/variants/Sinobit/license.txt @@ -0,0 +1,24 @@ +Software License Agreement (BSD License) + +Copyright (c) 2012 Adafruit Industries. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/variants/Sinobit/pins_arduino.h b/variants/Sinobit/pins_arduino.h new file mode 100644 index 00000000..3ef4d4a9 --- /dev/null +++ b/variants/Sinobit/pins_arduino.h @@ -0,0 +1,17 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// API compatibility +#include "variant.h" diff --git a/variants/Sinobit/scroll_support.cpp b/variants/Sinobit/scroll_support.cpp new file mode 100644 index 00000000..3e57cda1 --- /dev/null +++ b/variants/Sinobit/scroll_support.cpp @@ -0,0 +1,33 @@ +#include "scroll_support.h" + + +ScrollSupport *ScrollSupport::makeFor(readingDirection_t dir, String message) +{ + switch (dir) { + case TopToBottom: return new ScrollUp(message); + case LeftToRight: return new ScrollLeft(message); + case RightToLeft: return new ScrollRight(message); + } +} + + +ScrollSupport::ScrollSupport(String aMessage) +{ + message = aMessage; +} + + +ScrollLeft::ScrollLeft(String aMessage) : ScrollSupport(aMessage) +{ +} + + +ScrollRight::ScrollRight(String aMessage) : ScrollSupport(aMessage) +{ +} + + +ScrollUp::ScrollUp(String aMessage) : ScrollSupport(aMessage) +{ +} + diff --git a/variants/Sinobit/scroll_support.h b/variants/Sinobit/scroll_support.h new file mode 100644 index 00000000..d4d5e5e1 --- /dev/null +++ b/variants/Sinobit/scroll_support.h @@ -0,0 +1,82 @@ +#ifndef __SCROLL_SUPPORT__ +#define __SCROLL_SUPPORT__ + +#include + + +typedef enum { + TopToBottom, + BottomToTop, + LeftToRight, + RightToLeft +} readingDirection_t; + + +class ScrollSupport +{ + public: + static ScrollSupport *makeFor(readingDirection_t dir, String message); + ScrollSupport(String aMessage); + virtual int16_t initialX(int8_t w) = 0; + virtual int16_t initialY(int8_t h) = 0; + virtual boolean isFinished(int16_t x, int16_t y, int8_t w, int8_t h) = 0; + virtual int16_t nextX(int16_t x) = 0; + virtual int16_t nextY(int16_t y) = 0; + virtual int16_t nextCharacterX(int16_t x, int8_t advance) = 0; + virtual int16_t nextCharacterY(int16_t y, int8_t advance) = 0; + virtual int8_t selectAdvance(int8_t horizontal, int8_t vertical) = 0; + + protected: + + String message; +}; + +class ScrollLeft : public ScrollSupport +{ + public: + ScrollLeft(String message); + int16_t initialX(int8_t w) { return 12; } + int16_t initialY(int8_t h) { return 6 + (h / 2); } + boolean isFinished(int16_t x, int16_t y, int8_t w, int8_t h) { return x <= ((int)message.length() * -1 * w); } + int16_t nextX(int16_t x) { return x - 1; } + int16_t nextY(int16_t y) { return y; } + int16_t nextCharacterX(int16_t x, int8_t advance) { return x + (int16_t)advance; } + int16_t nextCharacterY(int16_t y, int8_t advance) { return y; } + int8_t selectAdvance(int8_t horizontal, int8_t vertical) { return horizontal; } +}; + + +class ScrollRight : public ScrollSupport +{ + public: + ScrollRight(String message); + int16_t initialX(int8_t w) { return (int)message.length() * -1 * w; } + int16_t initialY(int8_t h) { return 6 + (h / 2); } + boolean isFinished(int16_t x, int16_t y, int8_t w, int8_t h) { return x >= 12; } + int16_t nextX(int16_t x) { return x + 1; } + int16_t nextY(int16_t y) { return y; } + int16_t nextCharacterX(int16_t x, int8_t advance) { return x + (int16_t)advance; } + int16_t nextCharacterY(int16_t y, int8_t advance) { return y; } + int8_t selectAdvance(int8_t horizontal, int8_t vertical) { return horizontal; } +}; + + +class ScrollUp : public ScrollSupport +{ + public: + ScrollUp(String message); + int16_t initialX(int8_t w) { return 6 - (w / 2); } + int16_t initialY(int8_t h) { return 12 + h; } + boolean isFinished(int16_t x, int16_t y, int8_t w, int8_t h) { return y <= ((int)message.length() * -1 * h); } + int16_t nextX(int16_t x) { return x; } + int16_t nextY(int16_t y) { return y - 1; } + int16_t nextCharacterX(int16_t x, int8_t advance) { return x; } + int16_t nextCharacterY(int16_t y, int8_t advance) { return y + (int16_t)advance; } + int8_t selectAdvance(int8_t horizontal, int8_t vertical) { return vertical; } +}; + +/* class ScrollDown : public ScrollSupport */ +/* { */ +/* }; */ + +#endif diff --git a/variants/Sinobit/sinobit.cpp b/variants/Sinobit/sinobit.cpp new file mode 100644 index 00000000..e0f9e368 --- /dev/null +++ b/variants/Sinobit/sinobit.cpp @@ -0,0 +1,252 @@ +#include "sinobit.h" +#include "scroll_support.h" + + +#ifndef pgm_read_byte + #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#endif +#ifndef pgm_read_word + #define pgm_read_word(addr) (*(const unsigned short *)(addr)) +#endif +#ifndef pgm_read_dword + #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) +#endif + +// Pointers are a peculiar case...typically 16-bit on AVR boards, +// 32 bits elsewhere. Try to accommodate both... + +#if !defined(__INT_MAX__) || (__INT_MAX__ > 0xFFFF) + #define pgm_read_pointer(addr) ((void *)pgm_read_dword(addr)) +#else + #define pgm_read_pointer(addr) ((void *)pgm_read_word(addr)) +#endif + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef _swap_int16_t +#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; } +#endif + +Sinobit_HT1632::Sinobit_HT1632(int8_t data, int8_t wr, int8_t cs, int8_t rd) + : Adafruit_HT1632(data, wr, cs, rd) +{ +} + +void Sinobit_HT1632::blankScreen() +{ + memset(ledmatrix, 0, sizeof(ledmatrix)); +} + + +Sinobit::Sinobit() : Adafruit_GFX(12, 12), leds(15, 13, 16) {} + + +boolean Sinobit::translate(int16_t x, int16_t y, int16_t *x_out, int16_t *y_out) +{ + if (y < 0 || y > 11 || x < 0 || x > 11) { + return false; + } else if ((y < 8 && x < 8) || (y > 7 && x > 7)) { + *y_out = y; + *x_out = x; + } else if (y > 7 && x < 8) { + *y_out = y - 8; + *x_out = x + 8; + } else if (y < 8 && x > 7) { + *y_out = y + 8; + *x_out = x - 8; + } + return true; +} + +void Sinobit::setPixel(uint8_t x, uint8_t y) +{ + drawPixel(x, y, 1); +} + +void Sinobit::clrPixel(uint8_t x, uint8_t y) +{ + drawPixel(x, y, 0); +} + +void Sinobit::drawPixel(int16_t x, int16_t y, uint16_t color) +{ + if((x < 0) || (x >= _width) || (y < 0) || (y >= _height)) return; + + switch(rotation) { // Rotate pixel into device-specific coordinates + case 1: + _swap_int16_t(x, y); + x = WIDTH - 1 - x; + break; + case 2: + x = WIDTH - 1 - x; + y = HEIGHT - 1 - y; + break; + case 3: + _swap_int16_t(x, y); + y = HEIGHT - 1 - y; + break; + } + + int16_t real_row, real_col; + if (!translate(x, y, &real_col, &real_row)) return; + + uint16_t i; + + if (real_row < 8) i = 7; + else if (real_row < 16) i = 128 + 7; + else i = 256 + 7; + i -= (real_row & 7); + + if (real_col < 8) real_col *= 2; + else real_col = (real_col-8) * 2 + 1; + i += real_col * 8; + + if(color) leds.setPixel(i); + else leds.clrPixel(i); +} + +boolean Sinobit::begin() +{ + leds.begin(ADA_HT1632_COMMON_16NMOS); + return true; +} + +void Sinobit::clearScreen() +{ + leds.clearScreen(); +} + +void Sinobit::blankScreen() +{ + leds.blankScreen(); +} + +void Sinobit::fillScreen() +{ + leds.fillScreen(); +} + +void Sinobit::setBrightness(uint8_t b) +{ + leds.setBrightness(b); +} + +void Sinobit::blink(boolean b) +{ + leds.blink(b); +} + +void Sinobit::writeScreen() +{ + leds.writeScreen(); +} + +void Sinobit::setReadingDirection(readingDirection_t dir) +{ + reading_direction = dir; +} + + +// Retrieve a character's bounds +// returns true if spicified char as a glyph + +int8_t Sinobit::characterAdvance(char c, ScrollSupport *scroller) +{ + if(gfxFont) { + if (c != '\n' && c != '\r') { // Not a carriage return; is normal char + uint8_t first = pgm_read_byte(&gfxFont->first); + uint8_t last = pgm_read_byte(&gfxFont->last); + if((c >= first) && (c <= last)) { // Char present in this font? + GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c - first]); + return scroller->selectAdvance(pgm_read_byte(&glyph->xAdvance), + pgm_read_byte(&glyph->height) + 1); + } else { + return 0; + } + } + + } else { // Default font + + if(c != '\n' && c != '\r') { // Normal char; ignore carriage returns + return scroller->selectAdvance(7,8); + } + return true; + } +} + +int8_t Sinobit::fontHeight() +{ + if (gfxFont) { + return pgm_read_byte(&gfxFont->yAdvance); + } else { + return 8; + } +} + + +int8_t Sinobit::fontWidth() +{ + if (gfxFont) { + uint8_t first = pgm_read_byte(&gfxFont->first); + uint8_t last = pgm_read_byte(&gfxFont->last); + uint8_t w = 0; + for (int c = first; c <= last; c++) { + if (c != '\n' && c != '\r') { + GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c]); + int8_t glyph_width = pgm_read_byte(&glyph->xAdvance); + if (glyph_width <= 12) { + w = max(w, glyph_width); + } + } + } + return w; + } else { + return 7; + } +} + + +// print a string using the set reading direction + +void Sinobit::printDirectionally(String message, ScrollSupport *scroller) +{ + const char *buffer = message.c_str(); + size_t size = message.length(); + int16_t x = cursor_x; + int16_t y = cursor_y; + while (size--) { + drawChar(x, y, *buffer, 1, 0, 1); + int8_t advance = characterAdvance(*buffer, scroller); + x = scroller->nextCharacterX(x, advance); + y = scroller->nextCharacterY(y, advance); + buffer++; + } +} + + +// scroll a string onto the LED array based on the reading direction that's set + +void Sinobit::scroll(String message, uint16_t interstitialDelay) +{ + ScrollSupport *scroller = ScrollSupport::makeFor(reading_direction, message); + int8_t h = fontHeight(); + int8_t w = fontWidth(); + int16_t x = scroller->initialX(w); + int16_t y = scroller->initialY(gfxFont ? h : -h); + while (!scroller->isFinished(x, y, w, h)) { + setCursor(x, y); + blankScreen(); + printDirectionally(message, scroller); + writeScreen(); + x = scroller->nextX(x); + y = scroller->nextY(y); + delay(interstitialDelay); + } + delete scroller; +} diff --git a/variants/Sinobit/sinobit.h b/variants/Sinobit/sinobit.h new file mode 100644 index 00000000..74dd6cf9 --- /dev/null +++ b/variants/Sinobit/sinobit.h @@ -0,0 +1,76 @@ +#ifndef SINOBIT_H_ +#define SINOBIT_H_ + +#include "Adafruit_GFX.h" +#include "Adafruit_HT1632.h" +#include "scroll_support.h" + + +#define SINOBIT_PAD_P0 (0) +#define SINOBIT_PAD_P1 (1) +#define SINOBIT_PAD_P2 (2) +#define SINOBIT_PAD_P3 (3) +#define SINOBIT_PAD_P4 (4) +#define SINOBIT_PAD_P5 (10) + +#define SINOBIT_P0 (0) +#define SINOBIT_P1 (1) +#define SINOBIT_P2 (2) +#define SINOBIT_P3 (3) +#define SINOBIT_P4 (4) +#define SINOBIT_P5 (5) +#define SINOBIT_P6 (6) +#define SINOBIT_P7 (7) +#define SINOBIT_P8 (8) +#define SINOBIT_P9 (9) +#define SINOBIT_P10 (10) +#define SINOBIT_P11 (11) +#define SINOBIT_P12 (12) +#define SINOBIT_P13 (13) +#define SINOBIT_P14 (14) +#define SINOBIT_P15 (15) +#define SINOBIT_P16 (16) +/* #define SINOBIT_P17 (17) */ +/* #define SINOBIT_P18 (18) */ +#define SINOBIT_P19 (19) +#define SINOBIT_P20 (20) + +#define SINOBIT_BUTTON_A (5) +#define SINOBIT_BUTTON_B (11) + +class Sinobit_HT1632 : public Adafruit_HT1632 +{ + public: + Sinobit_HT1632(int8_t data, int8_t wr, int8_t cs, int8_t rd = -1); + void blankScreen(); +}; + + +class Sinobit : public Adafruit_GFX +{ + + public: + Sinobit(); + boolean begin(); + void clearScreen(void); + void blankScreen(void); + void fillScreen(void); + void blink(boolean b); + void setBrightness(uint8_t brightness); + void writeScreen(); + void clrPixel(uint8_t x, uint8_t y); + void setPixel(uint8_t x, uint8_t y); + void drawPixel(int16_t x, int16_t y, uint16_t color); + void setReadingDirection(readingDirection_t dir); + void scroll(String message, uint16_t interstitialDelay); + private: + boolean translate(int16_t x, int16_t y, int16_t *x_out, int16_t *y_out); + int8_t characterAdvance(char c, ScrollSupport *scroller); + int8_t fontHeight(); + int8_t fontWidth(); + void printDirectionally(String message, ScrollSupport *scroller); + Sinobit_HT1632 leds; + readingDirection_t reading_direction; +}; + +#endif diff --git a/variants/Sinobit/variant.cpp b/variants/Sinobit/variant.cpp new file mode 100644 index 00000000..fb637e0c --- /dev/null +++ b/variants/Sinobit/variant.cpp @@ -0,0 +1,68 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "variant.h" + +const uint32_t g_ADigitalPinMap[] = { + // 0 - 4 + 3, // A0 - left pad + 2, // A1 - middle pad + 1, // A2 - right pad + 4, // A3 - COL1 + 5, // A4 - COL2 + + // 5 - 9 + 17, // BTN A + 12, // COL9 + 11, // COL8 + 18, + 10, // COL7 + + 6, // A5 - COL3 + + 26, // BTN B + 20, + 23, // SCK + 22, // MISO + 21, // MOSI + 16, + + // 17 + 18 + (uint32_t)-1, // 3.3V + (uint32_t)-1, // 3.3V + + 0, // SCL + 30, // SDA + + 25, // RX + 24, // TX + + 7, // COL4 + 8, // COL5 + 9, // COL6 + 13, // ROW1 + 14, // ROW2 + 15, // ROW3 + + 28, // ACCEL INT 1 + 27, // ACCEL INT 2 + 29, // MAG INT 2 + + 19 // RST +}; diff --git a/variants/Sinobit/variant.h b/variants/Sinobit/variant.h new file mode 100644 index 00000000..35c7d720 --- /dev/null +++ b/variants/Sinobit/variant.h @@ -0,0 +1,104 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _VARIANT_BBC_MICROBIT_ +#define _VARIANT_BBC_MICROBIT_ + +/** Master clock frequency */ +#define VARIANT_MCK (16000000ul) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +// Number of pins defined in PinDescription array +#define PINS_COUNT (33u) +#define NUM_DIGITAL_PINS (20u) +#define NUM_ANALOG_INPUTS (6u) +#define NUM_ANALOG_OUTPUTS (0u) + +// LEDs +#define PIN_LED (13) +#define LED_BUILTIN PIN_LED +// #define + +// Buttons +#define PIN_BUTTON_A (5) +#define PIN_BUTTON_B (11) + +/* + * Analog pins + */ +#define PIN_A0 (0) +#define PIN_A1 (1) +#define PIN_A2 (2) +#define PIN_A3 (3) +#define PIN_A4 (4) +#define PIN_A5 (10) + + +static const uint8_t A0 = PIN_A0 ; +static const uint8_t A1 = PIN_A1 ; +static const uint8_t A2 = PIN_A2 ; +static const uint8_t A3 = PIN_A3 ; +static const uint8_t A4 = PIN_A4 ; +static const uint8_t A5 = PIN_A5 ; +#define ADC_RESOLUTION 10 + +/* + * Serial interfaces + */ +// Serial +#define PIN_SERIAL_RX (21) +#define PIN_SERIAL_TX (22) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO (14) +#define PIN_SPI_MOSI (15) +#define PIN_SPI_SCK (13) + +static const uint8_t SS = 16 ; +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (20u) +#define PIN_WIRE_SCL (19u) + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +#ifdef __cplusplus +} +#endif + +#endif From 57176649b907f0af667d7d7816dd01591bb95653 Mon Sep 17 00:00:00 2001 From: Tomas Lubkowitz Date: Sun, 7 Jan 2018 14:49:02 +0100 Subject: [PATCH 2/6] Removed 3rd party libraries and modification of JSON --- .vscode/settings.json | 5 + docs/package_nRF5_boards_index.json | 46 - variants/Sinobit/Adafruit_GFX.cpp | 1348 -------------------------- variants/Sinobit/Adafruit_GFX.h | 211 ---- variants/Sinobit/Adafruit_HT1632.cpp | 282 ------ variants/Sinobit/Adafruit_HT1632.h | 84 -- variants/Sinobit/README.md | 7 +- variants/Sinobit/gfxfont.h | 24 - variants/Sinobit/glcdfont.c | 276 ------ variants/Sinobit/license.txt | 24 - variants/Sinobit/scroll_support.cpp | 33 - variants/Sinobit/scroll_support.h | 82 -- variants/Sinobit/sinobit.cpp | 252 ----- variants/Sinobit/sinobit.h | 76 -- 14 files changed, 10 insertions(+), 2740 deletions(-) create mode 100644 .vscode/settings.json delete mode 100644 variants/Sinobit/Adafruit_GFX.cpp delete mode 100644 variants/Sinobit/Adafruit_GFX.h delete mode 100644 variants/Sinobit/Adafruit_HT1632.cpp delete mode 100644 variants/Sinobit/Adafruit_HT1632.h delete mode 100644 variants/Sinobit/gfxfont.h delete mode 100644 variants/Sinobit/glcdfont.c delete mode 100644 variants/Sinobit/license.txt delete mode 100644 variants/Sinobit/scroll_support.cpp delete mode 100644 variants/Sinobit/scroll_support.h delete mode 100644 variants/Sinobit/sinobit.cpp delete mode 100644 variants/Sinobit/sinobit.h diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..e7fa3d37 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "terminal.integrated.env.osx": { + "PATH": "/Users/Tomas/.platformio/penv/bin:/Users/Tomas/.npm-packages/bin:/Users/Tomas/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Users/Tomas/Library/Python/2.7/bin" + } +} \ No newline at end of file diff --git a/docs/package_nRF5_boards_index.json b/docs/package_nRF5_boards_index.json index c02d6005..bb97deac 100644 --- a/docs/package_nRF5_boards_index.json +++ b/docs/package_nRF5_boards_index.json @@ -157,52 +157,6 @@ "version": "0.10.0-dev.nrf5" } ] - }, - { - "name": "Nordic Semiconductor nRF5 Boards", - "architecture": "nRF5", - "version": "0.5.0", - "category": "Contributed", - "help": { - "online": "https://github.com/sandeepmistry/arduino-nRF5/issues" - }, - "url": "https://github.com/sandeepmistry/arduino-nRF5/archive/0.4.0.tar.gz", - "archiveFileName": "arduino-nRF52-0.4.0.tar.gz", - "checksum": "MD5:E82DA39642AB48492A9FEDE8159871F5", - "size": "573440", - "boards": [ - {"name": "BBC micro:bit"}, - {"name": "Bluz DK"}, - {"name": "Electronut labs bluey"}, - {"name": "Generic nRF51822"}, - {"name": "Generic nRF52823"}, - {"name": "OSHChip"}, - {"name": "ng-beacon"}, - {"name": "nRF51 Dongle"}, - {"name": "nRF51822 Development Kit"}, - {"name": "nRF52 DK"}, - {"name": "Nordic Beacon Kit"}, - {"name": "RedBear BLE Nano 2"}, - {"name": "RedBear Blend 2"}, - {"name": "RedBearLab BLE Nano"}, - {"name": "RedBearLab nRF51822"}, - {"name": "Taida Century nRF52 mini board"}, - {"name": "TinyBLE"}, - {"name": "Waveshare BLE400"}, - {"name": "Sino:bit"} - ], - "toolsDependencies": [ - { - "packager": "sandeepmistry", - "name": "gcc-arm-none-eabi", - "version": "5_2-2015q4" - }, - { - "packager": "sandeepmistry", - "name": "openocd", - "version": "0.10.0-dev.nrf5" - } - ] } ], "tools":[ diff --git a/variants/Sinobit/Adafruit_GFX.cpp b/variants/Sinobit/Adafruit_GFX.cpp deleted file mode 100644 index 53c7ad35..00000000 --- a/variants/Sinobit/Adafruit_GFX.cpp +++ /dev/null @@ -1,1348 +0,0 @@ -/* -This is the core graphics library for all our displays, providing a common -set of graphics primitives (points, lines, circles, etc.). It needs to be -paired with a hardware-specific library for each display device we carry -(to handle the lower-level functions). - -Adafruit invests time and resources providing this open source code, please -support Adafruit & open-source hardware by purchasing products from Adafruit! - -Copyright (c) 2013 Adafruit Industries. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - */ - -#include "Adafruit_GFX.h" -#include "glcdfont.c" -#ifdef __AVR__ - #include -#elif defined(ESP8266) || defined(ESP32) - #include -#endif - -// Many (but maybe not all) non-AVR board installs define macros -// for compatibility with existing PROGMEM-reading AVR code. -// Do our own checks and defines here for good measure... - -#ifndef pgm_read_byte - #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) -#endif -#ifndef pgm_read_word - #define pgm_read_word(addr) (*(const unsigned short *)(addr)) -#endif -#ifndef pgm_read_dword - #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) -#endif - -// Pointers are a peculiar case...typically 16-bit on AVR boards, -// 32 bits elsewhere. Try to accommodate both... - -#if !defined(__INT_MAX__) || (__INT_MAX__ > 0xFFFF) - #define pgm_read_pointer(addr) ((void *)pgm_read_dword(addr)) -#else - #define pgm_read_pointer(addr) ((void *)pgm_read_word(addr)) -#endif - -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef _swap_int16_t -#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; } -#endif - -Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h): -WIDTH(w), HEIGHT(h) -{ - _width = WIDTH; - _height = HEIGHT; - rotation = 0; - cursor_y = cursor_x = 0; - textsize = 1; - textcolor = textbgcolor = 0xFFFF; - wrap = true; - _cp437 = false; - gfxFont = NULL; -} - -// Bresenham's algorithm - thx wikpedia -void Adafruit_GFX::writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, - uint16_t color) { - int16_t steep = abs(y1 - y0) > abs(x1 - x0); - if (steep) { - _swap_int16_t(x0, y0); - _swap_int16_t(x1, y1); - } - - if (x0 > x1) { - _swap_int16_t(x0, x1); - _swap_int16_t(y0, y1); - } - - int16_t dx, dy; - dx = x1 - x0; - dy = abs(y1 - y0); - - int16_t err = dx / 2; - int16_t ystep; - - if (y0 < y1) { - ystep = 1; - } else { - ystep = -1; - } - - for (; x0<=x1; x0++) { - if (steep) { - writePixel(y0, x0, color); - } else { - writePixel(x0, y0, color); - } - err -= dy; - if (err < 0) { - y0 += ystep; - err += dx; - } - } -} - -void Adafruit_GFX::startWrite(){ - // Overwrite in subclasses if desired! -} - -void Adafruit_GFX::writePixel(int16_t x, int16_t y, uint16_t color){ - // Overwrite in subclasses if startWrite is defined! - drawPixel(x, y, color); -} - -// (x,y) is topmost point; if unsure, calling function -// should sort endpoints or call writeLine() instead -void Adafruit_GFX::writeFastVLine(int16_t x, int16_t y, - int16_t h, uint16_t color) { - // Overwrite in subclasses if startWrite is defined! - // Can be just writeLine(x, y, x, y+h-1, color); - // or writeFillRect(x, y, 1, h, color); - drawFastVLine(x, y, h, color); -} - -// (x,y) is leftmost point; if unsure, calling function -// should sort endpoints or call writeLine() instead -void Adafruit_GFX::writeFastHLine(int16_t x, int16_t y, - int16_t w, uint16_t color) { - // Overwrite in subclasses if startWrite is defined! - // Example: writeLine(x, y, x+w-1, y, color); - // or writeFillRect(x, y, w, 1, color); - drawFastHLine(x, y, w, color); -} - -void Adafruit_GFX::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, - uint16_t color) { - // Overwrite in subclasses if desired! - fillRect(x,y,w,h,color); -} - -void Adafruit_GFX::endWrite(){ - // Overwrite in subclasses if startWrite is defined! -} - -// (x,y) is topmost point; if unsure, calling function -// should sort endpoints or call drawLine() instead -void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, - int16_t h, uint16_t color) { - // Update in subclasses if desired! - startWrite(); - writeLine(x, y, x, y+h-1, color); - endWrite(); -} - -// (x,y) is leftmost point; if unsure, calling function -// should sort endpoints or call drawLine() instead -void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, - int16_t w, uint16_t color) { - // Update in subclasses if desired! - startWrite(); - writeLine(x, y, x+w-1, y, color); - endWrite(); -} - -void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, - uint16_t color) { - // Update in subclasses if desired! - startWrite(); - for (int16_t i=x; i y1) _swap_int16_t(y0, y1); - drawFastVLine(x0, y0, y1 - y0 + 1, color); - } else if(y0 == y1){ - if(x0 > x1) _swap_int16_t(x0, x1); - drawFastHLine(x0, y0, x1 - x0 + 1, color); - } else { - startWrite(); - writeLine(x0, y0, x1, y1, color); - endWrite(); - } -} - -// Draw a circle outline -void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r, - uint16_t color) { - int16_t f = 1 - r; - int16_t ddF_x = 1; - int16_t ddF_y = -2 * r; - int16_t x = 0; - int16_t y = r; - - startWrite(); - writePixel(x0 , y0+r, color); - writePixel(x0 , y0-r, color); - writePixel(x0+r, y0 , color); - writePixel(x0-r, y0 , color); - - while (x= 0) { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - - writePixel(x0 + x, y0 + y, color); - writePixel(x0 - x, y0 + y, color); - writePixel(x0 + x, y0 - y, color); - writePixel(x0 - x, y0 - y, color); - writePixel(x0 + y, y0 + x, color); - writePixel(x0 - y, y0 + x, color); - writePixel(x0 + y, y0 - x, color); - writePixel(x0 - y, y0 - x, color); - } - endWrite(); -} - -void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0, - int16_t r, uint8_t cornername, uint16_t color) { - int16_t f = 1 - r; - int16_t ddF_x = 1; - int16_t ddF_y = -2 * r; - int16_t x = 0; - int16_t y = r; - - while (x= 0) { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - if (cornername & 0x4) { - writePixel(x0 + x, y0 + y, color); - writePixel(x0 + y, y0 + x, color); - } - if (cornername & 0x2) { - writePixel(x0 + x, y0 - y, color); - writePixel(x0 + y, y0 - x, color); - } - if (cornername & 0x8) { - writePixel(x0 - y, y0 + x, color); - writePixel(x0 - x, y0 + y, color); - } - if (cornername & 0x1) { - writePixel(x0 - y, y0 - x, color); - writePixel(x0 - x, y0 - y, color); - } - } -} - -void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r, - uint16_t color) { - startWrite(); - writeFastVLine(x0, y0-r, 2*r+1, color); - fillCircleHelper(x0, y0, r, 3, 0, color); - endWrite(); -} - -// Used to do circles and roundrects -void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, - uint8_t cornername, int16_t delta, uint16_t color) { - - int16_t f = 1 - r; - int16_t ddF_x = 1; - int16_t ddF_y = -2 * r; - int16_t x = 0; - int16_t y = r; - - while (x= 0) { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - - if (cornername & 0x1) { - writeFastVLine(x0+x, y0-y, 2*y+1+delta, color); - writeFastVLine(x0+y, y0-x, 2*x+1+delta, color); - } - if (cornername & 0x2) { - writeFastVLine(x0-x, y0-y, 2*y+1+delta, color); - writeFastVLine(x0-y, y0-x, 2*x+1+delta, color); - } - } -} - -// Draw a rectangle -void Adafruit_GFX::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, - uint16_t color) { - startWrite(); - writeFastHLine(x, y, w, color); - writeFastHLine(x, y+h-1, w, color); - writeFastVLine(x, y, h, color); - writeFastVLine(x+w-1, y, h, color); - endWrite(); -} - -// Draw a rounded rectangle -void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w, - int16_t h, int16_t r, uint16_t color) { - // smarter version - startWrite(); - writeFastHLine(x+r , y , w-2*r, color); // Top - writeFastHLine(x+r , y+h-1, w-2*r, color); // Bottom - writeFastVLine(x , y+r , h-2*r, color); // Left - writeFastVLine(x+w-1, y+r , h-2*r, color); // Right - // draw four corners - drawCircleHelper(x+r , y+r , r, 1, color); - drawCircleHelper(x+w-r-1, y+r , r, 2, color); - drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color); - drawCircleHelper(x+r , y+h-r-1, r, 8, color); - endWrite(); -} - -// Fill a rounded rectangle -void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, - int16_t h, int16_t r, uint16_t color) { - // smarter version - startWrite(); - writeFillRect(x+r, y, w-2*r, h, color); - - // draw four corners - fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color); - fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color); - endWrite(); -} - -// Draw a triangle -void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0, - int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) { - drawLine(x0, y0, x1, y1, color); - drawLine(x1, y1, x2, y2, color); - drawLine(x2, y2, x0, y0, color); -} - -// Fill a triangle -void Adafruit_GFX::fillTriangle(int16_t x0, int16_t y0, - int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) { - - int16_t a, b, y, last; - - // Sort coordinates by Y order (y2 >= y1 >= y0) - if (y0 > y1) { - _swap_int16_t(y0, y1); _swap_int16_t(x0, x1); - } - if (y1 > y2) { - _swap_int16_t(y2, y1); _swap_int16_t(x2, x1); - } - if (y0 > y1) { - _swap_int16_t(y0, y1); _swap_int16_t(x0, x1); - } - - startWrite(); - if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing - a = b = x0; - if(x1 < a) a = x1; - else if(x1 > b) b = x1; - if(x2 < a) a = x2; - else if(x2 > b) b = x2; - writeFastHLine(a, y0, b-a+1, color); - endWrite(); - return; - } - - int16_t - dx01 = x1 - x0, - dy01 = y1 - y0, - dx02 = x2 - x0, - dy02 = y2 - y0, - dx12 = x2 - x1, - dy12 = y2 - y1; - int32_t - sa = 0, - sb = 0; - - // For upper part of triangle, find scanline crossings for segments - // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 - // is included here (and second loop will be skipped, avoiding a /0 - // error there), otherwise scanline y1 is skipped here and handled - // in the second loop...which also avoids a /0 error here if y0=y1 - // (flat-topped triangle). - if(y1 == y2) last = y1; // Include y1 scanline - else last = y1-1; // Skip it - - for(y=y0; y<=last; y++) { - a = x0 + sa / dy01; - b = x0 + sb / dy02; - sa += dx01; - sb += dx02; - /* longhand: - a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); - b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); - */ - if(a > b) _swap_int16_t(a,b); - writeFastHLine(a, y, b-a+1, color); - } - - // For lower part of triangle, find scanline crossings for segments - // 0-2 and 1-2. This loop is skipped if y1=y2. - sa = dx12 * (y - y1); - sb = dx02 * (y - y0); - for(; y<=y2; y++) { - a = x1 + sa / dy12; - b = x0 + sb / dy02; - sa += dx12; - sb += dx02; - /* longhand: - a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); - b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); - */ - if(a > b) _swap_int16_t(a,b); - writeFastHLine(a, y, b-a+1, color); - } - endWrite(); -} - -// BITMAP / XBITMAP / GRAYSCALE / RGB BITMAP FUNCTIONS --------------------- - -// Draw a PROGMEM-resident 1-bit image at the specified (x,y) position, -// using the specified foreground color (unset bits are transparent). -void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, - const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color) { - - int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte - uint8_t byte = 0; - - startWrite(); - for(int16_t j=0; j>= 1; - else byte = pgm_read_byte(&bitmap[j * byteWidth + i / 8]); - // Nearly identical to drawBitmap(), only the bit order - // is reversed here (left-to-right = LSB to MSB): - if(byte & 0x01) writePixel(x+i, y, color); - } - } - endWrite(); -} - -// Draw a PROGMEM-resident 8-bit image (grayscale) at the specified (x,y) -// pos. Specifically for 8-bit display devices such as IS31FL3731; -// no color reduction/expansion is performed. -void Adafruit_GFX::drawGrayscaleBitmap(int16_t x, int16_t y, - const uint8_t bitmap[], int16_t w, int16_t h) { - startWrite(); - for(int16_t j=0; j= _width) || // Clip right - (y >= _height) || // Clip bottom - ((x + 6 * size - 1) < 0) || // Clip left - ((y + 8 * size - 1) < 0)) // Clip top - return; - - if(!_cp437 && (c >= 176)) c++; // Handle 'classic' charset behavior - - startWrite(); - for(int8_t i=0; i<5; i++ ) { // Char bitmap = 5 columns - uint8_t line = pgm_read_byte(&font[c * 5 + i]); - for(int8_t j=0; j<8; j++, line >>= 1) { - if(line & 1) { - if(size == 1) - writePixel(x+i, y+j, color); - else - writeFillRect(x+i*size, y+j*size, size, size, color); - } else if(bg != color) { - if(size == 1) - writePixel(x+i, y+j, bg); - else - writeFillRect(x+i*size, y+j*size, size, size, bg); - } - } - } - if(bg != color) { // If opaque, draw vertical line for last column - if(size == 1) writeFastVLine(x+5, y, 8, bg); - else writeFillRect(x+5*size, y, size, 8*size, bg); - } - endWrite(); - - } else { // Custom font - - // Character is assumed previously filtered by write() to eliminate - // newlines, returns, non-printable characters, etc. Calling - // drawChar() directly with 'bad' characters of font may cause mayhem! - - c -= (uint8_t)pgm_read_byte(&gfxFont->first); - GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c]); - uint8_t *bitmap = (uint8_t *)pgm_read_pointer(&gfxFont->bitmap); - - uint16_t bo = pgm_read_word(&glyph->bitmapOffset); - uint8_t w = pgm_read_byte(&glyph->width), - h = pgm_read_byte(&glyph->height); - int8_t xo = pgm_read_byte(&glyph->xOffset), - yo = pgm_read_byte(&glyph->yOffset); - uint8_t xx, yy, bits = 0, bit = 0; - int16_t xo16 = 0, yo16 = 0; - - if(size > 1) { - xo16 = xo; - yo16 = yo; - } - - // Todo: Add character clipping here - - // NOTE: THERE IS NO 'BACKGROUND' COLOR OPTION ON CUSTOM FONTS. - // THIS IS ON PURPOSE AND BY DESIGN. The background color feature - // has typically been used with the 'classic' font to overwrite old - // screen contents with new data. This ONLY works because the - // characters are a uniform size; it's not a sensible thing to do with - // proportionally-spaced fonts with glyphs of varying sizes (and that - // may overlap). To replace previously-drawn text when using a custom - // font, use the getTextBounds() function to determine the smallest - // rectangle encompassing a string, erase the area with fillRect(), - // then draw new text. This WILL infortunately 'blink' the text, but - // is unavoidable. Drawing 'background' pixels will NOT fix this, - // only creates a new set of problems. Have an idea to work around - // this (a canvas object type for MCUs that can afford the RAM and - // displays supporting setAddrWindow() and pushColors()), but haven't - // implemented this yet. - - startWrite(); - for(yy=0; yy= 100 -size_t Adafruit_GFX::write(uint8_t c) { -#else -void Adafruit_GFX::write(uint8_t c) { -#endif - if(!gfxFont) { // 'Classic' built-in font - - if(c == '\n') { // Newline? - cursor_x = 0; // Reset x to zero, - cursor_y += textsize * 8; // advance y one line - } else if(c != '\r') { // Ignore carriage returns - if(wrap && ((cursor_x + textsize * 6) > _width)) { // Off right? - cursor_x = 0; // Reset x to zero, - cursor_y += textsize * 8; // advance y one line - } - drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize); - cursor_x += textsize * 6; // Advance x one char - } - - } else { // Custom font - - if(c == '\n') { - cursor_x = 0; - cursor_y += (int16_t)textsize * - (uint8_t)pgm_read_byte(&gfxFont->yAdvance); - } else if(c != '\r') { - uint8_t first = pgm_read_byte(&gfxFont->first); - if((c >= first) && (c <= (uint8_t)pgm_read_byte(&gfxFont->last))) { - GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer( - &gfxFont->glyph))[c - first]); - uint8_t w = pgm_read_byte(&glyph->width), - h = pgm_read_byte(&glyph->height); - if((w > 0) && (h > 0)) { // Is there an associated bitmap? - int16_t xo = (int8_t)pgm_read_byte(&glyph->xOffset); // sic - if(wrap && ((cursor_x + textsize * (xo + w)) > _width)) { - cursor_x = 0; - cursor_y += (int16_t)textsize * - (uint8_t)pgm_read_byte(&gfxFont->yAdvance); - } - drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize); - } - cursor_x += (uint8_t)pgm_read_byte(&glyph->xAdvance) * (int16_t)textsize; - } - } - - } -#if ARDUINO >= 100 - return 1; -#endif -} - -void Adafruit_GFX::setCursor(int16_t x, int16_t y) { - cursor_x = x; - cursor_y = y; -} - -int16_t Adafruit_GFX::getCursorX(void) const { - return cursor_x; -} - -int16_t Adafruit_GFX::getCursorY(void) const { - return cursor_y; -} - -void Adafruit_GFX::setTextSize(uint8_t s) { - textsize = (s > 0) ? s : 1; -} - -void Adafruit_GFX::setTextColor(uint16_t c) { - // For 'transparent' background, we'll set the bg - // to the same as fg instead of using a flag - textcolor = textbgcolor = c; -} - -void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) { - textcolor = c; - textbgcolor = b; -} - -void Adafruit_GFX::setTextWrap(boolean w) { - wrap = w; -} - -uint8_t Adafruit_GFX::getRotation(void) const { - return rotation; -} - -void Adafruit_GFX::setRotation(uint8_t x) { - rotation = (x & 3); - switch(rotation) { - case 0: - case 2: - _width = WIDTH; - _height = HEIGHT; - break; - case 1: - case 3: - _width = HEIGHT; - _height = WIDTH; - break; - } -} - -// Enable (or disable) Code Page 437-compatible charset. -// There was an error in glcdfont.c for the longest time -- one character -// (#176, the 'light shade' block) was missing -- this threw off the index -// of every character that followed it. But a TON of code has been written -// with the erroneous character indices. By default, the library uses the -// original 'wrong' behavior and old sketches will still work. Pass 'true' -// to this function to use correct CP437 character values in your code. -void Adafruit_GFX::cp437(boolean x) { - _cp437 = x; -} - -void Adafruit_GFX::setFont(const GFXfont *f) { - if(f) { // Font struct pointer passed in? - if(!gfxFont) { // And no current font struct? - // Switching from classic to new font behavior. - // Move cursor pos down 6 pixels so it's on baseline. - cursor_y += 6; - } - } else if(gfxFont) { // NULL passed. Current font struct defined? - // Switching from new to classic font behavior. - // Move cursor pos up 6 pixels so it's at top-left of char. - cursor_y -= 6; - } - gfxFont = (GFXfont *)f; -} - -// Broke this out as it's used by both the PROGMEM- and RAM-resident -// getTextBounds() functions. -void Adafruit_GFX::charBounds(char c, int16_t *x, int16_t *y, - int16_t *minx, int16_t *miny, int16_t *maxx, int16_t *maxy) { - - if(gfxFont) { - - if(c == '\n') { // Newline? - *x = 0; // Reset x to zero, advance y by one line - *y += textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance); - } else if(c != '\r') { // Not a carriage return; is normal char - uint8_t first = pgm_read_byte(&gfxFont->first), - last = pgm_read_byte(&gfxFont->last); - if((c >= first) && (c <= last)) { // Char present in this font? - GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer( - &gfxFont->glyph))[c - first]); - uint8_t gw = pgm_read_byte(&glyph->width), - gh = pgm_read_byte(&glyph->height), - xa = pgm_read_byte(&glyph->xAdvance); - int8_t xo = pgm_read_byte(&glyph->xOffset), - yo = pgm_read_byte(&glyph->yOffset); - if(wrap && ((*x+(((int16_t)xo+gw)*textsize)) > _width)) { - *x = 0; // Reset x to zero, advance y by one line - *y += textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance); - } - int16_t ts = (int16_t)textsize, - x1 = *x + xo * ts, - y1 = *y + yo * ts, - x2 = x1 + gw * ts - 1, - y2 = y1 + gh * ts - 1; - if(x1 < *minx) *minx = x1; - if(y1 < *miny) *miny = y1; - if(x2 > *maxx) *maxx = x2; - if(y2 > *maxy) *maxy = y2; - *x += xa * ts; - } - } - - } else { // Default font - - if(c == '\n') { // Newline? - *x = 0; // Reset x to zero, - *y += textsize * 8; // advance y one line - // min/max x/y unchaged -- that waits for next 'normal' character - } else if(c != '\r') { // Normal char; ignore carriage returns - if(wrap && ((*x + textsize * 6) > _width)) { // Off right? - *x = 0; // Reset x to zero, - *y += textsize * 8; // advance y one line - } - int x2 = *x + textsize * 6 - 1, // Lower-right pixel of char - y2 = *y + textsize * 8 - 1; - if(x2 > *maxx) *maxx = x2; // Track max x, y - if(y2 > *maxy) *maxy = y2; - if(*x < *minx) *minx = *x; // Track min x, y - if(*y < *miny) *miny = *y; - *x += textsize * 6; // Advance x one char - } - } -} - -// Pass string and a cursor position, returns UL corner and W,H. -void Adafruit_GFX::getTextBounds(char *str, int16_t x, int16_t y, - int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h) { - uint8_t c; // Current character - - *x1 = x; - *y1 = y; - *w = *h = 0; - - int16_t minx = _width, miny = _height, maxx = -1, maxy = -1; - - while((c = *str++)) - charBounds(c, &x, &y, &minx, &miny, &maxx, &maxy); - - if(maxx >= minx) { - *x1 = minx; - *w = maxx - minx + 1; - } - if(maxy >= miny) { - *y1 = miny; - *h = maxy - miny + 1; - } -} - -// Same as above, but for PROGMEM strings -void Adafruit_GFX::getTextBounds(const __FlashStringHelper *str, - int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h) { - uint8_t *s = (uint8_t *)str, c; - - *x1 = x; - *y1 = y; - *w = *h = 0; - - int16_t minx = _width, miny = _height, maxx = -1, maxy = -1; - - while((c = pgm_read_byte(s++))) - charBounds(c, &x, &y, &minx, &miny, &maxx, &maxy); - - if(maxx >= minx) { - *x1 = minx; - *w = maxx - minx + 1; - } - if(maxy >= miny) { - *y1 = miny; - *h = maxy - miny + 1; - } -} - -// Return the size of the display (per current rotation) -int16_t Adafruit_GFX::width(void) const { - return _width; -} - -int16_t Adafruit_GFX::height(void) const { - return _height; -} - -void Adafruit_GFX::invertDisplay(boolean i) { - // Do nothing, must be subclassed if supported by hardware -} - -/***************************************************************************/ -// code for the GFX button UI element - -Adafruit_GFX_Button::Adafruit_GFX_Button(void) { - _gfx = 0; -} - -// Classic initButton() function: pass center & size -void Adafruit_GFX_Button::initButton( - Adafruit_GFX *gfx, int16_t x, int16_t y, uint16_t w, uint16_t h, - uint16_t outline, uint16_t fill, uint16_t textcolor, - char *label, uint8_t textsize) -{ - // Tweak arguments and pass to the newer initButtonUL() function... - initButtonUL(gfx, x - (w / 2), y - (h / 2), w, h, outline, fill, - textcolor, label, textsize); -} - -// Newer function instead accepts upper-left corner & size -void Adafruit_GFX_Button::initButtonUL( - Adafruit_GFX *gfx, int16_t x1, int16_t y1, uint16_t w, uint16_t h, - uint16_t outline, uint16_t fill, uint16_t textcolor, - char *label, uint8_t textsize) -{ - _x1 = x1; - _y1 = y1; - _w = w; - _h = h; - _outlinecolor = outline; - _fillcolor = fill; - _textcolor = textcolor; - _textsize = textsize; - _gfx = gfx; - strncpy(_label, label, 9); -} - -void Adafruit_GFX_Button::drawButton(boolean inverted) { - uint16_t fill, outline, text; - - if(!inverted) { - fill = _fillcolor; - outline = _outlinecolor; - text = _textcolor; - } else { - fill = _textcolor; - outline = _outlinecolor; - text = _fillcolor; - } - - uint8_t r = min(_w, _h) / 4; // Corner radius - _gfx->fillRoundRect(_x1, _y1, _w, _h, r, fill); - _gfx->drawRoundRect(_x1, _y1, _w, _h, r, outline); - - _gfx->setCursor(_x1 + (_w/2) - (strlen(_label) * 3 * _textsize), - _y1 + (_h/2) - (4 * _textsize)); - _gfx->setTextColor(text); - _gfx->setTextSize(_textsize); - _gfx->print(_label); -} - -boolean Adafruit_GFX_Button::contains(int16_t x, int16_t y) { - return ((x >= _x1) && (x < (_x1 + _w)) && - (y >= _y1) && (y < (_y1 + _h))); -} - -void Adafruit_GFX_Button::press(boolean p) { - laststate = currstate; - currstate = p; -} - -boolean Adafruit_GFX_Button::isPressed() { return currstate; } -boolean Adafruit_GFX_Button::justPressed() { return (currstate && !laststate); } -boolean Adafruit_GFX_Button::justReleased() { return (!currstate && laststate); } - -// ------------------------------------------------------------------------- - -// GFXcanvas1, GFXcanvas8 and GFXcanvas16 (currently a WIP, don't get too -// comfy with the implementation) provide 1-, 8- and 16-bit offscreen -// canvases, the address of which can be passed to drawBitmap() or -// pushColors() (the latter appears only in a couple of GFX-subclassed TFT -// libraries at this time). This is here mostly to help with the recently- -// added proportionally-spaced fonts; adds a way to refresh a section of the -// screen without a massive flickering clear-and-redraw...but maybe you'll -// find other uses too. VERY RAM-intensive, since the buffer is in MCU -// memory and not the display driver...GXFcanvas1 might be minimally useful -// on an Uno-class board, but this and the others are much more likely to -// require at least a Mega or various recent ARM-type boards (recommended, -// as the text+bitmap draw can be pokey). GFXcanvas1 requires 1 bit per -// pixel (rounded up to nearest byte per scanline), GFXcanvas8 is 1 byte -// per pixel (no scanline pad), and GFXcanvas16 uses 2 bytes per pixel (no -// scanline pad). -// NOT EXTENSIVELY TESTED YET. MAY CONTAIN WORST BUGS KNOWN TO HUMANKIND. - -GFXcanvas1::GFXcanvas1(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) { - uint16_t bytes = ((w + 7) / 8) * h; - if((buffer = (uint8_t *)malloc(bytes))) { - memset(buffer, 0, bytes); - } -} - -GFXcanvas1::~GFXcanvas1(void) { - if(buffer) free(buffer); -} - -uint8_t* GFXcanvas1::getBuffer(void) { - return buffer; -} - -void GFXcanvas1::drawPixel(int16_t x, int16_t y, uint16_t color) { -#ifdef __AVR__ - // Bitmask tables of 0x80>>X and ~(0x80>>X), because X>>Y is slow on AVR - static const uint8_t PROGMEM - GFXsetBit[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, - GFXclrBit[] = { 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE }; -#endif - - if(buffer) { - if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return; - - int16_t t; - switch(rotation) { - case 1: - t = x; - x = WIDTH - 1 - y; - y = t; - break; - case 2: - x = WIDTH - 1 - x; - y = HEIGHT - 1 - y; - break; - case 3: - t = x; - x = y; - y = HEIGHT - 1 - t; - break; - } - - uint8_t *ptr = &buffer[(x / 8) + y * ((WIDTH + 7) / 8)]; -#ifdef __AVR__ - if(color) *ptr |= pgm_read_byte(&GFXsetBit[x & 7]); - else *ptr &= pgm_read_byte(&GFXclrBit[x & 7]); -#else - if(color) *ptr |= 0x80 >> (x & 7); - else *ptr &= ~(0x80 >> (x & 7)); -#endif - } -} - -void GFXcanvas1::fillScreen(uint16_t color) { - if(buffer) { - uint16_t bytes = ((WIDTH + 7) / 8) * HEIGHT; - memset(buffer, color ? 0xFF : 0x00, bytes); - } -} - -GFXcanvas8::GFXcanvas8(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) { - uint32_t bytes = w * h; - if((buffer = (uint8_t *)malloc(bytes))) { - memset(buffer, 0, bytes); - } -} - -GFXcanvas8::~GFXcanvas8(void) { - if(buffer) free(buffer); -} - -uint8_t* GFXcanvas8::getBuffer(void) { - return buffer; -} - -void GFXcanvas8::drawPixel(int16_t x, int16_t y, uint16_t color) { - if(buffer) { - if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return; - - int16_t t; - switch(rotation) { - case 1: - t = x; - x = WIDTH - 1 - y; - y = t; - break; - case 2: - x = WIDTH - 1 - x; - y = HEIGHT - 1 - y; - break; - case 3: - t = x; - x = y; - y = HEIGHT - 1 - t; - break; - } - - buffer[x + y * WIDTH] = color; - } -} - -void GFXcanvas8::fillScreen(uint16_t color) { - if(buffer) { - memset(buffer, color, WIDTH * HEIGHT); - } -} - -void GFXcanvas8::writeFastHLine(int16_t x, int16_t y, - int16_t w, uint16_t color) { - - if((x >= _width) || (y < 0) || (y >= _height)) return; - int16_t x2 = x + w - 1; - if(x2 < 0) return; - - // Clip left/right - if(x < 0) { - x = 0; - w = x2 + 1; - } - if(x2 >= _width) w = _width - x; - - int16_t t; - switch(rotation) { - case 1: - t = x; - x = WIDTH - 1 - y; - y = t; - break; - case 2: - x = WIDTH - 1 - x; - y = HEIGHT - 1 - y; - break; - case 3: - t = x; - x = y; - y = HEIGHT - 1 - t; - break; - } - - memset(buffer + y * WIDTH + x, color, w); -} - -GFXcanvas16::GFXcanvas16(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) { - uint32_t bytes = w * h * 2; - if((buffer = (uint16_t *)malloc(bytes))) { - memset(buffer, 0, bytes); - } -} - -GFXcanvas16::~GFXcanvas16(void) { - if(buffer) free(buffer); -} - -uint16_t* GFXcanvas16::getBuffer(void) { - return buffer; -} - -void GFXcanvas16::drawPixel(int16_t x, int16_t y, uint16_t color) { - if(buffer) { - if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return; - - int16_t t; - switch(rotation) { - case 1: - t = x; - x = WIDTH - 1 - y; - y = t; - break; - case 2: - x = WIDTH - 1 - x; - y = HEIGHT - 1 - y; - break; - case 3: - t = x; - x = y; - y = HEIGHT - 1 - t; - break; - } - - buffer[x + y * WIDTH] = color; - } -} - -void GFXcanvas16::fillScreen(uint16_t color) { - if(buffer) { - uint8_t hi = color >> 8, lo = color & 0xFF; - if(hi == lo) { - memset(buffer, lo, WIDTH * HEIGHT * 2); - } else { - uint32_t i, pixels = WIDTH * HEIGHT; - for(i=0; i= 100 - #include "Arduino.h" - #include "Print.h" -#else - #include "WProgram.h" -#endif -#include "gfxfont.h" - -class Adafruit_GFX : public Print { - - public: - - Adafruit_GFX(int16_t w, int16_t h); // Constructor - - // This MUST be defined by the subclass: - virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0; - - // TRANSACTION API / CORE DRAW API - // These MAY be overridden by the subclass to provide device-specific - // optimized code. Otherwise 'generic' versions are used. - virtual void startWrite(void); - virtual void writePixel(int16_t x, int16_t y, uint16_t color); - virtual void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); - virtual void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); - virtual void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); - virtual void writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color); - virtual void endWrite(void); - - // CONTROL API - // These MAY be overridden by the subclass to provide device-specific - // optimized code. Otherwise 'generic' versions are used. - virtual void setRotation(uint8_t r); - virtual void invertDisplay(boolean i); - - // BASIC DRAW API - // These MAY be overridden by the subclass to provide device-specific - // optimized code. Otherwise 'generic' versions are used. - virtual void - // It's good to implement those, even if using transaction API - drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color), - drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color), - fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color), - fillScreen(uint16_t color), - // Optional and probably not necessary to change - drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color), - drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); - - // These exist only with Adafruit_GFX (no subclass overrides) - void - drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color), - drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, - uint16_t color), - fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color), - fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, - int16_t delta, uint16_t color), - drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, - int16_t x2, int16_t y2, uint16_t color), - fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, - int16_t x2, int16_t y2, uint16_t color), - drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, - int16_t radius, uint16_t color), - fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, - int16_t radius, uint16_t color), - drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], - int16_t w, int16_t h, uint16_t color), - drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], - int16_t w, int16_t h, uint16_t color, uint16_t bg), - drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, - int16_t w, int16_t h, uint16_t color), - drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, - int16_t w, int16_t h, uint16_t color, uint16_t bg), - drawXBitmap(int16_t x, int16_t y, const uint8_t bitmap[], - int16_t w, int16_t h, uint16_t color), - drawGrayscaleBitmap(int16_t x, int16_t y, const uint8_t bitmap[], - int16_t w, int16_t h), - drawGrayscaleBitmap(int16_t x, int16_t y, uint8_t *bitmap, - int16_t w, int16_t h), - drawGrayscaleBitmap(int16_t x, int16_t y, - const uint8_t bitmap[], const uint8_t mask[], - int16_t w, int16_t h), - drawGrayscaleBitmap(int16_t x, int16_t y, - uint8_t *bitmap, uint8_t *mask, int16_t w, int16_t h), - drawRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[], - int16_t w, int16_t h), - drawRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, - int16_t w, int16_t h), - drawRGBBitmap(int16_t x, int16_t y, - const uint16_t bitmap[], const uint8_t mask[], - int16_t w, int16_t h), - drawRGBBitmap(int16_t x, int16_t y, - uint16_t *bitmap, uint8_t *mask, int16_t w, int16_t h), - drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, - uint16_t bg, uint8_t size), - setCursor(int16_t x, int16_t y), - setTextColor(uint16_t c), - setTextColor(uint16_t c, uint16_t bg), - setTextSize(uint8_t s), - setTextWrap(boolean w), - cp437(boolean x=true), - setFont(const GFXfont *f = NULL), - getTextBounds(char *string, int16_t x, int16_t y, - int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h), - getTextBounds(const __FlashStringHelper *s, int16_t x, int16_t y, - int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h); - -#if ARDUINO >= 100 - virtual size_t write(uint8_t); -#else - virtual void write(uint8_t); -#endif - - int16_t height(void) const; - int16_t width(void) const; - - uint8_t getRotation(void) const; - - // get current cursor position (get rotation safe maximum values, using: width() for x, height() for y) - int16_t getCursorX(void) const; - int16_t getCursorY(void) const; - - protected: - void - charBounds(char c, int16_t *x, int16_t *y, - int16_t *minx, int16_t *miny, int16_t *maxx, int16_t *maxy); - const int16_t - WIDTH, HEIGHT; // This is the 'raw' display w/h - never changes - int16_t - _width, _height, // Display w/h as modified by current rotation - cursor_x, cursor_y; - uint16_t - textcolor, textbgcolor; - uint8_t - textsize, - rotation; - boolean - wrap, // If set, 'wrap' text at right edge of display - _cp437; // If set, use correct CP437 charset (default is off) - GFXfont - *gfxFont; -}; - -class Adafruit_GFX_Button { - - public: - Adafruit_GFX_Button(void); - // "Classic" initButton() uses center & size - void initButton(Adafruit_GFX *gfx, int16_t x, int16_t y, - uint16_t w, uint16_t h, uint16_t outline, uint16_t fill, - uint16_t textcolor, char *label, uint8_t textsize); - // New/alt initButton() uses upper-left corner & size - void initButtonUL(Adafruit_GFX *gfx, int16_t x1, int16_t y1, - uint16_t w, uint16_t h, uint16_t outline, uint16_t fill, - uint16_t textcolor, char *label, uint8_t textsize); - void drawButton(boolean inverted = false); - boolean contains(int16_t x, int16_t y); - - void press(boolean p); - boolean isPressed(); - boolean justPressed(); - boolean justReleased(); - - private: - Adafruit_GFX *_gfx; - int16_t _x1, _y1; // Coordinates of top-left corner - uint16_t _w, _h; - uint8_t _textsize; - uint16_t _outlinecolor, _fillcolor, _textcolor; - char _label[10]; - - boolean currstate, laststate; -}; - -class GFXcanvas1 : public Adafruit_GFX { - public: - GFXcanvas1(uint16_t w, uint16_t h); - ~GFXcanvas1(void); - void drawPixel(int16_t x, int16_t y, uint16_t color), - fillScreen(uint16_t color); - uint8_t *getBuffer(void); - private: - uint8_t *buffer; -}; - -class GFXcanvas8 : public Adafruit_GFX { - public: - GFXcanvas8(uint16_t w, uint16_t h); - ~GFXcanvas8(void); - void drawPixel(int16_t x, int16_t y, uint16_t color), - fillScreen(uint16_t color), - writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); - - uint8_t *getBuffer(void); - private: - uint8_t *buffer; -}; - -class GFXcanvas16 : public Adafruit_GFX { - public: - GFXcanvas16(uint16_t w, uint16_t h); - ~GFXcanvas16(void); - void drawPixel(int16_t x, int16_t y, uint16_t color), - fillScreen(uint16_t color); - uint16_t *getBuffer(void); - private: - uint16_t *buffer; -}; - -#endif // _ADAFRUIT_GFX_H diff --git a/variants/Sinobit/Adafruit_HT1632.cpp b/variants/Sinobit/Adafruit_HT1632.cpp deleted file mode 100644 index ebf173e7..00000000 --- a/variants/Sinobit/Adafruit_HT1632.cpp +++ /dev/null @@ -1,282 +0,0 @@ -#include "Adafruit_HT1632.h" - -#ifndef _swap_int16_t -#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; } -#endif - -// Constructor for single GFX matrix -Adafruit_HT1632LEDMatrix::Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, - uint8_t cs1) : Adafruit_GFX(24, 16), matrices(NULL), matrixNum(0) { - if((matrices = (Adafruit_HT1632 *)malloc(sizeof(Adafruit_HT1632)))) { - matrices[0] = Adafruit_HT1632(data, wr, cs1); - matrixNum = 1; - } -} - -// Constructor for two matrices, tiled side-by-side for GFX -Adafruit_HT1632LEDMatrix::Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, - uint8_t cs1, uint8_t cs2) : Adafruit_GFX(48, 16), matrices(NULL), - matrixNum(0) { - if((matrices = (Adafruit_HT1632 *)malloc(2 * sizeof(Adafruit_HT1632)))) { - matrices[0] = Adafruit_HT1632(data, wr, cs1); - matrices[1] = Adafruit_HT1632(data, wr, cs2); - matrixNum = 2; - } -} - -// Constructor for three matrices, tiled side-by-side for GFX -Adafruit_HT1632LEDMatrix::Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, - uint8_t cs1, uint8_t cs2, uint8_t cs3) : Adafruit_GFX(72, 16), - matrices(NULL), matrixNum(0) { - if((matrices = (Adafruit_HT1632 *)malloc(3 * sizeof(Adafruit_HT1632)))) { - matrices[0] = Adafruit_HT1632(data, wr, cs1); - matrices[1] = Adafruit_HT1632(data, wr, cs2); - matrices[2] = Adafruit_HT1632(data, wr, cs3); - matrixNum = 3; - } -} - -// Constructor for four matrices, tiled side-by-side for GFX -Adafruit_HT1632LEDMatrix::Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, - uint8_t cs1, uint8_t cs2, uint8_t cs3, uint8_t cs4) : Adafruit_GFX(96, 16), - matrices(NULL), matrixNum(0) { - if((matrices = (Adafruit_HT1632 *)malloc(4 * sizeof(Adafruit_HT1632)))) { - matrices[0] = Adafruit_HT1632(data, wr, cs1); - matrices[1] = Adafruit_HT1632(data, wr, cs2); - matrices[2] = Adafruit_HT1632(data, wr, cs3); - matrices[3] = Adafruit_HT1632(data, wr, cs4); - matrixNum = 4; - } -} - -void Adafruit_HT1632LEDMatrix::setPixel(uint8_t x, uint8_t y) { - drawPixel(x, y, 1); -} - -void Adafruit_HT1632LEDMatrix::clrPixel(uint8_t x, uint8_t y) { - drawPixel(x, y, 0); -} - -void Adafruit_HT1632LEDMatrix::drawPixel(int16_t x, int16_t y, uint16_t color) { - if((x < 0) || (x >= _width) || (y < 0) || (y >= _height)) return; - - switch(rotation) { // Rotate pixel into device-specific coordinates - case 1: - _swap_int16_t(x, y); - x = WIDTH - 1 - x; - break; - case 2: - x = WIDTH - 1 - x; - y = HEIGHT - 1 - y; - break; - case 3: - _swap_int16_t(x, y); - y = HEIGHT - 1 - y; - break; - } - - uint8_t m = x / 24; // Which matrix controller is pixel on? - x %= 24; // Which column in matrix? - - uint16_t i; - - if(x < 8) i = 7; - else if(x < 16) i = 128 + 7; - else i = 256 + 7; - i -= (x & 7); - - if(y < 8) y *= 2; - else y = (y-8) * 2 + 1; - i += y * 8; - - if(color) matrices[m].setPixel(i); - else matrices[m].clrPixel(i); -} - -boolean Adafruit_HT1632LEDMatrix::begin(uint8_t type) { - if(matrixNum) { // Did malloc() work OK? - for(uint8_t i=0; i= 0) { - pinMode(_rd, OUTPUT); - digitalWrite(_rd, HIGH); - } - -#ifdef __AVR__ - csport = portOutputRegister(digitalPinToPort(_cs)); - csmask = digitalPinToBitMask(_cs); - wrport = portOutputRegister(digitalPinToPort(_wr)); - wrmask = digitalPinToBitMask(_wr); - dataport = portOutputRegister(digitalPinToPort(_data)); - datadir = portModeRegister(digitalPinToPort(_data)); - datamask = digitalPinToBitMask(_data); -#endif - - sendcommand(ADA_HT1632_SYS_EN); - sendcommand(ADA_HT1632_LED_ON); - sendcommand(ADA_HT1632_BLINK_OFF); - sendcommand(ADA_HT1632_MASTER_MODE); - sendcommand(ADA_HT1632_INT_RC); - sendcommand(type); - sendcommand(ADA_HT1632_PWM_CONTROL | 0xF); -} - -void Adafruit_HT1632::setBrightness(uint8_t pwm) { - if(pwm > 15) pwm = 15; - sendcommand(ADA_HT1632_PWM_CONTROL | pwm); -} - -void Adafruit_HT1632::blink(boolean blinky) { - sendcommand(blinky ? ADA_HT1632_BLINK_ON : ADA_HT1632_BLINK_OFF); -} - -void Adafruit_HT1632::setPixel(uint16_t i) { - ledmatrix[i/8] |= (1 << (i & 7)); -} - -void Adafruit_HT1632::clrPixel(uint16_t i) { - ledmatrix[i/8] &= ~(1 << (i & 7)); -} - -void Adafruit_HT1632::dumpScreen() { - Serial.println(F("---------------------------------------")); - - for (uint16_t i=0; i>= 1) { - *wrport &= ~wrmask; - if(d & bit) *dataport |= datamask; - else *dataport &= ~datamask; - *wrport |= wrmask; - } -#else - pinMode(_data, OUTPUT); - for(uint16_t bit = 1<<(bits-1); bit; bit >>= 1) { - digitalWrite(_wr, LOW); - digitalWrite(_data, (d & bit) ? HIGH : LOW); - digitalWrite(_wr, HIGH); - } - pinMode(_data, INPUT); -#endif -} - -void Adafruit_HT1632::writeRAM(uint8_t addr, uint8_t data) { - //Serial.print("Writing 0x"); Serial.print(data&0xF, HEX); - //Serial.print(" to 0x"); Serial.println(addr & 0x7F, HEX); - - uint16_t d = ADA_HT1632_WRITE; - d <<= 7; - d |= addr & 0x7F; - d <<= 4; - d |= data & 0xF; - -#ifdef __AVR__ - *csport &= ~csmask; - writedata(d, 14); - *csport |= csmask; -#else - digitalWrite(_cs, LOW); - writedata(d, 14); - digitalWrite(_cs, HIGH); -#endif -} - -void Adafruit_HT1632::sendcommand(uint8_t cmd) { -#ifdef __AVR__ - *csport &= ~csmask; - *datadir |= datamask; // OUTPUT - writedata((((uint16_t)ADA_HT1632_COMMAND << 8) | cmd) << 1, 12); - *datadir &= ~datamask; // INPUT - *csport |= csmask; -#else - digitalWrite(_cs, LOW); - writedata((((uint16_t)ADA_HT1632_COMMAND << 8) | cmd) << 1, 12); - digitalWrite(_cs, HIGH); -#endif -} - -void Adafruit_HT1632::fillScreen() { - memset(ledmatrix, 0xFF, sizeof(ledmatrix)); - writeScreen(); -} diff --git a/variants/Sinobit/Adafruit_HT1632.h b/variants/Sinobit/Adafruit_HT1632.h deleted file mode 100644 index f914bd87..00000000 --- a/variants/Sinobit/Adafruit_HT1632.h +++ /dev/null @@ -1,84 +0,0 @@ -#include "Adafruit_GFX.h" - -#ifndef ADA_HT1632_H_ -#define ADA_HT1632_H_ - -#if(ARDUINO >= 100) - #include -#else - #include -#endif - -#define ADA_HT1632_READ 0x06 -#define ADA_HT1632_WRITE 0x05 -#define ADA_HT1632_COMMAND 0x04 - -#define ADA_HT1632_SYS_DIS 0x00 -#define ADA_HT1632_SYS_EN 0x01 -#define ADA_HT1632_LED_OFF 0x02 -#define ADA_HT1632_LED_ON 0x03 -#define ADA_HT1632_BLINK_OFF 0x08 -#define ADA_HT1632_BLINK_ON 0x09 -#define ADA_HT1632_SLAVE_MODE 0x10 -#define ADA_HT1632_MASTER_MODE 0x14 -#define ADA_HT1632_INT_RC 0x18 -#define ADA_HT1632_EXT_CLK 0x1C -#define ADA_HT1632_PWM_CONTROL 0xA0 - -#define ADA_HT1632_COMMON_8NMOS 0x20 -#define ADA_HT1632_COMMON_16NMOS 0x24 -#define ADA_HT1632_COMMON_8PMOS 0x28 -#define ADA_HT1632_COMMON_16PMOS 0x2C - -class Adafruit_HT1632 { - - public: - Adafruit_HT1632(int8_t data, int8_t wr, int8_t cs, int8_t rd = -1); - - void begin(uint8_t type), - clrPixel(uint16_t i), - setPixel(uint16_t i), - blink(boolean state), - setBrightness(uint8_t pwm), - clearScreen(), - fillScreen(), - writeScreen(), - dumpScreen(); - - protected: - int8_t _data, _cs, _wr, _rd; - uint8_t ledmatrix[24 * 16 / 8]; - void sendcommand(uint8_t c), - writedata(uint16_t d, uint8_t bits), - writeRAM(uint8_t addr, uint8_t data); -#ifdef __AVR__ - volatile uint8_t *dataport, *csport, *wrport, *datadir; - uint8_t datamask, csmask, wrmask; -#endif -}; - -class Adafruit_HT1632LEDMatrix : public Adafruit_GFX { - public: - Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, uint8_t cs1); - Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, uint8_t cs1, uint8_t cs2); - Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, - uint8_t cs1, uint8_t cs, uint8_t cs3); - Adafruit_HT1632LEDMatrix(uint8_t data, uint8_t wr, - uint8_t cs1, uint8_t cs2, uint8_t cs3, uint8_t cs4); - - boolean begin(uint8_t type); - void clearScreen(void), - fillScreen(void), - blink(boolean b), - setBrightness(uint8_t brightness), - writeScreen(), - clrPixel(uint8_t x, uint8_t y), - setPixel(uint8_t x, uint8_t y), - drawPixel(int16_t x, int16_t y, uint16_t color); - - protected: - Adafruit_HT1632 *matrices; - uint8_t matrixNum; -}; - -#endif /* Adafruit HT1632_H_ */ diff --git a/variants/Sinobit/README.md b/variants/Sinobit/README.md index cab3216a..b666efc2 100644 --- a/variants/Sinobit/README.md +++ b/variants/Sinobit/README.md @@ -1,3 +1,6 @@ # Sino:Bit support files for Arduino -sinobit.cpp, sinobit.h courtesy of Dave Astels (Twitter @DAstels) -Adafruit files from Adafruit GFX and Adafruit HT1632 Arduino Libraries. +Contributed by Tomas Lubkowitz @sceptic_int for Sino:Bit + +For LED Matrix functionality please look at https://learn.adafruit.com/sino-bit-with-arduino/dastels-overview + + diff --git a/variants/Sinobit/gfxfont.h b/variants/Sinobit/gfxfont.h deleted file mode 100644 index 07381edd..00000000 --- a/variants/Sinobit/gfxfont.h +++ /dev/null @@ -1,24 +0,0 @@ -// Font structures for newer Adafruit_GFX (1.1 and later). -// Example fonts are included in 'Fonts' directory. -// To use a font in your Arduino sketch, #include the corresponding .h -// file and pass address of GFXfont struct to setFont(). Pass NULL to -// revert to 'classic' fixed-space bitmap font. - -#ifndef _GFXFONT_H_ -#define _GFXFONT_H_ - -typedef struct { // Data stored PER GLYPH - uint16_t bitmapOffset; // Pointer into GFXfont->bitmap - uint8_t width, height; // Bitmap dimensions in pixels - uint8_t xAdvance; // Distance to advance cursor (x axis) - int8_t xOffset, yOffset; // Dist from cursor pos to UL corner -} GFXglyph; - -typedef struct { // Data stored for FONT AS A WHOLE: - uint8_t *bitmap; // Glyph bitmaps, concatenated - GFXglyph *glyph; // Glyph array - uint8_t first, last; // ASCII extents - uint8_t yAdvance; // Newline distance (y axis) -} GFXfont; - -#endif // _GFXFONT_H_ diff --git a/variants/Sinobit/glcdfont.c b/variants/Sinobit/glcdfont.c deleted file mode 100644 index 6f88bd23..00000000 --- a/variants/Sinobit/glcdfont.c +++ /dev/null @@ -1,276 +0,0 @@ -// This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0. -// See gfxfont.h for newer custom bitmap font info. - -#ifndef FONT5X7_H -#define FONT5X7_H - -#ifdef __AVR__ - #include - #include -#elif defined(ESP8266) - #include -#else - #define PROGMEM -#endif - -// Standard ASCII 5x7 font - -static const unsigned char font[] PROGMEM = { - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, - 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, - 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, - 0x18, 0x3C, 0x7E, 0x3C, 0x18, - 0x1C, 0x57, 0x7D, 0x57, 0x1C, - 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, - 0x00, 0x18, 0x3C, 0x18, 0x00, - 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, - 0x00, 0x18, 0x24, 0x18, 0x00, - 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, - 0x30, 0x48, 0x3A, 0x06, 0x0E, - 0x26, 0x29, 0x79, 0x29, 0x26, - 0x40, 0x7F, 0x05, 0x05, 0x07, - 0x40, 0x7F, 0x05, 0x25, 0x3F, - 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, - 0x7F, 0x3E, 0x1C, 0x1C, 0x08, - 0x08, 0x1C, 0x1C, 0x3E, 0x7F, - 0x14, 0x22, 0x7F, 0x22, 0x14, - 0x5F, 0x5F, 0x00, 0x5F, 0x5F, - 0x06, 0x09, 0x7F, 0x01, 0x7F, - 0x00, 0x66, 0x89, 0x95, 0x6A, - 0x60, 0x60, 0x60, 0x60, 0x60, - 0x94, 0xA2, 0xFF, 0xA2, 0x94, - 0x08, 0x04, 0x7E, 0x04, 0x08, - 0x10, 0x20, 0x7E, 0x20, 0x10, - 0x08, 0x08, 0x2A, 0x1C, 0x08, - 0x08, 0x1C, 0x2A, 0x08, 0x08, - 0x1E, 0x10, 0x10, 0x10, 0x10, - 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, - 0x30, 0x38, 0x3E, 0x38, 0x30, - 0x06, 0x0E, 0x3E, 0x0E, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x5F, 0x00, 0x00, - 0x00, 0x07, 0x00, 0x07, 0x00, - 0x14, 0x7F, 0x14, 0x7F, 0x14, - 0x24, 0x2A, 0x7F, 0x2A, 0x12, - 0x23, 0x13, 0x08, 0x64, 0x62, - 0x36, 0x49, 0x56, 0x20, 0x50, - 0x00, 0x08, 0x07, 0x03, 0x00, - 0x00, 0x1C, 0x22, 0x41, 0x00, - 0x00, 0x41, 0x22, 0x1C, 0x00, - 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, - 0x08, 0x08, 0x3E, 0x08, 0x08, - 0x00, 0x80, 0x70, 0x30, 0x00, - 0x08, 0x08, 0x08, 0x08, 0x08, - 0x00, 0x00, 0x60, 0x60, 0x00, - 0x20, 0x10, 0x08, 0x04, 0x02, - 0x3E, 0x51, 0x49, 0x45, 0x3E, - 0x00, 0x42, 0x7F, 0x40, 0x00, - 0x72, 0x49, 0x49, 0x49, 0x46, - 0x21, 0x41, 0x49, 0x4D, 0x33, - 0x18, 0x14, 0x12, 0x7F, 0x10, - 0x27, 0x45, 0x45, 0x45, 0x39, - 0x3C, 0x4A, 0x49, 0x49, 0x31, - 0x41, 0x21, 0x11, 0x09, 0x07, - 0x36, 0x49, 0x49, 0x49, 0x36, - 0x46, 0x49, 0x49, 0x29, 0x1E, - 0x00, 0x00, 0x14, 0x00, 0x00, - 0x00, 0x40, 0x34, 0x00, 0x00, - 0x00, 0x08, 0x14, 0x22, 0x41, - 0x14, 0x14, 0x14, 0x14, 0x14, - 0x00, 0x41, 0x22, 0x14, 0x08, - 0x02, 0x01, 0x59, 0x09, 0x06, - 0x3E, 0x41, 0x5D, 0x59, 0x4E, - 0x7C, 0x12, 0x11, 0x12, 0x7C, - 0x7F, 0x49, 0x49, 0x49, 0x36, - 0x3E, 0x41, 0x41, 0x41, 0x22, - 0x7F, 0x41, 0x41, 0x41, 0x3E, - 0x7F, 0x49, 0x49, 0x49, 0x41, - 0x7F, 0x09, 0x09, 0x09, 0x01, - 0x3E, 0x41, 0x41, 0x51, 0x73, - 0x7F, 0x08, 0x08, 0x08, 0x7F, - 0x00, 0x41, 0x7F, 0x41, 0x00, - 0x20, 0x40, 0x41, 0x3F, 0x01, - 0x7F, 0x08, 0x14, 0x22, 0x41, - 0x7F, 0x40, 0x40, 0x40, 0x40, - 0x7F, 0x02, 0x1C, 0x02, 0x7F, - 0x7F, 0x04, 0x08, 0x10, 0x7F, - 0x3E, 0x41, 0x41, 0x41, 0x3E, - 0x7F, 0x09, 0x09, 0x09, 0x06, - 0x3E, 0x41, 0x51, 0x21, 0x5E, - 0x7F, 0x09, 0x19, 0x29, 0x46, - 0x26, 0x49, 0x49, 0x49, 0x32, - 0x03, 0x01, 0x7F, 0x01, 0x03, - 0x3F, 0x40, 0x40, 0x40, 0x3F, - 0x1F, 0x20, 0x40, 0x20, 0x1F, - 0x3F, 0x40, 0x38, 0x40, 0x3F, - 0x63, 0x14, 0x08, 0x14, 0x63, - 0x03, 0x04, 0x78, 0x04, 0x03, - 0x61, 0x59, 0x49, 0x4D, 0x43, - 0x00, 0x7F, 0x41, 0x41, 0x41, - 0x02, 0x04, 0x08, 0x10, 0x20, - 0x00, 0x41, 0x41, 0x41, 0x7F, - 0x04, 0x02, 0x01, 0x02, 0x04, - 0x40, 0x40, 0x40, 0x40, 0x40, - 0x00, 0x03, 0x07, 0x08, 0x00, - 0x20, 0x54, 0x54, 0x78, 0x40, - 0x7F, 0x28, 0x44, 0x44, 0x38, - 0x38, 0x44, 0x44, 0x44, 0x28, - 0x38, 0x44, 0x44, 0x28, 0x7F, - 0x38, 0x54, 0x54, 0x54, 0x18, - 0x00, 0x08, 0x7E, 0x09, 0x02, - 0x18, 0xA4, 0xA4, 0x9C, 0x78, - 0x7F, 0x08, 0x04, 0x04, 0x78, - 0x00, 0x44, 0x7D, 0x40, 0x00, - 0x20, 0x40, 0x40, 0x3D, 0x00, - 0x7F, 0x10, 0x28, 0x44, 0x00, - 0x00, 0x41, 0x7F, 0x40, 0x00, - 0x7C, 0x04, 0x78, 0x04, 0x78, - 0x7C, 0x08, 0x04, 0x04, 0x78, - 0x38, 0x44, 0x44, 0x44, 0x38, - 0xFC, 0x18, 0x24, 0x24, 0x18, - 0x18, 0x24, 0x24, 0x18, 0xFC, - 0x7C, 0x08, 0x04, 0x04, 0x08, - 0x48, 0x54, 0x54, 0x54, 0x24, - 0x04, 0x04, 0x3F, 0x44, 0x24, - 0x3C, 0x40, 0x40, 0x20, 0x7C, - 0x1C, 0x20, 0x40, 0x20, 0x1C, - 0x3C, 0x40, 0x30, 0x40, 0x3C, - 0x44, 0x28, 0x10, 0x28, 0x44, - 0x4C, 0x90, 0x90, 0x90, 0x7C, - 0x44, 0x64, 0x54, 0x4C, 0x44, - 0x00, 0x08, 0x36, 0x41, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, - 0x00, 0x41, 0x36, 0x08, 0x00, - 0x02, 0x01, 0x02, 0x04, 0x02, - 0x3C, 0x26, 0x23, 0x26, 0x3C, - 0x1E, 0xA1, 0xA1, 0x61, 0x12, - 0x3A, 0x40, 0x40, 0x20, 0x7A, - 0x38, 0x54, 0x54, 0x55, 0x59, - 0x21, 0x55, 0x55, 0x79, 0x41, - 0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut - 0x21, 0x55, 0x54, 0x78, 0x40, - 0x20, 0x54, 0x55, 0x79, 0x40, - 0x0C, 0x1E, 0x52, 0x72, 0x12, - 0x39, 0x55, 0x55, 0x55, 0x59, - 0x39, 0x54, 0x54, 0x54, 0x59, - 0x39, 0x55, 0x54, 0x54, 0x58, - 0x00, 0x00, 0x45, 0x7C, 0x41, - 0x00, 0x02, 0x45, 0x7D, 0x42, - 0x00, 0x01, 0x45, 0x7C, 0x40, - 0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut - 0xF0, 0x28, 0x25, 0x28, 0xF0, - 0x7C, 0x54, 0x55, 0x45, 0x00, - 0x20, 0x54, 0x54, 0x7C, 0x54, - 0x7C, 0x0A, 0x09, 0x7F, 0x49, - 0x32, 0x49, 0x49, 0x49, 0x32, - 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut - 0x32, 0x4A, 0x48, 0x48, 0x30, - 0x3A, 0x41, 0x41, 0x21, 0x7A, - 0x3A, 0x42, 0x40, 0x20, 0x78, - 0x00, 0x9D, 0xA0, 0xA0, 0x7D, - 0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut - 0x3D, 0x40, 0x40, 0x40, 0x3D, - 0x3C, 0x24, 0xFF, 0x24, 0x24, - 0x48, 0x7E, 0x49, 0x43, 0x66, - 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, - 0xFF, 0x09, 0x29, 0xF6, 0x20, - 0xC0, 0x88, 0x7E, 0x09, 0x03, - 0x20, 0x54, 0x54, 0x79, 0x41, - 0x00, 0x00, 0x44, 0x7D, 0x41, - 0x30, 0x48, 0x48, 0x4A, 0x32, - 0x38, 0x40, 0x40, 0x22, 0x7A, - 0x00, 0x7A, 0x0A, 0x0A, 0x72, - 0x7D, 0x0D, 0x19, 0x31, 0x7D, - 0x26, 0x29, 0x29, 0x2F, 0x28, - 0x26, 0x29, 0x29, 0x29, 0x26, - 0x30, 0x48, 0x4D, 0x40, 0x20, - 0x38, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x38, - 0x2F, 0x10, 0xC8, 0xAC, 0xBA, - 0x2F, 0x10, 0x28, 0x34, 0xFA, - 0x00, 0x00, 0x7B, 0x00, 0x00, - 0x08, 0x14, 0x2A, 0x14, 0x22, - 0x22, 0x14, 0x2A, 0x14, 0x08, - 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code - 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block - 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block - 0x00, 0x00, 0x00, 0xFF, 0x00, - 0x10, 0x10, 0x10, 0xFF, 0x00, - 0x14, 0x14, 0x14, 0xFF, 0x00, - 0x10, 0x10, 0xFF, 0x00, 0xFF, - 0x10, 0x10, 0xF0, 0x10, 0xF0, - 0x14, 0x14, 0x14, 0xFC, 0x00, - 0x14, 0x14, 0xF7, 0x00, 0xFF, - 0x00, 0x00, 0xFF, 0x00, 0xFF, - 0x14, 0x14, 0xF4, 0x04, 0xFC, - 0x14, 0x14, 0x17, 0x10, 0x1F, - 0x10, 0x10, 0x1F, 0x10, 0x1F, - 0x14, 0x14, 0x14, 0x1F, 0x00, - 0x10, 0x10, 0x10, 0xF0, 0x00, - 0x00, 0x00, 0x00, 0x1F, 0x10, - 0x10, 0x10, 0x10, 0x1F, 0x10, - 0x10, 0x10, 0x10, 0xF0, 0x10, - 0x00, 0x00, 0x00, 0xFF, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0xFF, 0x10, - 0x00, 0x00, 0x00, 0xFF, 0x14, - 0x00, 0x00, 0xFF, 0x00, 0xFF, - 0x00, 0x00, 0x1F, 0x10, 0x17, - 0x00, 0x00, 0xFC, 0x04, 0xF4, - 0x14, 0x14, 0x17, 0x10, 0x17, - 0x14, 0x14, 0xF4, 0x04, 0xF4, - 0x00, 0x00, 0xFF, 0x00, 0xF7, - 0x14, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0xF7, 0x00, 0xF7, - 0x14, 0x14, 0x14, 0x17, 0x14, - 0x10, 0x10, 0x1F, 0x10, 0x1F, - 0x14, 0x14, 0x14, 0xF4, 0x14, - 0x10, 0x10, 0xF0, 0x10, 0xF0, - 0x00, 0x00, 0x1F, 0x10, 0x1F, - 0x00, 0x00, 0x00, 0x1F, 0x14, - 0x00, 0x00, 0x00, 0xFC, 0x14, - 0x00, 0x00, 0xF0, 0x10, 0xF0, - 0x10, 0x10, 0xFF, 0x10, 0xFF, - 0x14, 0x14, 0x14, 0xFF, 0x14, - 0x10, 0x10, 0x10, 0x1F, 0x00, - 0x00, 0x00, 0x00, 0xF0, 0x10, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, - 0xFF, 0xFF, 0xFF, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xFF, 0xFF, - 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, - 0x38, 0x44, 0x44, 0x38, 0x44, - 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta - 0x7E, 0x02, 0x02, 0x06, 0x06, - 0x02, 0x7E, 0x02, 0x7E, 0x02, - 0x63, 0x55, 0x49, 0x41, 0x63, - 0x38, 0x44, 0x44, 0x3C, 0x04, - 0x40, 0x7E, 0x20, 0x1E, 0x20, - 0x06, 0x02, 0x7E, 0x02, 0x02, - 0x99, 0xA5, 0xE7, 0xA5, 0x99, - 0x1C, 0x2A, 0x49, 0x2A, 0x1C, - 0x4C, 0x72, 0x01, 0x72, 0x4C, - 0x30, 0x4A, 0x4D, 0x4D, 0x30, - 0x30, 0x48, 0x78, 0x48, 0x30, - 0xBC, 0x62, 0x5A, 0x46, 0x3D, - 0x3E, 0x49, 0x49, 0x49, 0x00, - 0x7E, 0x01, 0x01, 0x01, 0x7E, - 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, - 0x44, 0x44, 0x5F, 0x44, 0x44, - 0x40, 0x51, 0x4A, 0x44, 0x40, - 0x40, 0x44, 0x4A, 0x51, 0x40, - 0x00, 0x00, 0xFF, 0x01, 0x03, - 0xE0, 0x80, 0xFF, 0x00, 0x00, - 0x08, 0x08, 0x6B, 0x6B, 0x08, - 0x36, 0x12, 0x36, 0x24, 0x36, - 0x06, 0x0F, 0x09, 0x0F, 0x06, - 0x00, 0x00, 0x18, 0x18, 0x00, - 0x00, 0x00, 0x10, 0x10, 0x00, - 0x30, 0x40, 0xFF, 0x01, 0x01, - 0x00, 0x1F, 0x01, 0x01, 0x1E, - 0x00, 0x19, 0x1D, 0x17, 0x12, - 0x00, 0x3C, 0x3C, 0x3C, 0x3C, - 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP -}; -#endif // FONT5X7_H diff --git a/variants/Sinobit/license.txt b/variants/Sinobit/license.txt deleted file mode 100644 index 7492e93a..00000000 --- a/variants/Sinobit/license.txt +++ /dev/null @@ -1,24 +0,0 @@ -Software License Agreement (BSD License) - -Copyright (c) 2012 Adafruit Industries. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. diff --git a/variants/Sinobit/scroll_support.cpp b/variants/Sinobit/scroll_support.cpp deleted file mode 100644 index 3e57cda1..00000000 --- a/variants/Sinobit/scroll_support.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "scroll_support.h" - - -ScrollSupport *ScrollSupport::makeFor(readingDirection_t dir, String message) -{ - switch (dir) { - case TopToBottom: return new ScrollUp(message); - case LeftToRight: return new ScrollLeft(message); - case RightToLeft: return new ScrollRight(message); - } -} - - -ScrollSupport::ScrollSupport(String aMessage) -{ - message = aMessage; -} - - -ScrollLeft::ScrollLeft(String aMessage) : ScrollSupport(aMessage) -{ -} - - -ScrollRight::ScrollRight(String aMessage) : ScrollSupport(aMessage) -{ -} - - -ScrollUp::ScrollUp(String aMessage) : ScrollSupport(aMessage) -{ -} - diff --git a/variants/Sinobit/scroll_support.h b/variants/Sinobit/scroll_support.h deleted file mode 100644 index d4d5e5e1..00000000 --- a/variants/Sinobit/scroll_support.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef __SCROLL_SUPPORT__ -#define __SCROLL_SUPPORT__ - -#include - - -typedef enum { - TopToBottom, - BottomToTop, - LeftToRight, - RightToLeft -} readingDirection_t; - - -class ScrollSupport -{ - public: - static ScrollSupport *makeFor(readingDirection_t dir, String message); - ScrollSupport(String aMessage); - virtual int16_t initialX(int8_t w) = 0; - virtual int16_t initialY(int8_t h) = 0; - virtual boolean isFinished(int16_t x, int16_t y, int8_t w, int8_t h) = 0; - virtual int16_t nextX(int16_t x) = 0; - virtual int16_t nextY(int16_t y) = 0; - virtual int16_t nextCharacterX(int16_t x, int8_t advance) = 0; - virtual int16_t nextCharacterY(int16_t y, int8_t advance) = 0; - virtual int8_t selectAdvance(int8_t horizontal, int8_t vertical) = 0; - - protected: - - String message; -}; - -class ScrollLeft : public ScrollSupport -{ - public: - ScrollLeft(String message); - int16_t initialX(int8_t w) { return 12; } - int16_t initialY(int8_t h) { return 6 + (h / 2); } - boolean isFinished(int16_t x, int16_t y, int8_t w, int8_t h) { return x <= ((int)message.length() * -1 * w); } - int16_t nextX(int16_t x) { return x - 1; } - int16_t nextY(int16_t y) { return y; } - int16_t nextCharacterX(int16_t x, int8_t advance) { return x + (int16_t)advance; } - int16_t nextCharacterY(int16_t y, int8_t advance) { return y; } - int8_t selectAdvance(int8_t horizontal, int8_t vertical) { return horizontal; } -}; - - -class ScrollRight : public ScrollSupport -{ - public: - ScrollRight(String message); - int16_t initialX(int8_t w) { return (int)message.length() * -1 * w; } - int16_t initialY(int8_t h) { return 6 + (h / 2); } - boolean isFinished(int16_t x, int16_t y, int8_t w, int8_t h) { return x >= 12; } - int16_t nextX(int16_t x) { return x + 1; } - int16_t nextY(int16_t y) { return y; } - int16_t nextCharacterX(int16_t x, int8_t advance) { return x + (int16_t)advance; } - int16_t nextCharacterY(int16_t y, int8_t advance) { return y; } - int8_t selectAdvance(int8_t horizontal, int8_t vertical) { return horizontal; } -}; - - -class ScrollUp : public ScrollSupport -{ - public: - ScrollUp(String message); - int16_t initialX(int8_t w) { return 6 - (w / 2); } - int16_t initialY(int8_t h) { return 12 + h; } - boolean isFinished(int16_t x, int16_t y, int8_t w, int8_t h) { return y <= ((int)message.length() * -1 * h); } - int16_t nextX(int16_t x) { return x; } - int16_t nextY(int16_t y) { return y - 1; } - int16_t nextCharacterX(int16_t x, int8_t advance) { return x; } - int16_t nextCharacterY(int16_t y, int8_t advance) { return y + (int16_t)advance; } - int8_t selectAdvance(int8_t horizontal, int8_t vertical) { return vertical; } -}; - -/* class ScrollDown : public ScrollSupport */ -/* { */ -/* }; */ - -#endif diff --git a/variants/Sinobit/sinobit.cpp b/variants/Sinobit/sinobit.cpp deleted file mode 100644 index e0f9e368..00000000 --- a/variants/Sinobit/sinobit.cpp +++ /dev/null @@ -1,252 +0,0 @@ -#include "sinobit.h" -#include "scroll_support.h" - - -#ifndef pgm_read_byte - #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) -#endif -#ifndef pgm_read_word - #define pgm_read_word(addr) (*(const unsigned short *)(addr)) -#endif -#ifndef pgm_read_dword - #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) -#endif - -// Pointers are a peculiar case...typically 16-bit on AVR boards, -// 32 bits elsewhere. Try to accommodate both... - -#if !defined(__INT_MAX__) || (__INT_MAX__ > 0xFFFF) - #define pgm_read_pointer(addr) ((void *)pgm_read_dword(addr)) -#else - #define pgm_read_pointer(addr) ((void *)pgm_read_word(addr)) -#endif - -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif - -#ifndef _swap_int16_t -#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; } -#endif - -Sinobit_HT1632::Sinobit_HT1632(int8_t data, int8_t wr, int8_t cs, int8_t rd) - : Adafruit_HT1632(data, wr, cs, rd) -{ -} - -void Sinobit_HT1632::blankScreen() -{ - memset(ledmatrix, 0, sizeof(ledmatrix)); -} - - -Sinobit::Sinobit() : Adafruit_GFX(12, 12), leds(15, 13, 16) {} - - -boolean Sinobit::translate(int16_t x, int16_t y, int16_t *x_out, int16_t *y_out) -{ - if (y < 0 || y > 11 || x < 0 || x > 11) { - return false; - } else if ((y < 8 && x < 8) || (y > 7 && x > 7)) { - *y_out = y; - *x_out = x; - } else if (y > 7 && x < 8) { - *y_out = y - 8; - *x_out = x + 8; - } else if (y < 8 && x > 7) { - *y_out = y + 8; - *x_out = x - 8; - } - return true; -} - -void Sinobit::setPixel(uint8_t x, uint8_t y) -{ - drawPixel(x, y, 1); -} - -void Sinobit::clrPixel(uint8_t x, uint8_t y) -{ - drawPixel(x, y, 0); -} - -void Sinobit::drawPixel(int16_t x, int16_t y, uint16_t color) -{ - if((x < 0) || (x >= _width) || (y < 0) || (y >= _height)) return; - - switch(rotation) { // Rotate pixel into device-specific coordinates - case 1: - _swap_int16_t(x, y); - x = WIDTH - 1 - x; - break; - case 2: - x = WIDTH - 1 - x; - y = HEIGHT - 1 - y; - break; - case 3: - _swap_int16_t(x, y); - y = HEIGHT - 1 - y; - break; - } - - int16_t real_row, real_col; - if (!translate(x, y, &real_col, &real_row)) return; - - uint16_t i; - - if (real_row < 8) i = 7; - else if (real_row < 16) i = 128 + 7; - else i = 256 + 7; - i -= (real_row & 7); - - if (real_col < 8) real_col *= 2; - else real_col = (real_col-8) * 2 + 1; - i += real_col * 8; - - if(color) leds.setPixel(i); - else leds.clrPixel(i); -} - -boolean Sinobit::begin() -{ - leds.begin(ADA_HT1632_COMMON_16NMOS); - return true; -} - -void Sinobit::clearScreen() -{ - leds.clearScreen(); -} - -void Sinobit::blankScreen() -{ - leds.blankScreen(); -} - -void Sinobit::fillScreen() -{ - leds.fillScreen(); -} - -void Sinobit::setBrightness(uint8_t b) -{ - leds.setBrightness(b); -} - -void Sinobit::blink(boolean b) -{ - leds.blink(b); -} - -void Sinobit::writeScreen() -{ - leds.writeScreen(); -} - -void Sinobit::setReadingDirection(readingDirection_t dir) -{ - reading_direction = dir; -} - - -// Retrieve a character's bounds -// returns true if spicified char as a glyph - -int8_t Sinobit::characterAdvance(char c, ScrollSupport *scroller) -{ - if(gfxFont) { - if (c != '\n' && c != '\r') { // Not a carriage return; is normal char - uint8_t first = pgm_read_byte(&gfxFont->first); - uint8_t last = pgm_read_byte(&gfxFont->last); - if((c >= first) && (c <= last)) { // Char present in this font? - GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c - first]); - return scroller->selectAdvance(pgm_read_byte(&glyph->xAdvance), - pgm_read_byte(&glyph->height) + 1); - } else { - return 0; - } - } - - } else { // Default font - - if(c != '\n' && c != '\r') { // Normal char; ignore carriage returns - return scroller->selectAdvance(7,8); - } - return true; - } -} - -int8_t Sinobit::fontHeight() -{ - if (gfxFont) { - return pgm_read_byte(&gfxFont->yAdvance); - } else { - return 8; - } -} - - -int8_t Sinobit::fontWidth() -{ - if (gfxFont) { - uint8_t first = pgm_read_byte(&gfxFont->first); - uint8_t last = pgm_read_byte(&gfxFont->last); - uint8_t w = 0; - for (int c = first; c <= last; c++) { - if (c != '\n' && c != '\r') { - GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c]); - int8_t glyph_width = pgm_read_byte(&glyph->xAdvance); - if (glyph_width <= 12) { - w = max(w, glyph_width); - } - } - } - return w; - } else { - return 7; - } -} - - -// print a string using the set reading direction - -void Sinobit::printDirectionally(String message, ScrollSupport *scroller) -{ - const char *buffer = message.c_str(); - size_t size = message.length(); - int16_t x = cursor_x; - int16_t y = cursor_y; - while (size--) { - drawChar(x, y, *buffer, 1, 0, 1); - int8_t advance = characterAdvance(*buffer, scroller); - x = scroller->nextCharacterX(x, advance); - y = scroller->nextCharacterY(y, advance); - buffer++; - } -} - - -// scroll a string onto the LED array based on the reading direction that's set - -void Sinobit::scroll(String message, uint16_t interstitialDelay) -{ - ScrollSupport *scroller = ScrollSupport::makeFor(reading_direction, message); - int8_t h = fontHeight(); - int8_t w = fontWidth(); - int16_t x = scroller->initialX(w); - int16_t y = scroller->initialY(gfxFont ? h : -h); - while (!scroller->isFinished(x, y, w, h)) { - setCursor(x, y); - blankScreen(); - printDirectionally(message, scroller); - writeScreen(); - x = scroller->nextX(x); - y = scroller->nextY(y); - delay(interstitialDelay); - } - delete scroller; -} diff --git a/variants/Sinobit/sinobit.h b/variants/Sinobit/sinobit.h deleted file mode 100644 index 74dd6cf9..00000000 --- a/variants/Sinobit/sinobit.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef SINOBIT_H_ -#define SINOBIT_H_ - -#include "Adafruit_GFX.h" -#include "Adafruit_HT1632.h" -#include "scroll_support.h" - - -#define SINOBIT_PAD_P0 (0) -#define SINOBIT_PAD_P1 (1) -#define SINOBIT_PAD_P2 (2) -#define SINOBIT_PAD_P3 (3) -#define SINOBIT_PAD_P4 (4) -#define SINOBIT_PAD_P5 (10) - -#define SINOBIT_P0 (0) -#define SINOBIT_P1 (1) -#define SINOBIT_P2 (2) -#define SINOBIT_P3 (3) -#define SINOBIT_P4 (4) -#define SINOBIT_P5 (5) -#define SINOBIT_P6 (6) -#define SINOBIT_P7 (7) -#define SINOBIT_P8 (8) -#define SINOBIT_P9 (9) -#define SINOBIT_P10 (10) -#define SINOBIT_P11 (11) -#define SINOBIT_P12 (12) -#define SINOBIT_P13 (13) -#define SINOBIT_P14 (14) -#define SINOBIT_P15 (15) -#define SINOBIT_P16 (16) -/* #define SINOBIT_P17 (17) */ -/* #define SINOBIT_P18 (18) */ -#define SINOBIT_P19 (19) -#define SINOBIT_P20 (20) - -#define SINOBIT_BUTTON_A (5) -#define SINOBIT_BUTTON_B (11) - -class Sinobit_HT1632 : public Adafruit_HT1632 -{ - public: - Sinobit_HT1632(int8_t data, int8_t wr, int8_t cs, int8_t rd = -1); - void blankScreen(); -}; - - -class Sinobit : public Adafruit_GFX -{ - - public: - Sinobit(); - boolean begin(); - void clearScreen(void); - void blankScreen(void); - void fillScreen(void); - void blink(boolean b); - void setBrightness(uint8_t brightness); - void writeScreen(); - void clrPixel(uint8_t x, uint8_t y); - void setPixel(uint8_t x, uint8_t y); - void drawPixel(int16_t x, int16_t y, uint16_t color); - void setReadingDirection(readingDirection_t dir); - void scroll(String message, uint16_t interstitialDelay); - private: - boolean translate(int16_t x, int16_t y, int16_t *x_out, int16_t *y_out); - int8_t characterAdvance(char c, ScrollSupport *scroller); - int8_t fontHeight(); - int8_t fontWidth(); - void printDirectionally(String message, ScrollSupport *scroller); - Sinobit_HT1632 leds; - readingDirection_t reading_direction; -}; - -#endif From bce2b2681a973d4df33bf76b167905223e3a9b1f Mon Sep 17 00:00:00 2001 From: Tomas Lubkowitz Date: Sun, 7 Jan 2018 14:54:07 +0100 Subject: [PATCH 3/6] Removed and ignored .vscode folder --- .gitignore | 1 + .vscode/settings.json | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index 7c70bf33..82589cc8 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ cores/nRF5/SDK/components/softdevice/*/hex/*.txt # IDE tools extras/ide-tools/bin extras/ide-tools/nRF5FlashSoftDevice.jar +.vscode/* diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index e7fa3d37..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "terminal.integrated.env.osx": { - "PATH": "/Users/Tomas/.platformio/penv/bin:/Users/Tomas/.npm-packages/bin:/Users/Tomas/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Users/Tomas/Library/Python/2.7/bin" - } -} \ No newline at end of file From 4084725c021dbc082d9c6c891b8071782aed572d Mon Sep 17 00:00:00 2001 From: Tomas Lubkowitz Date: Sun, 7 Jan 2018 15:43:26 +0100 Subject: [PATCH 4/6] Removed unecessary comments in variant.cpp, Corrected include guard name in variant.h --- .travis.yml | 1 + README.md | 2 +- boards.txt | 2 +- variants/Sinobit/variant.cpp | 13 +------------ variants/Sinobit/variant.h | 4 ++-- 5 files changed, 6 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index e90af747..cdb46432 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,3 +35,4 @@ script: - buildExampleSketch sandeepmistry:nRF5:TinyBLE 01.Basics Blink - buildExampleSketch sandeepmistry:nRF5:bluey 01.Basics Blink - buildExampleSketch sandeepmistry:nRF5:hackaBLE 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:Sinobit 01.Basics BareMinimum \ No newline at end of file diff --git a/README.md b/README.md index 5f93e356..2ea9372e 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Does not require a custom bootloader on the device. * [Waveshare BLE400](http://www.waveshare.com/wiki/BLE400) * [ng-beacon](https://github.com/urish/ng-beacon) * [TinyBLE](https://www.seeedstudio.com/Seeed-Tiny-BLE-BLE-%2B-6DOF-Mbed-Platform-p-2268.html) - + * [Sino:bit](http://sinobit.org) ## Installing ### Board Manager diff --git a/boards.txt b/boards.txt index 6ce4a881..4c58437f 100644 --- a/boards.txt +++ b/boards.txt @@ -838,7 +838,7 @@ Sinobit.bootloader.tool=sandeepmistry:openocd Sinobit.build.mcu=cortex-m0 Sinobit.build.f_cpu=16000000 -Sinobit.build.board=BBC_MICROBIT +Sinobit.build.board=SINOBIT Sinobit.build.core=nRF5 Sinobit.build.variant=Sinobit Sinobit.build.variant_system_lib= diff --git a/variants/Sinobit/variant.cpp b/variants/Sinobit/variant.cpp index fb637e0c..93111220 100644 --- a/variants/Sinobit/variant.cpp +++ b/variants/Sinobit/variant.cpp @@ -20,49 +20,38 @@ #include "variant.h" const uint32_t g_ADigitalPinMap[] = { - // 0 - 4 + 3, // A0 - left pad 2, // A1 - middle pad 1, // A2 - right pad 4, // A3 - COL1 5, // A4 - COL2 - - // 5 - 9 17, // BTN A 12, // COL9 11, // COL8 18, 10, // COL7 - 6, // A5 - COL3 - 26, // BTN B 20, 23, // SCK 22, // MISO 21, // MOSI 16, - - // 17 + 18 (uint32_t)-1, // 3.3V (uint32_t)-1, // 3.3V - 0, // SCL 30, // SDA - 25, // RX 24, // TX - 7, // COL4 8, // COL5 9, // COL6 13, // ROW1 14, // ROW2 15, // ROW3 - 28, // ACCEL INT 1 27, // ACCEL INT 2 29, // MAG INT 2 - 19 // RST }; diff --git a/variants/Sinobit/variant.h b/variants/Sinobit/variant.h index 35c7d720..5dee52c0 100644 --- a/variants/Sinobit/variant.h +++ b/variants/Sinobit/variant.h @@ -14,8 +14,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef _VARIANT_BBC_MICROBIT_ -#define _VARIANT_BBC_MICROBIT_ +#ifndef _VARIANT_SINOBIT_ +#define _VARIANT_SINOBIT_ /** Master clock frequency */ #define VARIANT_MCK (16000000ul) From 7221b57942aaddaada8a3a63195ddbd7a4c698ab Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Sun, 14 Jan 2018 11:38:40 -0500 Subject: [PATCH 5/6] Add some new lines --- .travis.yml | 2 +- README.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index cdb46432..b5838239 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,4 +35,4 @@ script: - buildExampleSketch sandeepmistry:nRF5:TinyBLE 01.Basics Blink - buildExampleSketch sandeepmistry:nRF5:bluey 01.Basics Blink - buildExampleSketch sandeepmistry:nRF5:hackaBLE 01.Basics Blink - - buildExampleSketch sandeepmistry:nRF5:Sinobit 01.Basics BareMinimum \ No newline at end of file + - buildExampleSketch sandeepmistry:nRF5:Sinobit 01.Basics BareMinimum diff --git a/README.md b/README.md index 2ea9372e..d19df402 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Does not require a custom bootloader on the device. * [ng-beacon](https://github.com/urish/ng-beacon) * [TinyBLE](https://www.seeedstudio.com/Seeed-Tiny-BLE-BLE-%2B-6DOF-Mbed-Platform-p-2268.html) * [Sino:bit](http://sinobit.org) + ## Installing ### Board Manager @@ -58,7 +59,7 @@ No additional setup required. For 64-bit Linux users, ```libc6:i386```, ```libstdc++6:i386```, ```libncurses5:i386``` and ```libudev1:i386``` need to be installed : * ```sudo dpkg --add-architecture i386``` * ```sudo apt-get update``` - * ```sudo apt-get install libc6:i386 libstdc++6:i386 libncurses5:i386 libudev1:i386``` + * ```sudo apt-get install libc6:i386 libstdc++6:i386 libncurses5:i386 libudev1:i386``` ##### Windows From 0f3ddac5fafca0623579d78b473272d94de44867 Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Sun, 14 Jan 2018 11:42:21 -0500 Subject: [PATCH 6/6] Remove stray define --- variants/Sinobit/variant.h | 1 - 1 file changed, 1 deletion(-) diff --git a/variants/Sinobit/variant.h b/variants/Sinobit/variant.h index 5dee52c0..2e048b72 100644 --- a/variants/Sinobit/variant.h +++ b/variants/Sinobit/variant.h @@ -40,7 +40,6 @@ extern "C" // LEDs #define PIN_LED (13) #define LED_BUILTIN PIN_LED -// #define // Buttons #define PIN_BUTTON_A (5)