/* AVR (Arduino, etc.) driver for LTC-637D1G and similar LED displays. * Uses 3 bytes of memory and needs a timer interrupt. * * The LTC-637 series from Lite-On is an LED clock-radio display with * almost four seven-segment digits, which are each 15mm high and 8mm * wide, which can be driven (if somewhat dimly) directly from the * 40mA GPIO pins on an AVR ATMega. The family includes eight * different models with profoundly shitty pinouts. The one I yanked * out of a Philips clock radio is an “LTC-637D1G”, which as best as I * can tell from the datasheet¹ is interpreted as * follows: * * - the “D” means that the colon in the middle is placed 3.2 mm to * the right of the center of the display, rather than 2.2 mm to its * right as in the “C” version, although I have no idea why this * merits an entire separate set of models, and Lite-On’s datasheet * doesn’t deign to tell us; * - the “1” has no meaning whatsoever; * - the “G” means the LEDs are green instead of red (“P”), which * means they can dissipate up to 75mW each (25mA at an almost 3V * voltage drop), in contrast to the mere 40mW (15mA) of the red * ones; * - the fact that no “-12” follows the color letter indicates that * its first digit is only missing one segment (the one not used in * either “1” or “2”) rather than five. * * These are configured with two common cathodes, I guess so you only * need two current-limiting resistors instead of four, but the * tradeoff is that you need 11 anode pins instead of 7 to drive the * last three digits, or 14 anode pins if you want to drive (what * there is of) all four digits. I have no idea when it would be * cheaper to have two resistors but have to drive 16 pins instead of * 11, but that's the way they “designed” this piece of shit, so this * software exists to compensate. * * The datasheet suggests multiplexing the digits at 1kHz and an 0.1ms * duty cycle, which is pretty close to what we do here. This code * only supports the last three digits, which are the only ones that * fully work anyway, and it energizes only one of the anodes at any * given time, but either or both of the cathodes may be energized. * (The “non-energized” pins are all tri-stated.) * * Brightness is claimed to be minimally 200 microcandelas, typically * 600, at 10mA (125 and 350 μcd for the red ones), and I read the * datasheet graph to say that the relative luminous intensity varies * with current as follows: * * mA: 0 5 10 15 20 25 * ×: 0 0.4 1.0 1.7 2.4 3.1 * μcd: 0 80 200 340 480 620 (min) * μcd: 0 240 600 1020 1440 1860 (typ) * * You would think that you could get a higher duty cycle, and * therefore a higher brightness, by temporally alternating between * the 2 cathodes instead of the 11 anodes. And that will totally * work if you hook up a transistor to each cathode line, instead of * trying to drive the LEDs directly off the ATMega output, and a * resistor up to each anode line (instead of putting the resistors on * the cathodes). If you try to drive the cathodes directly off the * ATMega output, you are going to be sinking current from up to 11 * LEDs into a single ATMega pin, which means the maximum you can do * per LED is 40 mA ÷ 11 = 3.6 mA, and that only half the time, so an * average of 1.8 mA, but worse, an average of about 29 μcd. Those * LEDs are going to be very dim. * * So, instead, we alternate between the anodes, which means we can * run 20mA through each LED when it’s on (which is still only the * same average of 1.8mA, although 43 μcd average), and get away with * 2 resistors instead of 11 resistors. * * (Hmm, maybe it’s worthwhile to support the other mode? The 200mA * the AVR can source would be a quite bright 18mA if divided across * 11 LEDs, and two 200mA transistors is not really a big deal, * right?) * * The crappy pinout according to my tests, with pin numbers that are * not as the ones on the datasheet: * * K\A 9 10 11 12 13 14 15 16 17 18 19 * 1 βc βa βd βb γg γf γe δc δa δd δb * 2 αe βf βe βg γb γa γd γc δf δe δg * * There are single “skipped” pins between pins 10 and 11 (which is * pin 12 on the datasheet) and pins 12 and 13 (which are pins 13 and * 15 on the datasheet). αβγδ are the four digits. I’ve lettered the * segments as follows, which is backwards from how the datasheet does * it: --- * | g | * b| |f * --- * c| a |e * | d | * --- * * Questions to answer: * * - How should I represent the crappy pinout in code? * - How do I deal with timer interrupts in a way that won't interfere * with other Arduino libraries? Which timers does Arduino use for * delay() and millis()? * - What about RAM representation? I feel like the interrupt handler * should do a minimal amount of work since it runs so often. * - What about mapping microcontroller pins to LED pins? * * ¹ LTC-637 series datasheet: LITES01090-1.pdf, SHA-1 * bbec1f3d1fea55de9767887f2c3bac0dc8a0803d, pp. 9-215 to 9-218 of * their 2000–2001 databook. Did you know there were still * electronics companies that published databooks in 2001? */