Library for Siemens SDA5708 8 digit LED matrix display. The control interface is SPI.

Dependents:   mbed_SDA5708

SDA5708.cpp

Committer:
wim
Date:
2014-09-30
Revision:
1:d8a07b8468f6
Parent:
0:5265413226e5
Child:
2:966fca76e5aa

File content as of revision 1:d8a07b8468f6:

/* mbed SDA5708 LED matrix display Library
 * Copyright (c) 2014, v01: WH, Initial release
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "mbed.h"
#include "SDA5708.h"
#include "font_5x7.h"

// User Defined Characters (UDCs) are defined by a 7 byte bitpattern. The P0..P5 form the character pattern.
//     P7 P6 P5 P4 P3 P2 P1 P0 
// 0   B1 B0  x  0  1  1  1  0
// 1   B1 B0  x  1  0  0  0  1
// .       .............
// 6   B1 B0  x  1  0  0  0  1
//

/** Some sample User Defined Chars 5x7 dots */
const char udc_0[]      = {0x18, 0x14, 0x12, 0x11, 0x12, 0x14, 0x18};  // |>
const char udc_1[]      = {0x03, 0x05, 0x09, 0x11, 0x09, 0x05, 0x03};  // <|
const char udc_2[]      = {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10};  // |
const char udc_3[]      = {0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14};  // ||
const char udc_4[]      = {0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15};  // |||
const char udc_5[]      = {0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00};  // =
const char udc_6[]      = {0x15, 0x0a, 0x15, 0x0a, 0x15, 0x0a, 0x15};  // checkerboard
const char udc_7[]      = {0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x10};  // \

const char udc_Bat_Hi[] = {0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};  // Battery Full
const char udc_Bat_Ha[] = {0x0E, 0x11, 0x11, 0x1F, 0x1F, 0x1F, 0x1F};  // Battery Half
const char udc_Bat_Lo[] = {0x0E, 0x11, 0x11, 0x11, 0x11, 0x1F, 0x1F};  // Battery Low
const char udc_AC[]     = {0x0A, 0x0A, 0x1F, 0x11, 0x0E, 0x04, 0x04};  // AC Power
const char udc_smiley[] = {0x00, 0x0A, 0x00, 0x04, 0x11, 0x0E, 0x00};  // Smiley

/** Create an SDA5708 Display object connected to the proper pins
  *
  * @param  *spi SPI port
  * @param  cs   PinName for Chip Select (active low)
  * @param  rst  PinName for Reset (active low)
  */
SDA5708::SDA5708(SPI *spi, PinName cs, PinName rst) : _spi(spi), _cs(cs), _rst(rst) {
  _init();    
}

#if(SDA5708_PRINTF != 1)
/** Write a character to the LCD
  *
  * @param c The character to write to the display
  */
int SDA5708::putc(int c){
  return _putc(c);  
}

/** Write a raw string to the LCD
  *
  * @param string text, may be followed by variables to emulate formatting the string.
  *                     However, printf formatting is NOT supported and variables will be ignored! 
  */
int SDA5708::printf(const char* text, ...) {
  
  while (*text !=0) {
    _putc(*text);
    text++;
  }
  return 0;
}
#else    
#if DOXYGEN_ONLY
/** Write a character to the LCD
  *
  * @param c The character to write to the display
  */
int SDA5708::putc(int c){
    return _putc(c);
}

/** Write a formatted string to the LCD
  *
  * @param format A printf-style format string, followed by the
  *               variables to use in formatting the string.
  */
int SDA5708::printf(const char* format, ...){
}   
#endif
    
#endif    

/** Clear the screen and locate to 0,0
  */
void SDA5708::cls(){
  //Clear display
  _write(SDA5708_CMD_CLR);

  //Set display to normal
  _write(SDA5708_CMD_NORMAL | _peak | _brightness);  
    
}                              

/** Locate cursor to a screen column and row
  *
  * @param column  The horizontal position from the left, indexed from 0
  * @param row     The vertical position from the top, indexed from 0
  */
void SDA5708::locate(int column, int row){
  _column = column % 8;
}

/** Set Brightness
  *
  * @param brightness The brightness level (valid range 0..7)
  */
void SDA5708::set_brightness(uint8_t brightness){

  _brightness = brightness & 0x07;    

  //Set brightness
  _write(SDA5708_CMD_NORMAL | _peak | _brightness);     
}  

/** Set the Displaymode
  *
  * @param displayMode The Display mode (DispOff, DispOn)
  */
void SDA5708::setMode(DisplayMode displayMode){
    
  if (displayMode == DispOff) {
    //Set brightness to Zero
    _write(SDA5708_CMD_NORMAL | _peak | SDA5708_BRIGHT_0);
  }  
  else {
    //Restore brightness
    _write(SDA5708_CMD_NORMAL | _peak | _brightness);         
  }
}     

/** Set User Defined Characters (UDC)
  *
  * @param unsigned char c   The Index of the UDC (0..7)
  * @param char *udc_data    The bitpatterns for the UDC (7 bytes of 5 significant bits for bitpattern)       
  */
void SDA5708::setUDC(unsigned char c, char *udc_data){
  char *udc;
  int idx;
  
  c = c & 0x07; // mask to valid range
  
  udc = (char *) _udc[c];

  // Copy UDC data to local UDC memory
  for (idx=0; idx < 7; idx++) {
    *udc++ = *udc_data++; 
  }
}   
  

/** Low level Reset method for controller
  */  
void SDA5708::_reset(){

  // Reset
  _rst=0;
  wait_us(500);
  _rst=1;    
}
    
/** Low level Init method for controller
  */  
void SDA5708::_init(){
  
  // Hard Reset
  _reset();
      
  // Init CS
  _cs = 1;

  // Setup the spi for 8 bit data, high steady state clock,
  // rising edge capture, with a 500KHz or 1MHz clock rate  
  _spi->format(8,3);
  _spi->frequency(1000000);    // Max SCL is 5 MHz for SDA5708

  // default display brightness
  _brightness = SDA5708_DEF_BRIGHT;
  _peak       = SDA5708_MAX_PEAK;
   
  //Clear display
  _write(SDA5708_CMD_CLR);

  //Set display to normal
  _write(SDA5708_CMD_NORMAL | _peak | _brightness);  

  //Cursor
  _column=0;       
} 
 
/** Low level command byte write operation.
  */
void SDA5708::_write(uint8_t data){
  int flip;
    
  // Enable CS
  _cs = 0;
  wait_us(1);

  //flip the bits around cause SDA5708 expects LSB first.
  flip = 0;
  if (data & 0x01) flip |= 0x80;
  if (data & 0x02) flip |= 0x40;
  if (data & 0x04) flip |= 0x20;
  if (data & 0x08) flip |= 0x10;
  if (data & 0x10) flip |= 0x08;
  if (data & 0x20) flip |= 0x04;
  if (data & 0x40) flip |= 0x02;
  if (data & 0x80) flip |= 0x01;

  _spi->write(flip);     
  wait_us(1);  // Min setup time is 50ns for SDA5708
  
  // Disable CS
  _cs = 1;
    
}

// Stream implementation functions
int SDA5708::_putc(int value){
  char *fnt_ptr;
  int idx;
  
  //Set Digit address to current cursor position
  _write(SDA5708_CMD_DIG_ADDR | _column);

  if ((value == '\n') || (value == '\r')) {
    _column = 0;      
    return 0;
  }
  else
  { 
    // Sanity check
    if (value < 0x08) { 
      //Pointer to char pattern for UDC      
      fnt_ptr = (char *) _udc[value];
    }              
    else if ((value < 0x20) || (value > 0x7F)) {
      //Pointer to char pattern for 'space'
      fnt_ptr = (char *) font_5x7[0];     
    }  
    else {          
     //Pointer to char pattern 
     fnt_ptr = (char *) font_5x7[value - 0x20];
    }
    
    //Write char pattern 
    for (idx=0; idx < 7; idx++) {
      _write(*fnt_ptr);
      fnt_ptr++;
    }
   
    // Next cursor position
    _column = (_column + 1) % 8;
   
    return 0;     
  }

}

// Stream implementation functions
int SDA5708::_getc(){
  return -1;    
}