mirror of
https://github.com/fmalpartida/New-LiquidCrystal.git
synced 2026-07-27 19:56:57 +00:00
Included support for SoftI2C library.
This commit is contained in:
@@ -0,0 +1,294 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Created by Francisco Malpartida on 20/08/11.
|
||||
// Copyright 2011 - Under creative commons license 3.0:
|
||||
// Attribution-ShareAlike CC BY-SA
|
||||
//
|
||||
// This software is furnished "as is", without technical support, and with no
|
||||
// warranty, express or implied, as to its usefulness for any purpose.
|
||||
//
|
||||
// Thread Safe: No
|
||||
// Extendable: Yes
|
||||
//
|
||||
// @file LiquidCrystal_SI2C.c
|
||||
// This file implements a basic liquid crystal library that comes as standard
|
||||
// in the Arduino SDK but using an I2C IO extension board and software I2C.
|
||||
// It will use digital pins 6 and 7 for SCL and SDA, but it can be changed
|
||||
// in SI2CIO.cpp to use other pins if needed.
|
||||
//
|
||||
// @brief
|
||||
// This is a basic implementation of the LiquidCrystal library of the
|
||||
// Arduino SDK. The original library has been reworked in such a way that
|
||||
// this class implements the all methods to command an LCD based
|
||||
// on the Hitachi HD44780 and compatible chipsets using I2C extension
|
||||
// backpacks such as the I2CLCDextraIO with the PCF8574* I2C IO Expander ASIC.
|
||||
//
|
||||
// The functionality provided by this class and its base class is identical
|
||||
// to the original functionality of the Arduino LiquidCrystal library.
|
||||
//
|
||||
//
|
||||
//
|
||||
// @author F. Malpartida - fmalpartida@gmail.com
|
||||
// Adapted to SoftIC2 by Adrian Piccioli - adrianpiccioli@gmail.com
|
||||
// ---------------------------------------------------------------------------
|
||||
#if (ARDUINO < 100)
|
||||
#include <WProgram.h>
|
||||
#else
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
#include <inttypes.h>
|
||||
#include "SI2CIO.h"
|
||||
#include "LiquidCrystal_SI2C.h"
|
||||
|
||||
// CONSTANT definitions
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// flags for backlight control
|
||||
/*!
|
||||
@defined
|
||||
@abstract LCD_NOBACKLIGHT
|
||||
@discussion NO BACKLIGHT MASK
|
||||
*/
|
||||
#define LCD_NOBACKLIGHT 0x00
|
||||
|
||||
/*!
|
||||
@defined
|
||||
@abstract LCD_BACKLIGHT
|
||||
@discussion BACKLIGHT MASK used when backlight is on
|
||||
*/
|
||||
#define LCD_BACKLIGHT 0xFF
|
||||
|
||||
|
||||
// Default library configuration parameters used by class constructor with
|
||||
// only the I2C address field.
|
||||
// ---------------------------------------------------------------------------
|
||||
/*!
|
||||
@defined
|
||||
@abstract Enable bit of the LCD
|
||||
@discussion Defines the IO of the expander connected to the LCD Enable
|
||||
*/
|
||||
#define EN 6 // Enable bit
|
||||
|
||||
/*!
|
||||
@defined
|
||||
@abstract Read/Write bit of the LCD
|
||||
@discussion Defines the IO of the expander connected to the LCD Rw pin
|
||||
*/
|
||||
#define RW 5 // Read/Write bit
|
||||
|
||||
/*!
|
||||
@defined
|
||||
@abstract Register bit of the LCD
|
||||
@discussion Defines the IO of the expander connected to the LCD Register select pin
|
||||
*/
|
||||
#define RS 4 // Register select bit
|
||||
|
||||
/*!
|
||||
@defined
|
||||
@abstract LCD dataline allocation this library only supports 4 bit LCD control
|
||||
mode.
|
||||
@discussion D4, D5, D6, D7 LCD data lines pin mapping of the extender module
|
||||
*/
|
||||
#define D4 0
|
||||
#define D5 1
|
||||
#define D6 2
|
||||
#define D7 3
|
||||
|
||||
|
||||
// CONSTRUCTORS
|
||||
// ---------------------------------------------------------------------------
|
||||
LiquidCrystal_SI2C::LiquidCrystal_SI2C( uint8_t lcd_Addr )
|
||||
{
|
||||
config(lcd_Addr, EN, RW, RS, D4, D5, D6, D7);
|
||||
}
|
||||
|
||||
|
||||
LiquidCrystal_SI2C::LiquidCrystal_SI2C(uint8_t lcd_Addr, uint8_t backlighPin,
|
||||
t_backlighPol pol = POSITIVE)
|
||||
{
|
||||
config(lcd_Addr, EN, RW, RS, D4, D5, D6, D7);
|
||||
setBacklightPin(backlighPin, pol);
|
||||
}
|
||||
|
||||
LiquidCrystal_SI2C::LiquidCrystal_SI2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw,
|
||||
uint8_t Rs)
|
||||
{
|
||||
config(lcd_Addr, En, Rw, Rs, D4, D5, D6, D7);
|
||||
}
|
||||
|
||||
LiquidCrystal_SI2C::LiquidCrystal_SI2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw,
|
||||
uint8_t Rs, uint8_t backlighPin,
|
||||
t_backlighPol pol = POSITIVE)
|
||||
{
|
||||
config(lcd_Addr, En, Rw, Rs, D4, D5, D6, D7);
|
||||
setBacklightPin(backlighPin, pol);
|
||||
}
|
||||
|
||||
LiquidCrystal_SI2C::LiquidCrystal_SI2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw,
|
||||
uint8_t Rs, uint8_t d4, uint8_t d5,
|
||||
uint8_t d6, uint8_t d7 )
|
||||
{
|
||||
config(lcd_Addr, En, Rw, Rs, d4, d5, d6, d7);
|
||||
}
|
||||
|
||||
LiquidCrystal_SI2C::LiquidCrystal_SI2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw,
|
||||
uint8_t Rs, uint8_t d4, uint8_t d5,
|
||||
uint8_t d6, uint8_t d7, uint8_t backlighPin,
|
||||
t_backlighPol pol = POSITIVE )
|
||||
{
|
||||
config(lcd_Addr, En, Rw, Rs, d4, d5, d6, d7);
|
||||
setBacklightPin(backlighPin, pol);
|
||||
}
|
||||
|
||||
// PUBLIC METHODS
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// begin
|
||||
void LiquidCrystal_SI2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize)
|
||||
{
|
||||
|
||||
init(); // Initialise the I2C expander interface
|
||||
LCD::begin ( cols, lines, dotsize );
|
||||
}
|
||||
|
||||
|
||||
// User commands - users can expand this section
|
||||
//----------------------------------------------------------------------------
|
||||
// Turn the (optional) backlight off/on
|
||||
|
||||
//
|
||||
// setBacklightPin
|
||||
void LiquidCrystal_SI2C::setBacklightPin ( uint8_t value, t_backlighPol pol = POSITIVE )
|
||||
{
|
||||
_backlightPinMask = ( 1 << value );
|
||||
_polarity = pol;
|
||||
setBacklight(BACKLIGHT_OFF);
|
||||
}
|
||||
|
||||
//
|
||||
// setBacklight
|
||||
void LiquidCrystal_SI2C::setBacklight( uint8_t value )
|
||||
{
|
||||
// Check if backlight is available
|
||||
// ----------------------------------------------------
|
||||
if ( _backlightPinMask != 0x0 )
|
||||
{
|
||||
// Check for polarity to configure mask accordingly
|
||||
// ----------------------------------------------------------
|
||||
if (((_polarity == POSITIVE) && (value > 0)) ||
|
||||
((_polarity == NEGATIVE ) && ( value == 0 )))
|
||||
{
|
||||
_backlightStsMask = _backlightPinMask & LCD_BACKLIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
_backlightStsMask = _backlightPinMask & LCD_NOBACKLIGHT;
|
||||
}
|
||||
_i2cio.write( _backlightStsMask );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// PRIVATE METHODS
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// init
|
||||
int LiquidCrystal_SI2C::init()
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
// initialize the backpack IO expander
|
||||
// and display functions.
|
||||
// ------------------------------------------------------------------------
|
||||
if ( _i2cio.begin ( _Addr ) == 1 )
|
||||
{
|
||||
_i2cio.portMode ( OUTPUT ); // Set the entire IO extender to OUTPUT
|
||||
_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
|
||||
status = 1;
|
||||
_i2cio.write(0); // Set the entire port to LOW
|
||||
}
|
||||
return ( status );
|
||||
}
|
||||
|
||||
//
|
||||
// config
|
||||
void LiquidCrystal_SI2C::config (uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
|
||||
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7 )
|
||||
{
|
||||
_Addr = lcd_Addr;
|
||||
|
||||
_backlightPinMask = 0;
|
||||
_backlightStsMask = LCD_NOBACKLIGHT;
|
||||
_polarity = POSITIVE;
|
||||
|
||||
_En = ( 1 << En );
|
||||
_Rw = ( 1 << Rw );
|
||||
_Rs = ( 1 << Rs );
|
||||
|
||||
// Initialise pin mapping
|
||||
_data_pins[0] = ( 1 << d4 );
|
||||
_data_pins[1] = ( 1 << d5 );
|
||||
_data_pins[2] = ( 1 << d6 );
|
||||
_data_pins[3] = ( 1 << d7 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// low level data pushing commands
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// send - write either command or data
|
||||
void LiquidCrystal_SI2C::send(uint8_t value, uint8_t mode)
|
||||
{
|
||||
// No need to use the delay routines since the time taken to write takes
|
||||
// longer that what is needed both for toggling and enable pin an to execute
|
||||
// the command.
|
||||
|
||||
if ( mode == FOUR_BITS )
|
||||
{
|
||||
write4bits( (value & 0x0F), COMMAND );
|
||||
}
|
||||
else
|
||||
{
|
||||
write4bits( (value >> 4), mode );
|
||||
write4bits( (value & 0x0F), mode);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// write4bits
|
||||
void LiquidCrystal_SI2C::write4bits ( uint8_t value, uint8_t mode )
|
||||
{
|
||||
uint8_t pinMapValue = 0;
|
||||
|
||||
// Map the value to LCD pin mapping
|
||||
// --------------------------------
|
||||
for ( uint8_t i = 0; i < 4; i++ )
|
||||
{
|
||||
if ( ( value & 0x1 ) == 1 )
|
||||
{
|
||||
pinMapValue |= _data_pins[i];
|
||||
}
|
||||
value = ( value >> 1 );
|
||||
}
|
||||
|
||||
// Is it a command or data
|
||||
// -----------------------
|
||||
if ( mode == DATA )
|
||||
{
|
||||
mode = _Rs;
|
||||
}
|
||||
|
||||
pinMapValue |= mode | _backlightStsMask;
|
||||
pulseEnable ( pinMapValue );
|
||||
}
|
||||
|
||||
//
|
||||
// pulseEnable
|
||||
void LiquidCrystal_SI2C::pulseEnable (uint8_t data)
|
||||
{
|
||||
_i2cio.write (data | _En); // En HIGH
|
||||
_i2cio.write (data & ~_En); // En LOW
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Created by Francisco Malpartida on 20/08/11.
|
||||
// Copyright 2011 - Under creative commons license 3.0:
|
||||
// Attribution-ShareAlike CC BY-SA
|
||||
//
|
||||
// This software is furnished "as is", without technical support, and with no
|
||||
// warranty, express or implied, as to its usefulness for any purpose.
|
||||
//
|
||||
// Thread Safe: No
|
||||
// Extendable: Yes
|
||||
//
|
||||
// @file LiquidCrystal_I2C.h
|
||||
// This file implements a basic liquid crystal library that comes as standard
|
||||
// in the Arduino SDK but using an I2C IO extension board and software I2C.
|
||||
// It will use digital pins 6 and 7 for SCL and SDA, but it can be changed
|
||||
// in SI2CIO.cpp to use other pins if needed.
|
||||
|
||||
// @brief
|
||||
// This is a basic implementation of the LiquidCrystal library of the
|
||||
// Arduino SDK. The original library has been reworked in such a way that
|
||||
// this class implements the all methods to command an LCD based
|
||||
// on the Hitachi HD44780 and compatible chipsets using I2C extension
|
||||
// backpacks such as the I2CLCDextraIO with the PCF8574* I2C IO Expander ASIC.
|
||||
//
|
||||
// The functionality provided by this class and its base class is identical
|
||||
// to the original functionality of the Arduino LiquidCrystal library.
|
||||
//
|
||||
//
|
||||
// @author F. Malpartida - fmalpartida@gmail.com
|
||||
// Adapted to SoftIC2 by Adrian Piccioli - adrianpiccioli@gmail.com
|
||||
// ---------------------------------------------------------------------------
|
||||
#ifndef LiquidCrystal_SI2C_h
|
||||
#define LiquidCrystal_SI2C_h
|
||||
#include <inttypes.h>
|
||||
#include <Print.h>
|
||||
|
||||
#include "SI2CIO.h"
|
||||
#include "LCD.h"
|
||||
|
||||
|
||||
class LiquidCrystal_SI2C : public LCD
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
@method
|
||||
@abstract Class constructor.
|
||||
@discussion Initializes class variables and defines the I2C address of the
|
||||
LCD. The constructor does not initialize the LCD.
|
||||
|
||||
@param lcd_Addr[in] I2C address of the IO expansion module. For I2CLCDextraIO,
|
||||
the address can be configured using the on board jumpers.
|
||||
*/
|
||||
LiquidCrystal_SI2C (uint8_t lcd_Addr);
|
||||
// Constructor with backlight control
|
||||
LiquidCrystal_SI2C (uint8_t lcd_Addr, uint8_t backlighPin, t_backlighPol pol);
|
||||
|
||||
/*!
|
||||
@method
|
||||
@abstract Class constructor.
|
||||
@discussion Initializes class variables and defines the I2C address of the
|
||||
LCD. The constructor does not initialize the LCD.
|
||||
|
||||
@param lcd_Addr[in] I2C address of the IO expansion module. For I2CLCDextraIO,
|
||||
the address can be configured using the on board jumpers.
|
||||
@param En[in] LCD En (Enable) pin connected to the IO extender module
|
||||
@param Rw[in] LCD Rw (Read/write) pin connected to the IO extender module
|
||||
@param Rs[in] LCD Rs (Reset) pin connected to the IO extender module
|
||||
*/
|
||||
LiquidCrystal_SI2C( uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs);
|
||||
// Constructor with backlight control
|
||||
LiquidCrystal_SI2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
|
||||
uint8_t backlighPin, t_backlighPol pol);
|
||||
|
||||
/*!
|
||||
@method
|
||||
@abstract Class constructor.
|
||||
@discussion Initializes class variables and defines the I2C address of the
|
||||
LCD. The constructor does not initialize the LCD.
|
||||
|
||||
@param lcd_Addr[in] I2C address of the IO expansion module. For I2CLCDextraIO,
|
||||
the address can be configured using the on board jumpers.
|
||||
@param En[in] LCD En (Enable) pin connected to the IO extender module
|
||||
@param Rw[in] LCD Rw (Read/write) pin connected to the IO extender module
|
||||
@param Rs[in] LCD Rs (Reset) pin connected to the IO extender module
|
||||
@param d4[in] LCD data 0 pin map on IO extender module
|
||||
@param d5[in] LCD data 1 pin map on IO extender module
|
||||
@param d6[in] LCD data 2 pin map on IO extender module
|
||||
@param d7[in] LCD data 3 pin map on IO extender module
|
||||
*/
|
||||
LiquidCrystal_SI2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
|
||||
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7 );
|
||||
// Constructor with backlight control
|
||||
LiquidCrystal_SI2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
|
||||
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
|
||||
uint8_t backlighPin, t_backlighPol pol);
|
||||
/*!
|
||||
@function
|
||||
@abstract LCD initialization and associated HW.
|
||||
@discussion Initializes the LCD to a given size (col, row). This methods
|
||||
initializes the LCD, therefore, it MUST be called prior to using any other
|
||||
method from this class or parent class.
|
||||
|
||||
The begin method can be overloaded if necessary to initialize any HW that
|
||||
is implemented by a library and can't be done during construction, here
|
||||
we use the Wire class.
|
||||
|
||||
@param cols[in] the number of columns that the display has
|
||||
@param rows[in] the number of rows that the display has
|
||||
@param charsize[in] size of the characters of the LCD: LCD_5x8DOTS or
|
||||
LCD_5x10DOTS.
|
||||
*/
|
||||
virtual void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Send a particular value to the LCD.
|
||||
@discussion Sends a particular value to the LCD for writing to the LCD or
|
||||
as an LCD command.
|
||||
|
||||
Users should never call this method.
|
||||
|
||||
@param value[in] Value to send to the LCD.
|
||||
@param mode[in] DATA - write to the LCD CGRAM, COMMAND - write a
|
||||
command to the LCD.
|
||||
*/
|
||||
virtual void send(uint8_t value, uint8_t mode);
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Sets the pin to control the backlight.
|
||||
@discussion Sets the pin in the device to control the backlight. This device
|
||||
doesn't support dimming backlight capability.
|
||||
|
||||
@param 0: backlight off, 1..255: backlight on.
|
||||
*/
|
||||
void setBacklightPin ( uint8_t value, t_backlighPol pol );
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Switch-on/off the LCD backlight.
|
||||
@discussion Switch-on/off the LCD backlight.
|
||||
The setBacklightPin has to be called before setting the backlight for
|
||||
this method to work. @see setBacklightPin.
|
||||
|
||||
@param value: backlight mode (HIGH|LOW)
|
||||
*/
|
||||
void setBacklight ( uint8_t value );
|
||||
|
||||
private:
|
||||
|
||||
/*!
|
||||
@method
|
||||
@abstract Initializes the LCD class
|
||||
@discussion Initializes the LCD class and IO expansion module.
|
||||
*/
|
||||
int init();
|
||||
|
||||
/*!
|
||||
@function
|
||||
@abstract Initialises class private variables
|
||||
@discussion This is the class single point for initialising private variables.
|
||||
|
||||
@param lcd_Addr[in] I2C address of the IO expansion module. For I2CLCDextraIO,
|
||||
the address can be configured using the on board jumpers.
|
||||
@param En[in] LCD En (Enable) pin connected to the IO extender module
|
||||
@param Rw[in] LCD Rw (Read/write) pin connected to the IO extender module
|
||||
@param Rs[in] LCD Rs (Reset) pin connected to the IO extender module
|
||||
@param d4[in] LCD data 0 pin map on IO extender module
|
||||
@param d5[in] LCD data 1 pin map on IO extender module
|
||||
@param d6[in] LCD data 2 pin map on IO extender module
|
||||
@param d7[in] LCD data 3 pin map on IO extender module
|
||||
*/
|
||||
void config (uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
|
||||
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7 );
|
||||
|
||||
/*!
|
||||
@method
|
||||
@abstract Writes an 4 bit value to the LCD.
|
||||
@discussion Writes 4 bits (the least significant) to the LCD control data lines.
|
||||
@param value[in] Value to write to the LCD
|
||||
@param more[in] Value to distinguish between command and data.
|
||||
COMMAND == command, DATA == data.
|
||||
*/
|
||||
void write4bits(uint8_t value, uint8_t mode);
|
||||
|
||||
/*!
|
||||
@method
|
||||
@abstract Pulse the LCD enable line (En).
|
||||
@discussion Sends a pulse of 1 uS to the Enable pin to execute an command
|
||||
or write operation.
|
||||
*/
|
||||
void pulseEnable(uint8_t);
|
||||
|
||||
|
||||
uint8_t _Addr; // I2C Address of the IO expander
|
||||
uint8_t _backlightPinMask; // Backlight IO pin mask
|
||||
uint8_t _backlightStsMask; // Backlight status mask
|
||||
SI2CIO _i2cio; // I2CIO PCF8574* expansion module driver I2CLCDextraIO
|
||||
uint8_t _En; // LCD expander word for enable pin
|
||||
uint8_t _Rw; // LCD expander word for R/W pin
|
||||
uint8_t _Rs; // LCD expander word for Register Select pin
|
||||
uint8_t _data_pins[4]; // LCD data lines
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Created by Francisco Malpartida on 20/08/11.
|
||||
// Copyright 2011 - Under creative commons license 3.0:
|
||||
// Attribution-ShareAlike CC BY-SA
|
||||
//
|
||||
// This software is furnished "as is", without technical support, and with no
|
||||
// warranty, express or implied, as to its usefulness for any purpose.
|
||||
//
|
||||
// Thread Safe: No
|
||||
// Extendable: Yes
|
||||
//
|
||||
// @file SI2CIO.h
|
||||
// This file implements a basic IO library using the PCF8574 I2C IO Expander
|
||||
// chip, but using software I2C.
|
||||
//
|
||||
// @brief
|
||||
// Implement a basic IO library to drive the PCF8574* I2C IO Expander ASIC.
|
||||
// The library implements basic IO general methods to configure IO pin direction
|
||||
// read and write uint8_t operations and basic pin level routines to set or read
|
||||
// a particular IO port.
|
||||
//
|
||||
//
|
||||
// @version API 1.0.0
|
||||
//
|
||||
// @author F. Malpartida - fmalpartida@gmail.com
|
||||
// Adapted to SoftIC2 by Adrian Piccioli - adrianpiccioli@gmail.com
|
||||
// ---------------------------------------------------------------------------
|
||||
#if (ARDUINO < 100)
|
||||
#include <WProgram.h>
|
||||
#else
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
/*#define SCL_PIN 6
|
||||
#define SCL_PORT PORTD
|
||||
#define SDA_PIN 7
|
||||
#define SDA_PORT PORTD*/
|
||||
|
||||
//#define I2C_FASTMODE 1
|
||||
//#define I2C_SLOWMODE 1
|
||||
|
||||
#define SCL_PIN 0
|
||||
#define SCL_PORT PORTB
|
||||
#define SDA_PIN 1
|
||||
#define SDA_PORT PORTB
|
||||
|
||||
#include <../SoftI2CMaster/SoftI2CMaster.h>
|
||||
#include "SI2CIO.h"
|
||||
|
||||
// CLASS VARIABLES
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
// CONSTRUCTOR
|
||||
// ---------------------------------------------------------------------------
|
||||
SI2CIO::SI2CIO ( )
|
||||
{
|
||||
_i2cAddr = 0x0;
|
||||
_dirMask = 0xFF; // mark all as INPUTs
|
||||
_shadow = 0x0; // no values set
|
||||
_initialised = false;
|
||||
}
|
||||
|
||||
// PUBLIC METHODS
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// begin
|
||||
int SI2CIO::begin ( uint8_t i2cAddr )
|
||||
{
|
||||
_i2cAddr = i2cAddr;
|
||||
|
||||
i2c_init();
|
||||
|
||||
_initialised = i2c_start(_i2cAddr | I2C_READ);
|
||||
|
||||
_shadow = i2c_read(true);
|
||||
|
||||
i2c_stop();
|
||||
|
||||
return ( _initialised );
|
||||
}
|
||||
|
||||
//
|
||||
// pinMode
|
||||
void SI2CIO::pinMode ( uint8_t pin, uint8_t dir )
|
||||
{
|
||||
if ( _initialised )
|
||||
{
|
||||
if ( OUTPUT == dir )
|
||||
{
|
||||
_dirMask &= ~( 1 << pin );
|
||||
}
|
||||
else
|
||||
{
|
||||
_dirMask |= ( 1 << pin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// portMode
|
||||
void SI2CIO::portMode ( uint8_t dir )
|
||||
{
|
||||
|
||||
if ( _initialised )
|
||||
{
|
||||
if ( dir == INPUT )
|
||||
{
|
||||
_dirMask = 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
_dirMask = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// read
|
||||
uint8_t SI2CIO::read ( void )
|
||||
{
|
||||
uint8_t retVal = 0;
|
||||
|
||||
if ( _initialised )
|
||||
{
|
||||
i2c_start(_i2cAddr | I2C_READ);
|
||||
|
||||
retVal = (_dirMask & i2c_read(true));
|
||||
|
||||
i2c_stop();
|
||||
}
|
||||
return ( retVal );
|
||||
}
|
||||
|
||||
//
|
||||
// write
|
||||
int SI2CIO::write ( uint8_t value )
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
if ( _initialised )
|
||||
{
|
||||
// Only write HIGH the values of the ports that have been initialised as
|
||||
// outputs updating the output shadow of the device
|
||||
_shadow = ( value & ~(_dirMask) );
|
||||
|
||||
status = i2c_start(_i2cAddr | I2C_WRITE);
|
||||
|
||||
status &= i2c_write(_shadow);
|
||||
|
||||
i2c_stop();
|
||||
}
|
||||
return ( (status == 0) );
|
||||
}
|
||||
|
||||
//
|
||||
// digitalRead
|
||||
uint8_t SI2CIO::digitalRead ( uint8_t pin )
|
||||
{
|
||||
uint8_t pinVal = 0;
|
||||
|
||||
// Check if initialised and that the pin is within range of the device
|
||||
// -------------------------------------------------------------------
|
||||
if ( ( _initialised ) && ( pin <= 7 ) )
|
||||
{
|
||||
// Remove the values which are not inputs and get the value of the pin
|
||||
pinVal = this->read() & _dirMask;
|
||||
pinVal = ( pinVal >> pin ) & 0x01; // Get the pin value
|
||||
}
|
||||
return (pinVal);
|
||||
}
|
||||
|
||||
//
|
||||
// digitalWrite
|
||||
int SI2CIO::digitalWrite ( uint8_t pin, uint8_t level )
|
||||
{
|
||||
uint8_t writeVal;
|
||||
int status = 0;
|
||||
|
||||
// Check if initialised and that the pin is within range of the device
|
||||
// -------------------------------------------------------------------
|
||||
if ( ( _initialised ) && ( pin <= 7 ) )
|
||||
{
|
||||
// Only write to HIGH the port if the port has been configured as
|
||||
// an OUTPUT pin. Add the new state of the pin to the shadow
|
||||
writeVal = ( 1 << pin ) & ~_dirMask;
|
||||
if ( level == HIGH )
|
||||
{
|
||||
_shadow |= writeVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
_shadow &= ~writeVal;
|
||||
}
|
||||
status = this->write ( _shadow );
|
||||
}
|
||||
return ( status );
|
||||
}
|
||||
|
||||
//
|
||||
// PRIVATE METHODS
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -0,0 +1,149 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Created by Francisco Malpartida on 20/08/11.
|
||||
// Copyright 2011 - Under creative commons license 3.0:
|
||||
// Attribution-ShareAlike CC BY-SA
|
||||
//
|
||||
// This software is furnished "as is", without technical support, and with no
|
||||
// warranty, express or implied, as to its usefulness for any purpose.
|
||||
//
|
||||
// Thread Safe: No
|
||||
// Extendable: Yes
|
||||
//
|
||||
// @file SI2CIO.h
|
||||
// This file implements a basic IO library using the PCF8574 I2C IO Expander
|
||||
// chip, but using software I2C.
|
||||
//
|
||||
// @brief
|
||||
// Implement a basic IO library to drive the PCF8574* I2C IO Expander ASIC.
|
||||
// The library implements basic IO general methods to configure IO pin direction
|
||||
// read and write uint8_t operations and basic pin level routines to set or read
|
||||
// a particular IO port.
|
||||
//
|
||||
// @version API 1.0.0
|
||||
//
|
||||
// @author F. Malpartida - fmalpartida@gmail.com
|
||||
// Adapted to SoftIC2 by Adrian Piccioli - adrianpiccioli@gmail.com
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#ifndef _SI2CIO_H_
|
||||
#define _SI2CIO_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#define _SI2CIO_VERSION "1.0.0"
|
||||
|
||||
/*!
|
||||
@class
|
||||
@abstract SI2CIO
|
||||
@discussion Library driver to control PCF8574 based ASICs. Implementing
|
||||
library calls to set/get port through I2C bus.
|
||||
*/
|
||||
|
||||
class SI2CIO
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
@method
|
||||
@abstract Constructor method
|
||||
@discussion Class constructor constructor.
|
||||
*/
|
||||
SI2CIO ( );
|
||||
|
||||
/*!
|
||||
@method
|
||||
@abstract Initializes the device.
|
||||
@discussion This method initializes the device allocating an I2C address.
|
||||
This method is the first method that should be call prior to calling any
|
||||
other method form this class. On initialization all pins are configured
|
||||
as INPUT on the device.
|
||||
|
||||
@param i2cAddr: I2C Address where the device is located.
|
||||
@result 1 if the device was initialized correctly, 0 otherwise
|
||||
*/
|
||||
int begin ( uint8_t i2cAddr );
|
||||
|
||||
/*!
|
||||
@method
|
||||
@abstract Sets the mode of a particular pin.
|
||||
@discussion Sets the mode of a particular pin to INPUT, OUTPUT. digitalWrite
|
||||
has no effect on pins which are not declared as output.
|
||||
|
||||
@param pin[in] Pin from the I2C IO expander to be configured. Range 0..7
|
||||
@param dir[in] Pin direction (INPUT, OUTPUT).
|
||||
*/
|
||||
void pinMode ( uint8_t pin, uint8_t dir );
|
||||
|
||||
/*!
|
||||
@method
|
||||
@abstract Sets all the pins of the device in a particular direction.
|
||||
@discussion This method sets all the pins of the device in a particular
|
||||
direction. This method is useful to set all the pins of the device to be
|
||||
either inputs or outputs.
|
||||
@param dir[in] Direction of all the pins of the device (INPUT, OUTPUT).
|
||||
*/
|
||||
void portMode ( uint8_t dir );
|
||||
|
||||
/*!
|
||||
@method
|
||||
@abstract Reads all the pins of the device that are configured as INPUT.
|
||||
@discussion Reads from the device the status of the pins that are configured
|
||||
as INPUT. During initialization all pins are configured as INPUTs by default.
|
||||
Please refer to pinMode or portMode.
|
||||
|
||||
@param none
|
||||
*/
|
||||
uint8_t read ( void );
|
||||
|
||||
/*!
|
||||
@method
|
||||
@abstract Read a pin from the device.
|
||||
@discussion Reads a particular pin from the device. To read a particular
|
||||
pin it has to be configured as INPUT. During initialization all pins are
|
||||
configured as INPUTs by default. Please refer to pinMode or portMode.
|
||||
|
||||
@param pin[in] Pin from the port to read its status. Range (0..7)
|
||||
@result Returns the pin status (HIGH, LOW) if the pin is configured
|
||||
as an output, reading its value will always return LOW regardless of its
|
||||
real state.
|
||||
*/
|
||||
uint8_t digitalRead ( uint8_t pin );
|
||||
|
||||
/*!
|
||||
@method
|
||||
@abstract Write a value to the device.
|
||||
@discussion Writes to a set of pins in the device. The value is the binary
|
||||
representation of all the pins in device. The value written is masked with
|
||||
the configuration of the direction of the pins; to change the state of
|
||||
a particular pin with this method, such pin has to be configured as OUTPUT
|
||||
using the portMode or pinMode methods. If no pins have been configured as
|
||||
OUTPUTs this method will have no effect.
|
||||
|
||||
@param value[in] value to be written to the device.
|
||||
@result 1 on success, 0 otherwise
|
||||
*/
|
||||
int write ( uint8_t value );
|
||||
|
||||
/*!
|
||||
@method
|
||||
@abstract Writes a digital level to a particular pin.
|
||||
@discussion Write a level to the indicated pin of the device. For this
|
||||
method to have effect, the pin has to be configured as OUTPUT using the
|
||||
pinMode or portMode methods.
|
||||
|
||||
@param pin[in] device pin to change level. Range (0..7).
|
||||
@para level[in] logic level to set the pin at (HIGH, LOW).
|
||||
@result 1 on success, 0 otherwise.
|
||||
*/
|
||||
int digitalWrite ( uint8_t pin, uint8_t level );
|
||||
|
||||
|
||||
|
||||
private:
|
||||
uint8_t _shadow; // Shadow output
|
||||
uint8_t _dirMask; // Direction mask
|
||||
uint8_t _i2cAddr; // I2C address
|
||||
bool _initialised; // Initialised object
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -71,9 +71,9 @@ static char dummyvar; // dummy declaration for STUPID IDE!!!!
|
||||
//#define LCDIF_SR2W
|
||||
//#define LCDIF_SR_2W // SR in 2 wire mode
|
||||
//#define LCDIF_SR_3W // SR in 3 wire mode
|
||||
#define LCDIF_SR3W
|
||||
//#define LCDIF_SR3W
|
||||
//#define LCDIF_SR1W
|
||||
|
||||
#define LCDIF_SI2C
|
||||
|
||||
/*
|
||||
* Options
|
||||
@@ -143,13 +143,20 @@ LiquidCrystal_SR lcd (2, 3);
|
||||
// d,clk,strb
|
||||
LiquidCrystal_SR lcd (2, 3, 4);
|
||||
|
||||
#elif defined(LCDIF_SI2C)
|
||||
|
||||
#include <LiquidCrystal_SI2C.h>
|
||||
|
||||
LiquidCrystal_SI2C lcd(0x4e,2,1,0,4,5,6,7);
|
||||
|
||||
#endif
|
||||
|
||||
void setup()
|
||||
{
|
||||
// set up the LCD's number of columns and rows:
|
||||
lcd.begin(LCD_COLS, LCD_ROWS);
|
||||
|
||||
lcd.setBacklightPin(3, POSITIVE);
|
||||
lcd.setBacklight(HIGH);
|
||||
#ifdef BACKLIGHT_ON
|
||||
lcd.backlight(); // make sure backlight is on with new library
|
||||
#endif
|
||||
|
||||
@@ -25,12 +25,17 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
#include <Wire.h>
|
||||
|
||||
#define _LCD_I2C_
|
||||
//#define _LCD_I2C_
|
||||
#define _LCD_SI2C_
|
||||
|
||||
#ifdef _LCD_I2C_
|
||||
#include <LiquidCrystal_I2C.h>
|
||||
#endif
|
||||
|
||||
#ifdef _LCD_SI2C_
|
||||
#include <LiquidCrystal_SI2C.h>
|
||||
#endif
|
||||
|
||||
#ifdef _LCD_4BIT_
|
||||
#include <LiquidCrystal.h>
|
||||
#endif
|
||||
@@ -98,6 +103,12 @@ const int CONTRAST_PIN = 0; // none
|
||||
const int CONTRAST = 0; // none
|
||||
#endif
|
||||
|
||||
#ifdef _LCD_SI2C_
|
||||
const int BACKLIGHT_PIN = 3;
|
||||
const int CONTRAST_PIN = 0; // none
|
||||
const int CONTRAST = 0; // none
|
||||
#endif
|
||||
|
||||
#ifdef _LCD_4BIT_
|
||||
const int CONTRAST_PIN = 9;
|
||||
const int BACKLIGHT_PIN = 7;
|
||||
@@ -162,6 +173,10 @@ typedef struct
|
||||
LiquidCrystal_I2C lcd(0x38); // set the LCD address to 0x20 for a 16 chars and 2 line display
|
||||
#endif
|
||||
|
||||
#ifdef _LCD_SI2C_
|
||||
LiquidCrystal_SI2C lcd(0x4e,2,1,0,4,5,6,7);
|
||||
#endif
|
||||
|
||||
#ifdef _LCD_4BIT_
|
||||
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
|
||||
#endif
|
||||
@@ -246,12 +261,14 @@ static void LCDSetup ( uint8_t contrasPin, uint8_t backlight, uint8_t cols, uint
|
||||
analogWrite ( contrasPin, CONTRAST );
|
||||
}
|
||||
// Setup backlight pin
|
||||
if ( backlight != 0 ){
|
||||
/*if ( backlight != 0 ){
|
||||
pinMode(backlight, OUTPUT);
|
||||
digitalWrite(backlight, HIGH);
|
||||
}
|
||||
}*/
|
||||
|
||||
lcd.begin ( cols, rows );
|
||||
lcd.setBacklightPin(3, POSITIVE);
|
||||
lcd.setBacklight(HIGH);
|
||||
lcd.clear ( );
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user