Browse Source

LCD driver: change header macros to enums; polled SPI call for sendCommand; added drawRect

ChibiOS
Zack Marvel 2 years ago
parent
commit
c5d1704fff
2 changed files with 72 additions and 39 deletions
  1. +25
    -27
      include/LCD5110.h
  2. +47
    -12
      src/LCD5110.c

+ 25
- 27
include/LCD5110.h View File

@@ -3,44 +3,48 @@
#include "ch.h"
#include "hal.h"

#define LCD5110_FUNC_SET 0x20
#define LCD5110_WIDTH 84
#define LCD5110_HEIGHT 48

#define LCD5110_FUNC_SET (1 << 5)
#define LCD5110_FUNC_MASK 0x07
/* PD: 0=active, 1=power-down mode */
#define LCD5110_FUNC_PD_MASK (1 << 2)
#define LCD5110_FUNC_ACTIVE 0
#define LCD5110_FUNC_POWERDOWN (1 << 2)
typedef enum {
LCD5110_POWER_MODE_ACTIVE = LCD5110_FUNC_ACTIVE,
LCD5110_POWER_MODE_POWERDOWN = LCD5110_FUNC_POWERDOWN,
LCD5110_POWER_MODE_ACTIVE = 0,
LCD5110_POWER_MODE_POWERDOWN = (1 << 2),
} LCD5110PowerMode;
/* 0=horizontal, 1=vertical addressing */
#define LCD5110_FUNC_ADDR_MASK (1 << 1)
#define LCD5110_FUNC_ADDR_H 0
#define LCD5110_FUNC_ADDR_V (1 << 1)
typedef enum {
LCD5110_ADDR_HORIZ = LCD5110_FUNC_ADDR_H,
LCD5110_ADDR_VERT = LCD5110_FUNC_ADDR_V,
LCD5110_ADDR_HORIZ = 0,
LCD5110_ADDR_VERT = (1 << 1),
} LCD5110AddressMode;
/* 0=basic mode, 1=extended mode */
#define LCD5110_FUNC_MODE (1 << 0)
#define LCD5110_FUNC_MODE_BASIC 0
#define LCD5110_FUNC_MODE_EXT (1 << 0)
#define LCD5110_FUNC_MODE_MASK (1 << 0)
typedef enum {
LCD5110_INSTR_MODE_BASIC = LCD5110_FUNC_MODE_BASIC,
LCD5110_INSTR_MODE_EXT = LCD5110_FUNC_MODE_EXT,
LCD5110_INSTR_MODE_BASIC = 0,
LCD5110_INSTR_MODE_EXT = (1 << 0),
} LCD5110InstrMode;


/* Basic mode commands */

#define LCD5110_DISPLAY_CNTL 0x08
#define LCD5110_DISPLAY_CNTL (1 << 3)
#define LCD5110_DISPLAY_CNTL_MASK 0x05
#define LCD5110_DISPLAY_BLANK 0x00
#define LCD5110_DISPLAY_NORMAL 0x04
#define LCD5110_DISPLAY_ALL_ON 0x01
#define LCD5110_DISPLAY_INVERSE 0x05
typedef enum {
LCD5110_DISPLAY_MODE_BLANK = 0x00,
LCD5110_DISPLAY_MODE_NORMAL = 0x04,
LCD5110_DISPLAY_MODE_ALL_ON = 0x01,
LCD5110_DISPLAY_MODE_INVERSE = 0x05,
} LCD5110DisplayMode;


#define LCD5110_Y_ADDR 0x40
#define LCD5110_X_ADDR 0x80
#define LCD5110_Y_ADDR (1 << 6)
#define LCD5110_Y_ADDR_MASK 0x07
#define LCD5110_X_ADDR (1 << 7)
#define LCD5110_X_ADDR_MASK 0x3f


/* Extended mode commands */
@@ -48,6 +52,7 @@ typedef enum {
/* Temperature coefficient */
#define LCD5110_TEMP_MASK 0x03
#define LCD5110_TEMP (1 << 2)

#define LCD5110_BIAS_MASK 0x07
#define LCD5110_BIAS (1 << 4)

@@ -55,13 +60,6 @@ typedef enum {
#define LCD5110_VOP_MASK 0x7f


typedef enum {
LCD5110_DISPLAY_MODE_BLANK = 0x00,
LCD5110_DISPLAY_MODE_NORMAL = 0x04,
LCD5110_DISPLAY_MODE_ALL_ON = 0x01,
LCD5110_DISPLAY_MODE_INVERSE = 0x05,
} LCD5110DisplayMode;

typedef struct {
uint8_t x;
uint8_t y;


+ 47
- 12
src/LCD5110.c View File

@@ -1,29 +1,27 @@

#include <string.h>
#include "LCD5110.h"
#include "pins.h"


void LCD5110_sendCommand(uint8_t cmd) {
spiAcquireBus(&SPID1);
spiSelect(&SPID1);
palClearLine(LCD5110_LINE_DC);
spiSelect(&SPID1);

//spiPolledExchange(dev->spid, cmd);
spiSend(&SPID1, 1, &cmd);
spiPolledExchange(&SPID1, cmd);

palSetLine(LCD5110_LINE_DC);
spiUnselect(&SPID1);
spiReleaseBus(&SPID1);
}

void LCD5110_sendData(size_t n, uint8_t *data) {
spiAcquireBus(&SPID1);
spiSelect(&SPID1);
palSetLine(LCD5110_LINE_DC);
spiSelect(&SPID1);

spiSend(&SPID1, n, data);

palClearLine(LCD5110_LINE_DC);
spiUnselect(&SPID1);
spiReleaseBus(&SPID1);
}
@@ -44,7 +42,7 @@ void LCD5110_setDisplayMode(LCD5110DisplayMode mode) {
}

void LCD5110_setAddressMode(LCD5110AddressMode mode) {
LCD5110_sendCommand(LCD5110_DISPLAY_CNTL | mode);
LCD5110_sendCommand(LCD5110_FUNC_SET | mode);
}

void LCD5110_setRow(uint32_t row) {
@@ -68,7 +66,17 @@ void LCD5110_setColumn(uint32_t col) {
/* data should contain width*(height/8) bytes */

void LCD5110_draw(Rect box, uint8_t *data) {
for (int i = 0, bank = box.y; bank < box.y + box.height; i += box.width, bank += 8) {
/* We can take advantage of address auto-increment if box is screen width */
if (box.width == LCD5110_WIDTH) {
LCD5110_setRow(box.y);
LCD5110_setColumn(box.x);
LCD5110_sendData(box.width*box.height/8, data);
return;
}

for (int i = 0, bank = box.y;
bank < box.y + box.height;
i += box.width, bank += 8) {
LCD5110_setRow(bank);
LCD5110_setColumn(box.x);

@@ -76,14 +84,41 @@ void LCD5110_draw(Rect box, uint8_t *data) {
}
}

const uint8_t rectRow[84] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
void LCD5110_drawRect(Rect box) {
/* We can take advantage of address auto-increment if box is screen width */
if (box.width == LCD5110_WIDTH) {
LCD5110_setRow(box.y);
LCD5110_setColumn(box.x);
LCD5110_sendData(box.width*box.height/8, (uint8_t *)rectRow);
return;
}

for (int i = 0, bank = box.y;
bank < box.y + box.height;
i += box.width, bank += 8) {
LCD5110_setRow(bank);
LCD5110_setColumn(box.x);

LCD5110_sendData(box.width, (uint8_t *)rectRow);
}
}

void LCD5110_blank(void) {
uint8_t row[84];
for (int i = 0; i < 84; i++)
row[i] = 0;
memset(row, 0, 84);

LCD5110_setRow(0);
LCD5110_setColumn(0);
for (int bank = 0; bank < 6; bank++) {
LCD5110_setRow(bank*8);
LCD5110_setColumn(0);
LCD5110_sendData(84, row);
}
}


Loading…
Cancel
Save