Library for Sure Electronics HT1632 based LED matrix displays. Supports multiple displays connected together.
Dependents: HT1632MsgScroller SMS_LEDMatrixPrinter
HT1632_LedMatrix.cpp@14:b051965066db, 2013-07-29 (annotated)
- Committer:
- SomeRandomBloke
- Date:
- Mon Jul 29 21:10:07 2013 +0000
- Revision:
- 14:b051965066db
- Parent:
- 13:9a869360d0ae
- Child:
- 15:9323fab1db01
Updated library to specify pin names in constructor
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
SomeRandomBloke | 6:80f554fd77a0 | 1 | /** Library for Holtek HT1632 LED driver chip, |
SomeRandomBloke | 11:0fac71b7ec1d | 2 | * As implemented on the Sure Electronics DE-DP10X and DE-DP13X1X display boards |
SomeRandomBloke | 6:80f554fd77a0 | 3 | * 8 x 32 dot matrix LED module.) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 4 | * |
SomeRandomBloke | 0:b3e0f5bb3b87 | 5 | * Original code by: |
SomeRandomBloke | 0:b3e0f5bb3b87 | 6 | * Nov, 2008 by Bill Westfield ("WestfW") |
SomeRandomBloke | 0:b3e0f5bb3b87 | 7 | * Copyrighted and distributed under the terms of the Berkely license |
SomeRandomBloke | 0:b3e0f5bb3b87 | 8 | * (copy freely, but include this notice of original author.) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 9 | * |
SomeRandomBloke | 0:b3e0f5bb3b87 | 10 | * Adapted for 8x32 display by FlorinC. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 11 | * |
SomeRandomBloke | 2:3e477c909f7a | 12 | * Arduino Library Created and updated by Andrew Lindsay October/November 2009 |
SomeRandomBloke | 2:3e477c909f7a | 13 | * |
SomeRandomBloke | 2:3e477c909f7a | 14 | * Ported to Mbed platform by Andrew Lindsay, November 2012 |
SomeRandomBloke | 6:80f554fd77a0 | 15 | * |
SomeRandomBloke | 6:80f554fd77a0 | 16 | * @author Andrew Lindsay |
SomeRandomBloke | 6:80f554fd77a0 | 17 | * |
SomeRandomBloke | 6:80f554fd77a0 | 18 | * @section LICENSE |
SomeRandomBloke | 6:80f554fd77a0 | 19 | * |
SomeRandomBloke | 6:80f554fd77a0 | 20 | * Copyright (c) 2012 Andrew Lindsay (andrew [at] thiseldo [dot] co [dot] uk) |
SomeRandomBloke | 6:80f554fd77a0 | 21 | * |
SomeRandomBloke | 6:80f554fd77a0 | 22 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
SomeRandomBloke | 6:80f554fd77a0 | 23 | * of this software and associated documentation files (the "Software"), to deal |
SomeRandomBloke | 6:80f554fd77a0 | 24 | * in the Software without restriction, including without limitation the rights |
SomeRandomBloke | 6:80f554fd77a0 | 25 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
SomeRandomBloke | 6:80f554fd77a0 | 26 | * copies of the Software, and to permit persons to whom the Software is |
SomeRandomBloke | 6:80f554fd77a0 | 27 | * furnished to do so, subject to the following conditions: |
SomeRandomBloke | 6:80f554fd77a0 | 28 | |
SomeRandomBloke | 6:80f554fd77a0 | 29 | * The above copyright notice and this permission notice shall be included in |
SomeRandomBloke | 6:80f554fd77a0 | 30 | * all copies or substantial portions of the Software. |
SomeRandomBloke | 6:80f554fd77a0 | 31 | * |
SomeRandomBloke | 6:80f554fd77a0 | 32 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
SomeRandomBloke | 6:80f554fd77a0 | 33 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
SomeRandomBloke | 6:80f554fd77a0 | 34 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
SomeRandomBloke | 6:80f554fd77a0 | 35 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
SomeRandomBloke | 6:80f554fd77a0 | 36 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
SomeRandomBloke | 6:80f554fd77a0 | 37 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
SomeRandomBloke | 6:80f554fd77a0 | 38 | * THE SOFTWARE. |
SomeRandomBloke | 6:80f554fd77a0 | 39 | * |
SomeRandomBloke | 6:80f554fd77a0 | 40 | * @section DESCRIPTION |
SomeRandomBloke | 6:80f554fd77a0 | 41 | * Functions to drive displays |
SomeRandomBloke | 6:80f554fd77a0 | 42 | * |
SomeRandomBloke | 6:80f554fd77a0 | 43 | */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 44 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 45 | #include "mbed.h" |
SomeRandomBloke | 0:b3e0f5bb3b87 | 46 | #include "HT1632_LedMatrix.h" |
SomeRandomBloke | 0:b3e0f5bb3b87 | 47 | #include "font_5x7_p.h" |
SomeRandomBloke | 0:b3e0f5bb3b87 | 48 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 49 | #define HIGH 1 |
SomeRandomBloke | 0:b3e0f5bb3b87 | 50 | #define LOW 0 |
SomeRandomBloke | 0:b3e0f5bb3b87 | 51 | /* |
SomeRandomBloke | 0:b3e0f5bb3b87 | 52 | * Set these constants to the values of the pins connected to the SureElectronics Module |
SomeRandomBloke | 6:80f554fd77a0 | 53 | * For mbed, use WR=p7, DATA=p5, cs1=p17, cs2=p18, cs3=p19, cs4=p20 |
SomeRandomBloke | 0:b3e0f5bb3b87 | 54 | */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 55 | |
SomeRandomBloke | 2:3e477c909f7a | 56 | // CS pins 17, 18, 19, 20 used. |
SomeRandomBloke | 14:b051965066db | 57 | // Stripboard |
SomeRandomBloke | 14:b051965066db | 58 | //DigitalOut _cs[4] = {p17, p18, p19, p20}; // Chip Select (1, 2, 3, 4) |
SomeRandomBloke | 14:b051965066db | 59 | // PCB |
SomeRandomBloke | 14:b051965066db | 60 | DigitalOut *_cs[4]; // = { NC,NC,NC,NC}; //= { |
SomeRandomBloke | 14:b051965066db | 61 | //p19, p17, p18, p20}; // Chip Select (1, 2, 3, 4) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 62 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 63 | // helper macros |
SomeRandomBloke | 0:b3e0f5bb3b87 | 64 | #define chip_number(x,y) (x >> 5) + (y >> 3)*numYDevices |
SomeRandomBloke | 3:48f430fe186e | 65 | #define chip_nibble_address(x,y) ((x%32)<<1) + ((y%8)>>2); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 66 | #define chip_byte_address(x,y) ((x%32)<<1); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 67 | #define max(a, b) (((a) > (b)) ? (a) : (b)) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 68 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 69 | // Display size and configuration, defaul is for a single 8x32 display |
SomeRandomBloke | 0:b3e0f5bb3b87 | 70 | uint8_t numDevices = 1; // Total number of devices |
SomeRandomBloke | 0:b3e0f5bb3b87 | 71 | uint8_t numXDevices = 1; // Number of horizontal devices |
SomeRandomBloke | 0:b3e0f5bb3b87 | 72 | uint8_t numYDevices = 1; // Number of vertical devices |
SomeRandomBloke | 0:b3e0f5bb3b87 | 73 | uint8_t xMax = 32 * numXDevices-1; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 74 | uint8_t yMax = 8 * numYDevices-1; |
SomeRandomBloke | 9:8a3c981babd9 | 75 | uint8_t displayWidth = 32; |
SomeRandomBloke | 9:8a3c981babd9 | 76 | uint8_t displayHeight = 8; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 77 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 78 | // Variables used to keep track of cursor position |
SomeRandomBloke | 0:b3e0f5bb3b87 | 79 | int cursorX = 0; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 80 | int cursorY = 0; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 81 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 82 | /* |
SomeRandomBloke | 0:b3e0f5bb3b87 | 83 | * we keep a copy of the display controller contents so that we can |
SomeRandomBloke | 0:b3e0f5bb3b87 | 84 | * know which bits are on without having to (slowly) read the device. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 85 | */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 86 | // 4 boards at 32 bytes per board + 1 byte means we don't need to check overwrite in putChar |
SomeRandomBloke | 11:0fac71b7ec1d | 87 | uint8_t shadowram[256]; // our copy of the display's RAM |
SomeRandomBloke | 0:b3e0f5bb3b87 | 88 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 89 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 90 | // Custom character buffers - 8 characters available |
SomeRandomBloke | 0:b3e0f5bb3b87 | 91 | // 6 cols * 8 rows - first byte of each char is the number of columns used |
SomeRandomBloke | 0:b3e0f5bb3b87 | 92 | // Bits are aranged in columns with LSB at top |
SomeRandomBloke | 3:48f430fe186e | 93 | uint8_t cgram [8][7] = { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 94 | { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
SomeRandomBloke | 0:b3e0f5bb3b87 | 95 | { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
SomeRandomBloke | 0:b3e0f5bb3b87 | 96 | { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
SomeRandomBloke | 0:b3e0f5bb3b87 | 97 | { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
SomeRandomBloke | 0:b3e0f5bb3b87 | 98 | { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
SomeRandomBloke | 0:b3e0f5bb3b87 | 99 | { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
SomeRandomBloke | 0:b3e0f5bb3b87 | 100 | { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
SomeRandomBloke | 3:48f430fe186e | 101 | { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } |
SomeRandomBloke | 3:48f430fe186e | 102 | }; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 103 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 104 | |
SomeRandomBloke | 14:b051965066db | 105 | // Default constructor p19, p17, p18, p20 |
SomeRandomBloke | 14:b051965066db | 106 | //HT1632_LedMatrix::HT1632_LedMatrix( void ) { } |
SomeRandomBloke | 14:b051965066db | 107 | |
SomeRandomBloke | 14:b051965066db | 108 | HT1632_LedMatrix::HT1632_LedMatrix( PinName _clk, PinName _dat, PinName cs1, PinName cs2, PinName cs3, PinName cs4 ) : |
SomeRandomBloke | 14:b051965066db | 109 | _wrclk(_clk), _data(_dat), _cs1(cs1), _cs2(cs2), _cs3(cs3), _cs4(cs4) |
SomeRandomBloke | 3:48f430fe186e | 110 | { |
SomeRandomBloke | 14:b051965066db | 111 | _cs[0] = &_cs1; |
SomeRandomBloke | 14:b051965066db | 112 | _cs[1] = &_cs2; |
SomeRandomBloke | 14:b051965066db | 113 | _cs[2] = &_cs3; |
SomeRandomBloke | 14:b051965066db | 114 | _cs[3] = &_cs4; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 115 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 116 | |
SomeRandomBloke | 9:8a3c981babd9 | 117 | void HT1632_LedMatrix::init( uint8_t xDevices, uint8_t yDevices, uint8_t displayType ) |
SomeRandomBloke | 3:48f430fe186e | 118 | { |
SomeRandomBloke | 14:b051965066db | 119 | |
SomeRandomBloke | 3:48f430fe186e | 120 | // Set up the display size based on number of devices both horizontal and vertical |
SomeRandomBloke | 11:0fac71b7ec1d | 121 | |
SomeRandomBloke | 3:48f430fe186e | 122 | numXDevices = xDevices; |
SomeRandomBloke | 3:48f430fe186e | 123 | numYDevices = yDevices; |
SomeRandomBloke | 3:48f430fe186e | 124 | numDevices = numXDevices * numYDevices; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 125 | |
SomeRandomBloke | 10:af973a9c48b2 | 126 | if( displayType == HT1632_16x24 ) { |
SomeRandomBloke | 9:8a3c981babd9 | 127 | displayWidth = 24; |
SomeRandomBloke | 9:8a3c981babd9 | 128 | displayHeight = 16; |
SomeRandomBloke | 9:8a3c981babd9 | 129 | } else { |
SomeRandomBloke | 9:8a3c981babd9 | 130 | displayWidth = 32; |
SomeRandomBloke | 9:8a3c981babd9 | 131 | displayHeight = 8; |
SomeRandomBloke | 11:0fac71b7ec1d | 132 | } |
SomeRandomBloke | 9:8a3c981babd9 | 133 | xMax = displayWidth * numXDevices-1; |
SomeRandomBloke | 9:8a3c981babd9 | 134 | yMax = displayHeight * numYDevices-1; |
SomeRandomBloke | 9:8a3c981babd9 | 135 | |
SomeRandomBloke | 3:48f430fe186e | 136 | // Disable all display CS lines by taking high |
SomeRandomBloke | 3:48f430fe186e | 137 | for( uint8_t i = 0; i < 4; i++ ) |
SomeRandomBloke | 14:b051965066db | 138 | _cs[i] = HIGH; |
SomeRandomBloke | 14:b051965066db | 139 | // _cs1 = HIGH; |
SomeRandomBloke | 14:b051965066db | 140 | // _cs2 = HIGH; |
SomeRandomBloke | 14:b051965066db | 141 | // _cs3 = HIGH; |
SomeRandomBloke | 14:b051965066db | 142 | // _cs4 = HIGH; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 143 | |
SomeRandomBloke | 4:7513dd37efed | 144 | for (uint8_t chipno=0; chipno<4; chipno++) { |
SomeRandomBloke | 3:48f430fe186e | 145 | chipfree(chipno); // unselect it |
SomeRandomBloke | 8:61130f9b5b79 | 146 | |
SomeRandomBloke | 11:0fac71b7ec1d | 147 | sendcmd(chipno, HT1632_CMD_SYSON); // System on |
SomeRandomBloke | 11:0fac71b7ec1d | 148 | sendcmd(chipno, HT1632_CMD_LEDON); // LEDs on |
SomeRandomBloke | 11:0fac71b7ec1d | 149 | sendcmd(chipno, HT1632_CMD_BLOFF); // Blink Off |
SomeRandomBloke | 11:0fac71b7ec1d | 150 | sendcmd(chipno, HT1632_CMD_MSTMD); // Master Mode |
SomeRandomBloke | 9:8a3c981babd9 | 151 | sendcmd(chipno, HT1632_CMD_RCCLK); // Internal Oscillator |
SomeRandomBloke | 10:af973a9c48b2 | 152 | if( displayType == HT1632_16x24 ) { |
SomeRandomBloke | 9:8a3c981babd9 | 153 | // TODO - check |
SomeRandomBloke | 9:8a3c981babd9 | 154 | sendcmd(chipno, HT1632_CMD_COMS10); // 16*24, NMOS drivers |
SomeRandomBloke | 11:0fac71b7ec1d | 155 | } else { |
SomeRandomBloke | 9:8a3c981babd9 | 156 | sendcmd(chipno, HT1632_CMD_COMS00); // 08*32, NMOS drivers |
SomeRandomBloke | 9:8a3c981babd9 | 157 | } |
SomeRandomBloke | 3:48f430fe186e | 158 | sendcmd(chipno, HT1632_CMD_PWM | 0x0c); // PWM Duty |
SomeRandomBloke | 8:61130f9b5b79 | 159 | |
SomeRandomBloke | 3:48f430fe186e | 160 | for (uint8_t i=0; i<96; i++) |
SomeRandomBloke | 3:48f430fe186e | 161 | senddata(chipno, i, 0); // clear the display |
SomeRandomBloke | 3:48f430fe186e | 162 | wait(0.1); |
SomeRandomBloke | 3:48f430fe186e | 163 | } |
SomeRandomBloke | 3:48f430fe186e | 164 | cursorX = 0; |
SomeRandomBloke | 3:48f430fe186e | 165 | cursorY = 0; |
SomeRandomBloke | 14:b051965066db | 166 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 167 | } |
SomeRandomBloke | 3:48f430fe186e | 168 | |
SomeRandomBloke | 6:80f554fd77a0 | 169 | void HT1632_LedMatrix::displayOff( void ) |
SomeRandomBloke | 6:80f554fd77a0 | 170 | { |
SomeRandomBloke | 5:33b2bfce06b7 | 171 | for (uint8_t chipno=0; chipno<4; chipno++) { |
SomeRandomBloke | 5:33b2bfce06b7 | 172 | chipfree(chipno); // unselect it |
SomeRandomBloke | 5:33b2bfce06b7 | 173 | sendcmd(chipno, HT1632_CMD_LEDOFF); // LEDs on |
SomeRandomBloke | 5:33b2bfce06b7 | 174 | } |
SomeRandomBloke | 5:33b2bfce06b7 | 175 | } |
SomeRandomBloke | 5:33b2bfce06b7 | 176 | |
SomeRandomBloke | 6:80f554fd77a0 | 177 | void HT1632_LedMatrix::displayOn( void ) |
SomeRandomBloke | 6:80f554fd77a0 | 178 | { |
SomeRandomBloke | 5:33b2bfce06b7 | 179 | for (uint8_t chipno=0; chipno<4; chipno++) { |
SomeRandomBloke | 5:33b2bfce06b7 | 180 | chipfree(chipno); // unselect it |
SomeRandomBloke | 5:33b2bfce06b7 | 181 | sendcmd(chipno, HT1632_CMD_LEDON); // LEDs on |
SomeRandomBloke | 5:33b2bfce06b7 | 182 | } |
SomeRandomBloke | 5:33b2bfce06b7 | 183 | } |
SomeRandomBloke | 5:33b2bfce06b7 | 184 | |
SomeRandomBloke | 5:33b2bfce06b7 | 185 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 186 | /*********************************************************************** |
SomeRandomBloke | 0:b3e0f5bb3b87 | 187 | * chipselect / chipfree |
SomeRandomBloke | 0:b3e0f5bb3b87 | 188 | * Select or de-select a particular ht1632 chip. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 189 | * De-selecting a chip ends the commands being sent to a chip. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 190 | * CD pins are active-low; writing 0 to the pin selects the chip. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 191 | ***********************************************************************/ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 192 | void HT1632_LedMatrix::chipselect(uint8_t chipno) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 193 | { |
SomeRandomBloke | 14:b051965066db | 194 | *_cs[chipno] = LOW; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 195 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 196 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 197 | void HT1632_LedMatrix::chipfree(uint8_t chipno) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 198 | { |
SomeRandomBloke | 14:b051965066db | 199 | *_cs[chipno] = HIGH; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 200 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 201 | |
SomeRandomBloke | 9:8a3c981babd9 | 202 | /** |
SomeRandomBloke | 0:b3e0f5bb3b87 | 203 | * writebits |
SomeRandomBloke | 9:8a3c981babd9 | 204 | * Write bits to HT1632 on pins HT1632_DATA, HT1632_WRCLK |
SomeRandomBloke | 0:b3e0f5bb3b87 | 205 | * Chip is assumed to already be chip-selected |
SomeRandomBloke | 0:b3e0f5bb3b87 | 206 | * Bits are shifted out from MSB to LSB, with the first bit sent |
SomeRandomBloke | 0:b3e0f5bb3b87 | 207 | * being (bits & firstbit), shifted till firsbit is zero. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 208 | */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 209 | void HT1632_LedMatrix::writebits (uint8_t bits, uint8_t firstbit) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 210 | { |
SomeRandomBloke | 3:48f430fe186e | 211 | while (firstbit) { |
SomeRandomBloke | 14:b051965066db | 212 | _wrclk = LOW; |
SomeRandomBloke | 14:b051965066db | 213 | // for( int i=0; i<2; i++); |
SomeRandomBloke | 3:48f430fe186e | 214 | if (bits & firstbit) { |
SomeRandomBloke | 14:b051965066db | 215 | _data = HIGH; |
SomeRandomBloke | 3:48f430fe186e | 216 | } else { |
SomeRandomBloke | 14:b051965066db | 217 | _data = LOW; |
SomeRandomBloke | 3:48f430fe186e | 218 | } |
SomeRandomBloke | 14:b051965066db | 219 | _wrclk = HIGH; |
SomeRandomBloke | 3:48f430fe186e | 220 | firstbit >>= 1; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 221 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 222 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 223 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 224 | /* |
SomeRandomBloke | 0:b3e0f5bb3b87 | 225 | * writedatabits |
SomeRandomBloke | 9:8a3c981babd9 | 226 | * Write databits to HT1632 on pins HT1632_DATA, HT1632_WRCLK |
SomeRandomBloke | 0:b3e0f5bb3b87 | 227 | * Chip is assumed to already be chip-selected |
SomeRandomBloke | 0:b3e0f5bb3b87 | 228 | * Bits are shifted out from LSB to MSB |
SomeRandomBloke | 0:b3e0f5bb3b87 | 229 | */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 230 | void HT1632_LedMatrix::writedatabits (uint8_t bits, uint8_t count) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 231 | { |
SomeRandomBloke | 3:48f430fe186e | 232 | while (count) { |
SomeRandomBloke | 14:b051965066db | 233 | _wrclk = LOW; |
SomeRandomBloke | 14:b051965066db | 234 | // for( int i=0; i<2; i++); |
SomeRandomBloke | 14:b051965066db | 235 | _data = bits & 1; |
SomeRandomBloke | 14:b051965066db | 236 | _wrclk = HIGH; |
SomeRandomBloke | 3:48f430fe186e | 237 | count--; |
SomeRandomBloke | 3:48f430fe186e | 238 | bits >>= 1; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 239 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 240 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 241 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 242 | /* |
SomeRandomBloke | 0:b3e0f5bb3b87 | 243 | * sendcmd |
SomeRandomBloke | 0:b3e0f5bb3b87 | 244 | * Send a command to the ht1632 chip. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 245 | * A command consists of a 3-bit "CMD" ID, an 8bit command, and |
SomeRandomBloke | 0:b3e0f5bb3b87 | 246 | * one "don't care bit". |
SomeRandomBloke | 0:b3e0f5bb3b87 | 247 | * Select 1 0 0 c7 c6 c5 c4 c3 c2 c1 c0 xx Free |
SomeRandomBloke | 0:b3e0f5bb3b87 | 248 | */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 249 | void HT1632_LedMatrix::sendcmd (uint8_t chipno, uint8_t command) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 250 | { |
SomeRandomBloke | 3:48f430fe186e | 251 | chipselect(chipno); // Select chip |
SomeRandomBloke | 3:48f430fe186e | 252 | writebits(HT1632_ID_CMD, 0x04); // send 3 bits of id: COMMMAND |
SomeRandomBloke | 3:48f430fe186e | 253 | writebits(command, 0x80); // send the actual command |
SomeRandomBloke | 3:48f430fe186e | 254 | writebits(0, 1); // one extra dont-care bit in commands. |
SomeRandomBloke | 3:48f430fe186e | 255 | chipfree(chipno); //done |
SomeRandomBloke | 0:b3e0f5bb3b87 | 256 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 257 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 258 | /* |
SomeRandomBloke | 0:b3e0f5bb3b87 | 259 | * clear |
SomeRandomBloke | 0:b3e0f5bb3b87 | 260 | * clear the display, and the shadow memory, and the snapshot |
SomeRandomBloke | 0:b3e0f5bb3b87 | 261 | * memory. This uses the "write multiple words" capability of |
SomeRandomBloke | 0:b3e0f5bb3b87 | 262 | * the chipset by writing all 96 words of memory without raising |
SomeRandomBloke | 0:b3e0f5bb3b87 | 263 | * the chipselect signal. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 264 | */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 265 | void HT1632_LedMatrix::clear() |
SomeRandomBloke | 0:b3e0f5bb3b87 | 266 | { |
SomeRandomBloke | 3:48f430fe186e | 267 | char i; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 268 | |
SomeRandomBloke | 3:48f430fe186e | 269 | for (uint8_t chipno=0; chipno<numDevices; chipno++) { |
SomeRandomBloke | 3:48f430fe186e | 270 | chipselect(chipno); // Select chip |
SomeRandomBloke | 3:48f430fe186e | 271 | writebits(HT1632_ID_WR, 0x04); // send ID: WRITE to RAM |
SomeRandomBloke | 3:48f430fe186e | 272 | writebits(0, 0x40); // Send address |
SomeRandomBloke | 9:8a3c981babd9 | 273 | for (i = 0; i < displayWidth; i++) // Clear entire display |
SomeRandomBloke | 3:48f430fe186e | 274 | writedatabits(0, 8); // send 8 bits of data |
SomeRandomBloke | 3:48f430fe186e | 275 | chipfree(chipno); // done |
SomeRandomBloke | 3:48f430fe186e | 276 | for (i=0; i < 64; i++) |
SomeRandomBloke | 3:48f430fe186e | 277 | shadowram[i+64*chipno] = 0; |
SomeRandomBloke | 3:48f430fe186e | 278 | } |
SomeRandomBloke | 3:48f430fe186e | 279 | cursorX = 0; |
SomeRandomBloke | 3:48f430fe186e | 280 | cursorY = 0; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 281 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 282 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 283 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 284 | // Brighness is from 0 to 15 |
SomeRandomBloke | 3:48f430fe186e | 285 | void HT1632_LedMatrix::setBrightness( unsigned char brightness ) |
SomeRandomBloke | 3:48f430fe186e | 286 | { |
SomeRandomBloke | 3:48f430fe186e | 287 | for (uint8_t chipno=0; chipno<numDevices; chipno++) { |
SomeRandomBloke | 3:48f430fe186e | 288 | sendcmd(chipno, HT1632_CMD_PWM | (brightness & 0x0F )); |
SomeRandomBloke | 3:48f430fe186e | 289 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 290 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 291 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 292 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 293 | /* |
SomeRandomBloke | 0:b3e0f5bb3b87 | 294 | * senddata |
SomeRandomBloke | 0:b3e0f5bb3b87 | 295 | * send a nibble (4 bits) of data to a particular memory location of the |
SomeRandomBloke | 0:b3e0f5bb3b87 | 296 | * ht1632. The command has 3 bit ID, 7 bits of address, and 4 bits of data. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 297 | * Select 1 0 1 A6 A5 A4 A3 A2 A1 A0 D0 D1 D2 D3 Free |
SomeRandomBloke | 0:b3e0f5bb3b87 | 298 | * Note that the address is sent MSB first, while the data is sent LSB first! |
SomeRandomBloke | 0:b3e0f5bb3b87 | 299 | * This means that somewhere a bit reversal will have to be done to get |
SomeRandomBloke | 0:b3e0f5bb3b87 | 300 | * zero-based addressing of words and dots within words. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 301 | */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 302 | void HT1632_LedMatrix::senddata (uint8_t chipno, uint8_t address, uint8_t data) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 303 | { |
SomeRandomBloke | 3:48f430fe186e | 304 | chipselect(chipno); // Select chip |
SomeRandomBloke | 3:48f430fe186e | 305 | writebits(HT1632_ID_WR, 0x04); // send ID: WRITE to RAM |
SomeRandomBloke | 3:48f430fe186e | 306 | writebits(address, 0x40); // Send address |
SomeRandomBloke | 3:48f430fe186e | 307 | writedatabits(data, 4); // send 4 bits of data |
SomeRandomBloke | 3:48f430fe186e | 308 | chipfree(chipno); // done |
SomeRandomBloke | 0:b3e0f5bb3b87 | 309 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 310 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 311 | /* |
SomeRandomBloke | 0:b3e0f5bb3b87 | 312 | * sendcol |
SomeRandomBloke | 0:b3e0f5bb3b87 | 313 | * send a byte of data to a particular memory location of the |
SomeRandomBloke | 0:b3e0f5bb3b87 | 314 | * ht1632. The command has 3 bit ID, 7 bits of address, and 8 bits of data. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 315 | * Select 1 0 1 A6 A5 A4 A3 A2 A1 A0 D0 D1 D2 D3 D4 D5 D6 D7 D8 Free |
SomeRandomBloke | 0:b3e0f5bb3b87 | 316 | * Note that the address is sent MSB first, while the data is sent LSB first! |
SomeRandomBloke | 0:b3e0f5bb3b87 | 317 | * This means that somewhere a bit reversal will have to be done to get |
SomeRandomBloke | 0:b3e0f5bb3b87 | 318 | * zero-based addressing of words and dots within words. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 319 | */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 320 | void HT1632_LedMatrix::sendcol (uint8_t chipno, uint8_t address, uint8_t data) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 321 | { |
SomeRandomBloke | 3:48f430fe186e | 322 | chipselect(chipno); // Select chip |
SomeRandomBloke | 3:48f430fe186e | 323 | writebits(HT1632_ID_WR, 0x04); // send ID: WRITE to RAM |
SomeRandomBloke | 3:48f430fe186e | 324 | writebits(address, 0x40); // Send address |
SomeRandomBloke | 3:48f430fe186e | 325 | writedatabits(data, 8); // send 8 bits of data |
SomeRandomBloke | 3:48f430fe186e | 326 | chipfree(chipno); // done |
SomeRandomBloke | 0:b3e0f5bb3b87 | 327 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 328 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 329 | // Write a string at the position specified |
SomeRandomBloke | 4:7513dd37efed | 330 | // x and y start from 0 and count number of pixels, 2nd row on a 2 row display is y=8 |
SomeRandomBloke | 3:48f430fe186e | 331 | void HT1632_LedMatrix::putString(int x, int y, char *str) |
SomeRandomBloke | 3:48f430fe186e | 332 | { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 333 | cursorX = x; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 334 | cursorY = y; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 335 | while( *str ) { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 336 | putChar( cursorX, y, *str++ ); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 337 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 338 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 339 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 340 | /* |
SomeRandomBloke | 9:8a3c981babd9 | 341 | * Copy a character glyph from the font data structure to |
SomeRandomBloke | 0:b3e0f5bb3b87 | 342 | * display memory, with its upper left at the given coordinate |
SomeRandomBloke | 0:b3e0f5bb3b87 | 343 | * This is unoptimized and simply uses plot() to draw each dot. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 344 | */ |
SomeRandomBloke | 3:48f430fe186e | 345 | void HT1632_LedMatrix::write( uint8_t c) |
SomeRandomBloke | 3:48f430fe186e | 346 | { |
SomeRandomBloke | 3:48f430fe186e | 347 | putChar( cursorX, cursorY, (char)c ); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 348 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 349 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 350 | /* |
SomeRandomBloke | 9:8a3c981babd9 | 351 | * Copy a character glyph from the font data structure to |
SomeRandomBloke | 0:b3e0f5bb3b87 | 352 | * display memory, with its upper left at the given coordinate |
SomeRandomBloke | 0:b3e0f5bb3b87 | 353 | * This is unoptimized and simply uses plot() to draw each dot. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 354 | * returns number of columns that didn't fit |
SomeRandomBloke | 0:b3e0f5bb3b87 | 355 | */ |
SomeRandomBloke | 3:48f430fe186e | 356 | uint8_t HT1632_LedMatrix::putChar(int x, int y, char c) |
SomeRandomBloke | 3:48f430fe186e | 357 | { |
SomeRandomBloke | 3:48f430fe186e | 358 | // fonts defined for ascii 32 and beyond (index 0 in font array is ascii 32); |
SomeRandomBloke | 3:48f430fe186e | 359 | // CGRAM characters are in range 0 to 15 with 8-15 being repeat of 0-7 |
SomeRandomBloke | 3:48f430fe186e | 360 | // note we force y to be modulo 8 - we do not support writing character to partial y values. |
SomeRandomBloke | 3:48f430fe186e | 361 | |
SomeRandomBloke | 3:48f430fe186e | 362 | uint8_t charIndex; |
SomeRandomBloke | 3:48f430fe186e | 363 | uint8_t colData; |
SomeRandomBloke | 3:48f430fe186e | 364 | uint8_t numCols; |
SomeRandomBloke | 3:48f430fe186e | 365 | uint8_t chipno; |
SomeRandomBloke | 3:48f430fe186e | 366 | uint8_t addr; |
SomeRandomBloke | 3:48f430fe186e | 367 | uint8_t colsLeft = 0; // cols that didn't fit |
SomeRandomBloke | 3:48f430fe186e | 368 | |
SomeRandomBloke | 3:48f430fe186e | 369 | if( c > 15 ) { |
SomeRandomBloke | 3:48f430fe186e | 370 | // Regular characters |
SomeRandomBloke | 3:48f430fe186e | 371 | // replace undisplayable characters with blank; |
SomeRandomBloke | 3:48f430fe186e | 372 | if (c < 32 || c > 126) { |
SomeRandomBloke | 3:48f430fe186e | 373 | charIndex = 0; |
SomeRandomBloke | 3:48f430fe186e | 374 | } else { |
SomeRandomBloke | 3:48f430fe186e | 375 | charIndex = c - 32; |
SomeRandomBloke | 3:48f430fe186e | 376 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 377 | |
SomeRandomBloke | 3:48f430fe186e | 378 | // move character definition, pixel by pixel, onto the display; |
SomeRandomBloke | 3:48f430fe186e | 379 | // fonts are defined as one byte per col; |
SomeRandomBloke | 3:48f430fe186e | 380 | numCols=smallFont[charIndex][6]; // get the number of columns this character uses |
SomeRandomBloke | 3:48f430fe186e | 381 | for (uint8_t col=0; col<numCols; col++) { |
SomeRandomBloke | 3:48f430fe186e | 382 | colData = smallFont[charIndex][col]; |
SomeRandomBloke | 3:48f430fe186e | 383 | chipno = chip_number(x,y); |
SomeRandomBloke | 3:48f430fe186e | 384 | addr = chip_byte_address(x,y); // compute which memory byte this is in |
SomeRandomBloke | 3:48f430fe186e | 385 | if (x <= xMax && y <= yMax) { |
SomeRandomBloke | 9:8a3c981babd9 | 386 | shadowram[(addr>>1) + displayWidth * chipno] = colData; |
SomeRandomBloke | 3:48f430fe186e | 387 | sendcol(chipno,addr,colData); |
SomeRandomBloke | 3:48f430fe186e | 388 | x++; |
SomeRandomBloke | 3:48f430fe186e | 389 | } else { |
SomeRandomBloke | 3:48f430fe186e | 390 | colsLeft++; |
SomeRandomBloke | 3:48f430fe186e | 391 | } |
SomeRandomBloke | 3:48f430fe186e | 392 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 393 | } else { |
SomeRandomBloke | 3:48f430fe186e | 394 | // CGRAM Characters |
SomeRandomBloke | 3:48f430fe186e | 395 | charIndex = c & 0x07; // Only low 3 bits count |
SomeRandomBloke | 3:48f430fe186e | 396 | numCols=cgram[charIndex][0]; // get the number of columns this character uses |
SomeRandomBloke | 3:48f430fe186e | 397 | // fonts are defined as one byte per col; |
SomeRandomBloke | 3:48f430fe186e | 398 | for (uint8_t col=1; col<=numCols; col++) { |
SomeRandomBloke | 3:48f430fe186e | 399 | colData = cgram[charIndex][col]; |
SomeRandomBloke | 3:48f430fe186e | 400 | chipno = chip_number(x,y); |
SomeRandomBloke | 3:48f430fe186e | 401 | addr = chip_byte_address(x,y); // compute which memory byte this is in |
SomeRandomBloke | 3:48f430fe186e | 402 | if (x <= xMax && y <= yMax) { |
SomeRandomBloke | 9:8a3c981babd9 | 403 | shadowram[(addr>>1) + displayWidth * chipno] = colData; |
SomeRandomBloke | 3:48f430fe186e | 404 | sendcol(chipno,addr,colData); |
SomeRandomBloke | 3:48f430fe186e | 405 | x++; |
SomeRandomBloke | 3:48f430fe186e | 406 | } else { |
SomeRandomBloke | 3:48f430fe186e | 407 | colsLeft++; |
SomeRandomBloke | 3:48f430fe186e | 408 | } |
SomeRandomBloke | 3:48f430fe186e | 409 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 410 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 411 | |
SomeRandomBloke | 3:48f430fe186e | 412 | cursorX = x; |
SomeRandomBloke | 3:48f430fe186e | 413 | cursorY = y; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 414 | |
SomeRandomBloke | 3:48f430fe186e | 415 | return colsLeft; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 416 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 417 | |
SomeRandomBloke | 14:b051965066db | 418 | int HT1632_LedMatrix::_putc(int c) |
SomeRandomBloke | 14:b051965066db | 419 | { |
SomeRandomBloke | 14:b051965066db | 420 | if (c == '\n') { |
SomeRandomBloke | 14:b051965066db | 421 | cursorY += 8; |
SomeRandomBloke | 14:b051965066db | 422 | cursorX = 0; |
SomeRandomBloke | 14:b051965066db | 423 | } else if (c == '\r') { |
SomeRandomBloke | 14:b051965066db | 424 | // skip em |
SomeRandomBloke | 14:b051965066db | 425 | } else { |
SomeRandomBloke | 14:b051965066db | 426 | putChar(cursorX, cursorY, c); |
SomeRandomBloke | 14:b051965066db | 427 | cursorX += 6; |
SomeRandomBloke | 13:9a869360d0ae | 428 | // if (wrap && (cursorX > (_width - 6))) { |
SomeRandomBloke | 13:9a869360d0ae | 429 | // cursorY += 8; |
SomeRandomBloke | 13:9a869360d0ae | 430 | // cursorX = 0; |
SomeRandomBloke | 13:9a869360d0ae | 431 | // } |
SomeRandomBloke | 14:b051965066db | 432 | } |
SomeRandomBloke | 13:9a869360d0ae | 433 | |
SomeRandomBloke | 14:b051965066db | 434 | return c; |
SomeRandomBloke | 13:9a869360d0ae | 435 | } |
SomeRandomBloke | 14:b051965066db | 436 | int HT1632_LedMatrix::_getc() |
SomeRandomBloke | 14:b051965066db | 437 | { |
SomeRandomBloke | 13:9a869360d0ae | 438 | return -1; |
SomeRandomBloke | 13:9a869360d0ae | 439 | } |
SomeRandomBloke | 13:9a869360d0ae | 440 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 441 | // Set position of cursor for writing |
SomeRandomBloke | 3:48f430fe186e | 442 | void HT1632_LedMatrix::gotoXY(int x, int y) |
SomeRandomBloke | 3:48f430fe186e | 443 | { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 444 | cursorX = x; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 445 | cursorY = y; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 446 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 447 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 448 | void HT1632_LedMatrix::getXY(int* x, int* y) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 449 | { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 450 | *x = cursorX; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 451 | *y = cursorY; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 452 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 453 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 454 | void HT1632_LedMatrix::getXYMax(int* x, int* y) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 455 | { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 456 | *x = xMax; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 457 | *y = yMax; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 458 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 459 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 460 | // Shift cursor X position a number of positions either left or right. |
SomeRandomBloke | 3:48f430fe186e | 461 | void HT1632_LedMatrix::shiftCursorX(int xinc) |
SomeRandomBloke | 3:48f430fe186e | 462 | { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 463 | cursorX += xinc; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 464 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 465 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 466 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 467 | /* |
SomeRandomBloke | 0:b3e0f5bb3b87 | 468 | * plot a point on the display, with the upper left hand corner |
SomeRandomBloke | 0:b3e0f5bb3b87 | 469 | * being (0,0), and the lower right hand corner being (xMax-1, yMax-1). |
SomeRandomBloke | 0:b3e0f5bb3b87 | 470 | * Note that Y increases going "downward" in contrast with most |
SomeRandomBloke | 0:b3e0f5bb3b87 | 471 | * mathematical coordiate systems, but in common with many displays |
SomeRandomBloke | 0:b3e0f5bb3b87 | 472 | * basic bounds checking used. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 473 | */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 474 | void HT1632_LedMatrix::plot (int x, int y, char val) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 475 | { |
SomeRandomBloke | 3:48f430fe186e | 476 | if (x<0 || x>xMax || y<0 || y>yMax) |
SomeRandomBloke | 3:48f430fe186e | 477 | return; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 478 | |
SomeRandomBloke | 3:48f430fe186e | 479 | uint8_t chipno = chip_number(x,y); |
SomeRandomBloke | 3:48f430fe186e | 480 | char addr = chip_byte_address(x,y); // compute which memory word this is in |
SomeRandomBloke | 3:48f430fe186e | 481 | char shadowAddress = addr >>1; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 482 | |
SomeRandomBloke | 3:48f430fe186e | 483 | char bitval = 1<<(y&7); // compute which bit will need set |
SomeRandomBloke | 0:b3e0f5bb3b87 | 484 | |
SomeRandomBloke | 3:48f430fe186e | 485 | if (val) { // Modify the shadow memory |
SomeRandomBloke | 9:8a3c981babd9 | 486 | shadowram[shadowAddress + displayWidth * chipno] |= bitval; |
SomeRandomBloke | 3:48f430fe186e | 487 | } else { |
SomeRandomBloke | 9:8a3c981babd9 | 488 | shadowram[shadowAddress + displayWidth * chipno] &= ~bitval; |
SomeRandomBloke | 3:48f430fe186e | 489 | } |
SomeRandomBloke | 3:48f430fe186e | 490 | // Now copy the new memory value to the display |
SomeRandomBloke | 9:8a3c981babd9 | 491 | sendcol(chipno, addr, shadowram[shadowAddress + displayWidth * chipno]); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 492 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 493 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 494 | |
SomeRandomBloke | 3:48f430fe186e | 495 | void HT1632_LedMatrix::setCustomChar( int charNum, unsigned char cgchar[] ) |
SomeRandomBloke | 3:48f430fe186e | 496 | { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 497 | for(int i=1; i<7; i++ ) { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 498 | cgram[charNum][i] = (uint8_t)cgchar[i]; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 499 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 500 | cgram[charNum][6] = 0; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 501 | cgram[charNum][0] = 6; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 502 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 503 | |
SomeRandomBloke | 3:48f430fe186e | 504 | void HT1632_LedMatrix::setCustomChar( int charNum, unsigned char cgchar[], uint8_t numCols ) |
SomeRandomBloke | 3:48f430fe186e | 505 | { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 506 | numCols = max(numCols, 6 ); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 507 | for(int i=1; i<=numCols; i++ ) { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 508 | cgram[charNum][i] = (uint8_t)cgchar[i]; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 509 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 510 | cgram[charNum][0] = numCols; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 511 | cgram[charNum][numCols] = 0; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 512 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 513 | |
SomeRandomBloke | 4:7513dd37efed | 514 | void HT1632_LedMatrix::scrollLeft(uint8_t numberCols, uint8_t lineNum ) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 515 | { |
SomeRandomBloke | 4:7513dd37efed | 516 | for (int i=0; i<xMax-numberCols; i++) { |
SomeRandomBloke | 4:7513dd37efed | 517 | shadowram[i]=shadowram[i+numberCols]; |
SomeRandomBloke | 4:7513dd37efed | 518 | } |
SomeRandomBloke | 4:7513dd37efed | 519 | for (int i=xMax-numberCols; i<xMax; i++) { |
SomeRandomBloke | 4:7513dd37efed | 520 | shadowram[i]=0; |
SomeRandomBloke | 4:7513dd37efed | 521 | } |
SomeRandomBloke | 11:0fac71b7ec1d | 522 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 523 | cursorX -= numberCols; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 524 | if (cursorX < 0 ) cursorX = 0; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 525 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 526 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 527 | void HT1632_LedMatrix::putShadowRam() |
SomeRandomBloke | 0:b3e0f5bb3b87 | 528 | { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 529 | for (int chipno=0; chipno<numDevices; chipno++) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 530 | putShadowRam(chipno); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 531 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 532 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 533 | void HT1632_LedMatrix::putShadowRam(uint8_t chipno) |
SomeRandomBloke | 0:b3e0f5bb3b87 | 534 | { |
SomeRandomBloke | 3:48f430fe186e | 535 | for (int i=0; i<64; i+=2) { |
SomeRandomBloke | 9:8a3c981babd9 | 536 | sendcol(chipno,i,shadowram[(i>>1)+ displayWidth * chipno]); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 537 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 538 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 539 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 540 | #ifdef USE_GRAPHIC |
SomeRandomBloke | 0:b3e0f5bb3b87 | 541 | /* |
SomeRandomBloke | 0:b3e0f5bb3b87 | 542 | * Name : drawLine |
SomeRandomBloke | 0:b3e0f5bb3b87 | 543 | * Description : Draws a line between two points on the display. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 544 | * Argument(s) : x1, y1 - Absolute pixel coordinates for line origin. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 545 | * x2, y2 - Absolute pixel coordinates for line end. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 546 | * c - either PIXEL_ON, PIXEL_OFF |
SomeRandomBloke | 0:b3e0f5bb3b87 | 547 | * Return value : none |
SomeRandomBloke | 0:b3e0f5bb3b87 | 548 | */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 549 | void HT1632_LedMatrix::drawLine(unsigned char x1, unsigned char y1, |
SomeRandomBloke | 3:48f430fe186e | 550 | unsigned char x2, unsigned char y2, unsigned char c) |
SomeRandomBloke | 3:48f430fe186e | 551 | { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 552 | int dx, dy, stepx, stepy, fraction; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 553 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 554 | /* Calculate differential form */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 555 | /* dy y2 - y1 */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 556 | /* -- = ------- */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 557 | /* dx x2 - x1 */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 558 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 559 | /* Take differences */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 560 | dy = y2 - y1; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 561 | dx = x2 - x1; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 562 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 563 | /* dy is negative */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 564 | if ( dy < 0 ) { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 565 | dy = -dy; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 566 | stepy = -1; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 567 | } else { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 568 | stepy = 1; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 569 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 570 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 571 | /* dx is negative */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 572 | if ( dx < 0 ) { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 573 | dx = -dx; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 574 | stepx = -1; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 575 | } else { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 576 | stepx = 1; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 577 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 578 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 579 | dx <<= 1; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 580 | dy <<= 1; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 581 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 582 | /* Draw initial position */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 583 | plot( x1, y1, c ); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 584 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 585 | /* Draw next positions until end */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 586 | if ( dx > dy ) { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 587 | /* Take fraction */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 588 | fraction = dy - ( dx >> 1); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 589 | while ( x1 != x2 ) { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 590 | if ( fraction >= 0 ) { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 591 | y1 += stepy; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 592 | fraction -= dx; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 593 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 594 | x1 += stepx; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 595 | fraction += dy; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 596 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 597 | /* Draw calculated point */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 598 | plot( x1, y1, c ); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 599 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 600 | } else { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 601 | /* Take fraction */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 602 | fraction = dx - ( dy >> 1); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 603 | while ( y1 != y2 ) { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 604 | if ( fraction >= 0 ) { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 605 | x1 += stepx; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 606 | fraction -= dy; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 607 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 608 | y1 += stepy; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 609 | fraction += dx; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 610 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 611 | /* Draw calculated point */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 612 | plot( x1, y1, c ); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 613 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 614 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 615 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 616 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 617 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 618 | /* |
SomeRandomBloke | 0:b3e0f5bb3b87 | 619 | * Name : drawRectangle |
SomeRandomBloke | 0:b3e0f5bb3b87 | 620 | * Description : Draw a rectangle given to top left and bottom right points |
SomeRandomBloke | 0:b3e0f5bb3b87 | 621 | * Argument(s) : x1, y1 - Absolute pixel coordinates for top left corner |
SomeRandomBloke | 0:b3e0f5bb3b87 | 622 | * x2, y2 - Absolute pixel coordinates for bottom right corner |
SomeRandomBloke | 3:48f430fe186e | 623 | * c - either PIXEL_ON, PIXEL_OFF |
SomeRandomBloke | 0:b3e0f5bb3b87 | 624 | * Return value : none |
SomeRandomBloke | 0:b3e0f5bb3b87 | 625 | */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 626 | void HT1632_LedMatrix::drawRectangle(unsigned char x1, unsigned char y1, |
SomeRandomBloke | 3:48f430fe186e | 627 | unsigned char x2, unsigned char y2, unsigned char c) |
SomeRandomBloke | 3:48f430fe186e | 628 | { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 629 | drawLine( x1, y1, x2, y1, c ); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 630 | drawLine( x1, y1, x1, y2, c ); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 631 | drawLine( x1, y2, x2, y2, c ); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 632 | drawLine( x2, y1, x2, y2, c ); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 633 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 634 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 635 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 636 | /* |
SomeRandomBloke | 0:b3e0f5bb3b87 | 637 | * Name : drawFilledRectangle |
SomeRandomBloke | 0:b3e0f5bb3b87 | 638 | * Description : Draw a filled rectangle given to top left and bottom right points |
SomeRandomBloke | 0:b3e0f5bb3b87 | 639 | * just simply draws horizontal lines where the rectangle would be |
SomeRandomBloke | 0:b3e0f5bb3b87 | 640 | * Argument(s) : x1, y1 - Absolute pixel coordinates for top left corner |
SomeRandomBloke | 0:b3e0f5bb3b87 | 641 | * x2, y2 - Absolute pixel coordinates for bottom right corner |
SomeRandomBloke | 0:b3e0f5bb3b87 | 642 | * c - either PIXEL_ON, PIXEL_OFF |
SomeRandomBloke | 0:b3e0f5bb3b87 | 643 | * Return value : none |
SomeRandomBloke | 0:b3e0f5bb3b87 | 644 | */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 645 | void HT1632_LedMatrix::drawFilledRectangle(unsigned char x1, unsigned char y1, |
SomeRandomBloke | 3:48f430fe186e | 646 | unsigned char x2, unsigned char y2, unsigned char c) |
SomeRandomBloke | 3:48f430fe186e | 647 | { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 648 | for(int i=y1; i <= y2; i++ ) { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 649 | drawLine( x1, i, x2, i, c ); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 650 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 651 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 652 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 653 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 654 | /* |
SomeRandomBloke | 0:b3e0f5bb3b87 | 655 | * Name : drawCircle |
SomeRandomBloke | 3:48f430fe186e | 656 | * Description : Draw a circle using Bresenham's algorithm. |
SomeRandomBloke | 0:b3e0f5bb3b87 | 657 | * Some small circles will look like squares!! |
SomeRandomBloke | 0:b3e0f5bb3b87 | 658 | * Argument(s) : xc, yc - Centre of circle |
SomeRandomBloke | 0:b3e0f5bb3b87 | 659 | * r - Radius |
SomeRandomBloke | 0:b3e0f5bb3b87 | 660 | * c - either PIXEL_ON, PIXEL_OFF |
SomeRandomBloke | 3:48f430fe186e | 661 | * Return value : None |
SomeRandomBloke | 0:b3e0f5bb3b87 | 662 | */ |
SomeRandomBloke | 0:b3e0f5bb3b87 | 663 | void HT1632_LedMatrix::drawCircle(unsigned char xc, unsigned char yc, |
SomeRandomBloke | 3:48f430fe186e | 664 | unsigned char r, unsigned char c) |
SomeRandomBloke | 3:48f430fe186e | 665 | { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 666 | int x=0; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 667 | int y=r; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 668 | int p=3-(2*r); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 669 | |
SomeRandomBloke | 3:48f430fe186e | 670 | plot( xc+x,yc-y, c); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 671 | |
SomeRandomBloke | 3:48f430fe186e | 672 | for(x=0; x<=y; x++) { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 673 | if (p<0) { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 674 | y=y; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 675 | p=(p+(4*x)+6); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 676 | } else { |
SomeRandomBloke | 0:b3e0f5bb3b87 | 677 | y=y-1; |
SomeRandomBloke | 0:b3e0f5bb3b87 | 678 | p=p+((4*(x-y)+10)); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 679 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 680 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 681 | plot(xc+x,yc-y, c); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 682 | plot(xc-x,yc-y, c); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 683 | plot(xc+x,yc+y, c); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 684 | plot(xc-x,yc+y, c); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 685 | plot(xc+y,yc-x, c); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 686 | plot(xc-y,yc-x, c); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 687 | plot(xc+y,yc+x, c); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 688 | plot(xc-y,yc+x, c); |
SomeRandomBloke | 0:b3e0f5bb3b87 | 689 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 690 | } |
SomeRandomBloke | 0:b3e0f5bb3b87 | 691 | #endif |
SomeRandomBloke | 0:b3e0f5bb3b87 | 692 | |
SomeRandomBloke | 0:b3e0f5bb3b87 | 693 | // The end! |