refactor epd driver

This commit is contained in:
Shuanglei Tao
2025-03-05 18:05:03 +08:00
parent cc9d757aeb
commit 38eac07f99
3 changed files with 146 additions and 98 deletions

View File

@@ -13,8 +13,11 @@
******************************************************************************/
#include "app_error.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include "nrf_drv_spi.h"
#include "EPD_driver.h"
#include "nrf_log.h"
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
@@ -30,62 +33,69 @@ uint32_t EPD_EN_PIN = 0xFF;
#define SPI_INSTANCE 0 /**< SPI instance index. */
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */
extern epd_driver_t epd_driver_4in2;
extern epd_driver_t epd_driver_4in2bv2;
/** EPD drivers */
static epd_driver_t *epd_drivers[] = {
&epd_driver_4in2,
&epd_driver_4in2bv2,
};
/**< current EPD driver */
static epd_driver_t *m_driver = NULL;
epd_driver_t *epd_driver_get(void)
void pinMode(uint32_t pin, uint32_t mode)
{
if (m_driver == NULL)
m_driver = epd_drivers[0];
return m_driver;
switch (mode)
{
case INPUT:
nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_NOPULL);
break;
case INPUT_PULLUP:
nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_PULLUP);
break;
case INPUT_PULLDOWN:
nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_PULLDOWN);
break;
case OUTPUT:
nrf_gpio_cfg_output(pin);
break;
default:
break;
}
}
epd_driver_t *epd_driver_by_id(uint8_t id)
void digitalWrite(uint32_t pin, uint32_t value)
{
for (uint8_t i = 0; i < ARRAY_SIZE(epd_drivers); i++)
{
if (epd_drivers[i]->id == id)
{
return epd_drivers[i];
}
}
return NULL;
if (value == LOW)
nrf_gpio_pin_clear(pin);
else
nrf_gpio_pin_set(pin);
}
bool epd_driver_set(uint8_t id)
uint32_t digitalRead(uint32_t pin)
{
epd_driver_t *driver = epd_driver_by_id(id);
if (driver )
{
m_driver = driver;
return true;
}
return false;
#if defined(S112)
nrf_gpio_pin_dir_t dir = nrf_gpio_pin_dir_get(pin);
#else
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin);
nrf_gpio_pin_dir_t dir = (nrf_gpio_pin_dir_t)((reg->PIN_CNF[pin] &
GPIO_PIN_CNF_DIR_Msk) >> GPIO_PIN_CNF_DIR_Pos);
#endif
if (dir == NRF_GPIO_PIN_DIR_INPUT)
return nrf_gpio_pin_read(pin);
else
return nrf_gpio_pin_out_read(pin);
}
void delay(uint32_t ms)
{
nrf_delay_ms(ms);
}
void DEV_Module_Init(void)
{
nrf_gpio_cfg_output(EPD_CS_PIN);
nrf_gpio_cfg_output(EPD_DC_PIN);
nrf_gpio_cfg_output(EPD_RST_PIN);
nrf_gpio_cfg_input(EPD_BUSY_PIN, NRF_GPIO_PIN_NOPULL);
pinMode(EPD_CS_PIN, OUTPUT);
pinMode(EPD_DC_PIN, OUTPUT);
pinMode(EPD_RST_PIN, OUTPUT);
pinMode(EPD_BUSY_PIN, INPUT);
if (EPD_EN_PIN != 0xFF) {
nrf_gpio_cfg_output(EPD_EN_PIN);
DEV_Digital_Write(EPD_EN_PIN, 1);
pinMode(EPD_EN_PIN, OUTPUT);
digitalWrite(EPD_EN_PIN, HIGH);
}
nrf_gpio_cfg_output(EPD_BS_PIN);
DEV_Digital_Write(EPD_BS_PIN, 0);
pinMode(EPD_BS_PIN, OUTPUT);
digitalWrite(EPD_BS_PIN, LOW);
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
spi_config.sck_pin = EPD_SCLK_PIN;
@@ -97,16 +107,16 @@ void DEV_Module_Init(void)
APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, NULL));
#endif
DEV_Digital_Write(EPD_DC_PIN, 0);
DEV_Digital_Write(EPD_CS_PIN, 0);
DEV_Digital_Write(EPD_RST_PIN, 1);
digitalWrite(EPD_DC_PIN, LOW);
digitalWrite(EPD_CS_PIN, LOW);
digitalWrite(EPD_RST_PIN, HIGH);
}
void DEV_Module_Exit(void)
{
DEV_Digital_Write(EPD_DC_PIN, 0);
DEV_Digital_Write(EPD_CS_PIN, 0);
DEV_Digital_Write(EPD_RST_PIN, 0);
digitalWrite(EPD_DC_PIN, LOW);
digitalWrite(EPD_CS_PIN, LOW);
digitalWrite(EPD_RST_PIN, LOW);
nrf_drv_spi_uninit(&spi);
}
@@ -123,18 +133,81 @@ void DEV_SPI_WriteBytes(uint8_t *value, uint8_t len)
void EPD_WriteCommand(uint8_t Reg)
{
DEV_Digital_Write(EPD_DC_PIN, 0);
digitalWrite(EPD_DC_PIN, LOW);
DEV_SPI_WriteByte(Reg);
}
void EPD_WriteByte(uint8_t Data)
{
DEV_Digital_Write(EPD_DC_PIN, 1);
digitalWrite(EPD_DC_PIN, HIGH);
DEV_SPI_WriteByte(Data);
}
void EPD_WriteData(uint8_t *Data, uint8_t Len)
{
DEV_Digital_Write(EPD_DC_PIN, 1);
digitalWrite(EPD_DC_PIN, HIGH);
DEV_SPI_WriteBytes(Data, Len);
}
void EPD_Reset(uint32_t value, uint16_t duration)
{
uint32_t rvalue = (value == LOW) ? HIGH : LOW;
digitalWrite(EPD_RST_PIN, value);
delay(10);
digitalWrite(EPD_RST_PIN, rvalue);
delay(duration);
digitalWrite(EPD_RST_PIN, value);
delay(duration);
}
void EPD_WaitBusy(uint32_t value, uint16_t timeout)
{
NRF_LOG_DEBUG("[EPD]: check busy");
while (digitalRead(EPD_BUSY_PIN) == value) {
delay(1);
timeout--;
if (timeout == 0) {
NRF_LOG_DEBUG("[EPD]: busy timeout!");
break;
}
}
NRF_LOG_DEBUG("[EPD]: busy release");
}
extern epd_driver_t epd_driver_4in2;
extern epd_driver_t epd_driver_4in2bv2;
/** EPD drivers */
static epd_driver_t *epd_drivers[] = {
&epd_driver_4in2, // UC8176: 4.2 inch, BW
&epd_driver_4in2bv2, // UC8176: 4.2 inch, BWR
};
/**< current EPD driver */
static epd_driver_t *m_driver = NULL;
epd_driver_t *epd_driver_get(void)
{
if (m_driver == NULL)
m_driver = epd_drivers[0];
return m_driver;
}
epd_driver_t *epd_driver_by_id(uint8_t id)
{
for (uint8_t i = 0; i < ARRAY_SIZE(epd_drivers); i++) {
if (epd_drivers[i]->id == id)
return epd_drivers[i];
}
return NULL;
}
bool epd_driver_set(uint8_t id)
{
epd_driver_t *driver = epd_driver_by_id(id);
if (driver ) {
m_driver = driver;
return true;
}
return false;
}

View File

@@ -15,10 +15,9 @@
#ifndef __EPD_DRIVER_H
#define __EPD_DRIVER_H
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "nrf_delay.h"
#include "nrf_gpio.h"
/**< EPD driver IDs. */
enum EPD_DRIVER_IDS
@@ -55,17 +54,19 @@ extern uint32_t EPD_BUSY_PIN;
extern uint32_t EPD_BS_PIN;
extern uint32_t EPD_EN_PIN;
/**
* GPIO read and write
**/
#define DEV_Digital_Write(_pin, _value) nrf_gpio_pin_write(_pin, _value)
#define DEV_Digital_Read(_pin) nrf_gpio_pin_read(_pin)
#define LOW (0x0)
#define HIGH (0x1)
/**
* delay x ms
**/
#define DEV_Delay_ms(__xms) nrf_delay_ms(__xms);
#define DEV_Delay_us(__xus) nrf_delay_us(__xus);
#define INPUT (0x0)
#define OUTPUT (0x1)
#define INPUT_PULLUP (0x2)
#define INPUT_PULLDOWN (0x3)
// Arduino like function wrappers
void pinMode(uint32_t pin, uint32_t mode);
void digitalWrite(uint32_t pin, uint32_t value);
uint32_t digitalRead(uint32_t pin);
void delay(uint32_t ms);
void DEV_Module_Init(void);
void DEV_Module_Exit(void);
@@ -76,6 +77,8 @@ void DEV_SPI_WriteBytes(uint8_t *value, uint8_t len);
void EPD_WriteCommand(uint8_t Reg);
void EPD_WriteByte(uint8_t Data);
void EPD_WriteData(uint8_t *Data, uint8_t Len);
void EPD_Reset(uint32_t value, uint16_t duration);
void EPD_WaitBusy(uint32_t value, uint16_t timeout);
epd_driver_t *epd_driver_get(void);
epd_driver_t *epd_driver_by_id(uint8_t id);

View File

@@ -34,44 +34,16 @@
#define EPD_4IN2_WIDTH 400
#define EPD_4IN2_HEIGHT 300
/******************************************************************************
function : Software reset
parameter:
******************************************************************************/
static void EPD_4IN2_Reset(void)
{
DEV_Digital_Write(EPD_RST_PIN, 1);
DEV_Delay_ms(10);
for (uint8_t i = 0; i < 3; i++)
{
DEV_Digital_Write(EPD_RST_PIN, 0);
DEV_Delay_ms(10);
DEV_Digital_Write(EPD_RST_PIN, 1);
DEV_Delay_ms(10);
}
}
void EPD_4IN2_ReadBusy(void)
{
NRF_LOG_DEBUG("e-Paper busy\r\n");
do{
EPD_WriteCommand(0x71);
DEV_Delay_ms(50);
}while(!(DEV_Digital_Read(EPD_BUSY_PIN)));
NRF_LOG_DEBUG("e-Paper busy release\r\n");
DEV_Delay_ms(50);
}
void EPD_4IN2_PowerOn(void)
static void EPD_4IN2_PowerOn(void)
{
EPD_WriteCommand(0x04);
DEV_Delay_ms(50);
delay(50);
}
void EPD_4IN2_PowerOff(void)
static void EPD_4IN2_PowerOff(void)
{
EPD_WriteCommand(0x02);
EPD_4IN2_ReadBusy();
EPD_WaitBusy(LOW, 50);
}
/******************************************************************************
@@ -82,8 +54,8 @@ void EPD_4IN2_Refresh(void)
{
EPD_4IN2_PowerOn();
EPD_WriteCommand(0x12);
DEV_Delay_ms(100);
EPD_4IN2_ReadBusy();
delay(100);
EPD_WaitBusy(LOW, 50);
EPD_4IN2_PowerOff();
}
@@ -93,7 +65,7 @@ parameter:
******************************************************************************/
void EPD_4IN2_Init(void)
{
EPD_4IN2_Reset();
EPD_Reset(HIGH, 10);
EPD_WriteCommand(0x00); // panel setting
EPD_WriteByte(0x1f); // 400x300 B/W mode, LUT from OTP
@@ -104,7 +76,7 @@ void EPD_4IN2_Init(void)
void EPD_4IN2B_V2_Init(void)
{
EPD_4IN2_Reset();
EPD_Reset(HIGH, 10);
EPD_WriteCommand(0x00);
EPD_WriteByte(0x0f);