Skip to content

Commit

Permalink
0.1.0 I2C_LCD
Browse files Browse the repository at this point in the history
  • Loading branch information
RobTillaart committed Dec 17, 2023
1 parent 380fb0b commit eb376d2
Show file tree
Hide file tree
Showing 17 changed files with 917 additions and 0 deletions.
28 changes: 28 additions & 0 deletions libraries/I2C_LCD/.arduino-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
platforms:
rpipico:
board: rp2040:rp2040:rpipico
package: rp2040:rp2040
gcc:
features:
defines:
- ARDUINO_ARCH_RP2040
warnings:
flags:

packages:
rp2040:rp2040:
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json

compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
- uno
# - due
# - zero
# - leonardo
- m4
- esp32
- esp8266
# - mega2560
- rpipico

4 changes: 4 additions & 0 deletions libraries/I2C_LCD/.github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# These are supported funding model platforms

github: RobTillaart

13 changes: 13 additions & 0 deletions libraries/I2C_LCD/.github/workflows/arduino-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

name: Arduino-lint

on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: arduino/arduino-lint-action@v1
with:
library-manager: update
compliance: strict
17 changes: 17 additions & 0 deletions libraries/I2C_LCD/.github/workflows/arduino_test_runner.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: Arduino CI

on: [push, pull_request]

jobs:
runTest:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
- run: |
gem install arduino_ci
arduino_ci.rb
18 changes: 18 additions & 0 deletions libraries/I2C_LCD/.github/workflows/jsoncheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: JSON check

on:
push:
paths:
- '**.json'
pull_request:

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: json-syntax-check
uses: limitusus/json-syntax-check@v1
with:
pattern: "\\.json$"

12 changes: 12 additions & 0 deletions libraries/I2C_LCD/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Change Log I2C_LCD

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.1.0] - 2023-12-16
- initial version
- goal is to optimize footprint & performance

251 changes: 251 additions & 0 deletions libraries/I2C_LCD/I2C_LCD.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
//
// FILE: I2C_LCD.cpp
// AUTHOR: Rob.Tillaart@gmail.com
// VERSION: 0.1.0
// DATE: 2023-12-16
// PUPROSE: Arduino library for I2C_LCD
// URL: https://github.com/RobTillaart/I2C_LCD


#include "I2C_LCD.h"


// TODO redo simplify names shorter
// or keep them compatible?
#define I2C_LCD_CLEARDISPLAY 0x01
#define I2C_LCD_RETURNHOME 0x02
#define I2C_LCD_ENTRYMODESET 0x04
#define I2C_LCD_DISPLAYCONTROL 0x08
#define I2C_LCD_CURSORSHIFT 0x10
#define I2C_LCD_FUNCTIONSET 0x20
#define I2C_LCD_SETCGRAMADDR 0x40
#define I2C_LCD_SETDDRAMADDR 0x80

#define I2C_LCD_ENTRYRIGHT 0x00
#define I2C_LCD_ENTRYLEFT 0x02
#define I2C_LCD_ENTRYSHIFTINCREMENT 0x01
#define I2C_LCD_ENTRYSHIFTDECREMENT 0x00

#define I2C_LCD_DISPLAYON 0x04
#define I2C_LCD_DISPLAYOFF 0x00
#define I2C_LCD_CURSORON 0x02
#define I2C_LCD_CURSOROFF 0x00
#define I2C_LCD_BLINKON 0x01
#define I2C_LCD_BLINKOFF 0x00

#define I2C_LCD_DISPLAYMOVE 0x08
#define I2C_LCD_CURSORMOVE 0x00
#define I2C_LCD_MOVERIGHT 0x04
#define I2C_LCD_MOVELEFT 0x00

#define I2C_LCD_8BITMODE 0x10
#define I2C_LCD_4BITMODE 0x00
#define I2C_LCD_2LINE 0x08
#define I2C_LCD_1LINE 0x00
#define I2C_LCD_5x10DOTS 0x04
#define I2C_LCD_5x8DOTS 0x00


I2C_LCD::I2C_LCD(uint8_t address, TwoWire * wire)
{
_address = address;
_wire = wire;
}


void I2C_LCD::config (uint8_t address, uint8_t enable, uint8_t readwrite, uint8_t registerselect,
uint8_t data4, uint8_t data5, uint8_t data6, uint8_t data7,
uint8_t backlight)
{
if (_address != address) return; // compatible
_enable = ( 1 << enable);
_readWrite = ( 1 << readwrite);
_registerSelect = ( 1 << registerselect);
_dataPin[0] = ( 1 << data4);
_dataPin[1] = ( 1 << data5);
_dataPin[2] = ( 1 << data6);
_dataPin[3] = ( 1 << data7);
_backLight = ( 1 << backlight);

_pinsInOrder = ((data4 < data5) && (data5 < data6) && (data6 < data7));
}


void I2C_LCD::begin(uint8_t cols, uint8_t rows)
{
_cols = cols;
_rows = rows;

// ALL LOW.
_wire->beginTransmission(_address);
_wire->write(0x00);
_wire->endTransmission();

// wait for 50 ms
delay(50);

// Force 4 bit mode // todo timing...
write4bits(0x03);
delay(5);
write4bits(0x03);
delay(1);
write4bits(0x03);
delay(1);
write4bits(0x02);
delay(1);

// set "two" lines LCD - always a 20 x 4 for now.
sendCommand(I2C_LCD_FUNCTIONSET | I2C_LCD_2LINE);
}


void I2C_LCD::setBacklight(bool on)
{
if (on) display(); // todo fix for real.
else noDisplay();
}


void I2C_LCD::display()
{
sendCommand(I2C_LCD_DISPLAYCONTROL | I2C_LCD_DISPLAYON );
}


void I2C_LCD::noDisplay()
{
sendCommand(I2C_LCD_DISPLAYCONTROL | I2C_LCD_DISPLAYOFF);
}


void I2C_LCD::clear()
{
sendCommand(I2C_LCD_CLEARDISPLAY);
delay(2);
}


void I2C_LCD::home()
{
sendCommand(I2C_LCD_RETURNHOME);
delay(2);
}


void I2C_LCD::setCursor(uint8_t col, uint8_t row)
{
uint8_t startpos[4] = { 0x00, 0x40, 0x14, 0x54 };
sendCommand(I2C_LCD_SETDDRAMADDR | (startpos[row] + col) );
}


size_t I2C_LCD::write(uint8_t c)
{
sendData(c); // add timestamp..
return 1;
};


//////////////////////////////////////////////////////////
//
// PRIVATE
//

// TODO merge these two
// optimize 95% identical.
void I2C_LCD::sendCommand(uint8_t value)
{
uint8_t MSN = _backLight;
uint8_t LSN = MSN;

// pins are in the right order.
// TODO determine a flag and
if (_pinsInOrder)
{
MSN |= value & 0xF0;
LSN |= value << 4;
}
else
{
uint8_t tmp = value >> 4;
for ( uint8_t i = 0; i < 4; i++ )
{
if ( tmp & 0x01 ) MSN |= _dataPin[i];
tmp >>= 1;
}
tmp = value & 0x0F;
for ( uint8_t i = 0; i < 4; i++ )
{
if ( tmp & 0x01 ) LSN |= _dataPin[i];
tmp >>= 1;
}
}

_wire->beginTransmission(_address);
_wire->write(MSN | _enable);
_wire->write(MSN);
_wire->write(LSN | _enable);
_wire->write(LSN);
_wire->endTransmission();
}


void I2C_LCD::sendData(uint8_t value)
{
uint8_t MSN = _registerSelect | _backLight;
uint8_t LSN = MSN;

// if pins are in the right order speed up.
// todo determine a flag in config.
if (_pinsInOrder)
{
MSN |= value & 0xF0;
LSN |= value << 4;
}
else
{
uint8_t tmp = value >> 4;
for ( uint8_t i = 0; i < 4; i++ )
{
if ( tmp & 0x01 ) MSN |= _dataPin[i];
tmp >>= 1;
}
tmp = value & 0x0F;
for ( uint8_t i = 0; i < 4; i++ )
{
if ( tmp & 0x01 ) LSN |= _dataPin[i];
tmp >>= 1;
}
}

_wire->beginTransmission(_address);
_wire->write(MSN | _enable);
_wire->write(MSN);
_wire->write(LSN | _enable);
_wire->write(LSN);
_wire->endTransmission();
}


// really needed for setup
void I2C_LCD::write4bits(uint8_t value)
{
uint8_t cmd = _backLight;

for ( uint8_t i = 0; i < 4; i++ )
{
if ( value & 0x01 ) cmd |= _dataPin[i];
value >>= 1;
}

_wire->beginTransmission(_address);
_wire->write(cmd | _enable);
// _wire->endTransmission();
// _wire->beginTransmission(_address);
_wire->write(cmd);
_wire->endTransmission();
}


// -- END OF FILE --

0 comments on commit eb376d2

Please sign in to comment.