mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
99 lines
2.8 KiB
C
99 lines
2.8 KiB
C
/*
|
|
* This file is part of Espruino, a JavaScript interpreter for Microcontrollers
|
|
*
|
|
* Copyright (C) 2013 Gordon Williams <gw@pur3.co.uk>
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
* Graphics Backend for drawing to simple black and white SPI displays
|
|
* (PCD8544 - Nokia 5110 LCD)
|
|
* FIXME: UNFINISHED
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "platform_config.h"
|
|
#include "jsutils.h"
|
|
#include "lcd.h"
|
|
|
|
#define LCD_WIDTH 84
|
|
#define LCD_HEIGHT 48
|
|
|
|
typedef struct {
|
|
unsigned char changeX1,changeY1,changeX2,changeY2;
|
|
unsigned char pixels[LCD_WIDTH*LCD_HEIGHT/8];
|
|
} LCDDataPCD8544 PACKED_FLAGS;
|
|
|
|
unsigned int lcdGetPixel_PCD8544(JsGraphics *gfx, short x, short y) {
|
|
int yp = y>>3;
|
|
int addr = x + (yp*gfx->data.width);
|
|
return (pixels[addr]>>(y&7)) & 1;
|
|
}
|
|
|
|
|
|
void lcdSetPixel_PCD8544(JsGraphics *gfx, short x, short y, unsigned int col) {
|
|
int yp = y>>3;
|
|
int addr = x + (yp*gfx->data.width);
|
|
if (col) pixels[addr] |= 1<<(y&7);
|
|
else pixels[addr] &= ~(1<<(y&7));
|
|
if (x<changeX1) changeX1=x;
|
|
if (y<changeY1) changeY1=y;
|
|
if (x>changeX2) changeX2=x;
|
|
if (y>changeY2) changeY2=y;
|
|
}
|
|
|
|
void lcdIdle_PCD8544(JsGraphics *gfx) {
|
|
if (changeX1>=changeX2 && changeY1>=changeY2) {
|
|
// write...
|
|
int cy1 = changeY1 >> 3;
|
|
int cy2 = changeY2 >> 3;
|
|
int x,y;
|
|
jshPinOutput(CE, 0);
|
|
for (y=cy1;y<=cy2;y++) {
|
|
jshPinOutput(DC, 0); // command
|
|
jshSPISend(dev, 0x40 | y); // Y addr
|
|
jshSPISend(dev, 0x80); // X addr
|
|
jshPinOutput(DC, 1); // data
|
|
for (x=changeX1;x<=changeX2;x++)
|
|
jshSPISend(dev, pixels[x+y*LCD_WIDTH]);
|
|
}
|
|
jshPinOutput(DC, 0); // command
|
|
jshSPISend(dev, 0x40); // reset?
|
|
jshPinOutput(CE, 1);
|
|
|
|
changeX1 = LCD_WIDTH;
|
|
changeY1 = LCD_HEIGHT;
|
|
changeX2 = 0;
|
|
changeY2 = 0;
|
|
}
|
|
}
|
|
|
|
void lcdInit_PCD8544(JsGraphics *gfx) {
|
|
assert(gfx->data.bpp == 1);
|
|
|
|
IOEventFlags dev = EV_SPI1;
|
|
jshPinOutput(CE, 0);
|
|
// pulse reset 10ms?
|
|
jshPinOutput(DC, 0); // command
|
|
jshSPISend(dev, 0x21); // fnset extended
|
|
jshSPISend(dev, 0x80 | 0x40); // setvop (experiment with 2nd val to get the right contrast)
|
|
jshSPISend(dev, 0x14); // setbias 4
|
|
jshSPISend(dev, 0x04 | 0x02); // temp control
|
|
jshSPISend(dev, 0x20); // fnset normal
|
|
jshSPISend(dev, 0x08 | 0x04); // dispctl normal
|
|
jshPinOutput(CE, 1);
|
|
}
|
|
|
|
void lcdSetCallbacks_PCD8544(JsGraphics *gfx) {
|
|
gfx->data.width = LCD_WIDTH;
|
|
gfx->data.height = LCD_HEIGHT;
|
|
gfx->data.bpp = 1;
|
|
gfx->setPixel = lcdSetPixel_PCD8544;
|
|
gfx->getPixel = lcdGetPixel_PCD8544;
|
|
gfx->idle = lcdIdle_PCD8544;
|
|
|
|
}
|
|
|