1 /* 2 Interfacing the Arduino Duemilanove to the ElecFreaks alphanumeric display 3 brick. 4 5 Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk> 6 7 This program is free software; you can redistribute it and/or modify it under 8 the terms of the GNU General Public License as published by the Free Software 9 Foundation; either version 3 of the License, or (at your option) any later 10 version. 11 12 This program is distributed in the hope that it will be useful, but WITHOUT ANY 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 14 PARTICULAR PURPOSE. See the GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License along 17 with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include <Wire.h> 21 22 const int BUFSIZE = 17; 23 char inbuffer[BUFSIZE]; 24 uint8_t nread = 0; 25 26 uint8_t data[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 27 28 void enable_clock() 29 { 30 Wire.beginTransmission(0x70); 31 Wire.write(0x21); 32 Wire.endTransmission(); 33 } 34 35 void set_row_output() 36 { 37 Wire.beginTransmission(0x70); 38 Wire.write(0xa0); 39 Wire.endTransmission(); 40 } 41 42 void set_dimming() 43 { 44 Wire.beginTransmission(0x70); 45 Wire.write(0xe3); // pulse_width = 4/16 46 Wire.endTransmission(); 47 } 48 49 void enable_display() 50 { 51 Wire.beginTransmission(0x70); 52 Wire.write(0x81); // no blinking 53 Wire.endTransmission(); 54 } 55 56 void disable_display() 57 { 58 Wire.beginTransmission(0x70); 59 Wire.write(0x80); 60 Wire.endTransmission(); 61 } 62 63 void init_alphanumeric() 64 { 65 enable_clock(); 66 set_row_output(); 67 set_dimming(); 68 } 69 70 void write_digits(uint8_t data[], uint8_t len) 71 { 72 uint8_t i; 73 74 Wire.beginTransmission(0x70); 75 Wire.write(0x00); // address = 0 76 77 for (i = 0; i < len; i++) 78 { 79 Wire.write(data[i]); 80 } 81 82 Wire.endTransmission(); 83 } 84 85 /* User interface functions. */ 86 87 uint8_t fromHex(char c) 88 { 89 if ((c >= 48) && (c <= 57)) 90 return c - 48; 91 if ((c >= 65) && (c <= 70)) 92 return c - 65 + 10; 93 if ((c >= 97) && (c <= 102)) 94 return c - 97 + 10; 95 return 0; 96 } 97 98 void to_digits(char buffer[], uint8_t data[], uint8_t len) 99 { 100 uint8_t i, j, p, high, low; 101 102 for (i = 0, j = 0; j < len; j += 2) 103 { 104 for (p = 2; p > 0; p--, i += 2) 105 { 106 high = fromHex(buffer[i]); 107 if (high == 17) 108 return; 109 low = fromHex(buffer[i+1]); 110 if (low == 17) 111 return; 112 113 /* Switch to little-endian. */ 114 115 data[j+p-1] = (high << 4) + low; 116 } 117 } 118 } 119 120 void setup() 121 { 122 Wire.begin(); 123 Serial.begin(115200); 124 125 init_alphanumeric(); 126 write_digits(data, 8); 127 enable_display(); 128 129 // Interface loop. 130 131 Serial.println("?"); 132 } 133 134 void loop() 135 { 136 /* Read bytes, obtaining the number read excluding any newline terminator. */ 137 138 if (nread += Serial.readBytesUntil('\n', inbuffer + nread, BUFSIZE - nread)) 139 { 140 /* Handle each command, waiting for the newline. */ 141 142 if (nread >= 16) 143 { 144 to_digits(inbuffer, data, 8); 145 write_digits(data, 8); 146 nread = 0; 147 Serial.println("OK"); 148 } 149 else 150 { 151 Serial.print(nread); 152 Serial.println("..."); 153 } 154 155 Serial.flush(); 156 } 157 } 158 159 extern "C" void __cxa_pure_virtual(void) { 160 while(1); 161 } 162 163 // tabstop=4 expandtab shiftwidth=4