|
|
View previous topic :: View next topic |
Author |
Message |
mbradley
Joined: 11 Jul 2009 Posts: 118 Location: California, USA
|
EA DOGM Multi I/O LCD Driver v2.01 (updated 11/25/09) |
Posted: Sat Jul 11, 2009 10:42 pm |
|
|
Hi every one.
I was having issues with an EA DOG LCD, and I found very little examples out there, so I dove in and just got it done, and I thought I would share what I have thus far.
This works with the three models:
EADOGM081, EADOGM162, EADOGM163
And it works with 3.3volts or just 5volts.
EDIT:
I continue to update the source in this original post, to reflect current version, updates, and bug fixes.
In this version 2.01, I replaced several functions with macros, and I was able to reduce the amount of ROM used when compiled. A simple application I have showed 11 Bytes of rom saved, and 1 byte stack saved.
There is no syntax changes, if you are already using this driver, just drop it in.
Here is a simple example of header needed:
New version 2 allows for 8bit, SPI HW, or SPI SW (bit bang)
Example for 8bit mode
Code: |
#define EADOGM162 1 // the model we selected
#define EADOGMVDD 5 // 5v LCD Vdd
#define EADOGM_8BIT 1 // 8 bit data bus i/o
#define EADOGM_NOCSB 1 // set to 1 if pin 38 (CSB) on lcd is tied to Vss
//#define EADOGM_PIN_CSB PIN_C2 // /CSB line, (pin 38 on the LCD) Req for SPI Opt for 8BIT
#define EADOGM_PIN_E PIN_B1 // E (pin 36 on the LCD)
#define EADOGM_PIN_RW PIN_B2 // RW (pin 37 on the LCD)
#define EADOGM_PIN_RS PIN_B3 // RS line, (pin 39 on the LCD)
// we need to define how the byte goes out
//#define EADOGM_8BIT_PORT(d) output_b(d); // single 8bit port output
#include "EA-DOGM_MIO.c"
|
Example for SPI SW (bit bang)
Code: |
#define EADOGM163 1 // to use MODEL EADOG163
#define EADOGMVDD 5 // if single 5v instead a 3.3v supply otherwise skip
#define EADOGM_SPI_SW 1 // what mode
#define EADOGM_PIN_CSB PIN_C2 // /CS line, C2 is default if you skip this
#define EADOGM_PIN_RS PIN_C1 // RS line, C1 is default if you skip this
// if you want to use internal software SPI bit bang, other wise skip these
#define EADOGM_SCLK_BB PIN_C3 // C3 default for Bit Bang
#define EADOGM_MOSI_BB PIN_C5 // C5 default for Bit Bang
#include "EA-DOGM_MIO.c"
|
and in your program main()
Code: |
eaDogM_Initialize();
eaDogM_DisplayOn();
eaDogM_SetPos(0,0);
eaDogM_WriteString("This is Row 0");
|
Ok, here is the code:
EA-DOGM_MIO.c
Code: |
/*
* file: EA-DOGM_MIO.c
* version: 2.01
* description: Multi I/O driver for EA DOGM displays
* : Uses 8Bit, SPI HW or SPI SW (bitbang)
* written by : Michael Bradley (mbradley@ontura.com)
* contributions: Imaginos (CCS forum), Emil Nad (8Bit testing)
*
* Changelog:
* 11/25/2009 v2.01 Minor changes, replaced some functions with macros
* 09/17/2009 v2.00 Major change, IO is now 8Bit or SPI (hw or sw)
* rewrote some defines as related to pins
* 09/15/2009 v1.13 added function eaDogM_WriteIntAtPos()
* and eaDogM_WriteStringAtPos()
* added some defines to clean source
* 08/28/2009 v1.12 EADOGM_COLSPAN defined internaly, allowing for
* 162 model to position correcty (noted by Imaginos, CCS forum)
* Added support for 2nd SPI HW port (suggested by Imaginos, CCS forum)
* defined a few more special chr's
* 07/12/2009 v1.11 Fixed #define error surrounding BB SPI ini
* added eaDogM_ClearRow(row);
* 07/11/2009 Created/Consolidated this file from my testing sets
*
* Usage:
* In your source, you need to define which EA DOGM display you are using,
* there are 3 units supported EADOGM081 , EADOGM162 , EADOGM163 To use
* define with a 1.
*
* #define EADOGM081 1 // to use MODEL EADOG081
* #define EADOGM162 1 // to use MODEL EADOG162
* #define EADOGM163 1 // to use MODEL EADOG163
* #define EADOGMVDD 5 // 5v LCD Vdd
* //#define EADOGMVDD 3 // 3.3v LCD Vdd
*
*
* // we need to define the IO mode we want, select only one of these, set to 1
* #define EADOGM_SPI_HW 1 // hw spi, uses on chip spi
* #define EADOGM_SPI_HW2 1 // hw spi, 2nd on chip spi
* #define EADOGM_SPI_SW 1 // sw bit bang, can use any io pins
* #define EADOGM_8BIT 1 // 8 bit data bus
*
* // for 8Bit mode only, we need to define the output port
* // however, this can be our own function if need be.
* // example shows output to port b
* #define EADOGM_8BIT_PORT(d) output_b(d); // we need to define how the byte goes out
* //#define EADOGM_8BIT_PORT(d) your_func(d); // we need to define how the byte goes out
*
*
* // we need to define a few pins
* #define EADOGM_PIN_RS PIN_C1 // RS line, (pin 39 on the LCD)
* #define EADOGM_PIN_CSB PIN_C2 // /CSB line, (pin 38 on the LCD) Req for SPI Opt for 8BIT
*
* // for 8 bit mode, we need to define a few more pins
* #define EADOGM_NOCSB 1 // set to 1 if pin 38 (CSB) on lcd is tied to Vss
* #define EADOGM_PIN_E PIN_C2 // E (pin 36 on the LCD)
* #define EADOGM_PIN_RW PIN_C6 // RW (pin 37 on the LCD)
*
* // set these if you are using EADOGM_SPI_SW (bit bang)
* #define EADOGM_SCLK_BB PIN_C3 // Connects to pin 29 on LCD
* #define EADOGM_MOSI_BB PIN_C5 // Connects to pin 28 on LCD
*
*
*
* #include "EA-DOGM_MIO.c"
*
* In your main code, do an ini call
* eaDogM_Initialize();
* eaDogM_DisplayOn();
*
*
* Available Functions:
* -------------------------------------------------------------------------------
* eaDogM_Cls(); // clears the screen, homes cursor
* eaDogM_ClearRow(row); // clears a row (v1.11)
* eaDogM_CursorOn(); // turns on the cursor
* eaDogM_CursorOff(); // turns of the cursor
* eaDogM_DisplayOn(); // turns on display with cursor off
* eaDogM_DisplayOff(); // turns off display
* eaDogM_SetPos(row, col); // sets position row:0-2, col:0-15
* eaDogM_WriteChr(byte); // writes a single chr to the display
* eaDogM_WriteString(char str); // writes a string to the display
* // note: add this line after device selection
* // to do this: eaDogM_WriteString("Constant")
* // #device PASS_STRINGS=IN_RAM
*
* // writes a 2 digit integer at row,col set flag = 1 to diable interrupts
* eaDogM_WriteIntAtPos(row,col,int[,flag])
*
* // writes a string at row,col set flag = 1 to diable interrupts
* eaDogM_WriteStringAtPos(row,col,char str[,flag])
*
* eaDogM_SetContrast(c); // set contrast 0 to 15
* eaDogM_DoubleHeight(row); // turn on double height, row = 0 or 1
* eaDogM_DoubleHeightOff(); // turn off double height
* -------------------------------------------------------------------------------
*
*/
#ifndef EADOGM_SPI
#define EADOGM_SPI 1
// some special symbol chrs defined
#define EADMSYM_DEG 0b11011111 // degree symbol
#define EADMSYM_DARWL 0b11111011 // double <<
#define EADMSYM_DARWR 0b11111100 // double >>
#define EADMSYM_LT 0b00111100 // less than <
#define EADMSYM_GT 0b00111110 // greater than >
#define EADMSYM_OHM 0b00011110 // ohm symbol
// some command defines
#define EADMCMD_CONTRAST 0b0111000 // contrast command (0b0111xxxx)
// we noticed some issues with GLOBAL on pic24 devices
#ifndef GLOBAL
#define GLOBAL INTR_GLOBAL
#endif
// 1x16
#ifdef EADOGM081
#define EADOGM_ROWS 1
#if EADOGMVDD == 5
#define EADOGM_INIT_BIAS_SET 0x1C
#define EADOGM_INIT_POWER_CONTROL 0x51
#define EADOGM_INIT_FOLLOWER_CONTROL 0x6A
#define EADOGM_INIT_CONTRAST_SET 0x74
#else
#define EADOGM_INIT_BIAS_SET 0x14
#define EADOGM_INIT_POWER_CONTROL 0x55
#define EADOGM_INIT_FOLLOWER_CONTROL 0x6D
#define EADOGM_INIT_CONTRAST_SET 0x7C
#endif
#define EADOGM_INIT_FS1 0x31
#define EADOGM_INIT_FS2 0x30
#define EADOGM_INIT_CLEAR_DISPLAY 0x01
#define EADOGM_INIT_ENTRY_MODE 0x06
#define EADOGM_COLSPAN 16
#endif
// 2x16
#ifdef EADOGM162
#define EADOGM_ROWS 2
#if EADOGMVDD == 5
#define EADOGM_INIT_BIAS_SET 0x1C
#define EADOGM_INIT_POWER_CONTROL 0x52
#define EADOGM_INIT_FOLLOWER_CONTROL 0x69
#define EADOGM_INIT_CONTRAST_SET 0x74
#else
#define EADOGM_INIT_BIAS_SET 0x14
#define EADOGM_INIT_POWER_CONTROL 0x55
#define EADOGM_INIT_FOLLOWER_CONTROL 0x6D
#define EADOGM_INIT_CONTRAST_SET 0x78
#endif
#define EADOGM_INIT_FS1 0x39
#define EADOGM_INIT_FS2 0x38
#define EADOGM_INIT_CLEAR_DISPLAY 0x01
#define EADOGM_INIT_ENTRY_MODE 0x06
#define EADOGM_COLSPAN 40 // suggested that this be 40 on model 162
#endif
// 3x16
#ifdef EADOGM163
#define EADOGM_ROWS 3
#if EADOGMVDD == 5
#define EADOGM_INIT_BIAS_SET 0x1D
#define EADOGM_INIT_POWER_CONTROL 0x50
#define EADOGM_INIT_FOLLOWER_CONTROL 0x6C
#define EADOGM_INIT_CONTRAST_SET 0x7C
#else
#define EADOGM_INIT_BIAS_SET 0x15
#define EADOGM_INIT_POWER_CONTROL 0x55
#define EADOGM_INIT_FOLLOWER_CONTROL 0x6E
#define EADOGM_INIT_CONTRAST_SET 0x72
#endif
#define EADOGM_INIT_FS1 0x39
#define EADOGM_INIT_FS2 0x38
#define EADOGM_INIT_CLEAR_DISPLAY 0x01
#define EADOGM_INIT_ENTRY_MODE 0x06
#define EADOGM_COLSPAN 16
#endif
#define EADOGM_CMD_CLR 1
#define EADOGM_CMD_CURSOR_ON 0b00001111
#define EADOGM_CMD_CURSOR_OFF 0b00001100
#define EADOGM_CMD_DISPLAY_ON 0b00001100
#define EADOGM_CMD_DISPLAY_OFF 0b00001000
#define EADOGM_CMD_DDRAM_ADDR 0b10000000
#define EADOGM_CMD_SELECT_R0 0b00011000
#define EADOGM_CMD_SELECT_R1 0b00010000
#define EADOGM_CMD_SET_TABLE2 0b00101010
// sw spi emulation routine (bit bang)
#ifdef EADOGM_SPI_SW
#ifndef EADOGM_SCLK_BB
#define EADOGM_SCLK_BB PIN_C3
#endif
#ifndef EADOGM_MOSI_BB
#define EADOGM_MOSI_BB PIN_C5
#endif
void eaDogM_iniSPI_BB(void)
{
output_drive(EADOGM_SCLK_BB);
output_drive(EADOGM_MOSI_BB);
output_low(EADOGM_SCLK_BB);
output_low(EADOGM_MOSI_BB);
}
void eaDogM_spiWrite_BB(int8 regData)
{
int1 bitOut;
int8 SPICount; // Counter used to clock out the data
int8 SPIData; // Define a data structure for the SPI data.
output_low(EADOGM_SCLK_BB); // and CK low
SPIData = regData;
for (SPICount = 0; SPICount < 8; SPICount++) // Prepare to clock out the Address byte
{
bitOut = bit_test(SPIData,7);
output_bit(EADOGM_MOSI_BB,bitOut);
output_high(EADOGM_SCLK_BB); // Toggle the clock line
//delay_us(10);
output_low(EADOGM_SCLK_BB);
//delay_us(10);
SPIData = SPIData << 1; // Rotate to get the next bit
} // and loop back to send the next bit
output_low(EADOGM_MOSI_BB);
}
// wrapper for sw spi calls in main program
// v2.01 moved to macro define
#define eaDogM_outSPI(c) eaDogM_spiWrite_BB(c)
#endif
// wrapper for hw spi calls in main program
// v2.01 moved to a macro define
#ifdef EADOGM_SPI_HW
#define eaDogM_outSPI(c) spi_write(c)
#endif
// wrapper for hw2 spi calls in main program
// v2.01 moved to a macro define
#ifdef EADOGM_SPI_HW2
#define eaDogM_outSPI(c) spi_write2(c)
#endif
#ifdef EADOGM_8BIT
void eaDogM_ini8Bit(void)
{
#ifndef EADOGM_NOCSB
output_drive(EADOGM_PIN_CSB);
output_high(EADOGM_PIN_CSB);
#endif
output_drive(EADOGM_PIN_E);
output_drive(EADOGM_PIN_RW);
output_drive(EADOGM_PIN_RS);
output_low(EADOGM_PIN_E);
output_low(EADOGM_PIN_RS);
output_low(EADOGM_PIN_RW);
}
#endif
#ifdef EADOGM_8BIT
// 8bit mode
void eaDogM_WriteChr(char value)
{
output_high(EADOGM_PIN_RS);
output_low(EADOGM_PIN_RW);
output_low(EADOGM_PIN_E);
#ifndef EADOGM_NOCSB
output_low(EADOGM_PIN_CSB);
#endif
output_high(EADOGM_PIN_E);
delay_ms(1);
EADOGM_8BIT_PORT(value);
output_low(EADOGM_PIN_E);
delay_ms(1);
#ifndef EADOGM_NOCSB
output_low(EADOGM_PIN_CSB);
#endif
delay_ms(1);
}
void eaDogM_WriteCommand(int8 cmd)
{
output_low(EADOGM_PIN_RS);
output_low(EADOGM_PIN_RW);
output_low(EADOGM_PIN_E);
#ifndef EADOGM_NOCSB
output_low(EADOGM_PIN_CSB);
#endif
output_high(EADOGM_PIN_E);
delay_ms(1);
EADOGM_8BIT_PORT(cmd);
output_low(EADOGM_PIN_E);
delay_ms(1);
#ifndef EADOGM_NOCSB
output_low(EADOGM_PIN_CSB);
#endif
delay_ms(1);
}
#else
// spi mode
void eaDogM_WriteChr(char value)
{
output_high(EADOGM_PIN_RS);
output_low(EADOGM_PIN_CSB);
eaDogM_outSPI(value);
output_high(EADOGM_PIN_CSB);
delay_ms(1);
}
void eaDogM_WriteCommand(int8 cmd)
{
output_low(EADOGM_PIN_RS);
output_low(EADOGM_PIN_CSB);
eaDogM_outSPI(cmd);
output_high(EADOGM_PIN_CSB);
delay_ms(1);
}
#endif
void eaDogM_Initialize(void)
{
#ifdef EADOGM_SPI_SW
eaDogM_iniSPI_BB();
#endif
#ifdef EADOGM_8BIT
eaDogM_ini8Bit();
#else
output_drive(EADOGM_PIN_CSB);
output_drive(EADOGM_PIN_RS);
output_high(EADOGM_PIN_CSB);
output_high(EADOGM_PIN_RS);
#endif
delay_ms(200);
eaDogM_WriteCommand(EADOGM_INIT_FS1);
eaDogM_WriteCommand(EADOGM_INIT_BIAS_SET);
eaDogM_WriteCommand(EADOGM_INIT_POWER_CONTROL);
eaDogM_WriteCommand(EADOGM_INIT_FOLLOWER_CONTROL);
eaDogM_WriteCommand(EADOGM_INIT_CONTRAST_SET);
eaDogM_WriteCommand(EADOGM_INIT_FS2);
eaDogM_WriteCommand(EADOGM_INIT_CLEAR_DISPLAY);
eaDogM_WriteCommand(EADOGM_INIT_ENTRY_MODE);
}
// sets contrast, call with a value from 0 to 15
// we also mask off upper 4 bits from c
// v2.01 moved to a macro define
#define eaDogM_SetContrast(c) eaDogM_WriteCommand(EADMCMD_CONTRAST + (c & 0b00001111))
// only tested on 3 line display at the moment,
// thus no constants defined. when fully tested, I will define them
void eaDogM_DoubleHeight(int8 row) // row 0 or 1
{
eaDogM_WriteCommand(EADOGM_CMD_SET_TABLE2); // set instruction table 2
if (row == 0) {
eaDogM_WriteCommand(EADOGM_CMD_SELECT_R0); // select row 0
}
if (row == 1) {
eaDogM_WriteCommand(EADOGM_CMD_SELECT_R1); // select row 1
}
eaDogM_WriteCommand(0b00101100); // turns on double line mode
// and set instruction table back to 0
}
// v2.01 moved functions to macros
#define eaDogM_DoubleHeightOff() eaDogM_WriteCommand(0b00101000)
#define eaDogM_Cls() eaDogM_WriteCommand(EADOGM_CMD_CLR)
#define eaDogM_CursorOn() eaDogM_WriteCommand(EADOGM_CMD_CURSOR_ON)
#define eaDogM_CursorOff() eaDogM_WriteCommand(EADOGM_CMD_CURSOR_OFF)
#define eaDogM_DisplayOn() eaDogM_WriteCommand(EADOGM_CMD_DISPLAY_ON)
#define eaDogM_DisplayOff() eaDogM_WriteCommand(EADOGM_CMD_DISPLAY_OFF)
void eaDogM_SetPos(int8 r, int8 c)
{
int8 cmdPos;
cmdPos = EADOGM_CMD_DDRAM_ADDR + (r * EADOGM_COLSPAN) + c;
eaDogM_WriteCommand(cmdPos);
}
void eaDogM_ClearRow(int8 r)
{
int8 i;
eaDogM_SetPos(r,0);
for(i=0; i<EADOGM_COLSPAN; i++) {
eaDogM_WriteChr(' ');
}
}
void eaDogM_WriteString(char *strPtr)
{
while (*strPtr != 0)
{
eaDogM_WriteChr(*strPtr);
strPtr++;
}
}
// Optional DisGIE, set to 1 to disable interrupts
// v1.4 -- provided by Imaginos
void eaDogM_WriteStringAtPos(int8 r, int8 c, char *strPtr, int1 DisGIE=0)
{
if (DisGIE) {
disable_interrupts(GLOBAL);
}
eaDogM_WriteCommand((EADOGM_CMD_DDRAM_ADDR + (r * EADOGM_COLSPAN) + c));
while (*strPtr != 0)
{
eaDogM_WriteChr(*strPtr);
strPtr++;
}
if (DisGIE) {
enable_interrupts(GLOBAL);
}
}
// Optional DisGIE, set to 1 to disable interrupts
// v1.4 -- provided by Imaginos
void eaDogM_WriteIntAtPos(int8 r, int8 c, int8 i, int1 DisGIE=0)
{
if (DisGIE) {
disable_interrupts(GLOBAL);
}
eaDogM_WriteCommand((EADOGM_CMD_DDRAM_ADDR + (r * EADOGM_COLSPAN) + c));
eaDogM_WriteChr(i/10+'0');
eaDogM_WriteChr(i%10+'0');
if (DisGIE) {
enable_interrupts(GLOBAL);
}
}
#endif
|
Last edited by mbradley on Thu Nov 26, 2009 4:12 pm; edited 5 times in total |
|
|
mbradley
Joined: 11 Jul 2009 Posts: 118 Location: California, USA
|
|
Posted: Sun Jul 12, 2009 5:15 pm |
|
|
I am so sorry, I found a single error when moving this to another chip this morning.
EDIT: I didnt know I could edit a post, I made the corrections in the above listing.
This part should be changed:
void eaDogM_Initialize(void)
{
eaDogM_iniSPI_BB();
..
..
To this:
void eaDogM_Initialize(void)
{
#ifdef EADOGM_SPI_BB
eaDogM_iniSPI_BB();
#endif
..
.. |
|
|
yeti
Joined: 14 Sep 2009 Posts: 2
|
|
Posted: Mon Sep 14, 2009 2:02 pm |
|
|
Hi, Bradley,
will you be so kind and tell me do you have experience with drive this display but over the normal I/0 port and on parallel 8-bit port? Can you see if your driver is accptable for DOG162M , 3V, PIC24FJ?
Thanks in advance..
Zdenko
mbradley wrote: | I am so sorry, I found a single error when moving this to another chip this morning.
EDIT: I didnt know I could edit a post, I made the corrections in the above listing.
This part should be changed:
void eaDogM_Initialize(void)
{
eaDogM_iniSPI_BB();
..
..
To this:
void eaDogM_Initialize(void)
{
#ifdef EADOGM_SPI_BB
eaDogM_iniSPI_BB();
#endif
..
.. |
|
|
|
mbradley
Joined: 11 Jul 2009 Posts: 118 Location: California, USA
|
|
Posted: Mon Sep 21, 2009 12:56 am |
|
|
the updated driver v2.00 now works with DOG162M , 3V, PIC24FJ over 8bit |
|
|
yeti
Joined: 14 Sep 2009 Posts: 2
|
|
Posted: Mon Sep 21, 2009 1:18 am |
|
|
Where I can find this new version v2.00. I didn't find any attachment in your post?
Regards
Zdenko
mbradley wrote: | the updated driver v2.00 now works with DOG162M , 3V, PIC24FJ over 8bit |
|
|
|
mbradley
Joined: 11 Jul 2009 Posts: 118 Location: California, USA
|
|
Posted: Tue Sep 22, 2009 1:53 am |
|
|
v2.00 is in the main post, instead of adding all the bug fixes and updates to a really long post and having things scattered, I decided to edit and always update the source in the first post. |
|
|
mbradley
Joined: 11 Jul 2009 Posts: 118 Location: California, USA
|
|
|
luciano_schirmer
Joined: 09 Feb 2014 Posts: 2 Location: Brazil
|
|
Posted: Sun Feb 09, 2014 9:11 pm |
|
|
Hello mbradley,
Thanks for posting the code, it was really helpful. Actually I needed a 4Bit version, so I dove in your code and adapted to work with 4Bit mode also.
Example for 4Bit mode:
Code: |
#define EADOGM162 1 // to use MODEL EADOG162
#define EADOGMVDD 3 // 3.3v LCD Vdd
#define EADOGM_4BIT 1 // 4Bit tmode
#define EADOGM_NOCSB 1
#define EADOGM_PIN_E PIN_D3 // E line (pin 36 on the LCD)
#define EADOGM_PIN_RW PIN_D2 // RW line (pin 37 on the LCD)
#define EADOGM_PIN_RS PIN_D1 // RS line (pin 39 on the LCD)
#define EADOGM_DATA4 PIN_D4
#define EADOGM_DATA5 PIN_D5
#define EADOGM_DATA6 PIN_D6
#define EADOGM_DATA7 PIN_D7
#include "ea-dogm_mio.c"
|
Modified code for EA-DOGM_CIO.C:
Code: |
/*
* file: EA-DOGM_MIO.c
* version: 2.03a (unofficial)
* description: Multi I/O driver for EA DOGM displays
* : Uses 8Bit, 4Bit, SPI HW or SPI SW (bitbang)
* written by : Michael Bradley (mbradley@mculabs.com)
* contributions: Imaginos (CCS forum), Emil Nad (8Bit testing)
* jgschmidt (CCS forum)
* modified by : Eng. Luciano Schirmer (luciano.igtech@gmail.com)
*
* Changelog:
* 02/08/2014 v2.03a added 4Bit mode (Eng. Luciano Schirmer)
* 04/22/2010 v2.03 Minor update, changed EADOGM_SPI_HW for HW SPI 1 and 2
* Added setup_spi() for HW SPI use, and spi_clk_div option
* thanks to jgschmidt (ccs forum) for noticing hw setup issues
* 12/03/2009 v2.02 bug fix and printChr change, no user change needed for use
* 11/25/2009 v2.01 Minor changes, replaced some functions with macros
* 09/17/2009 v2.00 Major change, IO is now 8Bit or SPI (hw or sw)
* rewrote some defines as related to pins
* 09/15/2009 v1.13 added function eaDogM_WriteIntAtPos()
* and eaDogM_WriteStringAtPos()
* added some defines to clean source
* 08/28/2009 v1.12 EADOGM_COLSPAN defined internally, allowing for
* 162 model to position correctly (noted by Imaginos, CCS forum)
* Added support for 2nd SPI HW port (suggested by Imaginos, CCS forum)
* defined a few more special chr's
* 07/12/2009 v1.11 Fixed #define error surrounding BB SPI ini
* added eaDogM_ClearRow(row);
* 07/11/2009 Created/Consolidated this file from my testing sets
*
* Usage:
* In your source, you need to define which EA DOGM display you are using,
* there are 3 units supported EADOGM081 , EADOGM162 , EADOGM163 To use
* define with a 1.
*
* #define EADOGM081 1 // to use MODEL EADOG081
* #define EADOGM162 1 // to use MODEL EADOG162
* #define EADOGM163 1 // to use MODEL EADOG163
* #define EADOGMVDD 5 // 5v LCD Vdd
* //#define EADOGMVDD 3 // 3.3v LCD Vdd
*
*
* // we need to define the IO mode we want, select only one of these, set to 1
* #define EADOGM_SPI_HW 1 // hw spi, uses on chip spi
* #define EADOGM_SPI_HW 2 // hw spi, 2nd on chip spi
* #define EADOGM_SPI_DIV SPI_CLK_DIV_64 // used to slow hw spi clock (you can use other constants)
* #define EADOGM_SPI_SW 1 // sw bit bang, can use any io pins
* #define EADOGM_8BIT 1 // 8 bit data bus
* #define EADOGM_4BIT 1 // 4 bit data bus
*
* // we need to define a few pins
* #define EADOGM_PIN_RS PIN_C1 // RS line, (pin 39 on the LCD)
* #define EADOGM_PIN_CSB PIN_C2 // /CSB line, (pin 38 on the LCD) Req for SPI Opt
*
* // for 8Bit mode only, we need to define the output port
* // however, this can be our own function if need be.
* // example shows output to port b
* #define EADOGM_8BIT_PORT(d) output_b(d); // we need to define how the byte goes out
* //#define EADOGM_8BIT_PORT(d) your_func(d); // we need to define how the byte goes out
*
* // for 4/8 bit mode, we need to define a few more pins
* #define EADOGM_NOCSB 1 // set to 1 if pin 38 (CSB) on lcd is tied to Vss
* #define EADOGM_PIN_E PIN_C2 // E (pin 36 on the LCD)
* #define EADOGM_PIN_RW PIN_C6 // RW (pin 37 on the LCD)
*
* // set these if you are using EADOGM_4BIT
* #define EADOGM_DATA4 PIN_D4
* #define EADOGM_DATA5 PIN_D5
* #define EADOGM_DATA6 PIN_D6
* #define EADOGM_DATA7 PIN_D7
*
* // set these if you are using EADOGM_SPI_SW (bit bang)
* #define EADOGM_SCLK_BB PIN_C3 // Connects to pin 29 on LCD
* #define EADOGM_MOSI_BB PIN_C5 // Connects to pin 28 on LCD
*
*
*
* #include "EA-DOGM_MIO.c"
*
* In your main code, do an ini call
* eaDogM_Initialize();
* eaDogM_DisplayOn();
*
*
* Available Functions:
* -------------------------------------------------------------------------------
* eaDogM_Cls(); // clears the screen, homes cursor
* eaDogM_ClearRow(row); // clears a row (v1.11)
* eaDogM_CursorOn(); // turns on the cursor
* eaDogM_CursorOff(); // turns of the cursor
* eaDogM_DisplayOn(); // turns on display with cursor off
* eaDogM_DisplayOff(); // turns off display
* eaDogM_SetPos(row, col); // sets position row:0-2, col:0-15
* eaDogM_WriteChr(byte); // writes a single chr to the display
* eaDogM_WriteString(char str); // writes a string to the display
* // note: add this line after device selection
* // to do this: eaDogM_WriteString("Constant")
* // #device PASS_STRINGS=IN_RAM
*
* // writes a 2 digit integer at row,col set flag = 1 to disable interrupts
* eaDogM_WriteIntAtPos(row,col,int[,flag])
*
* // writes a string at row,col set flag = 1 to disable interrupts
* eaDogM_WriteStringAtPos(row,col,char str[,flag])
*
* eaDogM_SetContrast(c); // set contrast 0 to 15
* eaDogM_DoubleHeight(row); // turn on double height, row = 0 or 1
* eaDogM_DoubleHeightOff(); // turn off double height
* -------------------------------------------------------------------------------
*
*/
#ifndef EADOGM_SPI
#define EADOGM_SPI 1
// some special symbol chrs defined
#define EADMSYM_DEG 0b11011111 // degree symbol
#define EADMSYM_DARWL 0b11111011 // double <<
#define EADMSYM_DARWR 0b11111100 // double >>
#define EADMSYM_LT 0b00111100 // less than <
#define EADMSYM_GT 0b00111110 // greater than >
#define EADMSYM_OHM 0b00011110 // ohm symbol
// some command defines
#define EADMCMD_CONTRAST 0b0111000 // contrast command (0b0111xxxx)
// we noticed some issues with GLOBAL on pic24 devices
#ifndef GLOBAL
#define GLOBAL INTR_GLOBAL
#endif
// 1x16
#ifdef EADOGM081
#define EADOGM_ROWS 1
#if EADOGMVDD == 5
#define EADOGM_INIT_BIAS_SET 0x1C
#define EADOGM_INIT_POWER_CONTROL 0x51
#define EADOGM_INIT_FOLLOWER_CONTROL 0x6A
#define EADOGM_INIT_CONTRAST_SET 0x74
#else
#define EADOGM_INIT_BIAS_SET 0x14
#define EADOGM_INIT_POWER_CONTROL 0x55
#define EADOGM_INIT_FOLLOWER_CONTROL 0x6D
#define EADOGM_INIT_CONTRAST_SET 0x7C
#endif
#ifdef EADOGM_4BIT
#define EADOGM_INIT_FS1 0x21
#define EADOGM_INIT_FS2 0x20
#else
#define EADOGM_INIT_FS1 0x31
#define EADOGM_INIT_FS2 0x30
#endif
#define EADOGM_INIT_CLEAR_DISPLAY 0x01
#define EADOGM_INIT_ENTRY_MODE 0x06
#define EADOGM_COLSPAN 16
#endif
// 2x16
#ifdef EADOGM162
#define EADOGM_ROWS 2
#if EADOGMVDD == 5
#define EADOGM_INIT_BIAS_SET 0x1C
#define EADOGM_INIT_POWER_CONTROL 0x52
#define EADOGM_INIT_FOLLOWER_CONTROL 0x69
#define EADOGM_INIT_CONTRAST_SET 0x74
#else
#define EADOGM_INIT_BIAS_SET 0x14
#define EADOGM_INIT_POWER_CONTROL 0x55
#define EADOGM_INIT_FOLLOWER_CONTROL 0x6D
#define EADOGM_INIT_CONTRAST_SET 0x78
#endif
#ifdef EADOGM_4BIT
#define EADOGM_INIT_FS1 0x29
#define EADOGM_INIT_FS2 0x28
#else
#define EADOGM_INIT_FS1 0x39
#define EADOGM_INIT_FS2 0x38
#endif
#define EADOGM_INIT_CLEAR_DISPLAY 0x01
#define EADOGM_INIT_ENTRY_MODE 0x06
#define EADOGM_COLSPAN 40 // suggested that this be 40 on model 162
#endif
// 3x16
#ifdef EADOGM163
#define EADOGM_ROWS 3
#if EADOGMVDD == 5
#define EADOGM_INIT_BIAS_SET 0x1D
#define EADOGM_INIT_POWER_CONTROL 0x50
#define EADOGM_INIT_FOLLOWER_CONTROL 0x6C
#define EADOGM_INIT_CONTRAST_SET 0x7C
#else
#define EADOGM_INIT_BIAS_SET 0x15
#define EADOGM_INIT_POWER_CONTROL 0x55
#define EADOGM_INIT_FOLLOWER_CONTROL 0x6E
#define EADOGM_INIT_CONTRAST_SET 0x72
#endif
#ifdef EADOGM_4BIT
#define EADOGM_INIT_FS1 0x29
#define EADOGM_INIT_FS2 0x28
#else
#define EADOGM_INIT_FS1 0x39
#define EADOGM_INIT_FS2 0x38
#endif
#define EADOGM_INIT_CLEAR_DISPLAY 0x01
#define EADOGM_INIT_ENTRY_MODE 0x06
#define EADOGM_COLSPAN 16
#endif
#define EADOGM_CMD_CLR 1
#define EADOGM_CMD_CURSOR_ON 0b00001111
#define EADOGM_CMD_CURSOR_OFF 0b00001100
#define EADOGM_CMD_DISPLAY_ON 0b00001100
#define EADOGM_CMD_DISPLAY_OFF 0b00001000
#define EADOGM_CMD_DDRAM_ADDR 0b10000000
#define EADOGM_CMD_CGRAM_ADDR 0b01000000
#define EADOGM_CMD_SELECT_R0 0b00011000
#define EADOGM_CMD_SELECT_R1 0b00010000
#define EADOGM_CMD_SET_TABLE2 0b00101010
// spi hw clock div, v2.03 fix
#ifndef EADOGM_SPI_DIV
#define EADOGM_SPI_DIV SPI_CLK_DIV_4
#endif
// sw spi emulation routine (bit bang)
#ifdef EADOGM_SPI_SW
#ifndef EADOGM_SCLK_BB
#define EADOGM_SCLK_BB PIN_C3
#endif
#ifndef EADOGM_MOSI_BB
#define EADOGM_MOSI_BB PIN_C5
#endif
void eaDogM_iniSPI_BB(void)
{
output_drive(EADOGM_SCLK_BB);
output_drive(EADOGM_MOSI_BB);
output_low(EADOGM_SCLK_BB);
output_low(EADOGM_MOSI_BB);
}
void eaDogM_spiWrite_BB(int8 regData)
{
int1 bitOut;
int8 SPICount; // Counter used to clock out the data
int8 SPIData; // Define a data structure for the SPI data.
output_low(EADOGM_SCLK_BB); // and CK low
SPIData = regData;
for (SPICount = 0; SPICount < 8; SPICount++) // Prepare to clock out the Address byte
{
bitOut = bit_test(SPIData,7);
output_bit(EADOGM_MOSI_BB,bitOut);
output_high(EADOGM_SCLK_BB); // Toggle the clock line
//delay_us(10);
output_low(EADOGM_SCLK_BB);
//delay_us(10);
SPIData = SPIData << 1; // Rotate to get the next bit
} // and loop back to send the next bit
output_low(EADOGM_MOSI_BB);
}
// wrapper for sw spi calls in main program
// v2.01 moved to macro define
#define eaDogM_outSPI(c) eaDogM_spiWrite_BB(c)
#endif
// wrapper for hw spi calls in main program
// v2.01 moved to a macro define
#ifdef EADOGM_SPI_HW
#if EADOGM_SPI_HW == 1
#define eaDogM_outSPI(c) spi_write(c)
#endif
// wrapper for hw2 spi calls in main program
// v2.01 moved to a macro define, v2.03 using EADOGM_SPI_HW to test condition
#if EADOGM_SPI_HW == 2
#define eaDogM_outSPI(c) spi_write2(c)
#endif
#endif
#if (defined(EADOGM_4BIT) || defined(EADOGM_8BIT))
void eaDogM_ini8Bit(void)
{
#ifndef EADOGM_NOCSB
output_drive(EADOGM_PIN_CSB);
output_high(EADOGM_PIN_CSB);
#endif
output_drive(EADOGM_PIN_E);
output_drive(EADOGM_PIN_RW);
output_drive(EADOGM_PIN_RS);
#ifdef EADOGM_4BIT
output_drive(EADOGM_DATA4);
output_drive(EADOGM_DATA5);
output_drive(EADOGM_DATA6);
output_drive(EADOGM_DATA7);
#endif
output_low(EADOGM_PIN_E);
output_low(EADOGM_PIN_RS);
output_low(EADOGM_PIN_RW);
#ifdef EADOGM_4BIT
output_low(EADOGM_DATA4);
output_low(EADOGM_DATA5);
output_low(EADOGM_DATA6);
output_low(EADOGM_DATA7);
#endif
}
#endif
#if defined(EADOGM_8BIT)
// 8bit mode
void eaDogM_WriteChr(char value)
{
output_high(EADOGM_PIN_RS);
output_low(EADOGM_PIN_RW);
output_low(EADOGM_PIN_E);
#ifndef EADOGM_NOCSB
output_low(EADOGM_PIN_CSB);
#endif
output_high(EADOGM_PIN_E);
delay_ms(1);
EADOGM_8BIT_PORT(value);
output_low(EADOGM_PIN_E);
delay_ms(1);
#ifndef EADOGM_NOCSB
output_low(EADOGM_PIN_CSB);
#endif
delay_ms(1);
}
void eaDogM_WriteCommand(int8 cmd)
{
output_low(EADOGM_PIN_RS);
output_low(EADOGM_PIN_RW);
output_low(EADOGM_PIN_E);
#ifndef EADOGM_NOCSB
output_low(EADOGM_PIN_CSB);
#endif
output_high(EADOGM_PIN_E);
delay_ms(1);
EADOGM_8BIT_PORT(cmd);
output_low(EADOGM_PIN_E);
delay_ms(1);
#ifndef EADOGM_NOCSB
output_low(EADOGM_PIN_CSB);
#endif
delay_ms(1);
}
#elif defined(EADOGM_4BIT)
// 4bit mode
void eaDogM_WriteNibble(int8 value)
{
output_bit(EADOGM_DATA4, bit_test(value, 4));
output_bit(EADOGM_DATA5, bit_test(value, 5));
output_bit(EADOGM_DATA6, bit_test(value, 6));
output_bit(EADOGM_DATA7, bit_test(value, 7));
delay_cycles(1);
output_high(EADOGM_PIN_E);
delay_us(2);
output_low(EADOGM_PIN_E);
}
void eaDogM_WriteChr(char value)
{
output_high(EADOGM_PIN_RS);
output_low(EADOGM_PIN_RW);
output_low(EADOGM_PIN_E);
#ifndef EADOGM_NOCSB
output_low(EADOGM_PIN_CSB);
#endif
eaDogM_WriteNibble(value);
eaDogM_WriteNibble(value<<4);
delay_us(10);
}
void eaDogM_WriteCommand(int8 cmd)
{
output_low(EADOGM_PIN_RS);
output_low(EADOGM_PIN_RW);
output_low(EADOGM_PIN_E);
#ifndef EADOGM_NOCSB
output_low(EADOGM_PIN_CSB);
#endif
eaDogM_WriteNibble(cmd);
eaDogM_WriteNibble(cmd<<4);
delay_ms(1);
}
#else
// spi mode
void eaDogM_WriteChr(char value)
{
output_high(EADOGM_PIN_RS);
output_low(EADOGM_PIN_CSB);
eaDogM_outSPI(value);
output_high(EADOGM_PIN_CSB);
delay_ms(1);
}
void eaDogM_WriteCommand(int8 cmd)
{
output_low(EADOGM_PIN_RS);
output_low(EADOGM_PIN_CSB);
eaDogM_outSPI(cmd);
output_high(EADOGM_PIN_CSB);
delay_ms(1);
}
#endif
void eaDogM_Initialize(void)
{
#ifdef EADOGM_4BIT
int i;
#endif
// v2.03 fix
#ifdef EADOGM_SPI_HW
#if EADOGM_SPI_HW == 1
setup_spi( SPI_MASTER | SPI_H_TO_L | EADOGM_SPI_DIV );
#endif
// v2.03 fix
#if EADOGM_SPI_HW == 2
setup_spi2( SPI_MASTER | SPI_H_TO_L | EADOGM_SPI_DIV );
#endif
#endif
#ifdef EADOGM_SPI_SW
eaDogM_iniSPI_BB();
#endif
#if (defined(EADOGM_4BIT) || defined(EADOGM_8BIT))
eaDogM_ini8Bit();
#else
output_drive(EADOGM_PIN_CSB);
output_drive(EADOGM_PIN_RS);
output_high(EADOGM_PIN_CSB);
output_high(EADOGM_PIN_RS);
#endif
delay_ms(200);
#ifdef EADOGM_4BIT
output_low(EADOGM_PIN_RS);
output_low(EADOGM_PIN_RW);
output_low(EADOGM_PIN_E);
for(i=1;i<=3;++i)
{
eaDogM_WriteNibble(0x30);
delay_ms(5);
}
eaDogM_WriteNibble(0x20);
delay_ms(5);
#endif
eaDogM_WriteCommand(EADOGM_INIT_FS1);
eaDogM_WriteCommand(EADOGM_INIT_FS1);
eaDogM_WriteCommand(EADOGM_INIT_BIAS_SET);
eaDogM_WriteCommand(EADOGM_INIT_POWER_CONTROL);
eaDogM_WriteCommand(EADOGM_INIT_FOLLOWER_CONTROL);
eaDogM_WriteCommand(EADOGM_INIT_CONTRAST_SET);
eaDogM_WriteCommand(EADOGM_INIT_FS2);
eaDogM_WriteCommand(EADOGM_INIT_CLEAR_DISPLAY);
eaDogM_WriteCommand(EADOGM_INIT_ENTRY_MODE);
}
// sets contrast, call with a value from 0 to 15
// we also mask off upper 4 bits from c
// v2.01 moved to a macro define
#define eaDogM_SetContrast(c) eaDogM_WriteCommand(EADMCMD_CONTRAST + (c & 0b00001111))
// only tested on 3 line display at the moment,
// thus no constants defined. when fully tested, I will define them
void eaDogM_DoubleHeight(int8 row) // row 0 or 1
{
eaDogM_WriteCommand(EADOGM_CMD_SET_TABLE2); // set instruction table 2
if (row == 0) {
eaDogM_WriteCommand(EADOGM_CMD_SELECT_R0); // select row 0
}
if (row == 1) {
eaDogM_WriteCommand(EADOGM_CMD_SELECT_R1); // select row 1
}
eaDogM_WriteCommand(0b00101100); // turns on double line mode
// and set instruction table back to 0
}
// v2.01 moved functions to macros
#define eaDogM_DoubleHeightOff() eaDogM_WriteCommand(0b00101000)
#define eaDogM_Cls() eaDogM_WriteCommand(EADOGM_CMD_CLR)
#define eaDogM_CursorOn() eaDogM_WriteCommand(EADOGM_CMD_CURSOR_ON)
#define eaDogM_CursorOff() eaDogM_WriteCommand(EADOGM_CMD_CURSOR_OFF)
#define eaDogM_DisplayOn() eaDogM_WriteCommand(EADOGM_CMD_DISPLAY_ON)
#define eaDogM_DisplayOff() eaDogM_WriteCommand(EADOGM_CMD_DISPLAY_OFF)
void eaDogM_SetPos(int8 r, int8 c)
{
int8 cmdPos;
cmdPos = EADOGM_CMD_DDRAM_ADDR + (r * EADOGM_COLSPAN) + c;
eaDogM_WriteCommand(cmdPos);
}
void eaDogM_ClearRow(int8 r)
{
int8 i;
eaDogM_SetPos(r,0);
for(i=0; i<EADOGM_COLSPAN; i++) {
eaDogM_WriteChr(' ');
}
}
void eaDogM_WriteString(char *strPtr)
{
printf(eaDogM_WriteChr,"%s",strPtr);
}
// Optional DisGIE, set to 1 to disable interrupts
// v1.4 -- provided by Imaginos
void eaDogM_WriteStringAtPos(int8 r, int8 c, char *strPtr, int1 DisGIE=0)
{
if (DisGIE) {
disable_interrupts(GLOBAL);
}
eaDogM_WriteCommand((EADOGM_CMD_DDRAM_ADDR + (r * EADOGM_COLSPAN) + c));
printf(eaDogM_WriteChr,"%s",strPtr);
if (DisGIE) {
enable_interrupts(GLOBAL);
}
}
// Optional DisGIE, set to 1 to disable interrupts
// v1.4 -- provided by Imaginos
void eaDogM_WriteIntAtPos(int8 r, int8 c, int8 i, int1 DisGIE=0)
{
if (DisGIE) {
disable_interrupts(GLOBAL);
}
eaDogM_WriteCommand((EADOGM_CMD_DDRAM_ADDR + (r * EADOGM_COLSPAN) + c));
eaDogM_WriteChr(i/10+'0');
eaDogM_WriteChr(i%10+'0');
if (DisGIE) {
enable_interrupts(GLOBAL);
}
}
// this writes a byte to the internal CGRAM (v2.02)
// format for ndx: 00CCCRRR = CCC = character 0 to 7, RRR = row 0 to 7
void eaDogM_WriteByteToCGRAM(char ndx, char data)
{
unsigned int cmd;
cmd = ndx & 0b00111111; // mask off upper to bits
cmd = cmd | EADOGM_CMD_CGRAM_ADDR; // set bit cmd bits
eaDogM_WriteCommand(cmd);
eaDogM_WriteChr(data);
// this is done to make sure we are back in data mode
eaDogM_SetPos(0,0);
}
#endif
|
I tested the code and it works great in 4Bit, 8Bit and SPI SW (all running in 3.3V). I just didn't test the SPI HW mode. I tested with a PIC18F45K80 and a PIC18F45K20 (Pik Kit Demo Board, PCH Compiler).
Images:
https://db.tt/jDBSAIYz
https://db.tt/7XE3Egjd
_________________ Eng. Luciano Schirmer |
|
|
mbradley
Joined: 11 Jul 2009 Posts: 118 Location: California, USA
|
|
Posted: Sun Feb 09, 2014 11:12 pm |
|
|
That's awesome, I am happy to see someone add to it...
I will implement your changes into my main source, and give you credit as well!
main source:
http://www.mculabs.com/drivers/eadogm.html _________________ Michael Bradley
www.mculabs.com
Open Drivers and Projects |
|
|
luciano_schirmer
Joined: 09 Feb 2014 Posts: 2 Location: Brazil
|
|
Posted: Mon Feb 10, 2014 7:04 am |
|
|
I feel happy to contribute. Thanks for the credit.
I also noticed that the eaDogM_WriteCommand function needs a 1ms time between commands, but the eaDogM_WriteChr worked with as low as 5us, so I reduced the delay in my 4Bit mode to 10us. I think this reduced time may work with the other modes too.
This matters when you want to write a full 3x16 display in one single step without hanging your main loop for 48ms.
_________________ Eng. Luciano Schirmer |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|