initial cleanup and mapping
This commit is contained in:
673
devLib/lcd128x64.c
Normal file
673
devLib/lcd128x64.c
Normal file
@ -0,0 +1,673 @@
|
||||
/*
|
||||
* lcd128x64.c:
|
||||
* Graphics-based LCD driver.
|
||||
* This is designed to drive the parallel interface LCD drivers
|
||||
* based on the generic 12864H chips
|
||||
*
|
||||
* There are many variations on these chips, however they all mostly
|
||||
* seem to be similar.
|
||||
* This implementation has the Pins from the Pi hard-wired into it,
|
||||
* in particular wiringPi pins 0-7 so that we can use
|
||||
* digitalWriteByete() to speed things up somewhat.
|
||||
*
|
||||
* Copyright (c) 2013 Gordon Henderson.
|
||||
***********************************************************************
|
||||
* This file is part of wiringPi:
|
||||
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
||||
*
|
||||
* wiringPi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wiringPi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <wiringPi.h>
|
||||
|
||||
#include "font.h"
|
||||
#include "lcd128x64.h"
|
||||
|
||||
// Size
|
||||
|
||||
#define LCD_WIDTH 128
|
||||
#define LCD_HEIGHT 64
|
||||
|
||||
// Hardware Pins
|
||||
// Note pins 0-7 are the 8-bit data port
|
||||
|
||||
#define CS1 10
|
||||
#define CS2 11
|
||||
#define STROBE 12
|
||||
#define RS 13
|
||||
|
||||
// Software copy of the framebuffer
|
||||
// it's 8-bit deep although the display itself is only 1-bit deep.
|
||||
|
||||
static unsigned char frameBuffer [LCD_WIDTH * LCD_HEIGHT] ;
|
||||
|
||||
static int maxX, maxY ;
|
||||
static int lastX, lastY ;
|
||||
static int xOrigin, yOrigin ;
|
||||
static int lcdOrientation = 0 ;
|
||||
|
||||
/*
|
||||
* strobe:
|
||||
* Toggle the strobe (Really the "E") pin to the device.
|
||||
* According to the docs, data is latched on the falling edge.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void strobe (void)
|
||||
{
|
||||
digitalWrite (STROBE, 1) ; delayMicroseconds (1) ;
|
||||
digitalWrite (STROBE, 0) ; delayMicroseconds (5) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sentData:
|
||||
* Send an data or command byte to the display.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void sendData (const int data, const int chip)
|
||||
{
|
||||
digitalWrite (chip, 0) ;
|
||||
digitalWriteByte (data) ;
|
||||
strobe () ;
|
||||
digitalWrite (chip, 1) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sendCommand:
|
||||
* Send a command byte to the display
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void sendCommand (const int command, const int chip)
|
||||
{
|
||||
digitalWrite (RS, 0) ;
|
||||
sendData (command, chip) ;
|
||||
digitalWrite (RS, 1) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* setCol: SetLine:
|
||||
* Set the column and line addresses
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void setCol (int col, const int chip)
|
||||
{ sendCommand (0x40 | (col & 0x3F), chip) ; }
|
||||
|
||||
static void setLine (int line, const int chip)
|
||||
{ sendCommand (0xB8 | (line & 0x07), chip) ; }
|
||||
|
||||
|
||||
/*
|
||||
* lcd128x64update:
|
||||
* Copy our software version to the real display
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcd128x64update (void)
|
||||
{
|
||||
int line, x, y, fbLoc ;
|
||||
unsigned char byte ;
|
||||
|
||||
// Left side
|
||||
|
||||
for (line = 0 ; line < 8 ; ++line)
|
||||
{
|
||||
setCol (0, CS1) ;
|
||||
setLine (line, CS1) ;
|
||||
|
||||
for (x = 63 ; x >= 0 ; --x)
|
||||
{
|
||||
byte = 0 ;
|
||||
for (y = 0 ; y < 8 ; ++y)
|
||||
{
|
||||
fbLoc = x + (((7 - line) * 8) + (7 - y)) * LCD_WIDTH ;
|
||||
if (frameBuffer [fbLoc] != 0)
|
||||
byte |= (1 << y) ;
|
||||
}
|
||||
sendData (byte, CS1) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Right side
|
||||
|
||||
for (line = 0 ; line < 8 ; ++line)
|
||||
{
|
||||
setCol (0, CS2) ;
|
||||
setLine (line, CS2) ;
|
||||
|
||||
for (x = 127 ; x >= 64 ; --x)
|
||||
{
|
||||
byte = 0 ;
|
||||
for (y = 0 ; y < 8 ; ++y)
|
||||
{
|
||||
fbLoc = x + (((7 - line) * 8) + (7 - y)) * LCD_WIDTH ;
|
||||
if (frameBuffer [fbLoc] != 0)
|
||||
byte |= (1 << y) ;
|
||||
}
|
||||
sendData (byte, CS2) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcd128x64setOrigin:
|
||||
* Set the display offset origin
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcd128x64setOrigin (int x, int y)
|
||||
{
|
||||
xOrigin = x ;
|
||||
yOrigin = y ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcd128x64setOrientation:
|
||||
* Set the display orientation:
|
||||
* 0: Normal, the display is portrait mode, 0,0 is top left
|
||||
* 1: Landscape
|
||||
* 2: Portrait, flipped
|
||||
* 3: Landscape, flipped
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcd128x64setOrientation (int orientation)
|
||||
{
|
||||
lcdOrientation = orientation & 3 ;
|
||||
|
||||
lcd128x64setOrigin (0,0) ;
|
||||
|
||||
switch (lcdOrientation)
|
||||
{
|
||||
case 0:
|
||||
maxX = LCD_WIDTH ;
|
||||
maxY = LCD_HEIGHT ;
|
||||
break ;
|
||||
|
||||
case 1:
|
||||
maxX = LCD_HEIGHT ;
|
||||
maxY = LCD_WIDTH ;
|
||||
break ;
|
||||
|
||||
case 2:
|
||||
maxX = LCD_WIDTH ;
|
||||
maxY = LCD_HEIGHT ;
|
||||
break ;
|
||||
|
||||
case 3:
|
||||
maxX = LCD_HEIGHT ;
|
||||
maxY = LCD_WIDTH ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcd128x64orientCoordinates:
|
||||
* Adjust the coordinates given to the display orientation
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcd128x64orientCoordinates (int *x, int *y)
|
||||
{
|
||||
register int tmp ;
|
||||
|
||||
*x += xOrigin ;
|
||||
*y += yOrigin ;
|
||||
*y = maxY - *y - 1 ;
|
||||
|
||||
switch (lcdOrientation)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 1:
|
||||
tmp = maxY - *y - 1 ;
|
||||
*y = *x ;
|
||||
*x = tmp ;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*x = maxX - *x - 1 ;
|
||||
*y = maxY - *y - 1 ;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
*x = maxX - *x - 1 ;
|
||||
tmp = *y ;
|
||||
*y = *x ;
|
||||
*x = tmp ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcd128x64getScreenSize:
|
||||
* Return the max X & Y screen sizes. Needs to be called again, if you
|
||||
* change screen orientation.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcd128x64getScreenSize (int *x, int *y)
|
||||
{
|
||||
*x = maxX ;
|
||||
*y = maxY ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************
|
||||
* Standard Graphical Functions
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* lcd128x64point:
|
||||
* Plot a pixel.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcd128x64point (int x, int y, int colour)
|
||||
{
|
||||
lastX = x ;
|
||||
lastY = y ;
|
||||
|
||||
lcd128x64orientCoordinates (&x, &y) ;
|
||||
|
||||
if ((x < 0) || (x >= LCD_WIDTH) || (y < 0) || (y >= LCD_HEIGHT))
|
||||
return ;
|
||||
|
||||
frameBuffer [x + y * LCD_WIDTH] = colour ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcd128x64line: lcd128x64lineTo:
|
||||
* Classic Bressenham Line code
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcd128x64line (int x0, int y0, int x1, int y1, int colour)
|
||||
{
|
||||
int dx, dy ;
|
||||
int sx, sy ;
|
||||
int err, e2 ;
|
||||
|
||||
lastX = x1 ;
|
||||
lastY = y1 ;
|
||||
|
||||
dx = abs (x1 - x0) ;
|
||||
dy = abs (y1 - y0) ;
|
||||
|
||||
sx = (x0 < x1) ? 1 : -1 ;
|
||||
sy = (y0 < y1) ? 1 : -1 ;
|
||||
|
||||
err = dx - dy ;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
lcd128x64point (x0, y0, colour) ;
|
||||
|
||||
if ((x0 == x1) && (y0 == y1))
|
||||
break ;
|
||||
|
||||
e2 = 2 * err ;
|
||||
|
||||
if (e2 > -dy)
|
||||
{
|
||||
err -= dy ;
|
||||
x0 += sx ;
|
||||
}
|
||||
|
||||
if (e2 < dx)
|
||||
{
|
||||
err += dx ;
|
||||
y0 += sy ;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void lcd128x64lineTo (int x, int y, int colour)
|
||||
{
|
||||
lcd128x64line (lastX, lastY, x, y, colour) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcd128x64rectangle:
|
||||
* A rectangle is a spoilt days fishing
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcd128x64rectangle (int x1, int y1, int x2, int y2, int colour, int filled)
|
||||
{
|
||||
register int x ;
|
||||
|
||||
if (filled)
|
||||
{
|
||||
/**/ if (x1 == x2)
|
||||
lcd128x64line (x1, y1, x2, y2, colour) ;
|
||||
else if (x1 < x2)
|
||||
for (x = x1 ; x <= x2 ; ++x)
|
||||
lcd128x64line (x, y1, x, y2, colour) ;
|
||||
else
|
||||
for (x = x2 ; x <= x1 ; ++x)
|
||||
lcd128x64line (x, y1, x, y2, colour) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
lcd128x64line (x1, y1, x2, y1, colour) ;
|
||||
lcd128x64lineTo (x2, y2, colour) ;
|
||||
lcd128x64lineTo (x1, y2, colour) ;
|
||||
lcd128x64lineTo (x1, y1, colour) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcd128x64circle:
|
||||
* This is the midpoint circle algorithm.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcd128x64circle (int x, int y, int r, int colour, int filled)
|
||||
{
|
||||
int ddF_x = 1 ;
|
||||
int ddF_y = -2 * r ;
|
||||
|
||||
int f = 1 - r ;
|
||||
int x1 = 0 ;
|
||||
int y1 = r ;
|
||||
|
||||
if (filled)
|
||||
{
|
||||
lcd128x64line (x, y + r, x, y - r, colour) ;
|
||||
lcd128x64line (x + r, y, x - r, y, colour) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
lcd128x64point (x, y + r, colour) ;
|
||||
lcd128x64point (x, y - r, colour) ;
|
||||
lcd128x64point (x + r, y, colour) ;
|
||||
lcd128x64point (x - r, y, colour) ;
|
||||
}
|
||||
|
||||
while (x1 < y1)
|
||||
{
|
||||
if (f >= 0)
|
||||
{
|
||||
y1-- ;
|
||||
ddF_y += 2 ;
|
||||
f += ddF_y ;
|
||||
}
|
||||
x1++ ;
|
||||
ddF_x += 2 ;
|
||||
f += ddF_x ;
|
||||
if (filled)
|
||||
{
|
||||
lcd128x64line (x + x1, y + y1, x - x1, y + y1, colour) ;
|
||||
lcd128x64line (x + x1, y - y1, x - x1, y - y1, colour) ;
|
||||
lcd128x64line (x + y1, y + x1, x - y1, y + x1, colour) ;
|
||||
lcd128x64line (x + y1, y - x1, x - y1, y - x1, colour) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
lcd128x64point (x + x1, y + y1, colour) ; lcd128x64point (x - x1, y + y1, colour) ;
|
||||
lcd128x64point (x + x1, y - y1, colour) ; lcd128x64point (x - x1, y - y1, colour) ;
|
||||
lcd128x64point (x + y1, y + x1, colour) ; lcd128x64point (x - y1, y + x1, colour) ;
|
||||
lcd128x64point (x + y1, y - x1, colour) ; lcd128x64point (x - y1, y - x1, colour) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcd128x64ellipse:
|
||||
* Fast ellipse drawing algorithm by
|
||||
* John Kennedy
|
||||
* Mathematics Department
|
||||
* Santa Monica College
|
||||
* 1900 Pico Blvd.
|
||||
* Santa Monica, CA 90405
|
||||
* jrkennedy6@gmail.com
|
||||
* -Confirned in email this algorithm is in the public domain -GH-
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void plot4ellipsePoints (int cx, int cy, int x, int y, int colour, int filled)
|
||||
{
|
||||
if (filled)
|
||||
{
|
||||
lcd128x64line (cx + x, cy + y, cx - x, cy + y, colour) ;
|
||||
lcd128x64line (cx - x, cy - y, cx + x, cy - y, colour) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
lcd128x64point (cx + x, cy + y, colour) ;
|
||||
lcd128x64point (cx - x, cy + y, colour) ;
|
||||
lcd128x64point (cx - x, cy - y, colour) ;
|
||||
lcd128x64point (cx + x, cy - y, colour) ;
|
||||
}
|
||||
}
|
||||
|
||||
void lcd128x64ellipse (int cx, int cy, int xRadius, int yRadius, int colour, int filled)
|
||||
{
|
||||
int x, y ;
|
||||
int xChange, yChange, ellipseError ;
|
||||
int twoAsquare, twoBsquare ;
|
||||
int stoppingX, stoppingY ;
|
||||
|
||||
twoAsquare = 2 * xRadius * xRadius ;
|
||||
twoBsquare = 2 * yRadius * yRadius ;
|
||||
|
||||
x = xRadius ;
|
||||
y = 0 ;
|
||||
|
||||
xChange = yRadius * yRadius * (1 - 2 * xRadius) ;
|
||||
yChange = xRadius * xRadius ;
|
||||
|
||||
ellipseError = 0 ;
|
||||
stoppingX = twoBsquare * xRadius ;
|
||||
stoppingY = 0 ;
|
||||
|
||||
while (stoppingX >= stoppingY) // 1st set of points
|
||||
{
|
||||
plot4ellipsePoints (cx, cy, x, y, colour, filled) ;
|
||||
++y ;
|
||||
stoppingY += twoAsquare ;
|
||||
ellipseError += yChange ;
|
||||
yChange += twoAsquare ;
|
||||
|
||||
if ((2 * ellipseError + xChange) > 0 )
|
||||
{
|
||||
--x ;
|
||||
stoppingX -= twoBsquare ;
|
||||
ellipseError += xChange ;
|
||||
xChange += twoBsquare ;
|
||||
}
|
||||
}
|
||||
|
||||
x = 0 ;
|
||||
y = yRadius ;
|
||||
|
||||
xChange = yRadius * yRadius ;
|
||||
yChange = xRadius * xRadius * (1 - 2 * yRadius) ;
|
||||
|
||||
ellipseError = 0 ;
|
||||
stoppingX = 0 ;
|
||||
stoppingY = twoAsquare * yRadius ;
|
||||
|
||||
while (stoppingX <= stoppingY) //2nd set of points
|
||||
{
|
||||
plot4ellipsePoints (cx, cy, x, y, colour, filled) ;
|
||||
++x ;
|
||||
stoppingX += twoBsquare ;
|
||||
ellipseError += xChange ;
|
||||
xChange += twoBsquare ;
|
||||
|
||||
if ((2 * ellipseError + yChange) > 0 )
|
||||
{
|
||||
--y ;
|
||||
stoppingY -= twoAsquare ;
|
||||
ellipseError += yChange ;
|
||||
yChange += twoAsquare ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcd128x64putchar:
|
||||
* Print a single character to the screen
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcd128x64putchar (int x, int y, int c, int bgCol, int fgCol)
|
||||
{
|
||||
int y1, y2 ;
|
||||
|
||||
unsigned char line ;
|
||||
unsigned char *fontPtr ;
|
||||
|
||||
// Can't print if we're offscreen
|
||||
|
||||
//if ((x < 0) || (x >= (maxX - fontWidth)) || (y < 0) || (y >= (maxY - fontHeight)))
|
||||
// return ;
|
||||
|
||||
fontPtr = font + c * fontHeight ;
|
||||
|
||||
for (y1 = fontHeight - 1 ; y1 >= 0 ; --y1)
|
||||
{
|
||||
y2 = y + y1 ;
|
||||
line = *fontPtr++ ;
|
||||
lcd128x64point (x + 0, y2, (line & 0x80) == 0 ? bgCol : fgCol) ;
|
||||
lcd128x64point (x + 1, y2, (line & 0x40) == 0 ? bgCol : fgCol) ;
|
||||
lcd128x64point (x + 2, y2, (line & 0x20) == 0 ? bgCol : fgCol) ;
|
||||
lcd128x64point (x + 3, y2, (line & 0x10) == 0 ? bgCol : fgCol) ;
|
||||
lcd128x64point (x + 4, y2, (line & 0x08) == 0 ? bgCol : fgCol) ;
|
||||
lcd128x64point (x + 5, y2, (line & 0x04) == 0 ? bgCol : fgCol) ;
|
||||
lcd128x64point (x + 6, y2, (line & 0x02) == 0 ? bgCol : fgCol) ;
|
||||
lcd128x64point (x + 7, y2, (line & 0x01) == 0 ? bgCol : fgCol) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcd128x64puts:
|
||||
* Send a string to the display. Obeys \n and \r formatting
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcd128x64puts (int x, int y, const char *str, int bgCol, int fgCol)
|
||||
{
|
||||
int c, mx, my ;
|
||||
|
||||
mx = x ; my = y ;
|
||||
|
||||
while (*str)
|
||||
{
|
||||
c = *str++ ;
|
||||
|
||||
if (c == '\r')
|
||||
{
|
||||
mx = x ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
mx = x ;
|
||||
my -= fontHeight ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
lcd128x64putchar (mx, my, c, bgCol, fgCol) ;
|
||||
|
||||
mx += fontWidth ;
|
||||
if (mx >= (maxX - fontWidth))
|
||||
{
|
||||
mx = 0 ;
|
||||
my -= fontHeight ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcd128x64clear:
|
||||
* Clear the display to the given colour.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcd128x64clear (int colour)
|
||||
{
|
||||
register int i ;
|
||||
register unsigned char *ptr = frameBuffer ;
|
||||
|
||||
for (i = 0 ; i < (maxX * maxY) ; ++i)
|
||||
*ptr++ = colour ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* lcd128x64setup:
|
||||
* Initialise the display and GPIO.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int lcd128x64setup (void)
|
||||
{
|
||||
int i ;
|
||||
|
||||
for (i = 0 ; i < 8 ; ++i)
|
||||
pinMode (i, OUTPUT) ;
|
||||
|
||||
digitalWrite (CS1, 1) ;
|
||||
digitalWrite (CS2, 1) ;
|
||||
digitalWrite (STROBE, 0) ;
|
||||
digitalWrite (RS, 1) ;
|
||||
|
||||
pinMode (CS1, OUTPUT) ;
|
||||
pinMode (CS2, OUTPUT) ;
|
||||
pinMode (STROBE, OUTPUT) ;
|
||||
pinMode (RS, OUTPUT) ;
|
||||
|
||||
sendCommand (0x3F, CS1) ; // Display ON
|
||||
sendCommand (0xC0, CS1) ; // Set display start line to 0
|
||||
|
||||
sendCommand (0x3F, CS2) ; // Display ON
|
||||
sendCommand (0xC0, CS2) ; // Set display start line to 0
|
||||
|
||||
lcd128x64clear (0) ;
|
||||
lcd128x64setOrientation (0) ;
|
||||
lcd128x64update () ;
|
||||
|
||||
return 0 ;
|
||||
}
|
Reference in New Issue
Block a user