RPI fixes

This commit is contained in:
Larry Bank
2024-09-22 23:10:29 +01:00
parent e48de66aae
commit a35fb93709
7 changed files with 134 additions and 77 deletions
+16
View File
@@ -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
+14
View File
@@ -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
View File
@@ -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__
+10
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);