mirror of
https://github.com/jam422470459/EPD-nRF52-hema213.git
synced 2025-12-06 08:32:54 +08:00
refactor driver code
This commit is contained in:
@@ -28,7 +28,7 @@ void epd_config_init(epd_config_t *cfg)
|
||||
}
|
||||
}
|
||||
|
||||
void epd_config_load(epd_config_t *cfg)
|
||||
void epd_config_read(epd_config_t *cfg)
|
||||
{
|
||||
fds_flash_record_t flash_record;
|
||||
fds_record_desc_t record_desc;
|
||||
@@ -54,21 +54,7 @@ void epd_config_load(epd_config_t *cfg)
|
||||
fds_record_close(&record_desc);
|
||||
}
|
||||
|
||||
void epd_config_clear(epd_config_t *cfg)
|
||||
{
|
||||
fds_record_desc_t record_desc;
|
||||
fds_find_token_t ftok;
|
||||
|
||||
memset(&ftok, 0x00, sizeof(fds_find_token_t));
|
||||
if (fds_record_find(CONFIG_FILE_ID, CONFIG_REC_KEY, &record_desc, &ftok) != NRF_SUCCESS) {
|
||||
NRF_LOG_DEBUG("epd_config_clear: record not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fds_record_delete(&record_desc);
|
||||
}
|
||||
|
||||
void epd_config_save(epd_config_t *cfg)
|
||||
void epd_config_write(epd_config_t *cfg)
|
||||
{
|
||||
ret_code_t ret;
|
||||
fds_record_t record;
|
||||
@@ -100,6 +86,20 @@ void epd_config_save(epd_config_t *cfg)
|
||||
}
|
||||
}
|
||||
|
||||
void epd_config_clear(epd_config_t *cfg)
|
||||
{
|
||||
fds_record_desc_t record_desc;
|
||||
fds_find_token_t ftok;
|
||||
|
||||
memset(&ftok, 0x00, sizeof(fds_find_token_t));
|
||||
if (fds_record_find(CONFIG_FILE_ID, CONFIG_REC_KEY, &record_desc, &ftok) != NRF_SUCCESS) {
|
||||
NRF_LOG_DEBUG("epd_config_clear: record not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fds_record_delete(&record_desc);
|
||||
}
|
||||
|
||||
bool epd_config_empty(epd_config_t *cfg)
|
||||
{
|
||||
for (uint8_t i = 0; i < EPD_CONFIG_SIZE; i++) {
|
||||
|
||||
@@ -22,9 +22,9 @@ typedef struct
|
||||
#define EPD_CONFIG_EMPTY 0xFF
|
||||
|
||||
void epd_config_init(epd_config_t *cfg);
|
||||
void epd_config_load(epd_config_t *cfg);
|
||||
void epd_config_read(epd_config_t *cfg);
|
||||
void epd_config_write(epd_config_t *cfg);
|
||||
void epd_config_clear(epd_config_t *cfg);
|
||||
void epd_config_save(epd_config_t *cfg);
|
||||
bool epd_config_empty(epd_config_t *cfg);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,22 +22,18 @@
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
// GPIO Pins
|
||||
uint32_t EPD_MOSI_PIN = 5;
|
||||
uint32_t EPD_SCLK_PIN = 8;
|
||||
uint32_t EPD_CS_PIN = 9;
|
||||
uint32_t EPD_DC_PIN = 10;
|
||||
uint32_t EPD_RST_PIN = 11;
|
||||
uint32_t EPD_BUSY_PIN = 12;
|
||||
uint32_t EPD_BS_PIN = 13;
|
||||
uint32_t EPD_EN_PIN = 0xFF;
|
||||
uint32_t EPD_LED_PIN = 0xFF;
|
||||
static uint32_t EPD_MOSI_PIN = 5;
|
||||
static uint32_t EPD_SCLK_PIN = 8;
|
||||
static uint32_t EPD_CS_PIN = 9;
|
||||
static uint32_t EPD_DC_PIN = 10;
|
||||
static uint32_t EPD_RST_PIN = 11;
|
||||
static uint32_t EPD_BUSY_PIN = 12;
|
||||
static uint32_t EPD_BS_PIN = 13;
|
||||
static uint32_t EPD_EN_PIN = 0xFF;
|
||||
static uint32_t EPD_LED_PIN = 0xFF;
|
||||
|
||||
// Display resolution
|
||||
uint16_t EPD_WIDTH = 400;
|
||||
uint16_t EPD_HEIGHT = 300;
|
||||
|
||||
// BWR mode
|
||||
bool EPD_BWR_MODE = true;
|
||||
// EPD model
|
||||
static epd_model_t *EPD = NULL;
|
||||
|
||||
// Arduino like function wrappers
|
||||
|
||||
@@ -224,9 +220,11 @@ void EPD_Reset(uint32_t value, uint16_t duration)
|
||||
|
||||
void EPD_WaitBusy(uint32_t value, uint16_t timeout)
|
||||
{
|
||||
uint32_t led_status = digitalRead(EPD_LED_PIN);
|
||||
|
||||
NRF_LOG_DEBUG("[EPD]: check busy\n");
|
||||
while (digitalRead(EPD_BUSY_PIN) == value) {
|
||||
if (timeout % 100 == 0) EPD_LED_TOGGLE();
|
||||
if (timeout % 100 == 0) EPD_LED_Toggle();
|
||||
delay(1);
|
||||
timeout--;
|
||||
if (timeout == 0) {
|
||||
@@ -235,9 +233,29 @@ void EPD_WaitBusy(uint32_t value, uint16_t timeout)
|
||||
}
|
||||
}
|
||||
NRF_LOG_DEBUG("[EPD]: busy release\n");
|
||||
|
||||
// restore led status
|
||||
if (led_status == LOW)
|
||||
EPD_LED_ON();
|
||||
else
|
||||
EPD_LED_OFF();
|
||||
}
|
||||
|
||||
// GPIO
|
||||
void EPD_GPIO_Load(epd_config_t *cfg)
|
||||
{
|
||||
if (cfg == NULL) return;
|
||||
EPD_MOSI_PIN = cfg->mosi_pin;
|
||||
EPD_SCLK_PIN = cfg->sclk_pin;
|
||||
EPD_CS_PIN = cfg->cs_pin;
|
||||
EPD_DC_PIN = cfg->dc_pin;
|
||||
EPD_RST_PIN = cfg->rst_pin;
|
||||
EPD_BUSY_PIN = cfg->busy_pin;
|
||||
EPD_BS_PIN = cfg->bs_pin;
|
||||
EPD_EN_PIN = cfg->en_pin;
|
||||
EPD_LED_PIN = cfg->led_pin;
|
||||
}
|
||||
|
||||
void EPD_GPIO_Init(void)
|
||||
{
|
||||
pinMode(EPD_CS_PIN, OUTPUT);
|
||||
@@ -253,16 +271,12 @@ void EPD_GPIO_Init(void)
|
||||
pinMode(EPD_BS_PIN, OUTPUT);
|
||||
digitalWrite(EPD_BS_PIN, LOW);
|
||||
|
||||
EPD_SPI_Init();
|
||||
|
||||
digitalWrite(EPD_DC_PIN, LOW);
|
||||
digitalWrite(EPD_CS_PIN, LOW);
|
||||
digitalWrite(EPD_RST_PIN, HIGH);
|
||||
|
||||
if (EPD_LED_PIN != 0xFF) {
|
||||
if (EPD_LED_PIN != 0xFF)
|
||||
pinMode(EPD_LED_PIN, OUTPUT);
|
||||
EPD_LED_ON();
|
||||
}
|
||||
}
|
||||
|
||||
void EPD_GPIO_Uninit(void)
|
||||
@@ -289,7 +303,7 @@ void EPD_LED_OFF(void)
|
||||
digitalWrite(EPD_LED_PIN, HIGH);
|
||||
}
|
||||
|
||||
void EPD_LED_TOGGLE(void)
|
||||
void EPD_LED_Toggle(void)
|
||||
{
|
||||
if (EPD_LED_PIN != 0xFF)
|
||||
nrf_gpio_pin_toggle(EPD_LED_PIN);
|
||||
@@ -310,19 +324,19 @@ static epd_model_t *epd_models[] = {
|
||||
&epd_uc8276_420_bwr,
|
||||
};
|
||||
|
||||
static epd_model_t *epd_model_get(epd_model_id_t id)
|
||||
epd_model_t *epd_get(void)
|
||||
{
|
||||
return EPD == NULL ? epd_models[0] : EPD;
|
||||
}
|
||||
|
||||
epd_model_t *epd_init(epd_model_id_t id)
|
||||
{
|
||||
for (uint8_t i = 0; i < ARRAY_SIZE(epd_models); i++) {
|
||||
if (epd_models[i]->id == id) {
|
||||
return epd_models[i];
|
||||
EPD = epd_models[i];
|
||||
}
|
||||
}
|
||||
return epd_models[0];
|
||||
}
|
||||
|
||||
epd_driver_t *epd_model_init(epd_model_id_t id)
|
||||
{
|
||||
epd_model_t *model = epd_model_get(id);
|
||||
model->drv->init(model->res, model->bwr);
|
||||
return model->drv;
|
||||
if (EPD == NULL) EPD = epd_models[0];
|
||||
EPD->drv->init();
|
||||
return EPD;
|
||||
}
|
||||
|
||||
@@ -18,25 +18,17 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "EPD_config.h"
|
||||
|
||||
#define BIT(n) (1UL << (n))
|
||||
|
||||
// Display resolution
|
||||
typedef enum
|
||||
{
|
||||
EPD_RES_400x300,
|
||||
EPD_RES_320x300,
|
||||
EPD_RES_320x240,
|
||||
EPD_RES_200x300,
|
||||
} epd_res_t;
|
||||
|
||||
/**@brief EPD driver structure.
|
||||
*
|
||||
* @details This structure contains epd driver functions.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
void (*init)(epd_res_t res, bool bwr); /**< Initialize the e-Paper register */
|
||||
void (*init)(); /**< Initialize the e-Paper register */
|
||||
void (*clear)(void); /**< Clear screen */
|
||||
void (*write_image)(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h); /**< write image */
|
||||
void (*refresh)(void); /**< Sends the image buffer in RAM to e-Paper and displays */
|
||||
@@ -58,25 +50,12 @@ typedef struct
|
||||
{
|
||||
epd_model_id_t id;
|
||||
epd_driver_t *drv;
|
||||
epd_res_t res;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
bool bwr;
|
||||
bool invert_color;
|
||||
} epd_model_t;
|
||||
|
||||
extern uint32_t EPD_MOSI_PIN;
|
||||
extern uint32_t EPD_SCLK_PIN;
|
||||
extern uint32_t EPD_CS_PIN;
|
||||
extern uint32_t EPD_DC_PIN;
|
||||
extern uint32_t EPD_RST_PIN;
|
||||
extern uint32_t EPD_BUSY_PIN;
|
||||
extern uint32_t EPD_BS_PIN;
|
||||
extern uint32_t EPD_EN_PIN;
|
||||
extern uint32_t EPD_LED_PIN;
|
||||
|
||||
extern uint16_t EPD_WIDTH;
|
||||
extern uint16_t EPD_HEIGHT;
|
||||
|
||||
extern bool EPD_BWR_MODE;
|
||||
|
||||
#define LOW (0x0)
|
||||
#define HIGH (0x1)
|
||||
|
||||
@@ -92,6 +71,7 @@ uint32_t digitalRead(uint32_t pin);
|
||||
void delay(uint32_t ms);
|
||||
|
||||
// GPIO
|
||||
void EPD_GPIO_Load(epd_config_t *cfg);
|
||||
void EPD_GPIO_Init(void);
|
||||
void EPD_GPIO_Uninit(void);
|
||||
|
||||
@@ -115,8 +95,9 @@ void EPD_WaitBusy(uint32_t value, uint16_t timeout);
|
||||
// lED
|
||||
void EPD_LED_ON(void);
|
||||
void EPD_LED_OFF(void);
|
||||
void EPD_LED_TOGGLE(void);
|
||||
void EPD_LED_Toggle(void);
|
||||
|
||||
epd_driver_t *epd_model_init(epd_model_id_t id);
|
||||
epd_model_t *epd_get(void);
|
||||
epd_model_t *epd_init(epd_model_id_t id);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -65,8 +65,8 @@ static void calendar_update(void * p_event_data, uint16_t event_size)
|
||||
p_epd->calendar_mode = true;
|
||||
|
||||
epd_gpio_init();
|
||||
epd_driver_t *drv = epd_model_init((epd_model_id_t)p_epd->config.model_id);
|
||||
DrawCalendar(drv, event->timestamp);
|
||||
epd_model_t *epd = epd_init((epd_model_id_t)p_epd->config.model_id);
|
||||
DrawCalendar(epd, event->timestamp);
|
||||
epd_gpio_uninit();
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ static void on_connect(ble_epd_t * p_epd, ble_evt_t * p_ble_evt)
|
||||
{
|
||||
p_epd->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
|
||||
epd_gpio_init();
|
||||
EPD_LED_ON();
|
||||
}
|
||||
|
||||
/**@brief Function for handling the @ref BLE_GAP_EVT_DISCONNECTED event from the S110 SoftDevice.
|
||||
@@ -90,6 +91,7 @@ static void on_disconnect(ble_epd_t * p_epd, ble_evt_t * p_ble_evt)
|
||||
{
|
||||
UNUSED_PARAMETER(p_ble_evt);
|
||||
p_epd->conn_handle = BLE_CONN_HANDLE_INVALID;
|
||||
EPD_LED_OFF();
|
||||
epd_gpio_uninit();
|
||||
}
|
||||
|
||||
@@ -108,19 +110,19 @@ static void epd_service_process(ble_epd_t * p_epd, uint8_t * p_data, uint16_t le
|
||||
case EPD_CMD_SET_PINS:
|
||||
if (length < 8) return;
|
||||
|
||||
EPD_GPIO_Uninit();
|
||||
|
||||
EPD_MOSI_PIN = p_epd->config.mosi_pin = p_data[1];
|
||||
EPD_SCLK_PIN = p_epd->config.sclk_pin = p_data[2];
|
||||
EPD_CS_PIN = p_epd->config.cs_pin = p_data[3];
|
||||
EPD_DC_PIN = p_epd->config.dc_pin = p_data[4];
|
||||
EPD_RST_PIN = p_epd->config.rst_pin = p_data[5];
|
||||
EPD_BUSY_PIN = p_epd->config.busy_pin = p_data[6];
|
||||
EPD_BS_PIN = p_epd->config.bs_pin = p_data[7];
|
||||
p_epd->config.mosi_pin = p_data[1];
|
||||
p_epd->config.sclk_pin = p_data[2];
|
||||
p_epd->config.cs_pin = p_data[3];
|
||||
p_epd->config.dc_pin = p_data[4];
|
||||
p_epd->config.rst_pin = p_data[5];
|
||||
p_epd->config.busy_pin = p_data[6];
|
||||
p_epd->config.bs_pin = p_data[7];
|
||||
if (length > 8)
|
||||
EPD_EN_PIN = p_epd->config.en_pin = p_data[8];
|
||||
epd_config_save(&p_epd->config);
|
||||
p_epd->config.en_pin = p_data[8];
|
||||
epd_config_write(&p_epd->config);
|
||||
|
||||
EPD_GPIO_Uninit();
|
||||
EPD_GPIO_Load(&p_epd->config);
|
||||
EPD_GPIO_Init();
|
||||
break;
|
||||
|
||||
@@ -128,14 +130,14 @@ static void epd_service_process(ble_epd_t * p_epd, uint8_t * p_data, uint16_t le
|
||||
uint8_t id = length > 1 ? p_data[1] : p_epd->config.model_id;
|
||||
if (id != p_epd->config.model_id) {
|
||||
p_epd->config.model_id = id;
|
||||
epd_config_save(&p_epd->config);
|
||||
epd_config_write(&p_epd->config);
|
||||
}
|
||||
p_epd->driver = epd_model_init((epd_model_id_t)id);
|
||||
p_epd->epd = epd_init((epd_model_id_t)id);
|
||||
} break;
|
||||
|
||||
case EPD_CMD_CLEAR:
|
||||
p_epd->calendar_mode = false;
|
||||
p_epd->driver->clear();
|
||||
p_epd->epd->drv->clear();
|
||||
break;
|
||||
|
||||
case EPD_CMD_SEND_COMMAND:
|
||||
@@ -149,17 +151,17 @@ static void epd_service_process(ble_epd_t * p_epd, uint8_t * p_data, uint16_t le
|
||||
|
||||
case EPD_CMD_DISPLAY:
|
||||
p_epd->calendar_mode = false;
|
||||
p_epd->driver->refresh();
|
||||
p_epd->epd->drv->refresh();
|
||||
break;
|
||||
|
||||
case EPD_CMD_SLEEP:
|
||||
p_epd->driver->sleep();
|
||||
p_epd->epd->drv->sleep();
|
||||
break;
|
||||
|
||||
case EPD_CMD_SET_CONFIG:
|
||||
if (length < 2) return;
|
||||
memcpy(&p_epd->config, &p_data[1], (length - 1 > EPD_CONFIG_SIZE) ? EPD_CONFIG_SIZE : length - 1);
|
||||
epd_config_save(&p_epd->config);
|
||||
epd_config_write(&p_epd->config);
|
||||
break;
|
||||
|
||||
case EPD_CMD_CFG_ERASE:
|
||||
@@ -282,37 +284,6 @@ static uint32_t epd_service_init(ble_epd_t * p_epd)
|
||||
return characteristic_add(p_epd->service_handle, &add_char_params, &p_epd->char_handles);
|
||||
}
|
||||
|
||||
static void ble_epd_config_load(ble_epd_t * p_epd)
|
||||
{
|
||||
// write default config
|
||||
if (epd_config_empty(&p_epd->config))
|
||||
{
|
||||
uint8_t cfg[] = EPD_CFG_DEFAULT;
|
||||
memcpy(&p_epd->config, cfg, sizeof(cfg));
|
||||
epd_config_save(&p_epd->config);
|
||||
}
|
||||
|
||||
// load config
|
||||
EPD_MOSI_PIN = p_epd->config.mosi_pin;
|
||||
EPD_SCLK_PIN = p_epd->config.sclk_pin;
|
||||
EPD_CS_PIN = p_epd->config.cs_pin;
|
||||
EPD_DC_PIN = p_epd->config.dc_pin;
|
||||
EPD_RST_PIN = p_epd->config.rst_pin;
|
||||
EPD_BUSY_PIN = p_epd->config.busy_pin;
|
||||
EPD_BS_PIN = p_epd->config.bs_pin;
|
||||
EPD_EN_PIN = p_epd->config.en_pin;
|
||||
EPD_LED_PIN = p_epd->config.led_pin;
|
||||
|
||||
// blink LED on start
|
||||
if (EPD_LED_PIN != EPD_CONFIG_EMPTY)
|
||||
{
|
||||
pinMode(EPD_LED_PIN, OUTPUT);
|
||||
EPD_LED_ON();
|
||||
delay(100);
|
||||
EPD_LED_OFF();
|
||||
}
|
||||
}
|
||||
|
||||
void ble_epd_sleep_prepare(ble_epd_t * p_epd)
|
||||
{
|
||||
// Turn off led
|
||||
@@ -335,8 +306,24 @@ uint32_t ble_epd_init(ble_epd_t * p_epd, epd_callback_t cmd_cb)
|
||||
p_epd->is_notification_enabled = false;
|
||||
|
||||
epd_config_init(&p_epd->config);
|
||||
epd_config_load(&p_epd->config);
|
||||
ble_epd_config_load(p_epd);
|
||||
epd_config_read(&p_epd->config);
|
||||
|
||||
// write default config
|
||||
if (epd_config_empty(&p_epd->config))
|
||||
{
|
||||
uint8_t cfg[] = EPD_CFG_DEFAULT;
|
||||
memcpy(&p_epd->config, cfg, sizeof(cfg));
|
||||
epd_config_write(&p_epd->config);
|
||||
}
|
||||
|
||||
// load config
|
||||
EPD_GPIO_Load(&p_epd->config);
|
||||
epd_gpio_init();
|
||||
|
||||
// blink LED on start
|
||||
EPD_LED_ON();
|
||||
delay(100);
|
||||
EPD_LED_OFF();
|
||||
|
||||
// Add the service.
|
||||
return epd_service_init(p_epd);
|
||||
|
||||
@@ -82,7 +82,7 @@ typedef struct
|
||||
uint16_t conn_handle; /**< Handle of the current connection (as provided by the SoftDevice). BLE_CONN_HANDLE_INVALID if not in a connection. */
|
||||
uint16_t max_data_len; /**< Maximum length of data (in bytes) that can be transmitted to the peer */
|
||||
bool is_notification_enabled; /**< Variable to indicate if the peer has enabled notification of the RX characteristic.*/
|
||||
epd_driver_t *driver; /**< current EPD driver */
|
||||
epd_model_t *epd; /**< current EPD model */
|
||||
epd_config_t config; /**< EPD config */
|
||||
epd_callback_t epd_cmd_cb; /**< EPD callback */
|
||||
bool calendar_mode; /**< Calendar mode flag */
|
||||
|
||||
103
EPD/SSD1619.c
103
EPD/SSD1619.c
@@ -42,47 +42,28 @@ void SSD1619_Force_Temp(int8_t value)
|
||||
|
||||
static void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
||||
{
|
||||
EPD_WriteCommand(CMD_DATA_MODE); // set ram entry mode
|
||||
EPD_WriteByte(0x03); // x increase, y increase
|
||||
EPD_WriteCommand(CMD_RAM_XPOS);
|
||||
EPD_WriteByte(x / 8);
|
||||
EPD_WriteByte((x + w - 1) / 8);
|
||||
EPD_WriteCommand(CMD_RAM_YPOS);
|
||||
EPD_WriteByte(y % 256);
|
||||
EPD_WriteByte(y / 256);
|
||||
EPD_WriteByte((y + h - 1) % 256);
|
||||
EPD_WriteByte((y + h - 1) / 256);
|
||||
EPD_WriteCommand(CMD_RAM_XCOUNT);
|
||||
EPD_WriteByte(x / 8);
|
||||
EPD_WriteCommand(CMD_RAM_YCOUNT);
|
||||
EPD_WriteByte(y % 256);
|
||||
EPD_WriteByte(y / 256);
|
||||
EPD_WriteCommand(CMD_DATA_MODE); // set ram entry mode
|
||||
EPD_WriteByte(0x03); // x increase, y increase
|
||||
EPD_WriteCommand(CMD_RAM_XPOS);
|
||||
EPD_WriteByte(x / 8);
|
||||
EPD_WriteByte((x + w - 1) / 8);
|
||||
EPD_WriteCommand(CMD_RAM_YPOS);
|
||||
EPD_WriteByte(y % 256);
|
||||
EPD_WriteByte(y / 256);
|
||||
EPD_WriteByte((y + h - 1) % 256);
|
||||
EPD_WriteByte((y + h - 1) / 256);
|
||||
EPD_WriteCommand(CMD_RAM_XCOUNT);
|
||||
EPD_WriteByte(x / 8);
|
||||
EPD_WriteCommand(CMD_RAM_YCOUNT);
|
||||
EPD_WriteByte(y % 256);
|
||||
EPD_WriteByte(y / 256);
|
||||
}
|
||||
|
||||
void SSD1619_Init(epd_res_t res, bool bwr)
|
||||
void SSD1619_Init()
|
||||
{
|
||||
EPD_BWR_MODE = bwr;
|
||||
EPD_Reset(HIGH, 10);
|
||||
epd_model_t *EPD = epd_get();
|
||||
|
||||
switch (res) {
|
||||
case EPD_RES_320x300:
|
||||
EPD_WIDTH = 320;
|
||||
EPD_HEIGHT = 300;
|
||||
break;
|
||||
case EPD_RES_320x240:
|
||||
EPD_WIDTH = 320;
|
||||
EPD_HEIGHT = 240;
|
||||
break;
|
||||
case EPD_RES_200x300:
|
||||
EPD_WIDTH = 200;
|
||||
EPD_HEIGHT = 300;
|
||||
break;
|
||||
case EPD_RES_400x300:
|
||||
default:
|
||||
EPD_WIDTH = 400;
|
||||
EPD_HEIGHT = 300;
|
||||
break;
|
||||
}
|
||||
EPD_Reset(HIGH, 10);
|
||||
|
||||
EPD_WriteCommand(CMD_SW_RESET);
|
||||
EPD_WaitBusy(HIGH, 200);
|
||||
@@ -91,22 +72,13 @@ void SSD1619_Init(epd_res_t res, bool bwr)
|
||||
EPD_WriteByte(0x54);
|
||||
EPD_WriteCommand(CMD_DIGITAL_BLOCK_CTRL);
|
||||
EPD_WriteByte(0x3B);
|
||||
EPD_WriteCommand(CMD_VCOM_CTRL); // Reduce glitch under ACVCOM
|
||||
EPD_WriteByte(0x04);
|
||||
EPD_WriteByte(0x63);
|
||||
|
||||
EPD_WriteCommand(CMD_BOOSTER_CTRL);
|
||||
EPD_WriteByte(0x8B);
|
||||
EPD_WriteByte(0x9C);
|
||||
EPD_WriteByte(0x96);
|
||||
EPD_WriteByte(0x0F);
|
||||
|
||||
EPD_WriteCommand(CMD_DRIVER_CTRL);
|
||||
EPD_WriteByte((EPD_HEIGHT - 1) % 256);
|
||||
EPD_WriteByte((EPD_HEIGHT - 1) / 256);
|
||||
EPD_WriteByte((EPD->height - 1) % 256);
|
||||
EPD_WriteByte((EPD->height - 1) / 256);
|
||||
EPD_WriteByte(0x00);
|
||||
|
||||
_setPartialRamArea(0, 0, EPD_WIDTH, EPD_HEIGHT);
|
||||
_setPartialRamArea(0, 0, EPD->width, EPD->height);
|
||||
|
||||
EPD_WriteCommand(CMD_BORDER_CTRL);
|
||||
EPD_WriteByte(0x01);
|
||||
@@ -121,6 +93,8 @@ void SSD1619_Init(epd_res_t res, bool bwr)
|
||||
|
||||
static void SSD1619_Refresh(void)
|
||||
{
|
||||
epd_model_t *EPD = epd_get();
|
||||
|
||||
NRF_LOG_DEBUG("[EPD]: refresh begin\n");
|
||||
NRF_LOG_DEBUG("[EPD]: temperature: %d\n", SSD1619_Read_Temp());
|
||||
EPD_WriteCommand(CMD_DISP_CTRL2);
|
||||
@@ -129,14 +103,16 @@ static void SSD1619_Refresh(void)
|
||||
EPD_WaitBusy(HIGH, 30000);
|
||||
NRF_LOG_DEBUG("[EPD]: refresh end\n");
|
||||
|
||||
_setPartialRamArea(0, 0, EPD_WIDTH, EPD_HEIGHT);
|
||||
_setPartialRamArea(0, 0, EPD->width, EPD->height); // DO NOT REMOVE!
|
||||
}
|
||||
|
||||
void SSD1619_Clear(void)
|
||||
{
|
||||
uint16_t Width = (EPD_WIDTH + 7) / 8;
|
||||
uint16_t Height = EPD_HEIGHT;
|
||||
epd_model_t *EPD = epd_get();
|
||||
uint16_t Width = (EPD->width + 7) / 8;
|
||||
uint16_t Height = EPD->height;
|
||||
|
||||
_setPartialRamArea(0, 0, EPD->width, EPD->height);
|
||||
EPD_WriteCommand(CMD_WRITE_RAM1);
|
||||
for (uint16_t j = 0; j < Height; j++) {
|
||||
for (uint16_t i = 0; i < Width; i++) {
|
||||
@@ -146,7 +122,7 @@ void SSD1619_Clear(void)
|
||||
EPD_WriteCommand(CMD_WRITE_RAM2);
|
||||
for (uint16_t j = 0; j < Height; j++) {
|
||||
for (uint16_t i = 0; i < Width; i++) {
|
||||
EPD_WriteByte(EPD_BWR_MODE ? 0x00 : 0xFF);
|
||||
EPD_WriteByte(EPD->invert_color ? 0x00 : 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,10 +131,11 @@ void SSD1619_Clear(void)
|
||||
|
||||
void SSD1619_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
||||
{
|
||||
epd_model_t *EPD = epd_get();
|
||||
uint16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
|
||||
x -= x % 8; // byte boundary
|
||||
w = wb * 8; // byte boundary
|
||||
if (x + w > EPD_WIDTH || y + h > EPD_HEIGHT) return;
|
||||
if (x + w > EPD->width || y + h > EPD->height) return;
|
||||
_setPartialRamArea(x, y, w, h);
|
||||
EPD_WriteCommand(CMD_WRITE_RAM1);
|
||||
for (uint16_t i = 0; i < h; i++) {
|
||||
@@ -169,10 +146,12 @@ void SSD1619_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y,
|
||||
EPD_WriteCommand(CMD_WRITE_RAM2);
|
||||
for (uint16_t i = 0; i < h; i++) {
|
||||
for (uint16_t j = 0; j < w / 8; j++) {
|
||||
if (EPD_BWR_MODE)
|
||||
EPD_WriteByte(color ? ~color[j + i * wb] : 0x00);
|
||||
else
|
||||
if (EPD->bwr) {
|
||||
uint8_t data = color ? color[j + i * wb] : 0xFF;
|
||||
EPD_WriteByte(EPD->invert_color ? ~data : data);
|
||||
} else {
|
||||
EPD_WriteByte(black[j + i * wb]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,16 +173,22 @@ static epd_driver_t epd_drv_ssd1619 = {
|
||||
.force_temp = SSD1619_Force_Temp,
|
||||
};
|
||||
|
||||
// SSD1619 400x300 Black/White/Red
|
||||
const epd_model_t epd_ssd1619_420_bwr = {
|
||||
.id = EPD_SSD1619_420_BWR,
|
||||
.drv = &epd_drv_ssd1619,
|
||||
.res = EPD_RES_400x300,
|
||||
.width = 400,
|
||||
.height = 300,
|
||||
.bwr = true,
|
||||
.invert_color = true,
|
||||
};
|
||||
|
||||
// SSD1619 400x300 Black/White
|
||||
const epd_model_t epd_ssd1619_420_bw = {
|
||||
.id = EPD_SSD1619_420_BW,
|
||||
.drv = &epd_drv_ssd1619,
|
||||
.res = EPD_RES_400x300,
|
||||
.width = 400,
|
||||
.height = 300,
|
||||
.bwr = false,
|
||||
.invert_color = false,
|
||||
};
|
||||
|
||||
101
EPD/UC8176.c
101
EPD/UC8176.c
@@ -104,40 +104,28 @@ void UC8176_Refresh(void)
|
||||
function : Initialize the e-Paper register
|
||||
parameter:
|
||||
******************************************************************************/
|
||||
void UC8176_Init(epd_res_t res, bool bwr)
|
||||
void UC8176_Init()
|
||||
{
|
||||
EPD_BWR_MODE = bwr;
|
||||
EPD_Reset(HIGH, 10);
|
||||
|
||||
epd_model_t *EPD = epd_get();
|
||||
uint8_t psr = PSR_UD | PSR_SHL | PSR_SHD | PSR_RST;
|
||||
if (!EPD_BWR_MODE) psr |= PSR_BWR;
|
||||
switch (res) {
|
||||
case EPD_RES_320x300:
|
||||
EPD_WIDTH = 320;
|
||||
EPD_HEIGHT = 300;
|
||||
psr |= PSR_RES0;
|
||||
break;
|
||||
case EPD_RES_320x240:
|
||||
EPD_WIDTH = 320;
|
||||
EPD_HEIGHT = 240;
|
||||
psr |= PSR_RES1;
|
||||
break;
|
||||
case EPD_RES_200x300:
|
||||
EPD_WIDTH = 200;
|
||||
EPD_HEIGHT = 300;
|
||||
psr |= PSR_RES1 | PSR_RES0;
|
||||
break;
|
||||
case EPD_RES_400x300:
|
||||
default:
|
||||
EPD_WIDTH = 400;
|
||||
EPD_HEIGHT = 300;
|
||||
break;
|
||||
if (!EPD->bwr) psr |= PSR_BWR;
|
||||
if (EPD->width == 320 && EPD->height == 300) {
|
||||
psr |= PSR_RES0;
|
||||
} else if (EPD->width == 320 && EPD->height == 240) {
|
||||
psr |= PSR_RES1;
|
||||
} else if (EPD->width == 200 && EPD->height == 300) {
|
||||
psr |= PSR_RES1 | PSR_RES0;
|
||||
} else {
|
||||
// default to 400x300
|
||||
}
|
||||
|
||||
NRF_LOG_DEBUG("[EPD]: PSR=%02x\n", psr);
|
||||
EPD_WriteCommand(CMD_PSR);
|
||||
EPD_WriteByte(psr);
|
||||
|
||||
if (!EPD_BWR_MODE) {
|
||||
if (!EPD->bwr) {
|
||||
EPD_WriteCommand(CMD_CDI);
|
||||
EPD_WriteByte(0x97);
|
||||
}
|
||||
@@ -145,8 +133,9 @@ void UC8176_Init(epd_res_t res, bool bwr)
|
||||
|
||||
static void UC8176_Write_RAM(uint8_t cmd, uint8_t value)
|
||||
{
|
||||
uint16_t Width = (EPD_WIDTH + 7) / 8;
|
||||
uint16_t Height = EPD_HEIGHT;
|
||||
epd_model_t *EPD = epd_get();
|
||||
uint16_t Width = (EPD->width + 7) / 8;
|
||||
uint16_t Height = EPD->height;
|
||||
|
||||
EPD_WriteCommand(cmd);
|
||||
for (uint16_t j = 0; j < Height; j++) {
|
||||
@@ -162,15 +151,9 @@ parameter:
|
||||
******************************************************************************/
|
||||
void UC8176_Clear(void)
|
||||
{
|
||||
epd_model_t *EPD = epd_get();
|
||||
UC8176_Write_RAM(CMD_DTM1, 0xFF);
|
||||
UC8176_Write_RAM(CMD_DTM2, 0xFF);
|
||||
UC8176_Refresh();
|
||||
}
|
||||
|
||||
void UC8276_Clear(void)
|
||||
{
|
||||
UC8176_Write_RAM(CMD_DTM1, 0xFF);
|
||||
UC8176_Write_RAM(CMD_DTM2, 0x00);
|
||||
UC8176_Write_RAM(CMD_DTM2, EPD->invert_color ? 0x00 : 0xFF);
|
||||
UC8176_Refresh();
|
||||
}
|
||||
|
||||
@@ -192,15 +175,16 @@ static void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
||||
EPD_WriteByte(0x01);
|
||||
}
|
||||
|
||||
void UC8176_Write_Paritial(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool invertColor)
|
||||
void UC8176_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
||||
{
|
||||
epd_model_t *EPD = epd_get();
|
||||
uint16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
|
||||
x -= x % 8; // byte boundary
|
||||
w = wb * 8; // byte boundary
|
||||
if (x + w > EPD_WIDTH || y + h > EPD_HEIGHT) return;
|
||||
if (x + w > EPD->width || y + h > EPD->height) return;
|
||||
EPD_WriteCommand(CMD_PTIN); // partial in
|
||||
_setPartialRamArea(x, y, w, h);
|
||||
if (EPD_BWR_MODE) {
|
||||
if (EPD->bwr) {
|
||||
EPD_WriteCommand(CMD_DTM1);
|
||||
for (uint16_t i = 0; i < h; i++) {
|
||||
for (uint16_t j = 0; j < w / 8; j++) {
|
||||
@@ -211,9 +195,9 @@ void UC8176_Write_Paritial(uint8_t *black, uint8_t *color, uint16_t x, uint16_t
|
||||
EPD_WriteCommand(CMD_DTM2);
|
||||
for (uint16_t i = 0; i < h; i++) {
|
||||
for (uint16_t j = 0; j < w / 8; j++) {
|
||||
if (EPD_BWR_MODE) {
|
||||
if (EPD->bwr) {
|
||||
uint8_t data = color ? color[j + i * wb] : 0xFF;
|
||||
EPD_WriteByte(invertColor ? ~data : data);
|
||||
EPD_WriteByte(EPD->invert_color ? ~data : data);
|
||||
} else {
|
||||
EPD_WriteByte(black[j + i * wb]);
|
||||
}
|
||||
@@ -222,16 +206,6 @@ void UC8176_Write_Paritial(uint8_t *black, uint8_t *color, uint16_t x, uint16_t
|
||||
EPD_WriteCommand(CMD_PTOUT); // partial out
|
||||
}
|
||||
|
||||
void UC8176_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
||||
{
|
||||
UC8176_Write_Paritial(black, color, x, y, w, h, false);
|
||||
}
|
||||
|
||||
void UC8276_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
||||
{
|
||||
UC8176_Write_Paritial(black, color, x, y, w, h, true);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
function : Enter sleep mode
|
||||
parameter:
|
||||
@@ -255,33 +229,32 @@ static epd_driver_t epd_drv_uc8176 = {
|
||||
.force_temp = UC8176_Force_Temp,
|
||||
};
|
||||
|
||||
static epd_driver_t epd_drv_uc8276 = {
|
||||
.init = UC8176_Init,
|
||||
.clear = UC8276_Clear,
|
||||
.write_image = UC8276_Write_Image,
|
||||
.refresh = UC8176_Refresh,
|
||||
.sleep = UC8176_Sleep,
|
||||
.read_temp = UC8176_Read_Temp,
|
||||
.force_temp = UC8176_Force_Temp,
|
||||
};
|
||||
|
||||
// UC8176 400x300 Black/White
|
||||
const epd_model_t epd_uc8176_420_bw = {
|
||||
.id = EPD_UC8176_420_BW,
|
||||
.drv = &epd_drv_uc8176,
|
||||
.res = EPD_RES_400x300,
|
||||
.width = 400,
|
||||
.height = 300,
|
||||
.bwr = false,
|
||||
.invert_color = false,
|
||||
};
|
||||
|
||||
// UC8176 400x300 Black/White/Red
|
||||
const epd_model_t epd_uc8176_420_bwr = {
|
||||
.id = EPD_UC8176_420_BWR,
|
||||
.drv = &epd_drv_uc8176,
|
||||
.res = EPD_RES_400x300,
|
||||
.width = 400,
|
||||
.height = 300,
|
||||
.bwr = true,
|
||||
.invert_color = false,
|
||||
};
|
||||
|
||||
// UC8276 400x300 Black/White/Red
|
||||
const epd_model_t epd_uc8276_420_bwr = {
|
||||
.id = EPD_UC8276_420_BWR,
|
||||
.drv = &epd_drv_uc8276,
|
||||
.res = EPD_RES_400x300,
|
||||
.drv = &epd_drv_uc8176,
|
||||
.width = 400,
|
||||
.height = 300,
|
||||
.bwr = true,
|
||||
.invert_color = true,
|
||||
};
|
||||
|
||||
@@ -68,7 +68,7 @@ static void DrawMonthDays(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar)
|
||||
int16_t y = (monthDayRows > 5 ? 69 : 72) + (firstDayWeek + i) / 7 * (monthDayRows > 5 ? 39 : 48);
|
||||
|
||||
if (day == tm->tm_mday) {
|
||||
GFX_fillCircle(gfx, x + 10, y + (monthDayRows > 5 ? 10 : 12), 20, GFX_RED);
|
||||
GFX_fillCircle(gfx, x + 11, y + (monthDayRows > 5 ? 10 : 12), 20, GFX_RED);
|
||||
GFX_setTextColor(gfx, GFX_WHITE, GFX_RED);
|
||||
} else {
|
||||
GFX_setTextColor(gfx, weekend ? GFX_RED : GFX_BLACK, GFX_WHITE);
|
||||
@@ -96,7 +96,7 @@ static void DrawMonthDays(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar)
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCalendar(epd_driver_t *driver, uint32_t timestamp)
|
||||
void DrawCalendar(epd_model_t *epd, uint32_t timestamp)
|
||||
{
|
||||
tm_t tm = {0};
|
||||
struct Lunar_Date Lunar;
|
||||
@@ -105,10 +105,10 @@ void DrawCalendar(epd_driver_t *driver, uint32_t timestamp)
|
||||
|
||||
Adafruit_GFX gfx;
|
||||
|
||||
if (EPD_BWR_MODE)
|
||||
GFX_begin_3c(&gfx, EPD_WIDTH, EPD_HEIGHT, PAGE_HEIGHT);
|
||||
if (epd->bwr)
|
||||
GFX_begin_3c(&gfx, epd->width, epd->height, PAGE_HEIGHT);
|
||||
else
|
||||
GFX_begin(&gfx, EPD_WIDTH, EPD_HEIGHT, PAGE_HEIGHT);
|
||||
GFX_begin(&gfx, epd->width, epd->height, PAGE_HEIGHT);
|
||||
|
||||
GFX_firstPage(&gfx);
|
||||
do {
|
||||
@@ -118,11 +118,11 @@ void DrawCalendar(epd_driver_t *driver, uint32_t timestamp)
|
||||
DrawDateHeader(&gfx, 10, 28, &tm, &Lunar);
|
||||
DrawWeekHeader(&gfx, 10, 32);
|
||||
DrawMonthDays(&gfx, &tm, &Lunar);
|
||||
} while(GFX_nextPage(&gfx, driver->write_image));
|
||||
} while(GFX_nextPage(&gfx, epd->drv->write_image));
|
||||
|
||||
GFX_end(&gfx);
|
||||
|
||||
NRF_LOG_DEBUG("display start\n");
|
||||
driver->refresh();
|
||||
epd->drv->refresh();
|
||||
NRF_LOG_DEBUG("display end\n");
|
||||
}
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
#include <stdint.h>
|
||||
#include "EPD_driver.h"
|
||||
|
||||
void DrawCalendar(epd_driver_t *driver, uint32_t timestamp);
|
||||
void DrawCalendar(epd_model_t *epd, uint32_t timestamp);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -148,7 +148,8 @@ function getImageData(canvas, driver, mode) {
|
||||
} else {
|
||||
let data = canvas2bytes(canvas, 'bw');
|
||||
if (mode.startsWith('bwr')) {
|
||||
data.push(...canvas2bytes(canvas, 'red', driver === '02'));
|
||||
const invert = (driver === '02') || (driver === '05');
|
||||
data.push(...canvas2bytes(canvas, 'red', invert));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user