library for Seeed's Grove - 4 Digit Display

Dependents:   Arch_Digit_Display Arch_Display_Temperature clock DigitDisplay_Clock

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DigitDisplay.cpp Source File

DigitDisplay.cpp

00001 /* The library of Grove - 4 Digit Display
00002  *
00003  * \author  Yihui Xiong
00004  * \date    2014/2/8
00005  *
00006  * The MIT License (MIT)
00007  *
00008  * Copyright (c) 2014 Seeed Technology Inc.
00009  *
00010  * Permission is hereby granted, free of charge, to any person obtaining a copy
00011  * of this software and associated documentation files (the "Software"), to deal
00012  * in the Software without restriction, including without limitation the rights
00013  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00014  * copies of the Software, and to permit persons to whom the Software is
00015  * furnished to do so, subject to the following conditions:
00016  * 
00017  * The above copyright notice and this permission notice shall be included in
00018  * all copies or substantial portions of the Software.
00019  * 
00020  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00021  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00022  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00023  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00024  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00025  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00026  * THE SOFTWARE.
00027  */
00028 
00029 #include "DigitDisplay.h"
00030 
00031 #define ADDR_AUTO  0x40
00032 #define ADDR_FIXED 0x44
00033 
00034 #define POSITION_COLON 1
00035 
00036 #define DIGIT_UNKOWN 0x08
00037 #define DIGIT_NULL   0x00
00038 #define DIGIT_MINUS  0x40
00039 
00040 const uint8_t DIGIT_TABLE[] = {0x3f, 0x06, 0x5b, 0x4f,
00041                               0x66, 0x6d, 0x7d, 0x07,
00042                               0x7f, 0x6f, 0x77, 0x7c,
00043                               0x39, 0x5e, 0x79, 0x71
00044                              }; //0~9,A,b,C,d,E,F
00045 
00046 
00047 inline uint8_t conv(uint8_t n)
00048 {
00049     uint8_t segments;
00050     
00051     if (n <= sizeof(DIGIT_TABLE)) {
00052         segments = DIGIT_TABLE[n];
00053     }else if (n == 0xFF) {
00054         segments = DIGIT_NULL;
00055     } else {
00056         segments = DIGIT_UNKOWN;
00057     }
00058     
00059     return segments;
00060 }
00061 
00062 DigitDisplay::DigitDisplay(PinName clk, PinName dio) : _clk(clk), _dio(dio)
00063 {
00064     _dio.output();
00065     _dio = 1;
00066     _clk = 1;
00067     
00068     _brightness = 2;
00069     _colon      = false;
00070     _off        = true;
00071     
00072     for (uint8_t i = 0; i < sizeof(_content); i++) {
00073         _content[i] = DIGIT_NULL;
00074     }
00075 }
00076 
00077 void DigitDisplay::on()
00078 {
00079     start();
00080     send(0x88 | _brightness);
00081     stop();
00082 }
00083 
00084 void DigitDisplay::off()
00085 {
00086     start();
00087     send(0x80);
00088     stop();
00089 }
00090 
00091 void DigitDisplay::setBrightness(uint8_t brightness)
00092 {
00093     if (brightness > 7) {
00094         brightness = 7;
00095     }
00096     
00097     _brightness = brightness;
00098     
00099     start();
00100     send(0x88 | _brightness);
00101     stop();
00102 }
00103 
00104 void DigitDisplay::setColon(bool enable)
00105 {
00106     if (_colon != enable) {
00107         _colon = enable;
00108         
00109         if (enable) {
00110             _content[POSITION_COLON] |= 0x80;
00111         } else {
00112             _content[POSITION_COLON] &= 0x7F;
00113         }
00114         
00115         writeRaw(POSITION_COLON, _content[POSITION_COLON]);
00116     }    
00117 }
00118     
00119 void DigitDisplay::write(int16_t n)
00120 {
00121     uint8_t negative = 0;
00122     
00123     if (n < 0) {
00124         negative = 1;
00125         n = (-n) % 1000;
00126     } else {
00127         n = n % 10000;
00128     }
00129     
00130     int8_t i = 3;
00131     do {
00132         uint8_t  r = n % 10;
00133         _content[i] = conv(r);
00134         i--;
00135         n = n / 10;
00136     } while (n != 0);
00137     
00138     if (negative) {
00139         _content[i] = DIGIT_MINUS;
00140         i--;
00141     }
00142     
00143     for (int8_t j = 0; j <= i; j++) {
00144         _content[j] = DIGIT_NULL;
00145     }
00146     
00147     if (_colon) {
00148         _content[POSITION_COLON] |= 0x80;
00149     }
00150     
00151     writeRaw(_content);
00152 }
00153 
00154 void DigitDisplay::write(uint8_t numbers[])
00155 {
00156     for (uint8_t i = 0; i < 4; i++) {
00157         _content[i] = conv(numbers[i]);
00158     }
00159     
00160     if (_colon) {
00161         _content[POSITION_COLON] |= 0x80;
00162     }
00163     
00164     start();
00165     send(ADDR_AUTO);
00166     stop();
00167     start();
00168     send(0xC0);
00169     for (uint8_t i = 0; i < 4; i++) {
00170         send(_content[i]);
00171     }
00172     stop();
00173     
00174     if (_off) {
00175         _off = 0;
00176         start();
00177         send(0x88 | _brightness);
00178         stop();
00179     }
00180 }
00181 
00182 void DigitDisplay::write(uint8_t position, uint8_t number)
00183 {
00184     if (position >= 4) {
00185         return;
00186     }
00187     
00188     uint8_t segments = conv(number);
00189     
00190     if ((position == POSITION_COLON) && _colon) {
00191         segments |= 0x80;
00192     }
00193     
00194     _content[position] = segments;
00195     
00196     start();
00197     send(ADDR_FIXED);
00198     stop();
00199     start();
00200     send(0xC0 | position);
00201     send(segments);
00202     stop();
00203     
00204     if (_off) {
00205         _off = 0;
00206         start();
00207         send(0x88 | _brightness);
00208         stop();
00209     }
00210 }
00211 
00212 void DigitDisplay::writeRaw(uint8_t segments[])
00213 {
00214     for (uint8_t i = 0; i < 4; i++) {
00215         _content[i] = segments[i];
00216     }
00217     
00218     start();
00219     send(ADDR_AUTO);
00220     stop();
00221     start();
00222     send(0xC0);
00223     for (uint8_t i = 0; i < 4; i++) {
00224         send(segments[i]);
00225     }
00226     stop();
00227     
00228     if (_off) {
00229         _off = 0;
00230         start();
00231         send(0x88 | _brightness);
00232         stop();
00233     }
00234 }
00235 
00236 void DigitDisplay::writeRaw(uint8_t position, uint8_t segments)
00237 {
00238     if (position >= 4) {
00239         return;
00240     }
00241     
00242     _content[position] = segments;
00243 
00244     start();
00245     send(ADDR_FIXED);
00246     stop();
00247     start();
00248     send(0xC0 | position);
00249     send(segments);
00250     stop();
00251 
00252     if (_off) {
00253         _off = 0;
00254         start();
00255         send(0x88 | _brightness);
00256         stop();
00257     }
00258 }
00259 
00260 void DigitDisplay::clear()
00261 {
00262     for (uint8_t i = 0; i < 4; i++) {
00263         _content[i] = DIGIT_NULL;
00264     }
00265     _colon = false;
00266     
00267     writeRaw(0, DIGIT_NULL);
00268     writeRaw(1, DIGIT_NULL);
00269     writeRaw(2, DIGIT_NULL);
00270     writeRaw(3, DIGIT_NULL);
00271 }
00272     
00273 void DigitDisplay::start()
00274 {
00275     _clk = 1;
00276     _dio = 1;
00277     _dio = 0;
00278     _clk = 0;
00279 }
00280 
00281 bool DigitDisplay::send(uint8_t data)
00282 {
00283     for (uint8_t i = 0; i < 8; i++) {
00284         _clk = 0;
00285         _dio = data & 1;
00286         data >>= 1;
00287         _clk = 1;
00288     }
00289     
00290     // check ack
00291     _clk = 0;
00292     _dio = 1;
00293     _clk = 1;
00294     _dio.input();
00295     
00296     uint16_t count = 0;
00297     while (_dio) {
00298         count++;
00299         if (count >= 200) {
00300             _dio.output();
00301             return false;
00302         }
00303     }
00304     
00305     _dio.output();
00306     return true;
00307 }
00308 
00309 void DigitDisplay::stop()
00310 {
00311     _clk = 0;
00312     _dio = 0;
00313     _clk = 1;
00314     _dio = 1;
00315 }
00316 
00317