7 Segment LED Displaydriver, I2C interface, SAA1064

Dependents:   812_hello

SAA1064.cpp

Committer:
wim
Date:
2013-09-23
Revision:
2:970360b29a2a
Parent:
1:79cb73f852da

File content as of revision 2:970360b29a2a:

/* SAA1064 - I2C LED Driver used in multiplex mode (4x 7 Segments and Decimal Point)
 * Copyright (c) 2013 Wim Huiskamp
 *
 * Released under the MIT License: http://mbed.org/license/mit
 *
 * version 0.2 Initial Release
 * version 0.3 Improved Leading Zero suppress for writeInt 
*/
#include "mbed.h"
#include "SAA1064.h"


/** Create a SAA1064 LED displaydriver object using a specified I2C bus and slaveaddress
  *
  * @param I2C &i2c the I2C port to connect to 
  * @param char deviceAddress the address of the SAA1064
  */  
SAA1064::SAA1064(I2C *i2c, uint8_t deviceAddress) : _i2c(i2c) {

   _slaveAddress = deviceAddress;
   _init(); 
};

/** Set segment brightness
  *
  * @param intensity       intensity value, valid Range between 0-7, 0 = 0 mA/segment, 1 = 3 mA/segment etc 
  */  
void SAA1064::setIntensity(uint8_t intensity) {
  uint8_t data[6];
  
  intensity = (intensity & 0x07) << 4;        // Valid Range between 0-7
                                              //  0 = 0 mA/segment, 1 = 3 mA/segment etc 
  data[0] = SAA1064_CTRL;                     // Select Control Reg
  data[1] = SAA1064_CTRL_DEF | intensity;     // Init Control Reg

  // write data to the display
  _i2c->write(_slaveAddress, (char*) data, 2);  

};


/** Write digits 
  *
  * @param digit1  LED segment pattern for digit1 (MSB) 
  * @param digit2  LED segment pattern for digit2 
  * @param digit3  LED segment pattern for digit3
  * @param digit4  LED segment pattern for digit4 (LSB)       
  */  
void SAA1064::write(uint8_t digit1, uint8_t digit2, uint8_t digit3, uint8_t digit4) {
  uint8_t data[6];
  
  data[0] = SAA1064_DIG1;                     // Select Digit1 Reg
  data[1] = digit1;                           // Digit 1
  data[2] = digit2;                           // Digit 2 
  data[3] = digit3;                           // Digit 3 
  data[4] = digit4;                           // Digit 4

  // write data to the display
  _i2c->write(_slaveAddress, (char*) data, 5);   

};


/** Write Integer 
  *
  * @param value     integer value to display, valid range -999...9999 
  * @param dp_digit  digit where decimal point is set, valid range 1..4 (no DP shown for dp_digit = 0)
  * @param leading   suppress leading zero (false=show leading zero, true=suppress leading zero)
  */  
void SAA1064::writeInt(int value, uint8_t dp_digit, bool leading) {
  uint8_t digit_value;
  uint8_t data[6];  

  data[0] = SAA1064_DIG1;                     // Select Digit1 Reg
  
  // limit to valid range
  if (value >= 9999) value = 9999;
  if (value <= -999) value = -999;  

  if (value >= 0) {
    // value 0...9999
    digit_value = value/1000; // compute thousands
    value = value % 1000;     // compute remainder
    if ((digit_value==0) && !(dp_digit==1) && leading )
      data[1] = SAA1064_BLNK;               // suppress leading zero    
    else {
      data[1] = SAA1064_SEGM[digit_value];
      leading = false;                      // dont suppress zero's  
    }  
    if (dp_digit==1) {data[1] |= SAA1064_DP;} // Set decimal point

    
    digit_value = value/100;  // compute hundreds
    value = value % 100;      // compute remainder
    if ((digit_value==0) && !(dp_digit==2) && leading)
      data[2] = SAA1064_BLNK;               // suppress leading zero    
    else {
      data[2] = SAA1064_SEGM[digit_value];
      leading = false;                      // dont suppress zero's  
    }  
    if (dp_digit==2) {data[2] |= SAA1064_DP;} // Set decimal point
    
    digit_value = value/10;   // compute tens
    value = value % 10;       // compute remainder
    if ((digit_value==0) && !(dp_digit==3) && leading)
      data[3] = SAA1064_BLNK;               // suppress leading zero    
    else {
      data[3] = SAA1064_SEGM[digit_value];
      //leading = false;                      // dont suppress zero's  
    }  
    if (dp_digit==3) {data[3] |= SAA1064_DP;} // Set decimal point
    
    //digit_value = value;      // compute units
    data[4] = SAA1064_SEGM[value];          // never suppress units zero  
    if (dp_digit==4) {data[4] |= SAA1064_DP;} // Set decimal point    
    
  }
  else {
    // value -999...-1  
    value = -value;
    data[1] = SAA1064_MINUS;               // Sign 
    if (dp_digit==1) {data[1] |= SAA1064_DP;} // Set decimal point
          
    digit_value = value/100;  // compute hundreds
    value = value % 100;      // compute remainder
    if ((digit_value==0) && !(dp_digit==2) && leading)
      data[2] = SAA1064_BLNK;               // suppress leading zero    
    else {
      data[2] = SAA1064_SEGM[digit_value];
      leading = false;                      // dont suppress zero's  
    }  
    if (dp_digit==2) {data[2] |= SAA1064_DP;} // Set decimal point
        
    digit_value = value/10;   // compute tens
    value = value % 10;       // compute remainder
    if ((digit_value==0) && !(dp_digit==3) && leading)
      data[3] = SAA1064_BLNK;               // suppress leading zero    
    else {
      data[3] = SAA1064_SEGM[digit_value];
      //leading = false;                      // dont suppress zero's  
    }  
    if (dp_digit==3) {data[3] |= SAA1064_DP;} // Set decimal point
    
    //digit_value = value;      // compute units
    data[4] = SAA1064_SEGM[value];          // never suppress units zero         
    if (dp_digit==4) {data[4] |= SAA1064_DP;} // Set decimal point    
  } 

  // write data to the display
  _i2c->write(_slaveAddress, (char*) data, 5);   
     
};

/** snake: show a short animation
  *
  * @param count     number of times animation is repeated, valid range 0..15 
  *
  */  
void SAA1064::snake(uint8_t count) {
  uint8_t i;
  const float step = 0.1;
//  const float loop = 0.1;
  
  count = count & 0x0F; // Limit max count
    
  for (i=0; i<count; i++) {
    write(0x00,0x00,0x00,0x01); wait(step); 
    write(0x00,0x00,0x01,0x01); wait(step);     
    write(0x00,0x01,0x01,0x01); wait(step); 
    write(0x01,0x01,0x01,0x00); wait(step); 
    write(0x21,0x01,0x00,0x00); wait(step);     
    write(0x31,0x00,0x00,0x00); wait(step);         
    write(0x38,0x00,0x00,0x00); wait(step);         
    write(0x18,0x08,0x00,0x00); wait(step);         
    write(0x08,0x08,0x08,0x00); wait(step);         
    write(0x00,0x08,0x08,0x08); wait(step);           
    write(0x00,0x00,0x08,0x0C); wait(step);         
    write(0x00,0x00,0x00,0x0E); wait(step);         
    write(0x00,0x00,0x00,0x06); wait(step);         
    write(0x00,0x00,0x00,0x02); wait(step);         
    write(0x00,0x00,0x00,0x00); wait(step);             
                                        
//    wait(loop)    
  }

}        


/** splash: show a short animation
  *
  * @param count     number of times animation is repeated, valid range 0..15 
  *
  */  
void SAA1064::splash (uint8_t count){  
  uint8_t i;
  const float step = 0.3;
//  const float loop = 0.1;
  
  count = count & 0x0F; // Limit max count
    
  for (i=0; i<count; i++) {
    write(0x00,0x40,0x40,0x00); wait(step);       
    write(0x39,0x09,0x09,0x0F); wait(step); 
                                        
//    wait(loop)    
  }
  write(0x00,0x00,0x00,0x00);
}        


/** Initialise LED driver 
  *
  */  
void SAA1064::_init() { 
  uint8_t data[6];
  
  data[0] = SAA1064_CTRL;                     // Select Control Reg
  data[1] = SAA1064_CTRL_DEF | SAA1064_INT3;  // Init Control Reg
  data[2] = SAA1064_BLNK;                     // Digit 1: All Segments Off
  data[3] = SAA1064_BLNK;                     // Digit 2: All Segments Off 
  data[4] = SAA1064_BLNK;                     // Digit 3: All Segments Off      
  data[5] = SAA1064_BLNK;                     // Digit 4: All Segments Off   

//  data[2] = SAA1064_ALL;                      // Digit 1: All Segments On 
//  data[3] = SAA1064_ALL;                      // Digit 2: All Segments On 
//  data[4] = SAA1064_ALL;                      // Digit 3: All Segments On 
//  data[5] = SAA1064_ALL;                      // Digit 4: All Segments On     

  // write data to the display
  _i2c->write(_slaveAddress, (char*) data, 6);  
  
};