Skip to content

Instantly share code, notes, and snippets.

@rafacouto
Created April 8, 2020 00:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rafacouto/015a5033c1ed6cc39b0820f679f0e132 to your computer and use it in GitHub Desktop.
Save rafacouto/015a5033c1ed6cc39b0820f679f0e132 to your computer and use it in GitHub Desktop.
#include <Arduino.h>
#include "LCDHAL.h"
#include "PINOUT.h"
LCDHAL* LCDHAL::_lcdInstance = NULL;
int (*LCDHAL::_oriPutchar)(char, FILE *) = NULL;
int LCDHAL::_lcdPutchar(char c, FILE *stream)
{
_lcdInstance->LCDPutchar(c);
return 0;
}
LCDHAL::LCDHAL(void)
{
if (!_lcdInstance)
{
_lcdInstance = this;
_oriPutchar = stdout->put;
stdout->put = _lcdPutchar;
}
}
LCDHAL::~LCDHAL(void)
{
stdout->put = _oriPutchar;
_lcdInstance = NULL;
}
void LCDHAL::Update(void)
{
if(!LCDBufferEmpty()) _LCDPrint(_LCDBufferPop());
}
void LCDHAL::LCDPortInit(void)
{
bitWrite(LCD_RS_DDR,LCD_RS_BIT,1);
bitWrite(LCD_RW_DDR,LCD_RW_BIT,1);
bitWrite(LCD_E_DDR,LCD_E_BIT,1);
bitWrite(LCD_RS_PORT,LCD_RS_BIT,1);
bitWrite(LCD_RW_PORT,LCD_RW_BIT,0);
bitWrite(LCD_E_PORT,LCD_E_BIT,0);
LCD_DATA_DDR=0xFF;
}
bool LCDHAL::LCDInit(void)
{
sLCDBuffer LCDCommand;
LCDCommand.Command=1;
LCDCommand.Data=0x38;
if(!_LCDBufferPush(&LCDCommand)) return false;
LCDCommand.Data=0x0C;
if(!_LCDBufferPush(&LCDCommand)) return false;
LCDCommand.Data=0x06;
_LCDBufferPush(&LCDCommand);
return true;
}
void LCDHAL::_LCDPrint(sLCDBuffer *LCDData) // subroutine for lcd data
{
LCD_DATA_PORT = LCDData->Data; // data byte to lcd
if(LCDData->Command) bitWrite(LCD_RS_PORT,LCD_RS_BIT,0); //Set RS Low
bitWrite(LCD_E_PORT,LCD_E_BIT,1); //Toggle E
bitWrite(LCD_E_PORT,LCD_E_BIT,0);
if(LCDData->Command) bitWrite(LCD_RS_PORT,LCD_RS_BIT,1); //Set RS High
}
bool LCDHAL::LCDGoto(unsigned char Column, unsigned char Row)
{
if((Row>=4)||(Column>=20)||_LCDFlags.BufferFull) return false;
else
{
_LCDBuffer[_LCDBufferInputIndex].Command=1;
_LCDBuffer[_LCDBufferInputIndex].Data=Column+_RowOffset[Row];
if(++_LCDBufferInputIndex>=LCDBufferSize)_LCDBufferInputIndex=0;
if(_LCDBufferInputIndex==_LCDBufferOutputIndex) _LCDFlags.BufferFull=true;
_LCDFlags.BufferEmpty=false;
return true;
}
}
bool LCDHAL::LCDPutchar(char LCDChar)
{
if(_LCDFlags.BufferFull) return false;
else
{
_LCDBuffer[_LCDBufferInputIndex].Command=0;
_LCDBuffer[_LCDBufferInputIndex].Data=LCDChar;
if(++_LCDBufferInputIndex>=LCDBufferSize)_LCDBufferInputIndex=0;
if(_LCDBufferInputIndex==_LCDBufferOutputIndex) _LCDFlags.BufferFull=true;
_LCDFlags.BufferEmpty=false;
return true;
}
}
bool LCDHAL::_LCDBufferPush(sLCDBuffer *LCDCommand)
{
if(_LCDFlags.BufferFull) return false;
else
{
_LCDBuffer[_LCDBufferInputIndex]=*LCDCommand;
if(++_LCDBufferInputIndex>=LCDBufferSize)_LCDBufferInputIndex=0;
_LCDFlags.BufferEmpty=false;
if(_LCDBufferInputIndex==_LCDBufferOutputIndex)
{
_LCDFlags.BufferFull=true;
return(false);
}
else return true;
}
}
sLCDBuffer* LCDHAL::_LCDBufferPop(void)
{
sLCDBuffer *LCDCommand=&_LCDBuffer[_LCDBufferOutputIndex];
if(++_LCDBufferOutputIndex>=LCDBufferSize) _LCDBufferOutputIndex=0;
if(_LCDBufferOutputIndex==_LCDBufferInputIndex) _LCDFlags.BufferEmpty=true;
_LCDFlags.BufferFull=false;
return LCDCommand;
}
bool LCDHAL::LCDWrite(const char *OutputString,unsigned char Size)
{
while(Size--)
{
_LCDBuffer[_LCDBufferInputIndex].Command=0;
_LCDBuffer[_LCDBufferInputIndex].Data=*(unsigned char*)OutputString++;
if(++_LCDBufferInputIndex>=LCDBufferSize)_LCDBufferInputIndex=0;
_LCDFlags.BufferEmpty=false;
if(_LCDBufferInputIndex==_LCDBufferOutputIndex)
{
_LCDFlags.BufferFull=true;
if(Size!=0)return(false);
}
}
return true;
}
bool LCDHAL::LCDBufferEmpty(void)
{
return _LCDFlags.BufferEmpty;
}
bool LCDHAL::LCDBufferFull(void)
{
return _LCDFlags.BufferFull;
}
#ifndef LCDHAL_H
#define LCDHAL_H
#define LCDBufferSize 128
typedef struct
{
unsigned char Data;
unsigned Command:1;
unsigned :7;
}sLCDBuffer;
typedef struct
{
unsigned BufferFull:1;
unsigned BufferEmpty:1;
unsigned :6;
}sLCDFlags;
class LCDHAL
{
public:
LCDHAL(void);
~LCDHAL(void);
bool LCDBufferFull(void);
bool LCDBufferEmpty(void);
bool LCDGoto(unsigned char Column, unsigned char Row);
void LCDPortInit(void);
bool LCDInit(void);
bool LCDWrite(const char *OutputString, unsigned char Size);
bool LCDPutchar(char LCDChar);
void Update(void);
private:
const /*PROGMEM*/ unsigned char _RowOffset[4] = {0x80, 0xC0, 0x94, 0xD4};
sLCDFlags _LCDFlags = {false, true};
sLCDBuffer _LCDBuffer[LCDBufferSize];
bool _LCDBufferPush(sLCDBuffer *LCDCommand);
sLCDBuffer *_LCDBufferPop(void);
void _LCDPrint(sLCDBuffer *LCDData);
unsigned char _LCDBufferInputIndex = 0, _LCDBufferOutputIndex = 0;
static LCDHAL* _lcdInstance;
static int _lcdPutchar(char c, FILE *stream);
static int (*_oriPutchar)(char, FILE *);
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment