mirror of
https://github.com/tsl0922/EPD-nRF5.git
synced 2025-12-06 15:42:48 +08:00
simplify epd driver api
This commit is contained in:
@@ -34,7 +34,7 @@ void epd_config_load(epd_config_t *cfg)
|
||||
fds_record_desc_t record_desc;
|
||||
fds_find_token_t ftok;
|
||||
|
||||
memset(cfg, 0xFF, sizeof(epd_config_t));
|
||||
memset(cfg, EPD_CONFIG_EMPTY, sizeof(epd_config_t));
|
||||
memset(&ftok, 0x00, sizeof(fds_find_token_t));
|
||||
|
||||
if (fds_record_find(CONFIG_FILE_ID, CONFIG_REC_KEY, &record_desc, &ftok) != NRF_SUCCESS) {
|
||||
@@ -99,3 +99,12 @@ void epd_config_save(epd_config_t *cfg)
|
||||
NRF_LOG_ERROR("epd_config_save: record write/update failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
bool epd_config_empty(epd_config_t *cfg)
|
||||
{
|
||||
for (uint8_t i = 0; i < EPD_CONFIG_SIZE; i++) {
|
||||
if (((uint8_t *)cfg)[i] != EPD_CONFIG_EMPTY)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#ifndef EPD_CONFIG_H__
|
||||
#define EPD_CONFIG_H__
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct
|
||||
@@ -9,13 +12,19 @@ typedef struct
|
||||
uint8_t rst_pin;
|
||||
uint8_t busy_pin;
|
||||
uint8_t bs_pin;
|
||||
uint8_t driver_id;
|
||||
uint8_t model_id;
|
||||
uint8_t wakeup_pin;
|
||||
uint8_t led_pin;
|
||||
uint8_t en_pin;
|
||||
} epd_config_t;
|
||||
|
||||
#define EPD_CONFIG_SIZE (sizeof(epd_config_t) / sizeof(uint8_t))
|
||||
#define EPD_CONFIG_EMPTY 0xFF
|
||||
|
||||
void epd_config_init(epd_config_t *cfg);
|
||||
void epd_config_load(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
|
||||
|
||||
160
EPD/EPD_driver.c
160
EPD/EPD_driver.c
@@ -21,6 +21,7 @@
|
||||
|
||||
#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;
|
||||
@@ -31,6 +32,13 @@ uint32_t EPD_BS_PIN = 13;
|
||||
uint32_t EPD_EN_PIN = 0xFF;
|
||||
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;
|
||||
|
||||
// Arduino like function wrappers
|
||||
|
||||
void pinMode(uint32_t pin, uint32_t mode)
|
||||
@@ -82,50 +90,13 @@ void delay(uint32_t ms)
|
||||
nrf_delay_ms(ms);
|
||||
}
|
||||
|
||||
// GPIO
|
||||
void DEV_Module_Init(void)
|
||||
{
|
||||
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) {
|
||||
pinMode(EPD_EN_PIN, OUTPUT);
|
||||
digitalWrite(EPD_EN_PIN, HIGH);
|
||||
}
|
||||
|
||||
pinMode(EPD_BS_PIN, OUTPUT);
|
||||
digitalWrite(EPD_BS_PIN, LOW);
|
||||
|
||||
digitalWrite(EPD_DC_PIN, LOW);
|
||||
digitalWrite(EPD_CS_PIN, LOW);
|
||||
digitalWrite(EPD_RST_PIN, HIGH);
|
||||
|
||||
if (EPD_LED_PIN != 0xFF) {
|
||||
pinMode(EPD_LED_PIN, OUTPUT);
|
||||
EPD_LED_ON();
|
||||
}
|
||||
}
|
||||
|
||||
void DEV_Module_Exit(void)
|
||||
{
|
||||
digitalWrite(EPD_DC_PIN, LOW);
|
||||
digitalWrite(EPD_CS_PIN, LOW);
|
||||
digitalWrite(EPD_RST_PIN, LOW);
|
||||
|
||||
DEV_SPI_Exit();
|
||||
|
||||
EPD_LED_OFF();
|
||||
}
|
||||
|
||||
// Hardware SPI (write only)
|
||||
|
||||
#define SPI_INSTANCE 0 /**< SPI instance index. */
|
||||
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */
|
||||
static bool spi_initialized = false;
|
||||
|
||||
void DEV_SPI_Init(void)
|
||||
static void EPD_SPI_Init(void)
|
||||
{
|
||||
if (spi_initialized) return;
|
||||
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
|
||||
@@ -140,30 +111,30 @@ void DEV_SPI_Init(void)
|
||||
spi_initialized = true;
|
||||
}
|
||||
|
||||
void DEV_SPI_Exit(void)
|
||||
static void EPD_SPI_Uninit(void)
|
||||
{
|
||||
if (!spi_initialized) return;
|
||||
nrf_drv_spi_uninit(&spi);
|
||||
spi_initialized = false;
|
||||
}
|
||||
|
||||
void DEV_SPI_WriteByte(uint8_t value)
|
||||
void EPD_SPI_WriteByte(uint8_t value)
|
||||
{
|
||||
DEV_SPI_Init();
|
||||
EPD_SPI_Init();
|
||||
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, &value, 1, NULL, 0));
|
||||
}
|
||||
|
||||
void DEV_SPI_WriteBytes(uint8_t *value, uint8_t len)
|
||||
void EPD_SPI_WriteBytes(uint8_t *value, uint8_t len)
|
||||
{
|
||||
DEV_SPI_Init();
|
||||
EPD_SPI_Init();
|
||||
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, value, len, NULL, 0));
|
||||
}
|
||||
|
||||
|
||||
// Software SPI (read / write)
|
||||
void DEV_SPI_WriteByte_SW(uint8_t data)
|
||||
void EPD_SPI_WriteByte_SW(uint8_t data)
|
||||
{
|
||||
DEV_SPI_Exit();
|
||||
EPD_SPI_Uninit();
|
||||
pinMode(EPD_MOSI_PIN, OUTPUT);
|
||||
digitalWrite(EPD_CS_PIN, LOW);
|
||||
for (int i = 0; i < 8; i++)
|
||||
@@ -178,9 +149,9 @@ void DEV_SPI_WriteByte_SW(uint8_t data)
|
||||
digitalWrite(EPD_CS_PIN, HIGH);
|
||||
}
|
||||
|
||||
uint8_t DEV_SPI_ReadByte_SW(void)
|
||||
uint8_t EPD_SPI_ReadByte_SW(void)
|
||||
{
|
||||
DEV_SPI_Exit();
|
||||
EPD_SPI_Uninit();
|
||||
uint8_t j = 0xff;
|
||||
pinMode(EPD_MOSI_PIN, INPUT);
|
||||
digitalWrite(EPD_CS_PIN, LOW);
|
||||
@@ -202,7 +173,7 @@ void EPD_WriteCommand_SW(uint8_t Reg)
|
||||
{
|
||||
digitalWrite(EPD_DC_PIN, LOW);
|
||||
digitalWrite(EPD_CS_PIN, LOW);
|
||||
DEV_SPI_WriteByte_SW(Reg);
|
||||
EPD_SPI_WriteByte_SW(Reg);
|
||||
digitalWrite(EPD_CS_PIN, HIGH);
|
||||
}
|
||||
|
||||
@@ -210,14 +181,14 @@ void EPD_WriteByte_SW(uint8_t Data)
|
||||
{
|
||||
digitalWrite(EPD_DC_PIN, HIGH);
|
||||
digitalWrite(EPD_CS_PIN, LOW);
|
||||
DEV_SPI_WriteByte_SW(Data);
|
||||
EPD_SPI_WriteByte_SW(Data);
|
||||
digitalWrite(EPD_CS_PIN, HIGH);
|
||||
}
|
||||
|
||||
uint8_t EPD_ReadByte_SW(void)
|
||||
{
|
||||
digitalWrite(EPD_DC_PIN, HIGH);
|
||||
return DEV_SPI_ReadByte_SW();
|
||||
return EPD_SPI_ReadByte_SW();
|
||||
}
|
||||
|
||||
|
||||
@@ -225,19 +196,19 @@ uint8_t EPD_ReadByte_SW(void)
|
||||
void EPD_WriteCommand(uint8_t Reg)
|
||||
{
|
||||
digitalWrite(EPD_DC_PIN, LOW);
|
||||
DEV_SPI_WriteByte(Reg);
|
||||
EPD_SPI_WriteByte(Reg);
|
||||
}
|
||||
|
||||
void EPD_WriteByte(uint8_t Data)
|
||||
{
|
||||
digitalWrite(EPD_DC_PIN, HIGH);
|
||||
DEV_SPI_WriteByte(Data);
|
||||
EPD_SPI_WriteByte(Data);
|
||||
}
|
||||
|
||||
void EPD_WriteData(uint8_t *Data, uint8_t Len)
|
||||
{
|
||||
digitalWrite(EPD_DC_PIN, HIGH);
|
||||
DEV_SPI_WriteBytes(Data, Len);
|
||||
EPD_SPI_WriteBytes(Data, Len);
|
||||
}
|
||||
|
||||
void EPD_Reset(uint32_t value, uint16_t duration)
|
||||
@@ -266,6 +237,44 @@ void EPD_WaitBusy(uint32_t value, uint16_t timeout)
|
||||
NRF_LOG_DEBUG("[EPD]: busy release\n");
|
||||
}
|
||||
|
||||
// GPIO
|
||||
void EPD_GPIO_Init(void)
|
||||
{
|
||||
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) {
|
||||
pinMode(EPD_EN_PIN, OUTPUT);
|
||||
digitalWrite(EPD_EN_PIN, HIGH);
|
||||
}
|
||||
|
||||
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) {
|
||||
pinMode(EPD_LED_PIN, OUTPUT);
|
||||
EPD_LED_ON();
|
||||
}
|
||||
}
|
||||
|
||||
void EPD_GPIO_Uninit(void)
|
||||
{
|
||||
digitalWrite(EPD_DC_PIN, LOW);
|
||||
digitalWrite(EPD_CS_PIN, LOW);
|
||||
digitalWrite(EPD_RST_PIN, LOW);
|
||||
|
||||
EPD_SPI_Uninit();
|
||||
|
||||
EPD_LED_OFF();
|
||||
}
|
||||
|
||||
// lED
|
||||
void EPD_LED_ON(void)
|
||||
@@ -286,41 +295,28 @@ void EPD_LED_TOGGLE(void)
|
||||
nrf_gpio_pin_toggle(EPD_LED_PIN);
|
||||
}
|
||||
|
||||
// EPD models
|
||||
extern epd_model_t epd_4in2;
|
||||
extern epd_model_t epd_4in2bv2;
|
||||
|
||||
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
|
||||
static epd_model_t *epd_models[] = {
|
||||
&epd_4in2,
|
||||
&epd_4in2bv2,
|
||||
};
|
||||
|
||||
/**< current EPD driver */
|
||||
static epd_driver_t *m_driver = NULL;
|
||||
|
||||
epd_driver_t *epd_driver_get(void)
|
||||
static epd_model_t *epd_model_get(epd_model_id_t id)
|
||||
{
|
||||
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];
|
||||
for (uint8_t i = 0; i < ARRAY_SIZE(epd_models); i++) {
|
||||
if (epd_models[i]->id == id) {
|
||||
return epd_models[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return epd_models[0];
|
||||
}
|
||||
|
||||
bool epd_driver_set(uint8_t id)
|
||||
epd_driver_t *epd_model_init(epd_model_id_t id)
|
||||
{
|
||||
epd_driver_t *driver = epd_driver_by_id(id);
|
||||
if (driver ) {
|
||||
m_driver = driver;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
epd_model_t *model = epd_model_get(id);
|
||||
model->drv->init(model->res, model->bwr);
|
||||
return model->drv;
|
||||
}
|
||||
|
||||
@@ -19,12 +19,16 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**< EPD driver IDs. */
|
||||
enum EPD_DRIVER_IDS
|
||||
#define BIT(n) (1UL << (n))
|
||||
|
||||
// Display resolution
|
||||
typedef enum
|
||||
{
|
||||
EPD_DRIVER_4IN2 = 1,
|
||||
EPD_DRIVER_4IN2B_V2 = 3,
|
||||
};
|
||||
EPD_RES_400x300,
|
||||
EPD_RES_320x300,
|
||||
EPD_RES_320x240,
|
||||
EPD_RES_200x300,
|
||||
} epd_res_t;
|
||||
|
||||
/**@brief EPD driver structure.
|
||||
*
|
||||
@@ -32,14 +36,8 @@ enum EPD_DRIVER_IDS
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t id; /**< driver ID. */
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
void (*init)(void); /**< Initialize the e-Paper register */
|
||||
void (*init)(epd_res_t res, bool bwr); /**< Initialize the e-Paper register */
|
||||
void (*clear)(void); /**< Clear screen */
|
||||
void (*send_command)(uint8_t Reg); /**< send command */
|
||||
void (*send_byte)(uint8_t Reg); /**< send byte */
|
||||
void (*send_data)(uint8_t *Data, uint8_t Len); /**< send data */
|
||||
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 */
|
||||
void (*sleep)(void); /**< Enter sleep mode */
|
||||
@@ -47,6 +45,21 @@ typedef struct
|
||||
void (*force_temp)(int8_t value); /**< Force temperature (will trigger OTP LUT switch) */
|
||||
} epd_driver_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EPD_4IN2 = 1,
|
||||
EPD_4IN2_V2 = 2,
|
||||
EPD_4IN2B_V2 = 3,
|
||||
} epd_model_id_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
epd_model_id_t id;
|
||||
epd_driver_t *drv;
|
||||
epd_res_t res;
|
||||
bool bwr;
|
||||
} epd_model_t;
|
||||
|
||||
extern uint32_t EPD_MOSI_PIN;
|
||||
extern uint32_t EPD_SCLK_PIN;
|
||||
extern uint32_t EPD_CS_PIN;
|
||||
@@ -57,6 +70,11 @@ 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)
|
||||
|
||||
@@ -72,21 +90,19 @@ uint32_t digitalRead(uint32_t pin);
|
||||
void delay(uint32_t ms);
|
||||
|
||||
// GPIO
|
||||
void DEV_Module_Init(void);
|
||||
void DEV_Module_Exit(void);
|
||||
void EPD_GPIO_Init(void);
|
||||
void EPD_GPIO_Uninit(void);
|
||||
|
||||
// Software SPI (read / write)
|
||||
void DEV_SPI_WriteByte_SW(uint8_t data);
|
||||
uint8_t DEV_SPI_ReadByte_SW(void);
|
||||
void EPD_SPI_WriteByte_SW(uint8_t data);
|
||||
uint8_t EPD_SPI_ReadByte_SW(void);
|
||||
void EPD_WriteCommand_SW(uint8_t Reg);
|
||||
void EPD_WriteByte_SW(uint8_t Data);
|
||||
uint8_t EPD_ReadByte_SW(void);
|
||||
|
||||
// Hardware SPI (write only)
|
||||
void DEV_SPI_Init(void);
|
||||
void DEV_SPI_Exit(void);
|
||||
void DEV_SPI_WriteByte(uint8_t value);
|
||||
void DEV_SPI_WriteBytes(uint8_t *value, uint8_t len);
|
||||
void EPD_SPI_WriteByte(uint8_t value);
|
||||
void EPD_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);
|
||||
@@ -99,8 +115,6 @@ void EPD_LED_ON(void);
|
||||
void EPD_LED_OFF(void);
|
||||
void EPD_LED_TOGGLE(void);
|
||||
|
||||
epd_driver_t *epd_driver_get(void);
|
||||
epd_driver_t *epd_driver_by_id(uint8_t id);
|
||||
bool epd_driver_set(uint8_t id);
|
||||
epd_driver_t *epd_model_init(epd_model_id_t id);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,12 +15,14 @@
|
||||
#include "ble_srv_common.h"
|
||||
#include "nrf_delay.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "app_scheduler.h"
|
||||
#include "EPD_service.h"
|
||||
#include "Calendar.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
#if defined(S112)
|
||||
#define EPD_CFG_DEFAULT {0x14, 0x13, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0xFF, 0x12, 0x07} // 52811
|
||||
//#define EPD_CFG_DEFAULT {0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x03, 0xFF, 0x0D, 0x02} // 52810
|
||||
//#define EPD_CFG_DEFAULT {0x14, 0x13, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0xFF, 0x12, 0x07} // 52811
|
||||
#define EPD_CFG_DEFAULT {0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x03, 0xFF, 0x0D, 0x02} // 52810
|
||||
#else
|
||||
#define EPD_CFG_DEFAULT {0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x01, 0x07}
|
||||
#endif
|
||||
@@ -33,8 +35,40 @@
|
||||
0X8D, 0X91, 0X28, 0XD8, 0X22, 0X36, 0X75, 0X62}}
|
||||
#define BLE_UUID_EPD_CHARACTERISTIC 0x0002
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#define EPD_CONFIG_SIZE (sizeof(epd_config_t) / sizeof(uint8_t))
|
||||
extern uint32_t timestamp(void); // defined in main.c
|
||||
|
||||
static uint16_t m_driver_refs = 0;
|
||||
|
||||
static void epd_gpio_init()
|
||||
{
|
||||
if (m_driver_refs == 0) {
|
||||
NRF_LOG_DEBUG("[EPD]: driver init\n");
|
||||
EPD_GPIO_Init();
|
||||
}
|
||||
m_driver_refs++;
|
||||
}
|
||||
|
||||
static void epd_gpio_uninit()
|
||||
{
|
||||
m_driver_refs--;
|
||||
if (m_driver_refs == 0) {
|
||||
NRF_LOG_DEBUG("[EPD]: driver exit\n");
|
||||
EPD_GPIO_Uninit();
|
||||
}
|
||||
}
|
||||
|
||||
static void calendar_update(void * p_event_data, uint16_t event_size)
|
||||
{
|
||||
epd_calendar_update_event_t *event = (epd_calendar_update_event_t *)p_event_data;
|
||||
ble_epd_t *p_epd = event->p_epd;
|
||||
|
||||
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_gpio_uninit();
|
||||
}
|
||||
|
||||
/**@brief Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the S110 SoftDevice.
|
||||
*
|
||||
@@ -44,9 +78,9 @@
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling the @ref BLE_GAP_EVT_DISCONNECTED event from the S110 SoftDevice.
|
||||
*
|
||||
* @param[in] p_epd EPD Service structure.
|
||||
@@ -56,6 +90,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_gpio_uninit();
|
||||
}
|
||||
|
||||
static void epd_service_process(ble_epd_t * p_epd, uint8_t * p_data, uint16_t length)
|
||||
@@ -73,7 +108,7 @@ 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;
|
||||
|
||||
DEV_Module_Exit();
|
||||
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];
|
||||
@@ -86,38 +121,34 @@ static void epd_service_process(ble_epd_t * p_epd, uint8_t * p_data, uint16_t le
|
||||
EPD_EN_PIN = p_epd->config.en_pin = p_data[8];
|
||||
epd_config_save(&p_epd->config);
|
||||
|
||||
DEV_Module_Init();
|
||||
EPD_GPIO_Init();
|
||||
break;
|
||||
|
||||
case EPD_CMD_INIT:
|
||||
if (length > 1)
|
||||
{
|
||||
if (epd_driver_set(p_data[1]))
|
||||
{
|
||||
p_epd->driver = epd_driver_get();
|
||||
p_epd->config.driver_id = p_epd->driver->id;
|
||||
case EPD_CMD_INIT: {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
NRF_LOG_INFO("[EPD]: DRIVER=%d\n", p_epd->driver->id);
|
||||
p_epd->driver->init();
|
||||
break;
|
||||
p_epd->driver = epd_model_init((epd_model_id_t)id);
|
||||
} break;
|
||||
|
||||
case EPD_CMD_CLEAR:
|
||||
p_epd->calendar_mode = false;
|
||||
p_epd->driver->clear();
|
||||
break;
|
||||
|
||||
case EPD_CMD_SEND_COMMAND:
|
||||
if (length < 2) return;
|
||||
p_epd->driver->send_command(p_data[1]);
|
||||
EPD_WriteCommand(p_data[1]);
|
||||
break;
|
||||
|
||||
case EPD_CMD_SEND_DATA:
|
||||
p_epd->driver->send_data(&p_data[1], length - 1);
|
||||
EPD_WriteData(&p_data[1], length - 1);
|
||||
break;
|
||||
|
||||
case EPD_CMD_DISPLAY:
|
||||
p_epd->calendar_mode = false;
|
||||
p_epd->driver->refresh();
|
||||
break;
|
||||
|
||||
@@ -253,21 +284,11 @@ static uint32_t epd_service_init(ble_epd_t * p_epd)
|
||||
|
||||
static void ble_epd_config_load(ble_epd_t * p_epd)
|
||||
{
|
||||
bool is_empty_config = true;
|
||||
|
||||
for (uint8_t i = 0; i < EPD_CONFIG_SIZE; i++)
|
||||
{
|
||||
if (((uint8_t *)&p_epd->config)[i] != 0xFF)
|
||||
{
|
||||
is_empty_config = false;
|
||||
}
|
||||
}
|
||||
NRF_LOG_DEBUG("is_empty_config: %d\n", is_empty_config);
|
||||
// write default config
|
||||
if (is_empty_config)
|
||||
if (epd_config_empty(&p_epd->config))
|
||||
{
|
||||
uint8_t cfg[] = EPD_CFG_DEFAULT;
|
||||
memcpy(&p_epd->config, cfg, ARRAY_SIZE(cfg));
|
||||
memcpy(&p_epd->config, cfg, sizeof(cfg));
|
||||
epd_config_save(&p_epd->config);
|
||||
}
|
||||
|
||||
@@ -282,11 +303,8 @@ static void ble_epd_config_load(ble_epd_t * p_epd)
|
||||
EPD_EN_PIN = p_epd->config.en_pin;
|
||||
EPD_LED_PIN = p_epd->config.led_pin;
|
||||
|
||||
epd_driver_set(p_epd->config.driver_id);
|
||||
p_epd->driver = epd_driver_get();
|
||||
|
||||
// blink LED on start
|
||||
if (EPD_LED_PIN != 0xFF)
|
||||
if (EPD_LED_PIN != EPD_CONFIG_EMPTY)
|
||||
{
|
||||
pinMode(EPD_LED_PIN, OUTPUT);
|
||||
EPD_LED_ON();
|
||||
@@ -352,3 +370,12 @@ uint32_t ble_epd_string_send(ble_epd_t * p_epd, uint8_t * p_string, uint16_t len
|
||||
|
||||
return sd_ble_gatts_hvx(p_epd->conn_handle, &hvx_params);
|
||||
}
|
||||
|
||||
void ble_epd_on_timer(ble_epd_t * p_epd, uint32_t timestamp, bool force_update)
|
||||
{
|
||||
// Update calendar on 00:00:00
|
||||
if (force_update || (p_epd->calendar_mode && timestamp % 86400 == 0)) {
|
||||
epd_calendar_update_event_t event = { p_epd, timestamp };
|
||||
app_sched_event_put(&event, sizeof(epd_calendar_update_event_t), calendar_update);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EPD_BLE_H__
|
||||
#define EPD_BLE_H__
|
||||
#ifndef EPD_SERVICE_H__
|
||||
#define EPD_SERVICE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
@@ -85,8 +85,17 @@ typedef struct
|
||||
epd_driver_t *driver; /**< current EPD driver */
|
||||
epd_config_t config; /**< EPD config */
|
||||
epd_callback_t epd_cmd_cb; /**< EPD callback */
|
||||
bool calendar_mode; /**< Calendar mode flag */
|
||||
} ble_epd_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ble_epd_t *p_epd;
|
||||
uint32_t timestamp;
|
||||
} epd_calendar_update_event_t;
|
||||
|
||||
#define EPD_CALENDAR_SCHD_EVENT_DATA_SIZE sizeof(epd_calendar_update_event_t)
|
||||
|
||||
/**@brief Function for preparing sleep mode.
|
||||
*
|
||||
* @param[in] p_epd EPD Service structure.
|
||||
@@ -130,6 +139,8 @@ void ble_epd_on_ble_evt(ble_epd_t * p_epd, ble_evt_t * p_ble_evt);
|
||||
*/
|
||||
uint32_t ble_epd_string_send(ble_epd_t * p_epd, uint8_t * p_string, uint16_t length);
|
||||
|
||||
void ble_epd_on_timer(ble_epd_t * p_epd, uint32_t timestamp, bool force_update);
|
||||
|
||||
#endif // EPD_BLE_H__
|
||||
|
||||
/** @} */
|
||||
|
||||
194
EPD/UC8176.c
194
EPD/UC8176.c
@@ -31,48 +31,52 @@
|
||||
#include "nrf_log.h"
|
||||
|
||||
// commands used by this driver
|
||||
enum {
|
||||
CMD_PSR = 0x00, // Panel Setting
|
||||
CMD_POF = 0x02, // Power OFF
|
||||
CMD_PON = 0x04, // Power ON
|
||||
CMD_DSLP = 0x07, // Deep sleep
|
||||
CMD_DTM1 = 0x10, // Display Start Transmission 1
|
||||
CMD_DRF = 0x12, // Display Refresh
|
||||
CMD_DTM2 = 0x13, // Display Start transmission 2
|
||||
CMD_TSC = 0x40, // Temperature Sensor Calibration
|
||||
CMD_CDI = 0x50, // Vcom and data interval setting
|
||||
CMD_PTL = 0x90, // Partial Window
|
||||
CMD_PTIN = 0x91, // Partial In
|
||||
CMD_PTOUT = 0x92, // Partial Out
|
||||
CMD_CCSET = 0xE0, // Cascade Setting
|
||||
CMD_TSSET = 0xE5, // Force Temperauture
|
||||
} UC8176_CMD;
|
||||
#define CMD_PSR 0x00 // Panel Setting
|
||||
#define CMD_POF 0x02 // Power OFF
|
||||
#define CMD_PON 0x04 // Power ON
|
||||
#define CMD_DSLP 0x07 // Deep sleep
|
||||
#define CMD_DTM1 0x10 // Display Start Transmission 1
|
||||
#define CMD_DRF 0x12 // Display Refresh
|
||||
#define CMD_DTM2 0x13 // Display Start transmission 2
|
||||
#define CMD_TSC 0x40 // Temperature Sensor Calibration
|
||||
#define CMD_CDI 0x50 // Vcom and data interval setting
|
||||
#define CMD_PTL 0x90 // Partial Window
|
||||
#define CMD_PTIN 0x91 // Partial In
|
||||
#define CMD_PTOUT 0x92 // Partial Out
|
||||
#define CMD_CCSET 0xE0 // Cascade Setting
|
||||
#define CMD_TSSET 0xE5 // Force Temperauture
|
||||
|
||||
// Display resolution
|
||||
#define EPD_4IN2_WIDTH 400
|
||||
#define EPD_4IN2_HEIGHT 300
|
||||
// PSR registers
|
||||
#define PSR_RES1 BIT(7)
|
||||
#define PSR_RES0 BIT(6)
|
||||
#define PSR_REG BIT(5)
|
||||
#define PSR_BWR BIT(4)
|
||||
#define PSR_UD BIT(3)
|
||||
#define PSR_SHL BIT(2)
|
||||
#define PSR_SHD BIT(1)
|
||||
#define PSR_RST BIT(0)
|
||||
|
||||
static void EPD_4IN2_PowerOn(void)
|
||||
static void UC8176_PowerOn(void)
|
||||
{
|
||||
EPD_WriteCommand(CMD_PON);
|
||||
EPD_WaitBusy(LOW, 100);
|
||||
}
|
||||
|
||||
static void EPD_4IN2_PowerOff(void)
|
||||
static void UC8176_PowerOff(void)
|
||||
{
|
||||
EPD_WriteCommand(CMD_POF);
|
||||
EPD_WaitBusy(LOW, 100);
|
||||
}
|
||||
|
||||
// Read temperature from driver chip
|
||||
int8_t EPD_4IN2_Read_Temp(void)
|
||||
int8_t UC8176_Read_Temp(void)
|
||||
{
|
||||
EPD_WriteCommand_SW(CMD_TSC);
|
||||
return (int8_t) EPD_ReadByte_SW();
|
||||
}
|
||||
|
||||
// Force temperature (will trigger OTP LUT switch)
|
||||
void EPD_4IN2_Force_Temp(int8_t value)
|
||||
void UC8176_Force_Temp(int8_t value)
|
||||
{
|
||||
EPD_WriteCommand_SW(CMD_CCSET);
|
||||
EPD_WriteByte_SW(0x02);
|
||||
@@ -84,15 +88,15 @@ void EPD_4IN2_Force_Temp(int8_t value)
|
||||
function : Turn On Display
|
||||
parameter:
|
||||
******************************************************************************/
|
||||
void EPD_4IN2_Refresh(void)
|
||||
void UC8176_Refresh(void)
|
||||
{
|
||||
NRF_LOG_DEBUG("[EPD]: refresh begin\n");
|
||||
EPD_4IN2_PowerOn();
|
||||
NRF_LOG_DEBUG("[EPD]: temperature: %d\n", EPD_4IN2_Read_Temp());
|
||||
UC8176_PowerOn();
|
||||
NRF_LOG_DEBUG("[EPD]: temperature: %d\n", UC8176_Read_Temp());
|
||||
EPD_WriteCommand(CMD_DRF);
|
||||
delay(100);
|
||||
EPD_WaitBusy(LOW, 20000);
|
||||
EPD_4IN2_PowerOff();
|
||||
EPD_WaitBusy(LOW, 30000);
|
||||
UC8176_PowerOff();
|
||||
NRF_LOG_DEBUG("[EPD]: refresh end\n");
|
||||
}
|
||||
|
||||
@@ -100,34 +104,53 @@ void EPD_4IN2_Refresh(void)
|
||||
function : Initialize the e-Paper register
|
||||
parameter:
|
||||
******************************************************************************/
|
||||
void EPD_4IN2_Init(void)
|
||||
void UC8176_Init(epd_res_t res, bool bwr)
|
||||
{
|
||||
EPD_BWR_MODE = bwr;
|
||||
EPD_Reset(HIGH, 10);
|
||||
|
||||
EPD_WriteCommand(CMD_PSR); // panel setting
|
||||
EPD_WriteByte(0x1f); // 400x300 B/W mode, LUT from OTP
|
||||
|
||||
EPD_WriteCommand(CMD_CDI); // VCOM AND DATA INTERVAL SETTING
|
||||
EPD_WriteByte(0x97); // LUTB=0 LUTW=1 interval=10
|
||||
}
|
||||
|
||||
void EPD_4IN2B_V2_Init(void)
|
||||
{
|
||||
EPD_Reset(HIGH, 200);
|
||||
|
||||
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;
|
||||
}
|
||||
NRF_LOG_DEBUG("[EPD]: PSR=%02x\n", psr);
|
||||
EPD_WriteCommand(CMD_PSR);
|
||||
EPD_WriteByte(0x0f); // 400x300 B/W/R mode, LUT from OTP
|
||||
EPD_WriteByte(psr);
|
||||
|
||||
if (!EPD_BWR_MODE) {
|
||||
EPD_WriteCommand(CMD_CDI);
|
||||
EPD_WriteByte(0x97);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
function : Clear screen
|
||||
parameter:
|
||||
******************************************************************************/
|
||||
void EPD_4IN2_Clear(void)
|
||||
void UC8176_Clear(void)
|
||||
{
|
||||
uint16_t Width, Height;
|
||||
Width = (EPD_4IN2_WIDTH % 8 == 0)? (EPD_4IN2_WIDTH / 8 ): (EPD_4IN2_WIDTH / 8 + 1);
|
||||
Height = EPD_4IN2_HEIGHT;
|
||||
uint16_t Width = (EPD_WIDTH % 8 == 0)? (EPD_WIDTH / 8 ): (EPD_WIDTH / 8 + 1);
|
||||
uint16_t Height = EPD_HEIGHT;
|
||||
|
||||
EPD_WriteCommand(CMD_DTM1);
|
||||
for (uint16_t j = 0; j < Height; j++) {
|
||||
@@ -143,7 +166,7 @@ void EPD_4IN2_Clear(void)
|
||||
}
|
||||
}
|
||||
|
||||
EPD_4IN2_Refresh();
|
||||
UC8176_Refresh();
|
||||
}
|
||||
|
||||
static void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
||||
@@ -164,41 +187,29 @@ static void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
||||
EPD_WriteByte(0x01);
|
||||
}
|
||||
|
||||
void EPD_4IN2_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
||||
void UC8176_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
||||
{
|
||||
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_4IN2_WIDTH || y + h > EPD_4IN2_HEIGHT) return;
|
||||
EPD_WriteCommand(CMD_PTIN); // partial in
|
||||
_setPartialRamArea(x, y, w, h);
|
||||
EPD_WriteCommand(CMD_DTM2);
|
||||
for (uint16_t i = 0; i < h; i++) {
|
||||
for (uint16_t j = 0; j < w / 8; j++) {
|
||||
EPD_WriteByte(black[j + i * wb]);
|
||||
}
|
||||
}
|
||||
EPD_WriteCommand(CMD_PTOUT); // partial out
|
||||
}
|
||||
|
||||
void EPD_4IN2B_V2_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
||||
{
|
||||
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_4IN2_WIDTH || y + h > EPD_4IN2_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) {
|
||||
EPD_WriteCommand(CMD_DTM1);
|
||||
for (uint16_t i = 0; i < h; i++) {
|
||||
for (uint16_t j = 0; j < w / 8; j++) {
|
||||
EPD_WriteByte(black ? black[j + i * wb] : 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
EPD_WriteByte(color ? color[j + i * wb] : 0xFF);
|
||||
else
|
||||
EPD_WriteByte(black[j + i * wb]);
|
||||
}
|
||||
}
|
||||
EPD_WriteCommand(CMD_PTOUT); // partial out
|
||||
@@ -208,42 +219,35 @@ void EPD_4IN2B_V2_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16
|
||||
function : Enter sleep mode
|
||||
parameter:
|
||||
******************************************************************************/
|
||||
void EPD_4IN2_Sleep(void)
|
||||
void UC8176_Sleep(void)
|
||||
{
|
||||
EPD_4IN2_PowerOff();
|
||||
UC8176_PowerOff();
|
||||
|
||||
EPD_WriteCommand(CMD_DSLP);
|
||||
EPD_WriteByte(0XA5);
|
||||
}
|
||||
|
||||
const epd_driver_t epd_driver_4in2 = {
|
||||
.id = EPD_DRIVER_4IN2,
|
||||
.width = EPD_4IN2_WIDTH,
|
||||
.height = EPD_4IN2_HEIGHT,
|
||||
.init = EPD_4IN2_Init,
|
||||
.clear = EPD_4IN2_Clear,
|
||||
.send_command = EPD_WriteCommand,
|
||||
.send_byte = EPD_WriteByte,
|
||||
.send_data = EPD_WriteData,
|
||||
.write_image = EPD_4IN2_Write_Image,
|
||||
.refresh = EPD_4IN2_Refresh,
|
||||
.sleep = EPD_4IN2_Sleep,
|
||||
.read_temp = EPD_4IN2_Read_Temp,
|
||||
.force_temp = EPD_4IN2_Force_Temp,
|
||||
// Declare driver and models
|
||||
static epd_driver_t epd_drv_uc8176 = {
|
||||
.init = UC8176_Init,
|
||||
.clear = UC8176_Clear,
|
||||
.write_image = UC8176_Write_Image,
|
||||
.refresh = UC8176_Refresh,
|
||||
.sleep = UC8176_Sleep,
|
||||
.read_temp = UC8176_Read_Temp,
|
||||
.force_temp = UC8176_Force_Temp,
|
||||
};
|
||||
|
||||
const epd_driver_t epd_driver_4in2bv2 = {
|
||||
.id = EPD_DRIVER_4IN2B_V2,
|
||||
.width = EPD_4IN2_WIDTH,
|
||||
.height = EPD_4IN2_HEIGHT,
|
||||
.init = EPD_4IN2B_V2_Init,
|
||||
.clear = EPD_4IN2_Clear,
|
||||
.send_command = EPD_WriteCommand,
|
||||
.send_byte = EPD_WriteByte,
|
||||
.send_data = EPD_WriteData,
|
||||
.write_image = EPD_4IN2B_V2_Write_Image,
|
||||
.refresh = EPD_4IN2_Refresh,
|
||||
.sleep = EPD_4IN2_Sleep,
|
||||
.read_temp = EPD_4IN2_Read_Temp,
|
||||
.force_temp = EPD_4IN2_Force_Temp,
|
||||
const epd_model_t epd_4in2 = {
|
||||
.id = EPD_4IN2,
|
||||
.drv = &epd_drv_uc8176,
|
||||
.res = EPD_RES_400x300,
|
||||
.bwr = false,
|
||||
};
|
||||
|
||||
const epd_model_t epd_4in2bv2 = {
|
||||
.id = EPD_4IN2B_V2,
|
||||
.drv = &epd_drv_uc8176,
|
||||
.res = EPD_RES_400x300,
|
||||
.bwr = true,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "Adafruit_GFX.h"
|
||||
#include "fonts.h"
|
||||
#include "EPD_driver.h"
|
||||
#include "Lunar.h"
|
||||
#include "Calendar.h"
|
||||
#include "nrf_log.h"
|
||||
@@ -73,11 +72,10 @@ static void DrawMonthDay(Adafruit_GFX *gfx, int16_t x, int16_t y, tm_t *tm, stru
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCalendar(uint32_t timestamp)
|
||||
void DrawCalendar(epd_driver_t *driver, uint32_t timestamp)
|
||||
{
|
||||
tm_t tm = {0};
|
||||
struct Lunar_Date Lunar;
|
||||
epd_driver_t *driver = epd_driver_get();
|
||||
|
||||
transformTime(timestamp, &tm);
|
||||
|
||||
@@ -87,10 +85,10 @@ void DrawCalendar(uint32_t timestamp)
|
||||
|
||||
Adafruit_GFX gfx;
|
||||
|
||||
if (driver->id == EPD_DRIVER_4IN2B_V2)
|
||||
GFX_begin_3c(&gfx, driver->width, driver->height, PAGE_HEIGHT);
|
||||
if (EPD_BWR_MODE)
|
||||
GFX_begin_3c(&gfx, EPD_WIDTH, EPD_HEIGHT, PAGE_HEIGHT);
|
||||
else
|
||||
GFX_begin(&gfx, driver->width, driver->height, PAGE_HEIGHT);
|
||||
GFX_begin(&gfx, EPD_WIDTH, EPD_HEIGHT, PAGE_HEIGHT);
|
||||
|
||||
GFX_firstPage(&gfx);
|
||||
do {
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
#define __CALENDAR_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "EPD_driver.h"
|
||||
|
||||
void DrawCalendar(uint32_t timestamp);
|
||||
void DrawCalendar(epd_driver_t *driver, uint32_t timestamp);
|
||||
|
||||
#endif
|
||||
|
||||
60
main.c
60
main.c
@@ -36,7 +36,6 @@
|
||||
#include "nrf_drv_gpiote.h"
|
||||
#include "nrf_pwr_mgmt.h"
|
||||
#include "EPD_service.h"
|
||||
#include "Calendar.h"
|
||||
|
||||
#include "nrf_log.h"
|
||||
#include "nrf_log_ctrl.h"
|
||||
@@ -74,7 +73,7 @@
|
||||
#define NEXT_CONN_PARAMS_UPDATE_DELAY TIMER_TICKS(30000) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
|
||||
#define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */
|
||||
|
||||
#define SCHED_MAX_EVENT_DATA_SIZE 0 /**< Maximum size of scheduler events. */
|
||||
#define SCHED_MAX_EVENT_DATA_SIZE EPD_CALENDAR_SCHD_EVENT_DATA_SIZE /**< Maximum size of scheduler events. */
|
||||
#define SCHED_QUEUE_SIZE 10 /**< Maximum number of events in the scheduler queue. */
|
||||
|
||||
#define CLOCK_TIMER_INTERVAL TIMER_TICKS(1000) /**< Clock timer interval (ticks). */
|
||||
@@ -85,49 +84,14 @@
|
||||
NRF_BLE_GATT_DEF(m_gatt); /**< GATT module instance. */
|
||||
BLE_ADVERTISING_DEF(m_advertising); /**< Advertising module instance. */
|
||||
#endif
|
||||
static uint16_t m_driver_refs = 0;
|
||||
static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
|
||||
static ble_uuid_t m_adv_uuids[] = {{BLE_UUID_EPD_SERVICE, \
|
||||
EPD_SERVICE_UUID_TYPE}}; /**< Universally unique service identifier. */
|
||||
|
||||
BLE_EPD_DEF(m_epd); /**< Structure to identify the EPD Service. */
|
||||
static uint32_t m_timestamp = 1735689600; /**< Current timestamp. */
|
||||
static bool m_calendar_mode = false; /**< Whether we are in calendar mode */
|
||||
|
||||
APP_TIMER_DEF(m_clock_timer_id); /**< Clock timer. */
|
||||
|
||||
static void epd_driver_init()
|
||||
{
|
||||
if (m_driver_refs == 0) {
|
||||
NRF_LOG_DEBUG("[EPD]: driver init\n");
|
||||
DEV_Module_Init();
|
||||
}
|
||||
m_driver_refs++;
|
||||
}
|
||||
|
||||
static void epd_driver_exit()
|
||||
{
|
||||
m_driver_refs--;
|
||||
if (m_driver_refs == 0) {
|
||||
NRF_LOG_DEBUG("[EPD]: driver exit\n");
|
||||
DEV_Module_Exit();
|
||||
}
|
||||
}
|
||||
|
||||
static void calendar_update(void * p_event_data, uint16_t event_size)
|
||||
{
|
||||
m_calendar_mode = true;
|
||||
epd_driver_init();
|
||||
m_epd.driver->init();
|
||||
DrawCalendar(m_timestamp);
|
||||
epd_driver_exit();
|
||||
}
|
||||
|
||||
static uint32_t calendar_update_schedule(void)
|
||||
{
|
||||
return app_sched_event_put(NULL, 0, calendar_update);
|
||||
}
|
||||
|
||||
/**@brief Callback function for asserts in the SoftDevice.
|
||||
*
|
||||
* @details This function will be called in case of an assert in the SoftDevice.
|
||||
@@ -150,9 +114,7 @@ static void clock_timer_timeout_handler(void * p_context)
|
||||
|
||||
m_timestamp++;
|
||||
|
||||
// Update calendar on 00:00:00
|
||||
if (m_calendar_mode && m_timestamp % 86400 == 0)
|
||||
calendar_update_schedule();
|
||||
ble_epd_on_timer(&m_epd, m_timestamp, false);
|
||||
}
|
||||
|
||||
/**@brief Function for the Event Scheduler initialization.
|
||||
@@ -217,14 +179,9 @@ bool epd_cmd_callback(uint8_t cmd, uint8_t *data, uint16_t len)
|
||||
m_timestamp = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
|
||||
m_timestamp += (len > 4 ? (int8_t)data[4] : 8) * 60 * 60; // timezone
|
||||
app_timer_start(m_clock_timer_id, CLOCK_TIMER_INTERVAL, NULL);
|
||||
calendar_update_schedule();
|
||||
ble_epd_on_timer(&m_epd, m_timestamp, true);
|
||||
return true;
|
||||
|
||||
case EPD_CMD_CLEAR:
|
||||
case EPD_CMD_DISPLAY:
|
||||
m_calendar_mode = false;
|
||||
break;
|
||||
|
||||
case EPD_CMD_SYS_SLEEP:
|
||||
sleep_mode_enter();
|
||||
return true;
|
||||
@@ -385,7 +342,7 @@ static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
|
||||
case BLE_ADV_EVT_IDLE:
|
||||
NRF_LOG_INFO("advertising timeout\n");
|
||||
if (m_epd.config.wakeup_pin != 0xFF) {
|
||||
if (m_calendar_mode)
|
||||
if (m_epd.calendar_mode)
|
||||
setup_wakeup_pin(m_epd.config.wakeup_pin);
|
||||
else
|
||||
sleep_mode_enter();
|
||||
@@ -409,13 +366,11 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
|
||||
case BLE_GAP_EVT_CONNECTED:
|
||||
NRF_LOG_INFO("CONNECTED\n");
|
||||
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
|
||||
epd_driver_init();
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVT_DISCONNECTED:
|
||||
NRF_LOG_INFO("DISCONNECTED\n");
|
||||
m_conn_handle = BLE_CONN_HANDLE_INVALID;
|
||||
epd_driver_exit();
|
||||
#if !defined(S112)
|
||||
advertising_start();
|
||||
#endif
|
||||
@@ -642,18 +597,17 @@ static void advertising_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NRF_MODULE_ENABLED(NRF_LOG)
|
||||
static uint32_t timestamp_func(void)
|
||||
// return current timestamp
|
||||
uint32_t timestamp(void)
|
||||
{
|
||||
return m_timestamp;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**@brief Function for initializing the nrf log module.
|
||||
*/
|
||||
static void log_init(void)
|
||||
{
|
||||
APP_ERROR_CHECK(NRF_LOG_INIT(timestamp_func));
|
||||
APP_ERROR_CHECK(NRF_LOG_INIT(timestamp));
|
||||
#if defined(S112)
|
||||
NRF_LOG_DEFAULT_BACKENDS_INIT();
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user