mirror of
https://github.com/usetrmnl/bb_epaper.git
synced 2026-04-29 13:43:26 -07:00
RPI fixes
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
CFLAGS=-D_LINUX_ -Wall -O2 -I../../
|
||||
LIBS=-lgpiod
|
||||
|
||||
all: hello_epaper
|
||||
|
||||
hello_epaper: main.o bb_epaper.o
|
||||
$(CXX) main.o bb_epaper.o $(LIBS) -o hello_epaper
|
||||
|
||||
main.o: main.cpp
|
||||
$(CXX) $(CFLAGS) -c main.cpp
|
||||
|
||||
bb_epaper.o: ../../../src/bb_epaper.cpp ../../../src/bb_epaper.h
|
||||
$(CXX) $(CFLAGS) -c ../../../src/bb_epaper.cpp
|
||||
|
||||
clean:
|
||||
rm -rf *.o hello_epaper
|
||||
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// C++ example for bb_epaper library
|
||||
// written by Larry Bank (bitbank@pobox.com)
|
||||
// Project started 9/23/2024
|
||||
// Copyright (c) 2024 BitBank Software, Inc.
|
||||
//
|
||||
#include "../../../src/bb_epaper.h"
|
||||
BBEPAPER bbep(EPD27_176x264); // Waveshare 2.7" e-paper HAT
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
return 0;
|
||||
} /* main() */
|
||||
|
||||
|
||||
+62
-70
@@ -17,8 +17,8 @@
|
||||
// Adapt these functions to whatever target platform you're using
|
||||
// and the rest of the code can remain unchanged
|
||||
//
|
||||
#ifndef __BB_EI_IO__
|
||||
#define __BB_EI_IO__
|
||||
#ifndef __BB_EP_IO__
|
||||
#define __BB_EP_IO__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@@ -31,17 +31,22 @@
|
||||
#include <linux/spi/spidev.h>
|
||||
#include <gpiod.h>
|
||||
#include <math.h>
|
||||
#ifndef CONSUMER
|
||||
#define CONSUMER "Consumer"
|
||||
#endif
|
||||
#define pgm_read_byte(a) *(uint8_t *)a
|
||||
#define memcpy_P memcpy
|
||||
struct gpiod_chip *chip = NULL;
|
||||
struct gpiod_line *lines[64];
|
||||
static int spi_fd; // SPI handle
|
||||
|
||||
void SPI_transfer(BBEIDISP *pBBEI, uint8_t *pBuf, int iLen)
|
||||
void SPI_transfer(BBEPDISP *pBBEP, uint8_t *pBuf, int iLen)
|
||||
{
|
||||
struct spi_ioc_transfer spi;
|
||||
memset(&spi, 0, sizeof(spi));
|
||||
spi.tx_buf = (unsigned long)pBuf;
|
||||
spi.len = iLen;
|
||||
spi.speed_hz = pBBEI->iSpeed;
|
||||
spi.speed_hz = pBBEP->iSpeed;
|
||||
spi.bits_per_word = 8;
|
||||
ioctl(spi_fd, SPI_IOC_MESSAGE(1), &spi);
|
||||
} /* SPI_transfer() */
|
||||
@@ -71,7 +76,7 @@ void pinMode(int iPin, int iMode)
|
||||
}
|
||||
} /* pinMode() */
|
||||
|
||||
static void delay(int iMS)
|
||||
void delay(int iMS)
|
||||
{
|
||||
usleep(iMS * 1000);
|
||||
} /* delay() */
|
||||
@@ -84,105 +89,92 @@ static void delayMicroseconds(int iMS)
|
||||
//
|
||||
// Initialize the GPIO pins and SPI for use by bb_eink
|
||||
//
|
||||
void bbeiInitIO(BBEIDISP *pBBEI, uint32_t u32Speed)
|
||||
void bbepInitIO(BBEPDISP *pBBEP, uint32_t u32Speed)
|
||||
{
|
||||
pinMode(pBBEI->iDCPin, OUTPUT);
|
||||
pinMode(pBBEI->iRSTPin, OUTPUT);
|
||||
digitalWrite(pBBEI->iRSTPin, LOW);
|
||||
char szName[32];
|
||||
|
||||
pinMode(pBBEP->iDCPin, OUTPUT);
|
||||
pinMode(pBBEP->iRSTPin, OUTPUT);
|
||||
digitalWrite(pBBEP->iRSTPin, LOW);
|
||||
delay(100);
|
||||
digitalWrite(pBBEI->iRSTPin, HIGH);
|
||||
digitalWrite(pBBEP->iRSTPin, HIGH);
|
||||
delay(100);
|
||||
if (pBBEI->iBUSYPin != 0xff) {
|
||||
pinMode(pBBEI->iBUSYPin, INPUT);
|
||||
if (pBBEP->iBUSYPin != 0xff) {
|
||||
pinMode(pBBEP->iBUSYPin, INPUT);
|
||||
}
|
||||
pBBEI->iSpeed = u32Speed;
|
||||
pinMode(pBBEI->iCSPin, OUTPUT);
|
||||
digitalWrite(pBBEI->iCSPin, HIGH); // we have to manually control the CS pin
|
||||
spi_fd = open("/dev/spidev0.1", O_RDWR); // DEBUG - open SPI channel 0
|
||||
} /* bbeiInitIO() */
|
||||
pBBEP->iSpeed = u32Speed;
|
||||
pinMode(pBBEP->iCSPin, OUTPUT);
|
||||
digitalWrite(pBBEP->iCSPin, HIGH); // we have to manually control the CS pin
|
||||
sprintf(szName, "/dev/spidev%d.0", pBBEP->iMOSIPin); // SPI channel #
|
||||
spi_fd = open(szName, O_RDWR);
|
||||
//spi_fd = open("/dev/spidev0.1", O_RDWR); // DEBUG - open SPI channel 0
|
||||
} /* bbepInitIO() */
|
||||
//
|
||||
// Toggle the reset line to wake up the eink from deep sleep
|
||||
//
|
||||
void bbeiWakeUp(BBEIDISP *pBBEI)
|
||||
void bbepWakeUp(BBEPDISP *pBBEP)
|
||||
{
|
||||
digitalWrite(pBBEI->iRSTPin, LOW);
|
||||
digitalWrite(pBBEP->iRSTPin, LOW);
|
||||
delay(10);
|
||||
digitalWrite(pBBEI->iRSTPin, HIGH);
|
||||
digitalWrite(pBBEP->iRSTPin, HIGH);
|
||||
delay(10);
|
||||
} /* bbeiWakeUp() */
|
||||
} /* bbepWakeUp() */
|
||||
//
|
||||
// Wait for the busy status line to show idle
|
||||
// The polarity of the busy signal is reversed on the UC81xx compared
|
||||
// to the SSD16xx controllers
|
||||
//
|
||||
void bbeiWaitBusy(BBEIDISP *pBBEI)
|
||||
void bbepWaitBusy(BBEPDISP *pBBEP)
|
||||
{
|
||||
uint8_t busy_idle = (pBBEI->chip_type == BBEI_CHIP_UC81xx) ? HIGH : LOW;
|
||||
uint8_t busy_idle = (pBBEP->chip_type == BBEP_CHIP_UC81xx) ? HIGH : LOW;
|
||||
delay(1); // some panels need a short delay before testing the BUSY line
|
||||
while (1) {
|
||||
if (digitalRead(pBBEI->iBUSYPin) == busy_idle) break;
|
||||
if (digitalRead(pBBEP->iBUSYPin) == busy_idle) break;
|
||||
}
|
||||
} /* bbeiWaitBusy() */
|
||||
} /* bbepWaitBusy() */
|
||||
//
|
||||
// Convenience function to write a command byte along with a data
|
||||
// byte (it's single parameter)
|
||||
//
|
||||
void bbeiCMD2(BBEIDISP *pBBEI, uint8_t cmd1, uint8_t cmd2)
|
||||
void bbepCMD2(BBEPDISP *pBBEP, uint8_t cmd1, uint8_t cmd2)
|
||||
{
|
||||
if (!pBBEI->is_awake) {
|
||||
if (!pBBEP->is_awake) {
|
||||
// if it's asleep, it can't receive commands
|
||||
bbeiWakeUp(pBBEI);
|
||||
pBBEI->is_awake = 1;
|
||||
bbepWakeUp(pBBEP);
|
||||
pBBEP->is_awake = 1;
|
||||
}
|
||||
digitalWrite(pBBEI->iDCPin, LOW);
|
||||
digitalWrite(pBBEI->iCSPin, LOW);
|
||||
SPI_transfer(pBBEI, &cmd1, 1);
|
||||
digitalWrite(pBBEI->iDCPin, HIGH);
|
||||
SPI_transfer(pBBEI, &cmd2, 1); // second byte is data
|
||||
digitalWrite(pBBEI->iCSPin, HIGH);
|
||||
digitalWrite(pBBEI->iDCPin, HIGH); // leave data mode as the default
|
||||
} /* bbeiCMD2() */
|
||||
digitalWrite(pBBEP->iDCPin, LOW);
|
||||
digitalWrite(pBBEP->iCSPin, LOW);
|
||||
SPI_transfer(pBBEP, &cmd1, 1);
|
||||
digitalWrite(pBBEP->iDCPin, HIGH);
|
||||
SPI_transfer(pBBEP, &cmd2, 1); // second byte is data
|
||||
digitalWrite(pBBEP->iCSPin, HIGH);
|
||||
digitalWrite(pBBEP->iDCPin, HIGH); // leave data mode as the default
|
||||
} /* bbepCMD2() */
|
||||
//
|
||||
// Write a single byte as a COMMAND (D/C set low)
|
||||
//
|
||||
void bbeiWriteCmd(BBEIDISP *pBBEI, uint8_t cmd)
|
||||
void bbepWriteCmd(BBEPDISP *pBBEP, uint8_t cmd)
|
||||
{
|
||||
if (!pBBEI->is_awake) {
|
||||
if (!pBBEP->is_awake) {
|
||||
// if it's asleep, it can't receive commands
|
||||
bbeiWakeUp(pBBEI);
|
||||
pBBEI->is_awake = 1;
|
||||
bbepWakeUp(pBBEP);
|
||||
pBBEP->is_awake = 1;
|
||||
}
|
||||
digitalWrite(pBBEI->iDCPin, LOW);
|
||||
digitalWrite(pBBEI->iCSPin, LOW);
|
||||
SPI_transfer(pBBEI, &cmd, 1);
|
||||
digitalWrite(pBBEI->iCSPin, HIGH);
|
||||
digitalWrite(pBBEI->iDCPin, HIGH); // leave data mode as the default
|
||||
} /* bbeiWriteCmd() */
|
||||
//
|
||||
// Put the eink into light or deep sleep
|
||||
//
|
||||
void bbeiSleep(BBEIDISP *pBBEI, int bDeep)
|
||||
{
|
||||
if (pBBEI->chip_type == BBEI_CHIP_UC81xx) {
|
||||
bbeiCMD2(pBBEI, UC8151_CDI, 0x17); // border floating
|
||||
bbeiWriteCmd(pBBEI, UC8151_POFF); // power off
|
||||
bbeiWaitBusy(pBBEI);
|
||||
if (bDeep) {
|
||||
bbeiCMD2(pBBEI, UC8151_DSLP, 0xa5); // deep sleep
|
||||
}
|
||||
} else {
|
||||
bbeiCMD2(pBBEI, SSD1608_DEEP_SLEEP, (bDeep) ? 0x02 : 0x01); // deep sleep mode 1 keeps RAM, mode 2 loses RAM
|
||||
}
|
||||
pBBEI->is_awake = 0;
|
||||
} /* bbeiSleep() */
|
||||
digitalWrite(pBBEP->iDCPin, LOW);
|
||||
digitalWrite(pBBEP->iCSPin, LOW);
|
||||
SPI_transfer(pBBEP, &cmd, 1);
|
||||
digitalWrite(pBBEP->iCSPin, HIGH);
|
||||
digitalWrite(pBBEP->iDCPin, HIGH); // leave data mode as the default
|
||||
} /* bbepWriteCmd() */
|
||||
//
|
||||
// Write 1 or more bytes as DATA (D/C set high)
|
||||
//
|
||||
void bbeiWriteData(BBEIDISP *pBBEI, uint8_t *pData, int iLen)
|
||||
void bbepWriteData(BBEPDISP *pBBEP, uint8_t *pData, int iLen)
|
||||
{
|
||||
digitalWrite(pBBEI->iCSPin, LOW);
|
||||
SPI_transfer(pBBEI, pData, iLen);
|
||||
digitalWrite(pBBEI->iCSPin, HIGH);
|
||||
} /* bbeiWriteData() */
|
||||
digitalWrite(pBBEP->iCSPin, LOW);
|
||||
SPI_transfer(pBBEP, pData, iLen);
|
||||
digitalWrite(pBBEP->iCSPin, HIGH);
|
||||
} /* bbepWriteData() */
|
||||
|
||||
#endif // __BB_EI_IO__
|
||||
#endif // __BB_EP_IO__
|
||||
|
||||
@@ -587,6 +587,15 @@ const uint8_t epd266_init_sequence_full[] PROGMEM =
|
||||
0x00 // end of table
|
||||
}; /* epd266_init_sequence_full[] */
|
||||
|
||||
const uint8_t epd27_ws_init_sequence_full[] = {
|
||||
1, UC8151_PON,
|
||||
BUSY_WAIT,
|
||||
3, 0x00, 0x1f, 0x0b, // panel setting
|
||||
5, UC8151_TRES, 0x01, 0x08, 0x00, 0xb0,
|
||||
2, 0x50, 0x97, // VCOM
|
||||
0
|
||||
};
|
||||
|
||||
const uint8_t epd266_init_sequence_part[] PROGMEM =
|
||||
{
|
||||
0x02, 0x11, 0x03,
|
||||
@@ -960,6 +969,7 @@ const EPD_PANEL panelDefs[] PROGMEM = {
|
||||
{400, 300, epd42r_init_sequence_full, NULL, NULL, BBEP_3COLOR, BBEP_CHIP_SSD16xx}, // EPD42R_400x300
|
||||
{400, 300, epd42r2_init_sequence_full, NULL, NULL, BBEP_3COLOR, BBEP_CHIP_UC81xx}, // EPD42R2_400x300
|
||||
{240, 416, epd37_init_sequence_full, NULL, epd37_init_sequence_part, 0, BBEP_CHIP_UC81xx}, // EPD37_240x416
|
||||
{176, 264, epd27_ws_init_sequence_full, NULL, NULL, BBEP_CS_EVERY_BYTE, BBEP_CHIP_UC81xx}, // EPD27_176x264 Waveshare 2.7" e-paper HAT
|
||||
};
|
||||
int bbepSetPanelType(BBEPDISP *pBBEP, int iPanel)
|
||||
{
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
//
|
||||
#ifndef __BB_EP_GFX__
|
||||
#define __BB_EP_GFX__
|
||||
#include <Group5.h>
|
||||
#include "Group5.h"
|
||||
#include "g5dec.inl"
|
||||
#include "bb_font.h"
|
||||
static G5DECIMAGE g5dec;
|
||||
|
||||
+23
-5
@@ -20,10 +20,9 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
// convert wire library constants into ArmbianIO values
|
||||
#define OUTPUT GPIO_OUT
|
||||
#define INPUT GPIO_IN
|
||||
#define INPUT_PULLUP GPIO_IN_PULLUP
|
||||
#define OUTPUT 0
|
||||
#define INPUT 1
|
||||
#define INPUT_PULLUP 2
|
||||
#define HIGH 1
|
||||
#define LOW 0
|
||||
void delay(int);
|
||||
@@ -32,7 +31,11 @@ void delay(int);
|
||||
#endif // _LINUX_
|
||||
|
||||
#include "bb_epaper.h"
|
||||
#ifdef _LINUX_
|
||||
#include "rpi_io.inl"
|
||||
#else
|
||||
#include "arduino_io.inl" // I/O (non-portable) code is in here
|
||||
#endif
|
||||
#include "bb_ep.inl" // All of the display interface code is in here
|
||||
#include "bb_ep_gfx.inl" // drawing code
|
||||
#include "bb_font.h" // bitbank compressed font info
|
||||
@@ -57,6 +60,7 @@ void BBEPAPER::setAddrWindow(int x, int y, int w, int h)
|
||||
bbepSetAddrWindow(&_bbep, x, y, w, h);
|
||||
}
|
||||
|
||||
#ifdef ARDUINO
|
||||
void BBEPAPER::initIO(int iDC, int iReset, int iBusy, int iCS, int iMOSI, int iSCLK, uint32_t u32Speed)
|
||||
{
|
||||
_bbep.iCSPin = iCS;
|
||||
@@ -69,7 +73,19 @@ void BBEPAPER::initIO(int iDC, int iReset, int iBusy, int iCS, int iMOSI, int iS
|
||||
bbepWakeUp(&_bbep);
|
||||
bbepSendCMDSequence(&_bbep, _bbep.pInitFull);
|
||||
} /* initIO() */
|
||||
|
||||
#else // Linux
|
||||
void BBEPAPER::initIO(int iDC, int iReset, int iBusy, int iCS, int iSPIChannel, uint32_t u32Speed)
|
||||
{
|
||||
_bbep.iCSPin = iCS;
|
||||
_bbep.iDCPin = iDC;
|
||||
_bbep.iBUSYPin = iBusy;
|
||||
_bbep.iRSTPin = iReset;
|
||||
_bbep.iMOSIPin = iSPIChannel;
|
||||
bbepInitIO(&_bbep, u32Speed);
|
||||
bbepWakeUp(&_bbep);
|
||||
bbepSendCMDSequence(&_bbep, _bbep.pInitFull);
|
||||
} /* initIO() */
|
||||
#endif
|
||||
int BBEPAPER::writePlane(int iPlane)
|
||||
{
|
||||
return bbepWritePlane(&_bbep, iPlane);
|
||||
@@ -388,10 +404,12 @@ void BBEPAPER::getTextBounds(const char *string, int16_t x, int16_t y, int16_t *
|
||||
*h = (bottom - top + 1);
|
||||
}
|
||||
}
|
||||
#ifdef ARDUINO
|
||||
void BBEPAPER::getTextBounds(const String &str, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h)
|
||||
{
|
||||
getTextBounds(str.c_str(), x, y, x1, y1, w, h);
|
||||
}
|
||||
#endif
|
||||
int BBEPAPER::dataTime(void)
|
||||
{
|
||||
return _bbep.iDataTime;
|
||||
|
||||
+8
-1
@@ -24,6 +24,7 @@
|
||||
#define OCT 8
|
||||
#define BIN 2
|
||||
#define PROGMEM
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@@ -102,6 +103,7 @@ enum {
|
||||
EPD42R_400x300,
|
||||
EPD42R2_400x300, // GDEQ042Z21
|
||||
EPD37_240x416, // GDEY037T03
|
||||
EPD27_176x264, // Waveshare 2.7" e-paper HAT
|
||||
EPD_PANEL_COUNT
|
||||
};
|
||||
#ifdef FUTURE
|
||||
@@ -119,7 +121,6 @@ enum {
|
||||
EPD154Y_152x152, // DEPG0154YN
|
||||
EPD154_200x200, // waveshare
|
||||
EPD154B_200x200, // DEPG01540BN
|
||||
EPD27_176x264, // waveshare
|
||||
EPD266B_152x296, // DEPG0266BN
|
||||
EPD266Y_152x296, // DEPG0266YN
|
||||
EPD31R_168x296, // DEPG0310RW
|
||||
@@ -279,7 +280,11 @@ class BBEPAPER
|
||||
public:
|
||||
BBEPAPER(int iPanel);
|
||||
void setAddrWindow(int x, int y, int w, int h);
|
||||
#ifdef ARDUINO
|
||||
void initIO(int iDC, int iReset, int iBusy, int iCS = SS, int iMOSI = MOSI, int iSCLK = SCK, uint32_t u32Speed = 8000000);
|
||||
#else
|
||||
void initIO(int iDC, int iReset, int iBusy, int iCS, int iSPIChannel, uint32_t u32Speed = 8000000);
|
||||
#endif
|
||||
int writePlane(int iPlane = PLANE_DUPLICATE);
|
||||
void startWrite(int iPlane);
|
||||
void writeData(uint8_t *pData, int iLen);
|
||||
@@ -307,7 +312,9 @@ class BBEPAPER
|
||||
int16_t getCursorX(void);
|
||||
int16_t getCursorY(void);
|
||||
void getTextBounds(const char *string, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
|
||||
#ifdef ARDUINO
|
||||
void getTextBounds(const String &str, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
|
||||
#endif
|
||||
int dataTime();
|
||||
int opTime();
|
||||
int16_t height(void);
|
||||
|
||||
Reference in New Issue
Block a user