Subversion Repositories idreammicro-arduino

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

/***
 *
 *
 * Deuligne library
 *
 * copyleft 2011 snootlab
 * free software, have fun !
 *
 **/

#include "Deuligne.h"
#include <Wire.h>

extern "C" {
  #include <stdio.h>  //not needed yet
  #include <string.h> //needed for strlen()
  #include <inttypes.h>
#if defined(ARDUINO) &&ARDUINO < 100
  #include "WConstants.h"  //all things wiring / arduino
#endif
}
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#endif


//command bytes for LCD
#define CMD_CLR 0x01
#define CMD_RIGHT 0x1C
#define CMD_LEFT 0x18
#define CMD_HOME 0x02

//stuff the library user might call---------------------------------

//constructor.  num_lines must be 1 or 2, currently.

byte dataPlusMask = 0x20; // TODO!!!

int   adc_key_val[5] ={
  50, 190, 400, 540, 770 };

Deuligne::Deuligne( int devI2CAddress, int num_lines, int lcdwidth, int bufferwidth)  {
  myNumLines = num_lines;
  myWidth = lcdwidth;
  myAddress = devI2CAddress;
  myBufferwidth= bufferwidth;
  NUM_KEYS = 5;
}

void SetMCPReg( byte deviceAddr, byte reg, byte val ) {
  Wire.beginTransmission(deviceAddr);
  SNOOT_WIREWRITE(reg);
  SNOOT_WIREWRITE(val);
  Wire.endTransmission();
}

void SendToLCD( byte deviceAddr, byte data ) {
  data |= dataPlusMask;
  SetMCPReg(deviceAddr,0x0A,data);
  data ^= 0x10; // E
  delayMicroseconds(1);
  SetMCPReg(deviceAddr,0x0A,data);
  data ^= 0x10; // E
  delayMicroseconds(1);
  SetMCPReg(deviceAddr,0x0A,data);
  delay(1);
}

void WriteLCDByte( byte deviceAddr, byte bdata ) {
  SendToLCD(deviceAddr,bdata >> 4);
  SendToLCD(deviceAddr,bdata & 0x0F);
}

void Deuligne::init( void ) {
  TWBR = ((CPU_FREQ / TWI_FREQ_MCP23008) - 16) / 2;
  dataPlusMask = 0; // initial: 0
  SetMCPReg(myAddress,0x05,0x0C); // set CONFREG (0x05) to 0
  SetMCPReg(myAddress,0x00,0x00); // set IOREG (0x00) to 0
  //
  delay(50);
  SendToLCD(myAddress,0x03);
  delay(5);
  SendToLCD(myAddress,0x03);
  delayMicroseconds(100);
  SendToLCD(myAddress,0x03);
  delay(5);
  SendToLCD(myAddress,0x02);
  WriteLCDByte(myAddress,0x28);
  WriteLCDByte(myAddress,0x08);
  WriteLCDByte(myAddress,0x0C); // turn on, cursor off, no blinking
  delayMicroseconds(60);
  WriteLCDByte(myAddress,LCD_CLEARDISPLAY); // clear display
  delay(3);  
  _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;  
  // Initialize to default text direction (for romance languages)
  _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
  // set the entry mode
  command(LCD_ENTRYMODESET | _displaymode);
  backLight(1);
  display();
}

void Deuligne::backLight( bool turnOn ) {
  dataPlusMask |= 0x80; // Lights mask
  if (!turnOn) dataPlusMask ^= 0x80;
  SetMCPReg(myAddress,0x0A,dataPlusMask);  
}


SNOOT_RETURN Deuligne::write( uint8_t value ) {
  dataPlusMask |= 0x40; // RS
  WriteLCDByte(myAddress,(byte)value);
  dataPlusMask ^= 0x40; // RS
}
/*
void Deuligne::printIn( char value[] ) {
  for ( char *p = value; *p != 0; p++ )
    print(*p);
}

*/

void Deuligne::clear() {
  command(CMD_CLR);
}

void Deuligne::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {

}

void Deuligne::setCursor(uint8_t col, uint8_t row) {
  int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
  if ( row > myNumLines ) {
    row = myNumLines-1;    // we count rows starting w/0
  }
 
  command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}

/*
void Deuligne::cursorTo(int line_num, int x) {
  command(CMD_HOME);
  int targetPos = x + line_num * myBufferwidth;
  for ( int i = 0; i < targetPos; i++)
    command(0x14);
}*/


void Deuligne::command( uint8_t command ) {
  // RS - leave low
  WriteLCDByte(myAddress,command);
  delay(1);
}


/**
 *  From LiquidCrystal (official arduino) Library
 **/


// Allows us to fill the first 8 CGRAM locations
// with custom characters
void Deuligne::createChar(uint8_t location, uint8_t charmap[]) {
  location &= 0x7; // we only have 8 locations 0-7
  command(LCD_SETCGRAMADDR | (location << 3));
  for (int i=0; i<8; i++) {
    write(charmap[i]);
  }
}



// Turn the display on/off (quickly)
void Deuligne::noDisplay() {
  _displaycontrol &= ~LCD_DISPLAYON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void Deuligne::display() {
  _displaycontrol |= LCD_DISPLAYON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// Turns the underline cursor on/off
void Deuligne::noCursor() {
  _displaycontrol &= ~LCD_CURSORON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void Deuligne::cursor() {
  _displaycontrol |= LCD_CURSORON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// Turn on and off the blinking cursor
void Deuligne::noBlink() {
  _displaycontrol &= ~LCD_BLINKON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void Deuligne::blink() {
  _displaycontrol |= LCD_BLINKON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// These commands scroll the display without changing the RAM
void Deuligne::scrollDisplayLeft(void) {
  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
}
void Deuligne::scrollDisplayRight(void) {
  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
}

// This is for text that flows Left to Right
void Deuligne::leftToRight(void) {
  _displaymode |= LCD_ENTRYLEFT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This is for text that flows Right to Left
void Deuligne::rightToLeft(void) {
  _displaymode &= ~LCD_ENTRYLEFT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This will 'right justify' text from the cursor
void Deuligne::autoscroll(void) {
  _displaymode |= LCD_ENTRYSHIFTINCREMENT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This will 'left justify' text from the cursor
void Deuligne::noAutoscroll(void) {
  _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
  command(LCD_ENTRYMODESET | _displaymode);
}

void Deuligne::home()
{
  command(LCD_RETURNHOME);  // set cursor position to zero
  delayMicroseconds(2000);  // this command takes a long time!
}


// Get Joystick value
// Convert ADC value to key number :
// 0: Right Key
// 1: Up Key
// 2: Down Key
// 3: Left Key
// 4: Select Key

int Deuligne::get_key(){
  adc_key_in = analogRead(0);    // read the value from the sensor  

  int k;

  //   determine which key is pressed
  for (k = 0; k < NUM_KEYS; k++)
  {
    if (adc_key_in < adc_key_val[k])
    {

      return k;
    }
  }

  if (k >= NUM_KEYS)
    k = -1;     // No valid key pressed

  return k;
}