mirror of
https://github.com/tsl0922/EPD-nRF5.git
synced 2025-12-06 15:42:48 +08:00
clang-format code
This commit is contained in:
6
.clang-format
Normal file
6
.clang-format
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
BasedOnStyle: Google
|
||||||
|
Language: Cpp
|
||||||
|
ColumnLimit: 120
|
||||||
|
IndentWidth: 4
|
||||||
|
TabWidth: 4
|
||||||
|
UseTab: Never
|
||||||
@@ -1,26 +1,25 @@
|
|||||||
#include <string.h>
|
|
||||||
#include "nordic_common.h"
|
|
||||||
#include "fds.h"
|
|
||||||
#include "app_scheduler.h"
|
|
||||||
#include "EPD_config.h"
|
#include "EPD_config.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "app_scheduler.h"
|
||||||
|
#include "fds.h"
|
||||||
|
#include "nordic_common.h"
|
||||||
#include "nrf_log.h"
|
#include "nrf_log.h"
|
||||||
|
|
||||||
#define CONFIG_FILE_ID 0x0000
|
#define CONFIG_FILE_ID 0x0000
|
||||||
#define CONFIG_REC_KEY 0x0001
|
#define CONFIG_REC_KEY 0x0001
|
||||||
|
|
||||||
static void fds_evt_handler(fds_evt_t const * const p_fds_evt)
|
static void fds_evt_handler(fds_evt_t const* const p_fds_evt) {
|
||||||
{
|
|
||||||
NRF_LOG_DEBUG("fds evt: id=%d result=%d\n", p_fds_evt->id, p_fds_evt->result);
|
NRF_LOG_DEBUG("fds evt: id=%d result=%d\n", p_fds_evt->id, p_fds_evt->result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void run_fds_gc(void * p_event_data, uint16_t event_size)
|
static void run_fds_gc(void* p_event_data, uint16_t event_size) {
|
||||||
{
|
|
||||||
NRF_LOG_DEBUG("run garbage collection (fds_gc)\n");
|
NRF_LOG_DEBUG("run garbage collection (fds_gc)\n");
|
||||||
fds_gc();
|
fds_gc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void epd_config_init(epd_config_t *cfg)
|
void epd_config_init(epd_config_t* cfg) {
|
||||||
{
|
|
||||||
ret_code_t ret;
|
ret_code_t ret;
|
||||||
|
|
||||||
ret = fds_register(fds_evt_handler);
|
ret = fds_register(fds_evt_handler);
|
||||||
@@ -38,11 +37,10 @@ void epd_config_init(epd_config_t *cfg)
|
|||||||
run_fds_gc(NULL, 0);
|
run_fds_gc(NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void epd_config_read(epd_config_t *cfg)
|
void epd_config_read(epd_config_t* cfg) {
|
||||||
{
|
fds_flash_record_t flash_record;
|
||||||
fds_flash_record_t flash_record;
|
fds_record_desc_t record_desc;
|
||||||
fds_record_desc_t record_desc;
|
fds_find_token_t ftok;
|
||||||
fds_find_token_t ftok;
|
|
||||||
|
|
||||||
memset(cfg, 0xFF, sizeof(epd_config_t));
|
memset(cfg, 0xFF, sizeof(epd_config_t));
|
||||||
memset(&ftok, 0x00, sizeof(fds_find_token_t));
|
memset(&ftok, 0x00, sizeof(fds_find_token_t));
|
||||||
@@ -64,12 +62,11 @@ void epd_config_read(epd_config_t *cfg)
|
|||||||
fds_record_close(&record_desc);
|
fds_record_close(&record_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void epd_config_write(epd_config_t *cfg)
|
void epd_config_write(epd_config_t* cfg) {
|
||||||
{
|
ret_code_t ret;
|
||||||
ret_code_t ret;
|
fds_record_t record;
|
||||||
fds_record_t record;
|
fds_record_desc_t record_desc;
|
||||||
fds_record_desc_t record_desc;
|
fds_find_token_t ftok;
|
||||||
fds_find_token_t ftok;
|
|
||||||
|
|
||||||
record.file_id = CONFIG_FILE_ID;
|
record.file_id = CONFIG_FILE_ID;
|
||||||
record.key = CONFIG_REC_KEY;
|
record.key = CONFIG_REC_KEY;
|
||||||
@@ -93,16 +90,14 @@ void epd_config_write(epd_config_t *cfg)
|
|||||||
|
|
||||||
if (ret != NRF_SUCCESS) {
|
if (ret != NRF_SUCCESS) {
|
||||||
NRF_LOG_ERROR("epd_config_save: record write/update failed, code=%d\n", ret);
|
NRF_LOG_ERROR("epd_config_save: record write/update failed, code=%d\n", ret);
|
||||||
if (ret == FDS_ERR_NO_SPACE_IN_FLASH)
|
if (ret == FDS_ERR_NO_SPACE_IN_FLASH) app_sched_event_put(NULL, 0, run_fds_gc);
|
||||||
app_sched_event_put(NULL, 0, run_fds_gc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void epd_config_clear(epd_config_t *cfg)
|
void epd_config_clear(epd_config_t* cfg) {
|
||||||
{
|
ret_code_t ret;
|
||||||
ret_code_t ret;
|
fds_record_desc_t record_desc;
|
||||||
fds_record_desc_t record_desc;
|
fds_find_token_t ftok;
|
||||||
fds_find_token_t ftok;
|
|
||||||
|
|
||||||
memset(&ftok, 0x00, sizeof(fds_find_token_t));
|
memset(&ftok, 0x00, sizeof(fds_find_token_t));
|
||||||
if (fds_record_find(CONFIG_FILE_ID, CONFIG_REC_KEY, &record_desc, &ftok) != NRF_SUCCESS) {
|
if (fds_record_find(CONFIG_FILE_ID, CONFIG_REC_KEY, &record_desc, &ftok) != NRF_SUCCESS) {
|
||||||
@@ -116,11 +111,9 @@ void epd_config_clear(epd_config_t *cfg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool epd_config_empty(epd_config_t *cfg)
|
bool epd_config_empty(epd_config_t* cfg) {
|
||||||
{
|
|
||||||
for (uint8_t i = 0; i < EPD_CONFIG_SIZE; i++) {
|
for (uint8_t i = 0; i < EPD_CONFIG_SIZE; i++) {
|
||||||
if (((uint8_t *)cfg)[i] != 0xFF)
|
if (((uint8_t*)cfg)[i] != 0xFF) return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
uint8_t mosi_pin;
|
uint8_t mosi_pin;
|
||||||
uint8_t sclk_pin;
|
uint8_t sclk_pin;
|
||||||
uint8_t cs_pin;
|
uint8_t cs_pin;
|
||||||
@@ -21,11 +20,11 @@ typedef struct
|
|||||||
} epd_config_t;
|
} epd_config_t;
|
||||||
|
|
||||||
#define EPD_CONFIG_SIZE (sizeof(epd_config_t) / sizeof(uint8_t))
|
#define EPD_CONFIG_SIZE (sizeof(epd_config_t) / sizeof(uint8_t))
|
||||||
|
|
||||||
void epd_config_init(epd_config_t *cfg);
|
void epd_config_init(epd_config_t* cfg);
|
||||||
void epd_config_read(epd_config_t *cfg);
|
void epd_config_read(epd_config_t* cfg);
|
||||||
void epd_config_write(epd_config_t *cfg);
|
void epd_config_write(epd_config_t* cfg);
|
||||||
void epd_config_clear(epd_config_t *cfg);
|
void epd_config_clear(epd_config_t* cfg);
|
||||||
bool epd_config_empty(epd_config_t *cfg);
|
bool epd_config_empty(epd_config_t* cfg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
130
EPD/EPD_driver.c
130
EPD/EPD_driver.c
@@ -1,6 +1,7 @@
|
|||||||
|
#include "EPD_driver.h"
|
||||||
|
|
||||||
#include "app_error.h"
|
#include "app_error.h"
|
||||||
#include "nrf_drv_spi.h"
|
#include "nrf_drv_spi.h"
|
||||||
#include "EPD_driver.h"
|
|
||||||
#include "nrf_log.h"
|
#include "nrf_log.h"
|
||||||
|
|
||||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||||
@@ -17,26 +18,22 @@ static uint32_t EPD_BS_PIN = 13;
|
|||||||
static uint32_t EPD_EN_PIN = 0xFF;
|
static uint32_t EPD_EN_PIN = 0xFF;
|
||||||
static uint32_t EPD_LED_PIN = 0xFF;
|
static uint32_t EPD_LED_PIN = 0xFF;
|
||||||
|
|
||||||
#define SPI_INSTANCE 0 /**< SPI instance index. */
|
#define SPI_INSTANCE 0 /**< SPI instance index. */
|
||||||
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */
|
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */
|
||||||
|
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
#define HAL_SPI_INSTANCE spi.u.spi.p_reg
|
#define HAL_SPI_INSTANCE spi.u.spi.p_reg
|
||||||
#else
|
#else
|
||||||
#define HAL_SPI_INSTANCE spi.p_registers
|
#define HAL_SPI_INSTANCE spi.p_registers
|
||||||
nrf_gpio_pin_dir_t nrf_gpio_pin_dir_get(uint32_t pin)
|
nrf_gpio_pin_dir_t nrf_gpio_pin_dir_get(uint32_t pin) {
|
||||||
{
|
NRF_GPIO_Type* reg = nrf_gpio_pin_port_decode(&pin);
|
||||||
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin);
|
return (nrf_gpio_pin_dir_t)((reg->PIN_CNF[pin] & GPIO_PIN_CNF_DIR_Msk) >> GPIO_PIN_CNF_DIR_Pos);
|
||||||
return (nrf_gpio_pin_dir_t)((reg->PIN_CNF[pin] &
|
|
||||||
GPIO_PIN_CNF_DIR_Msk) >> GPIO_PIN_CNF_DIR_Pos);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Arduino like function wrappers
|
// Arduino like function wrappers
|
||||||
void pinMode(uint32_t pin, uint32_t mode)
|
void pinMode(uint32_t pin, uint32_t mode) {
|
||||||
{
|
switch (mode) {
|
||||||
switch (mode)
|
|
||||||
{
|
|
||||||
case INPUT:
|
case INPUT:
|
||||||
nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_NOPULL);
|
nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_NOPULL);
|
||||||
break;
|
break;
|
||||||
@@ -59,8 +56,7 @@ void pinMode(uint32_t pin, uint32_t mode)
|
|||||||
// GPIO
|
// GPIO
|
||||||
static uint16_t m_driver_refs = 0;
|
static uint16_t m_driver_refs = 0;
|
||||||
|
|
||||||
void EPD_GPIO_Load(epd_config_t *cfg)
|
void EPD_GPIO_Load(epd_config_t* cfg) {
|
||||||
{
|
|
||||||
if (cfg == NULL) return;
|
if (cfg == NULL) return;
|
||||||
EPD_MOSI_PIN = cfg->mosi_pin;
|
EPD_MOSI_PIN = cfg->mosi_pin;
|
||||||
EPD_SCLK_PIN = cfg->sclk_pin;
|
EPD_SCLK_PIN = cfg->sclk_pin;
|
||||||
@@ -73,8 +69,7 @@ void EPD_GPIO_Load(epd_config_t *cfg)
|
|||||||
EPD_LED_PIN = cfg->led_pin;
|
EPD_LED_PIN = cfg->led_pin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EPD_GPIO_Init(void)
|
void EPD_GPIO_Init(void) {
|
||||||
{
|
|
||||||
if (m_driver_refs++ > 0) return;
|
if (m_driver_refs++ > 0) return;
|
||||||
|
|
||||||
pinMode(EPD_DC_PIN, OUTPUT);
|
pinMode(EPD_DC_PIN, OUTPUT);
|
||||||
@@ -103,14 +98,12 @@ void EPD_GPIO_Init(void)
|
|||||||
digitalWrite(EPD_DC_PIN, LOW);
|
digitalWrite(EPD_DC_PIN, LOW);
|
||||||
digitalWrite(EPD_RST_PIN, HIGH);
|
digitalWrite(EPD_RST_PIN, HIGH);
|
||||||
|
|
||||||
if (EPD_LED_PIN != 0xFF)
|
if (EPD_LED_PIN != 0xFF) pinMode(EPD_LED_PIN, OUTPUT);
|
||||||
pinMode(EPD_LED_PIN, OUTPUT);
|
|
||||||
|
|
||||||
EPD_LED_ON();
|
EPD_LED_ON();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EPD_GPIO_Uninit(void)
|
void EPD_GPIO_Uninit(void) {
|
||||||
{
|
|
||||||
if (--m_driver_refs > 0) return;
|
if (--m_driver_refs > 0) return;
|
||||||
|
|
||||||
EPD_LED_OFF();
|
EPD_LED_OFF();
|
||||||
@@ -120,8 +113,7 @@ void EPD_GPIO_Uninit(void)
|
|||||||
digitalWrite(EPD_DC_PIN, LOW);
|
digitalWrite(EPD_DC_PIN, LOW);
|
||||||
digitalWrite(EPD_CS_PIN, LOW);
|
digitalWrite(EPD_CS_PIN, LOW);
|
||||||
digitalWrite(EPD_RST_PIN, LOW);
|
digitalWrite(EPD_RST_PIN, LOW);
|
||||||
if (EPD_EN_PIN != 0xFF)
|
if (EPD_EN_PIN != 0xFF) digitalWrite(EPD_EN_PIN, LOW);
|
||||||
digitalWrite(EPD_EN_PIN, LOW);
|
|
||||||
|
|
||||||
// reset pin state
|
// reset pin state
|
||||||
pinMode(EPD_MOSI_PIN, DEFAULT);
|
pinMode(EPD_MOSI_PIN, DEFAULT);
|
||||||
@@ -136,8 +128,7 @@ void EPD_GPIO_Uninit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SPI
|
// SPI
|
||||||
void EPD_SPI_Write(uint8_t *value, uint8_t len)
|
void EPD_SPI_Write(uint8_t* value, uint8_t len) {
|
||||||
{
|
|
||||||
nrf_gpio_pin_dir_t dir = nrf_gpio_pin_dir_get(EPD_MOSI_PIN);
|
nrf_gpio_pin_dir_t dir = nrf_gpio_pin_dir_get(EPD_MOSI_PIN);
|
||||||
if (dir != NRF_GPIO_PIN_DIR_OUTPUT) {
|
if (dir != NRF_GPIO_PIN_DIR_OUTPUT) {
|
||||||
pinMode(EPD_MOSI_PIN, OUTPUT);
|
pinMode(EPD_MOSI_PIN, OUTPUT);
|
||||||
@@ -146,8 +137,7 @@ void EPD_SPI_Write(uint8_t *value, uint8_t len)
|
|||||||
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, value, len, NULL, 0));
|
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, value, len, NULL, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EPD_SPI_Read(uint8_t *value, uint8_t len)
|
void EPD_SPI_Read(uint8_t* value, uint8_t len) {
|
||||||
{
|
|
||||||
nrf_gpio_pin_dir_t dir = nrf_gpio_pin_dir_get(EPD_MOSI_PIN);
|
nrf_gpio_pin_dir_t dir = nrf_gpio_pin_dir_get(EPD_MOSI_PIN);
|
||||||
if (dir != NRF_GPIO_PIN_DIR_INPUT) {
|
if (dir != NRF_GPIO_PIN_DIR_INPUT) {
|
||||||
pinMode(EPD_MOSI_PIN, INPUT);
|
pinMode(EPD_MOSI_PIN, INPUT);
|
||||||
@@ -157,43 +147,36 @@ void EPD_SPI_Read(uint8_t *value, uint8_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EPD
|
// EPD
|
||||||
void EPD_WriteCmd(uint8_t cmd)
|
void EPD_WriteCmd(uint8_t cmd) {
|
||||||
{
|
|
||||||
digitalWrite(EPD_DC_PIN, LOW);
|
digitalWrite(EPD_DC_PIN, LOW);
|
||||||
EPD_SPI_Write(&cmd, 1);
|
EPD_SPI_Write(&cmd, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EPD_WriteData(uint8_t *value, uint8_t len)
|
void EPD_WriteData(uint8_t* value, uint8_t len) {
|
||||||
{
|
|
||||||
digitalWrite(EPD_DC_PIN, HIGH);
|
digitalWrite(EPD_DC_PIN, HIGH);
|
||||||
EPD_SPI_Write(value, len);
|
EPD_SPI_Write(value, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EPD_ReadData(uint8_t *value, uint8_t len)
|
void EPD_ReadData(uint8_t* value, uint8_t len) {
|
||||||
{
|
|
||||||
digitalWrite(EPD_DC_PIN, HIGH);
|
digitalWrite(EPD_DC_PIN, HIGH);
|
||||||
EPD_SPI_Read(value, len);
|
EPD_SPI_Read(value, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EPD_WriteByte(uint8_t value)
|
void EPD_WriteByte(uint8_t value) {
|
||||||
{
|
|
||||||
digitalWrite(EPD_DC_PIN, HIGH);
|
digitalWrite(EPD_DC_PIN, HIGH);
|
||||||
EPD_SPI_Write(&value, 1);
|
EPD_SPI_Write(&value, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EPD_ReadByte(void)
|
uint8_t EPD_ReadByte(void) {
|
||||||
{
|
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
digitalWrite(EPD_DC_PIN, HIGH);
|
digitalWrite(EPD_DC_PIN, HIGH);
|
||||||
EPD_SPI_Read(&value, 1);
|
EPD_SPI_Read(&value, 1);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EPD_FillRAM(uint8_t cmd, uint8_t value, uint32_t len)
|
void EPD_FillRAM(uint8_t cmd, uint8_t value, uint32_t len) {
|
||||||
{
|
|
||||||
uint8_t buffer[BUFFER_SIZE];
|
uint8_t buffer[BUFFER_SIZE];
|
||||||
for (uint8_t i = 0; i < BUFFER_SIZE; i++)
|
for (uint8_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = value;
|
||||||
buffer[i] = value;
|
|
||||||
|
|
||||||
EPD_WriteCmd(cmd);
|
EPD_WriteCmd(cmd);
|
||||||
uint16_t remaining = len;
|
uint16_t remaining = len;
|
||||||
@@ -204,8 +187,7 @@ void EPD_FillRAM(uint8_t cmd, uint8_t value, uint32_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EPD_Reset(uint32_t value, uint16_t duration)
|
void EPD_Reset(uint32_t value, uint16_t duration) {
|
||||||
{
|
|
||||||
digitalWrite(EPD_RST_PIN, value);
|
digitalWrite(EPD_RST_PIN, value);
|
||||||
delay(duration);
|
delay(duration);
|
||||||
digitalWrite(EPD_RST_PIN, (value == LOW) ? HIGH : LOW);
|
digitalWrite(EPD_RST_PIN, (value == LOW) ? HIGH : LOW);
|
||||||
@@ -214,8 +196,7 @@ void EPD_Reset(uint32_t value, uint16_t duration)
|
|||||||
delay(duration);
|
delay(duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EPD_WaitBusy(uint32_t value, uint16_t timeout)
|
void EPD_WaitBusy(uint32_t value, uint16_t timeout) {
|
||||||
{
|
|
||||||
uint32_t led_status = digitalRead(EPD_LED_PIN);
|
uint32_t led_status = digitalRead(EPD_LED_PIN);
|
||||||
|
|
||||||
NRF_LOG_DEBUG("[EPD]: check busy\n");
|
NRF_LOG_DEBUG("[EPD]: check busy\n");
|
||||||
@@ -238,26 +219,19 @@ void EPD_WaitBusy(uint32_t value, uint16_t timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lED
|
// lED
|
||||||
void EPD_LED_ON(void)
|
void EPD_LED_ON(void) {
|
||||||
{
|
if (EPD_LED_PIN != 0xFF) digitalWrite(EPD_LED_PIN, LOW);
|
||||||
if (EPD_LED_PIN != 0xFF)
|
|
||||||
digitalWrite(EPD_LED_PIN, LOW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EPD_LED_OFF(void)
|
void EPD_LED_OFF(void) {
|
||||||
{
|
if (EPD_LED_PIN != 0xFF) digitalWrite(EPD_LED_PIN, HIGH);
|
||||||
if (EPD_LED_PIN != 0xFF)
|
|
||||||
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);
|
||||||
if (EPD_LED_PIN != 0xFF)
|
|
||||||
nrf_gpio_pin_toggle(EPD_LED_PIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EPD_LED_BLINK(void)
|
void EPD_LED_BLINK(void) {
|
||||||
{
|
|
||||||
if (EPD_LED_PIN != 0xFF) {
|
if (EPD_LED_PIN != 0xFF) {
|
||||||
pinMode(EPD_LED_PIN, OUTPUT);
|
pinMode(EPD_LED_PIN, OUTPUT);
|
||||||
digitalWrite(EPD_LED_PIN, LOW);
|
digitalWrite(EPD_LED_PIN, LOW);
|
||||||
@@ -268,18 +242,18 @@ void EPD_LED_BLINK(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float EPD_ReadVoltage(void)
|
float EPD_ReadVoltage(void) {
|
||||||
{
|
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
volatile int16_t value = 0;
|
volatile int16_t value = 0;
|
||||||
NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_10bit;
|
NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_10bit;
|
||||||
NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos);
|
NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos);
|
||||||
NRF_SAADC->CH[0].CONFIG = ((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos) & SAADC_CH_CONFIG_RESP_Msk)
|
NRF_SAADC->CH[0].CONFIG =
|
||||||
| ((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk)
|
((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos) & SAADC_CH_CONFIG_RESP_Msk) |
|
||||||
| ((SAADC_CH_CONFIG_GAIN_Gain1_6 << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk)
|
((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk) |
|
||||||
| ((SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_Msk)
|
((SAADC_CH_CONFIG_GAIN_Gain1_6 << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk) |
|
||||||
| ((SAADC_CH_CONFIG_TACQ_3us << SAADC_CH_CONFIG_TACQ_Pos) & SAADC_CH_CONFIG_TACQ_Msk)
|
((SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_Msk) |
|
||||||
| ((SAADC_CH_CONFIG_MODE_SE << SAADC_CH_CONFIG_MODE_Pos) & SAADC_CH_CONFIG_MODE_Msk);
|
((SAADC_CH_CONFIG_TACQ_3us << SAADC_CH_CONFIG_TACQ_Pos) & SAADC_CH_CONFIG_TACQ_Msk) |
|
||||||
|
((SAADC_CH_CONFIG_MODE_SE << SAADC_CH_CONFIG_MODE_Pos) & SAADC_CH_CONFIG_MODE_Msk);
|
||||||
NRF_SAADC->CH[0].PSELN = SAADC_CH_PSELN_PSELN_NC;
|
NRF_SAADC->CH[0].PSELN = SAADC_CH_PSELN_PSELN_NC;
|
||||||
NRF_SAADC->CH[0].PSELP = SAADC_CH_PSELP_PSELP_VDD;
|
NRF_SAADC->CH[0].PSELP = SAADC_CH_PSELP_PSELP_VDD;
|
||||||
NRF_SAADC->RESULT.PTR = (uint32_t)&value;
|
NRF_SAADC->RESULT.PTR = (uint32_t)&value;
|
||||||
@@ -303,7 +277,7 @@ float EPD_ReadVoltage(void)
|
|||||||
(ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) |
|
(ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) |
|
||||||
(ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
|
(ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
|
||||||
NRF_ADC->TASKS_START = 1;
|
NRF_ADC->TASKS_START = 1;
|
||||||
while(!NRF_ADC->EVENTS_END);
|
while (!NRF_ADC->EVENTS_END);
|
||||||
NRF_ADC->EVENTS_END = 0;
|
NRF_ADC->EVENTS_END = 0;
|
||||||
uint16_t value = NRF_ADC->RESULT;
|
uint16_t value = NRF_ADC->RESULT;
|
||||||
NRF_ADC->TASKS_STOP = 1;
|
NRF_ADC->TASKS_STOP = 1;
|
||||||
@@ -327,24 +301,14 @@ extern epd_model_t epd_ssd1677_750_bw;
|
|||||||
extern epd_model_t epd_jd79668_420_bwry;
|
extern epd_model_t epd_jd79668_420_bwry;
|
||||||
extern epd_model_t epd_jd79668_750_bwry;
|
extern epd_model_t epd_jd79668_750_bwry;
|
||||||
|
|
||||||
static epd_model_t *epd_models[] = {
|
static epd_model_t* epd_models[] = {
|
||||||
&epd_uc8176_420_bw,
|
&epd_uc8176_420_bw, &epd_uc8176_420_bwr, &epd_uc8159_750_bw, &epd_uc8159_750_bwr,
|
||||||
&epd_uc8176_420_bwr,
|
&epd_uc8179_750_bw, &epd_uc8179_750_bwr, &epd_ssd1619_420_bwr, &epd_ssd1619_420_bw,
|
||||||
&epd_uc8159_750_bw,
|
&epd_ssd1677_750_bwr, &epd_ssd1677_750_bw, &epd_jd79668_420_bwry, &epd_jd79668_750_bwry,
|
||||||
&epd_uc8159_750_bwr,
|
|
||||||
&epd_uc8179_750_bw,
|
|
||||||
&epd_uc8179_750_bwr,
|
|
||||||
&epd_ssd1619_420_bwr,
|
|
||||||
&epd_ssd1619_420_bw,
|
|
||||||
&epd_ssd1677_750_bwr,
|
|
||||||
&epd_ssd1677_750_bw,
|
|
||||||
&epd_jd79668_420_bwry,
|
|
||||||
&epd_jd79668_750_bwry,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
epd_model_t *epd_init(epd_model_id_t id)
|
epd_model_t* epd_init(epd_model_id_t id) {
|
||||||
{
|
epd_model_t* epd = NULL;
|
||||||
epd_model_t *epd = NULL;
|
|
||||||
for (uint8_t i = 0; i < ARRAY_SIZE(epd_models); i++) {
|
for (uint8_t i = 0; i < ARRAY_SIZE(epd_models); i++) {
|
||||||
if (epd_models[i]->id == id) {
|
if (epd_models[i]->id == id) {
|
||||||
epd = epd_models[i];
|
epd = epd_models[i];
|
||||||
|
|||||||
255
EPD/EPD_driver.h
255
EPD/EPD_driver.h
@@ -4,13 +4,13 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "EPD_config.h"
|
||||||
#include "nrf_delay.h"
|
#include "nrf_delay.h"
|
||||||
#include "nrf_gpio.h"
|
#include "nrf_gpio.h"
|
||||||
#include "EPD_config.h"
|
|
||||||
|
|
||||||
// EPD driver IC types
|
// EPD driver IC types
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
EPD_DRIVER_IC_UC8159 = 0x10,
|
EPD_DRIVER_IC_UC8159 = 0x10,
|
||||||
EPD_DRIVER_IC_UC8176 = 0x11,
|
EPD_DRIVER_IC_UC8176 = 0x11,
|
||||||
EPD_DRIVER_IC_UC8179 = 0x12,
|
EPD_DRIVER_IC_UC8179 = 0x12,
|
||||||
@@ -22,114 +22,112 @@ typedef enum
|
|||||||
|
|
||||||
// UC81xx commands
|
// UC81xx commands
|
||||||
enum {
|
enum {
|
||||||
UC81xx_PSR = 0x00, // Panel Setting
|
UC81xx_PSR = 0x00, // Panel Setting
|
||||||
UC81xx_PWR = 0x01, // Power Setting
|
UC81xx_PWR = 0x01, // Power Setting
|
||||||
UC81xx_POF = 0x02, // Power OFF
|
UC81xx_POF = 0x02, // Power OFF
|
||||||
UC81xx_PFS = 0x03, // Power OFF Sequence Setting
|
UC81xx_PFS = 0x03, // Power OFF Sequence Setting
|
||||||
UC81xx_PON = 0x04, // Power ON
|
UC81xx_PON = 0x04, // Power ON
|
||||||
UC81xx_PMES = 0x05, // Power ON Measure
|
UC81xx_PMES = 0x05, // Power ON Measure
|
||||||
UC81xx_BTST = 0x06, // Booster Soft Start
|
UC81xx_BTST = 0x06, // Booster Soft Start
|
||||||
UC81xx_DSLP = 0x07, // Deep sleep
|
UC81xx_DSLP = 0x07, // Deep sleep
|
||||||
UC81xx_DTM1 = 0x10, // Display Start Transmission 1
|
UC81xx_DTM1 = 0x10, // Display Start Transmission 1
|
||||||
UC81xx_DSP = 0x11, // Data Stop
|
UC81xx_DSP = 0x11, // Data Stop
|
||||||
UC81xx_DRF = 0x12, // Display Refresh
|
UC81xx_DRF = 0x12, // Display Refresh
|
||||||
UC81xx_DTM2 = 0x13, // Display Start transmission 2
|
UC81xx_DTM2 = 0x13, // Display Start transmission 2
|
||||||
UC81xx_LUTC = 0x20, // VCOM LUT (LUTC)
|
UC81xx_LUTC = 0x20, // VCOM LUT (LUTC)
|
||||||
UC81xx_LUTWW = 0x21, // W2W LUT (LUTWW)
|
UC81xx_LUTWW = 0x21, // W2W LUT (LUTWW)
|
||||||
UC81xx_LUTBW = 0x22, // B2W LUT (LUTBW / LUTR)
|
UC81xx_LUTBW = 0x22, // B2W LUT (LUTBW / LUTR)
|
||||||
UC81xx_LUTWB = 0x23, // W2B LUT (LUTWB / LUTW)
|
UC81xx_LUTWB = 0x23, // W2B LUT (LUTWB / LUTW)
|
||||||
UC81xx_LUTBB = 0x24, // B2B LUT (LUTBB / LUTB)
|
UC81xx_LUTBB = 0x24, // B2B LUT (LUTBB / LUTB)
|
||||||
UC81xx_PLL = 0x30, // PLL control
|
UC81xx_PLL = 0x30, // PLL control
|
||||||
UC81xx_TSC = 0x40, // Temperature Sensor Calibration
|
UC81xx_TSC = 0x40, // Temperature Sensor Calibration
|
||||||
UC81xx_TSE = 0x41, // Temperature Sensor Selection
|
UC81xx_TSE = 0x41, // Temperature Sensor Selection
|
||||||
UC81xx_TSW = 0x42, // Temperature Sensor Write
|
UC81xx_TSW = 0x42, // Temperature Sensor Write
|
||||||
UC81xx_TSR = 0x43, // Temperature Sensor Read
|
UC81xx_TSR = 0x43, // Temperature Sensor Read
|
||||||
UC81xx_CDI = 0x50, // Vcom and data interval setting
|
UC81xx_CDI = 0x50, // Vcom and data interval setting
|
||||||
UC81xx_LPD = 0x51, // Lower Power Detection
|
UC81xx_LPD = 0x51, // Lower Power Detection
|
||||||
UC81xx_TCON = 0x60, // TCON setting
|
UC81xx_TCON = 0x60, // TCON setting
|
||||||
UC81xx_TRES = 0x61, // Resolution setting
|
UC81xx_TRES = 0x61, // Resolution setting
|
||||||
UC81xx_GSST = 0x65, // GSST Setting
|
UC81xx_GSST = 0x65, // GSST Setting
|
||||||
UC81xx_REV = 0x70, // Revision
|
UC81xx_REV = 0x70, // Revision
|
||||||
UC81xx_FLG = 0x71, // Get Status
|
UC81xx_FLG = 0x71, // Get Status
|
||||||
UC81xx_AMV = 0x80, // Auto Measurement Vcom
|
UC81xx_AMV = 0x80, // Auto Measurement Vcom
|
||||||
UC81xx_VV = 0x81, // Read Vcom Value
|
UC81xx_VV = 0x81, // Read Vcom Value
|
||||||
UC81xx_VDCS = 0x82, // VCM_DC Setting
|
UC81xx_VDCS = 0x82, // VCM_DC Setting
|
||||||
UC81xx_PTL = 0x90, // Partial Window
|
UC81xx_PTL = 0x90, // Partial Window
|
||||||
UC81xx_PTIN = 0x91, // Partial In
|
UC81xx_PTIN = 0x91, // Partial In
|
||||||
UC81xx_PTOUT = 0x92, // Partial Out
|
UC81xx_PTOUT = 0x92, // Partial Out
|
||||||
UC81xx_PGM = 0xA0, // Program Mode
|
UC81xx_PGM = 0xA0, // Program Mode
|
||||||
UC81xx_APG = 0xA1, // Active Progrmming
|
UC81xx_APG = 0xA1, // Active Progrmming
|
||||||
UC81xx_ROTP = 0xA2, // Read OTP
|
UC81xx_ROTP = 0xA2, // Read OTP
|
||||||
UC81xx_CCSET = 0xE0, // Cascade Setting
|
UC81xx_CCSET = 0xE0, // Cascade Setting
|
||||||
UC81xx_PWS = 0xE3, // Power Saving
|
UC81xx_PWS = 0xE3, // Power Saving
|
||||||
UC81xx_TSSET = 0xE5, // Force Temperauture
|
UC81xx_TSSET = 0xE5, // Force Temperauture
|
||||||
};
|
};
|
||||||
|
|
||||||
// SSD16xx commands
|
// SSD16xx commands
|
||||||
enum {
|
enum {
|
||||||
SSD16xx_GDO_CTR = 0x01, // Driver Output control
|
SSD16xx_GDO_CTR = 0x01, // Driver Output control
|
||||||
SSD16xx_GDV_CTRL = 0x03, // Gate Driving voltage Control
|
SSD16xx_GDV_CTRL = 0x03, // Gate Driving voltage Control
|
||||||
SSD16xx_SDV_CTRL = 0x04, // Source Driving voltage Control
|
SSD16xx_SDV_CTRL = 0x04, // Source Driving voltage Control
|
||||||
SSD16xx_SOFTSTART = 0x0C, // Booster Soft start Control
|
SSD16xx_SOFTSTART = 0x0C, // Booster Soft start Control
|
||||||
SSD16xx_GSCAN_START = 0x0F, // Gate scan start position
|
SSD16xx_GSCAN_START = 0x0F, // Gate scan start position
|
||||||
SSD16xx_SLEEP_MODE = 0x10, // Deep Sleep mode
|
SSD16xx_SLEEP_MODE = 0x10, // Deep Sleep mode
|
||||||
SSD16xx_ENTRY_MODE = 0x11, // Data Entry mode setting
|
SSD16xx_ENTRY_MODE = 0x11, // Data Entry mode setting
|
||||||
SSD16xx_SW_RESET = 0x12, // SW RESET
|
SSD16xx_SW_RESET = 0x12, // SW RESET
|
||||||
SSD16xx_HV_RD_DETECT = 0x14, // HV Ready Detection
|
SSD16xx_HV_RD_DETECT = 0x14, // HV Ready Detection
|
||||||
SSD16xx_VCI_DETECT = 0x15, // VCI Detection
|
SSD16xx_VCI_DETECT = 0x15, // VCI Detection
|
||||||
SSD16xx_TSENSOR_CTRL = 0x18, // Temperature Sensor Control
|
SSD16xx_TSENSOR_CTRL = 0x18, // Temperature Sensor Control
|
||||||
SSD16xx_TSENSOR_WRITE = 0x1A, // Temperature Sensor Control (Write to temperature register)
|
SSD16xx_TSENSOR_WRITE = 0x1A, // Temperature Sensor Control (Write to temperature register)
|
||||||
SSD16xx_TSENSOR_READ = 0x1B, // Temperature Sensor Control (Read from temperature register)
|
SSD16xx_TSENSOR_READ = 0x1B, // Temperature Sensor Control (Read from temperature register)
|
||||||
SSD16xx_TSENSOR_WRITE_EXT = 0x1C, // Temperature Sensor Control (Write Command to External temperature sensor)
|
SSD16xx_TSENSOR_WRITE_EXT = 0x1C, // Temperature Sensor Control (Write Command to External temperature sensor)
|
||||||
SSD16xx_MASTER_ACTIVATE = 0x20, // Master Activation
|
SSD16xx_MASTER_ACTIVATE = 0x20, // Master Activation
|
||||||
SSD16xx_DISP_CTRL1 = 0x21, // Display Update Control 1
|
SSD16xx_DISP_CTRL1 = 0x21, // Display Update Control 1
|
||||||
SSD16xx_DISP_CTRL2 = 0x22, // Display Update Control 2
|
SSD16xx_DISP_CTRL2 = 0x22, // Display Update Control 2
|
||||||
SSD16xx_WRITE_RAM1 = 0x24, // Write RAM (BW)
|
SSD16xx_WRITE_RAM1 = 0x24, // Write RAM (BW)
|
||||||
SSD16xx_WRITE_RAM2 = 0x26, // Write RAM (RED)
|
SSD16xx_WRITE_RAM2 = 0x26, // Write RAM (RED)
|
||||||
SSD16xx_READ_RAM = 0x27, // Read RAM
|
SSD16xx_READ_RAM = 0x27, // Read RAM
|
||||||
SSD16xx_VCOM_SENSE = 0x28, // VCOM Sense
|
SSD16xx_VCOM_SENSE = 0x28, // VCOM Sense
|
||||||
SSD16xx_VCOM_SENSE_DURATON = 0x29, // VCOM Sense Duration
|
SSD16xx_VCOM_SENSE_DURATON = 0x29, // VCOM Sense Duration
|
||||||
SSD16xx_PRGM_VCOM_OTP = 0x2A, // Program VCOM OTP
|
SSD16xx_PRGM_VCOM_OTP = 0x2A, // Program VCOM OTP
|
||||||
SSD16xx_VCOM_CTRL = 0x2B, // Write Register for VCOM Control
|
SSD16xx_VCOM_CTRL = 0x2B, // Write Register for VCOM Control
|
||||||
SSD16xx_VCOM_VOLTAGE = 0x2C, // Write VCOM register
|
SSD16xx_VCOM_VOLTAGE = 0x2C, // Write VCOM register
|
||||||
SSD16xx_READ_OTP_REG = 0x2D, // OTP Register Read for Display Option
|
SSD16xx_READ_OTP_REG = 0x2D, // OTP Register Read for Display Option
|
||||||
SSD16xx_READ_USER_ID = 0x2E, // User ID Read
|
SSD16xx_READ_USER_ID = 0x2E, // User ID Read
|
||||||
SSD16xx_READ_STATUS = 0x2F, // Status Bit Read
|
SSD16xx_READ_STATUS = 0x2F, // Status Bit Read
|
||||||
SSD16xx_PRGM_WS_OTP = 0x30, // Program WS OTP
|
SSD16xx_PRGM_WS_OTP = 0x30, // Program WS OTP
|
||||||
SSD16xx_LOAD_WS_OTP = 0x31, // Load WS OTP
|
SSD16xx_LOAD_WS_OTP = 0x31, // Load WS OTP
|
||||||
SSD16xx_WRITE_LUT = 0x32, // Write LUT register
|
SSD16xx_WRITE_LUT = 0x32, // Write LUT register
|
||||||
SSD16xx_READ_LUT = 0x33, // Read LUT
|
SSD16xx_READ_LUT = 0x33, // Read LUT
|
||||||
SSD16xx_CRC_CALC = 0x34, // CRC calculation
|
SSD16xx_CRC_CALC = 0x34, // CRC calculation
|
||||||
SSD16xx_CRC_STATUS = 0x35, // CRC Status Read
|
SSD16xx_CRC_STATUS = 0x35, // CRC Status Read
|
||||||
SSD16xx_PRGM_OTP_SELECTION = 0x36, // Program OTP selection
|
SSD16xx_PRGM_OTP_SELECTION = 0x36, // Program OTP selection
|
||||||
SSD16xx_OTP_SELECTION_CTRL = 0x37, // Write OTP selection
|
SSD16xx_OTP_SELECTION_CTRL = 0x37, // Write OTP selection
|
||||||
SSD16xx_USER_ID_CTRL = 0x38, // Write Register for User ID
|
SSD16xx_USER_ID_CTRL = 0x38, // Write Register for User ID
|
||||||
SSD16xx_OTP_PROG_MODE = 0x39, // OTP program mode
|
SSD16xx_OTP_PROG_MODE = 0x39, // OTP program mode
|
||||||
SSD16xx_DUMMY_LINE = 0x3A, // Set dummy line period
|
SSD16xx_DUMMY_LINE = 0x3A, // Set dummy line period
|
||||||
SSD16xx_GATE_LINE_WIDTH = 0x3B, // Set Gate line width
|
SSD16xx_GATE_LINE_WIDTH = 0x3B, // Set Gate line width
|
||||||
SSD16xx_BORDER_CTRL = 0x3C, // Border Waveform Control
|
SSD16xx_BORDER_CTRL = 0x3C, // Border Waveform Control
|
||||||
SSD16xx_RAM_READ_CTRL = 0x41, // Read RAM Option
|
SSD16xx_RAM_READ_CTRL = 0x41, // Read RAM Option
|
||||||
SSD16xx_RAM_XPOS = 0x44, // Set RAM X - address Start / End position
|
SSD16xx_RAM_XPOS = 0x44, // Set RAM X - address Start / End position
|
||||||
SSD16xx_RAM_YPOS = 0x45, // Set Ram Y- address Start / End position
|
SSD16xx_RAM_YPOS = 0x45, // Set Ram Y- address Start / End position
|
||||||
SSD16xx_AUTO_WRITE_RED_RAM = 0x46, // Auto Write RED RAM for Regular Pattern
|
SSD16xx_AUTO_WRITE_RED_RAM = 0x46, // Auto Write RED RAM for Regular Pattern
|
||||||
SSD16xx_AUTO_WRITE_BW_RAM = 0x47, // Auto Write B/W RAM for Regular Pattern
|
SSD16xx_AUTO_WRITE_BW_RAM = 0x47, // Auto Write B/W RAM for Regular Pattern
|
||||||
SSD16xx_RAM_XCOUNT = 0x4E, // Set RAM X address counter
|
SSD16xx_RAM_XCOUNT = 0x4E, // Set RAM X address counter
|
||||||
SSD16xx_RAM_YCOUNT = 0x4F, // Set RAM Y address counter
|
SSD16xx_RAM_YCOUNT = 0x4F, // Set RAM Y address counter
|
||||||
SSD16xx_ANALOG_BLOCK_CTRL = 0x74, // Set Analog Block Control
|
SSD16xx_ANALOG_BLOCK_CTRL = 0x74, // Set Analog Block Control
|
||||||
SSD16xx_DIGITAL_BLOCK_CTRL = 0x7E, // Set Digital Block Control
|
SSD16xx_DIGITAL_BLOCK_CTRL = 0x7E, // Set Digital Block Control
|
||||||
SSD16xx_NOP = 0x7F, // NOP
|
SSD16xx_NOP = 0x7F, // NOP
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
BW = 1,
|
BW = 1,
|
||||||
BWR = 2,
|
BWR = 2,
|
||||||
BWRY = 3,
|
BWRY = 3,
|
||||||
} epd_color_t;
|
} epd_color_t;
|
||||||
|
|
||||||
// Do not change the existing IDs!
|
// Do not change the existing IDs!
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
EPD_UC8176_420_BW = 1,
|
EPD_UC8176_420_BW = 1,
|
||||||
EPD_UC8176_420_BWR = 3,
|
EPD_UC8176_420_BWR = 3,
|
||||||
EPD_SSD1619_420_BWR = 2,
|
EPD_SSD1619_420_BWR = 2,
|
||||||
@@ -146,11 +144,10 @@ typedef enum
|
|||||||
|
|
||||||
struct epd_driver;
|
struct epd_driver;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
epd_model_id_t id;
|
epd_model_id_t id;
|
||||||
epd_color_t color;
|
epd_color_t color;
|
||||||
struct epd_driver *drv;
|
struct epd_driver* drv;
|
||||||
uint16_t width;
|
uint16_t width;
|
||||||
uint16_t height;
|
uint16_t height;
|
||||||
} epd_model_t;
|
} epd_model_t;
|
||||||
@@ -159,26 +156,26 @@ typedef struct
|
|||||||
*
|
*
|
||||||
* @details This structure contains epd driver functions.
|
* @details This structure contains epd driver functions.
|
||||||
*/
|
*/
|
||||||
typedef struct epd_driver
|
typedef struct epd_driver {
|
||||||
{
|
epd_driver_ic_t ic; /**< EPD driver IC type */
|
||||||
epd_driver_ic_t ic; /**< EPD driver IC type */
|
void (*init)(epd_model_t* epd); /**< Initialize the e-Paper register */
|
||||||
void (*init)(epd_model_t *epd); /**< Initialize the e-Paper register */
|
void (*clear)(epd_model_t* epd, bool refresh); /**< Clear screen */
|
||||||
void (*clear)(epd_model_t *epd, bool refresh); /**< Clear screen */
|
void (*write_image)(epd_model_t* epd, uint8_t* black, uint8_t* color, uint16_t x, uint16_t y, uint16_t w,
|
||||||
void (*write_image)(epd_model_t *epd, uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h); /**< write image */
|
uint16_t h); /**< write image */
|
||||||
void (*write_ram)(epd_model_t *epd, uint8_t cfg, uint8_t *data, uint8_t len); /* write data to epd ram */
|
void (*write_ram)(epd_model_t* epd, uint8_t cfg, uint8_t* data, uint8_t len); /* write data to epd ram */
|
||||||
void (*refresh)(epd_model_t *epd); /**< Sends the image buffer in RAM to e-Paper and displays */
|
void (*refresh)(epd_model_t* epd); /**< Sends the image buffer in RAM to e-Paper and displays */
|
||||||
void (*sleep)(epd_model_t *epd); /**< Enter sleep mode */
|
void (*sleep)(epd_model_t* epd); /**< Enter sleep mode */
|
||||||
int8_t (*read_temp)(epd_model_t *epd); /**< Read temperature from driver chip */
|
int8_t (*read_temp)(epd_model_t* epd); /**< Read temperature from driver chip */
|
||||||
} epd_driver_t;
|
} epd_driver_t;
|
||||||
|
|
||||||
#define LOW (0x0)
|
#define LOW (0x0)
|
||||||
#define HIGH (0x1)
|
#define HIGH (0x1)
|
||||||
|
|
||||||
#define DEFAULT (0xFF)
|
#define DEFAULT (0xFF)
|
||||||
#define INPUT (0x0)
|
#define INPUT (0x0)
|
||||||
#define OUTPUT (0x1)
|
#define OUTPUT (0x1)
|
||||||
#define INPUT_PULLUP (0x2)
|
#define INPUT_PULLUP (0x2)
|
||||||
#define INPUT_PULLDOWN (0x3)
|
#define INPUT_PULLDOWN (0x3)
|
||||||
|
|
||||||
// Arduino like function wrappers
|
// Arduino like function wrappers
|
||||||
void pinMode(uint32_t pin, uint32_t mode);
|
void pinMode(uint32_t pin, uint32_t mode);
|
||||||
@@ -187,24 +184,24 @@ void pinMode(uint32_t pin, uint32_t mode);
|
|||||||
#define delay(ms) nrf_delay_ms(ms)
|
#define delay(ms) nrf_delay_ms(ms)
|
||||||
|
|
||||||
// GPIO
|
// GPIO
|
||||||
void EPD_GPIO_Load(epd_config_t *cfg);
|
void EPD_GPIO_Load(epd_config_t* cfg);
|
||||||
void EPD_GPIO_Init(void);
|
void EPD_GPIO_Init(void);
|
||||||
void EPD_GPIO_Uninit(void);
|
void EPD_GPIO_Uninit(void);
|
||||||
|
|
||||||
// SPI
|
// SPI
|
||||||
void EPD_SPI_Write(uint8_t *value, uint8_t len);
|
void EPD_SPI_Write(uint8_t* value, uint8_t len);
|
||||||
void EPD_SPI_Read(uint8_t *value, uint8_t len);
|
void EPD_SPI_Read(uint8_t* value, uint8_t len);
|
||||||
|
|
||||||
// EPD
|
// EPD
|
||||||
void EPD_WriteCmd(uint8_t cmd);
|
void EPD_WriteCmd(uint8_t cmd);
|
||||||
void EPD_WriteData(uint8_t *value, uint8_t len);
|
void EPD_WriteData(uint8_t* value, uint8_t len);
|
||||||
void EPD_ReadData(uint8_t *value, uint8_t len);
|
void EPD_ReadData(uint8_t* value, uint8_t len);
|
||||||
void EPD_WriteByte(uint8_t value);
|
void EPD_WriteByte(uint8_t value);
|
||||||
uint8_t EPD_ReadByte(void);
|
uint8_t EPD_ReadByte(void);
|
||||||
#define EPD_Write(cmd, ...) \
|
#define EPD_Write(cmd, ...) \
|
||||||
do { \
|
do { \
|
||||||
uint8_t _data[] = {__VA_ARGS__}; \
|
uint8_t _data[] = {__VA_ARGS__}; \
|
||||||
EPD_WriteCmd(cmd); \
|
EPD_WriteCmd(cmd); \
|
||||||
EPD_WriteData(_data, sizeof(_data)); \
|
EPD_WriteData(_data, sizeof(_data)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
void EPD_FillRAM(uint8_t cmd, uint8_t value, uint32_t len);
|
void EPD_FillRAM(uint8_t cmd, uint8_t value, uint32_t len);
|
||||||
@@ -220,6 +217,6 @@ void EPD_LED_BLINK(void);
|
|||||||
// VDD voltage
|
// VDD voltage
|
||||||
float EPD_ReadVoltage(void);
|
float EPD_ReadVoltage(void);
|
||||||
|
|
||||||
epd_model_t *epd_init(epd_model_id_t id);
|
epd_model_t* epd_init(epd_model_id_t id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,16 +10,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "EPD_service.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "sdk_macros.h"
|
|
||||||
|
#include "app_scheduler.h"
|
||||||
#include "ble_srv_common.h"
|
#include "ble_srv_common.h"
|
||||||
|
#include "main.h"
|
||||||
#include "nrf_delay.h"
|
#include "nrf_delay.h"
|
||||||
#include "nrf_gpio.h"
|
#include "nrf_gpio.h"
|
||||||
#include "nrf_pwr_mgmt.h"
|
|
||||||
#include "app_scheduler.h"
|
|
||||||
#include "EPD_service.h"
|
|
||||||
#include "main.h"
|
|
||||||
#include "nrf_log.h"
|
#include "nrf_log.h"
|
||||||
|
#include "nrf_pwr_mgmt.h"
|
||||||
|
#include "sdk_macros.h"
|
||||||
|
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
#define EPD_CFG_52811 {0x14, 0x13, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02, 0xFF, 0x12, 0x07}
|
#define EPD_CFG_52811 {0x14, 0x13, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02, 0xFF, 0x12, 0x07}
|
||||||
@@ -29,28 +31,26 @@
|
|||||||
// #define EPD_CFG_DEFAULT {0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x01, 0x07}
|
// #define EPD_CFG_DEFAULT {0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x01, 0x07}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void epd_gui_update(void * p_event_data, uint16_t event_size)
|
static void epd_gui_update(void* p_event_data, uint16_t event_size) {
|
||||||
{
|
epd_gui_update_event_t* event = (epd_gui_update_event_t*)p_event_data;
|
||||||
epd_gui_update_event_t *event = (epd_gui_update_event_t *)p_event_data;
|
ble_epd_t* p_epd = event->p_epd;
|
||||||
ble_epd_t *p_epd = event->p_epd;
|
|
||||||
|
|
||||||
EPD_GPIO_Init();
|
EPD_GPIO_Init();
|
||||||
epd_model_t *epd = epd_init((epd_model_id_t)p_epd->config.model_id);
|
epd_model_t* epd = epd_init((epd_model_id_t)p_epd->config.model_id);
|
||||||
gui_data_t data = {
|
gui_data_t data = {
|
||||||
.mode = (display_mode_t)p_epd->config.display_mode,
|
.mode = (display_mode_t)p_epd->config.display_mode,
|
||||||
.color = epd->color,
|
.color = epd->color,
|
||||||
.width = epd->width,
|
.width = epd->width,
|
||||||
.height = epd->height,
|
.height = epd->height,
|
||||||
.timestamp = event->timestamp,
|
.timestamp = event->timestamp,
|
||||||
.week_start = p_epd->config.week_start,
|
.week_start = p_epd->config.week_start,
|
||||||
.temperature = epd->drv->read_temp(epd),
|
.temperature = epd->drv->read_temp(epd),
|
||||||
.voltage = EPD_ReadVoltage(),
|
.voltage = EPD_ReadVoltage(),
|
||||||
};
|
};
|
||||||
|
|
||||||
uint16_t dev_name_len = sizeof(data.ssid);
|
uint16_t dev_name_len = sizeof(data.ssid);
|
||||||
uint32_t err_code = sd_ble_gap_device_name_get((uint8_t *)data.ssid, &dev_name_len);
|
uint32_t err_code = sd_ble_gap_device_name_get((uint8_t*)data.ssid, &dev_name_len);
|
||||||
if (err_code == NRF_SUCCESS && dev_name_len > 0)
|
if (err_code == NRF_SUCCESS && dev_name_len > 0) data.ssid[dev_name_len] = '\0';
|
||||||
data.ssid[dev_name_len] = '\0';
|
|
||||||
|
|
||||||
DrawGUI(&data, (buffer_callback)epd->drv->write_image, epd);
|
DrawGUI(&data, (buffer_callback)epd->drv->write_image, epd);
|
||||||
epd->drv->refresh(epd);
|
epd->drv->refresh(epd);
|
||||||
@@ -64,8 +64,7 @@ static void epd_gui_update(void * p_event_data, uint16_t event_size)
|
|||||||
* @param[in] p_epd EPD Service structure.
|
* @param[in] p_epd EPD Service structure.
|
||||||
* @param[in] p_ble_evt Pointer to the event received from BLE stack.
|
* @param[in] p_ble_evt Pointer to the event received from BLE stack.
|
||||||
*/
|
*/
|
||||||
static void on_connect(ble_epd_t * p_epd, ble_evt_t * p_ble_evt)
|
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;
|
p_epd->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
|
||||||
EPD_GPIO_Init();
|
EPD_GPIO_Init();
|
||||||
}
|
}
|
||||||
@@ -75,132 +74,125 @@ static void on_connect(ble_epd_t * p_epd, ble_evt_t * p_ble_evt)
|
|||||||
* @param[in] p_epd EPD Service structure.
|
* @param[in] p_epd EPD Service structure.
|
||||||
* @param[in] p_ble_evt Pointer to the event received from BLE stack.
|
* @param[in] p_ble_evt Pointer to the event received from BLE stack.
|
||||||
*/
|
*/
|
||||||
static void on_disconnect(ble_epd_t * p_epd, ble_evt_t * p_ble_evt)
|
static void on_disconnect(ble_epd_t* p_epd, ble_evt_t* p_ble_evt) {
|
||||||
{
|
|
||||||
UNUSED_PARAMETER(p_ble_evt);
|
UNUSED_PARAMETER(p_ble_evt);
|
||||||
p_epd->conn_handle = BLE_CONN_HANDLE_INVALID;
|
p_epd->conn_handle = BLE_CONN_HANDLE_INVALID;
|
||||||
p_epd->epd->drv->sleep(p_epd->epd);
|
p_epd->epd->drv->sleep(p_epd->epd);
|
||||||
nrf_delay_ms(200); // for sleep
|
nrf_delay_ms(200); // for sleep
|
||||||
EPD_GPIO_Uninit();
|
EPD_GPIO_Uninit();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void epd_update_display_mode(ble_epd_t * p_epd, display_mode_t mode)
|
static void epd_update_display_mode(ble_epd_t* p_epd, display_mode_t mode) {
|
||||||
{
|
|
||||||
if (p_epd->config.display_mode != mode) {
|
if (p_epd->config.display_mode != mode) {
|
||||||
p_epd->config.display_mode = mode;
|
p_epd->config.display_mode = mode;
|
||||||
epd_config_write(&p_epd->config);
|
epd_config_write(&p_epd->config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void epd_send_time(ble_epd_t * p_epd)
|
static void epd_send_time(ble_epd_t* p_epd) {
|
||||||
{
|
|
||||||
char buf[20] = {0};
|
char buf[20] = {0};
|
||||||
snprintf(buf, 20, "t=%"PRIu32, timestamp());
|
snprintf(buf, 20, "t=%" PRIu32, timestamp());
|
||||||
ble_epd_string_send(p_epd, (uint8_t *)buf, strlen(buf));
|
ble_epd_string_send(p_epd, (uint8_t*)buf, strlen(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void epd_send_mtu(ble_epd_t * p_epd)
|
static void epd_send_mtu(ble_epd_t* p_epd) {
|
||||||
{
|
|
||||||
char buf[10] = {0};
|
char buf[10] = {0};
|
||||||
snprintf(buf, sizeof(buf), "mtu=%d", p_epd->max_data_len);
|
snprintf(buf, sizeof(buf), "mtu=%d", p_epd->max_data_len);
|
||||||
ble_epd_string_send(p_epd, (uint8_t *)buf, strlen(buf));
|
ble_epd_string_send(p_epd, (uint8_t*)buf, strlen(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void epd_service_on_write(ble_epd_t * p_epd, uint8_t * p_data, uint16_t length)
|
static void epd_service_on_write(ble_epd_t* p_epd, uint8_t* p_data, uint16_t length) {
|
||||||
{
|
|
||||||
NRF_LOG_DEBUG("[EPD]: on_write LEN=%d\n", length);
|
NRF_LOG_DEBUG("[EPD]: on_write LEN=%d\n", length);
|
||||||
NRF_LOG_HEXDUMP_DEBUG(p_data, length);
|
NRF_LOG_HEXDUMP_DEBUG(p_data, length);
|
||||||
if (p_data == NULL || length <= 0) return;
|
if (p_data == NULL || length <= 0) return;
|
||||||
|
|
||||||
switch (p_data[0])
|
switch (p_data[0]) {
|
||||||
{
|
case EPD_CMD_SET_PINS:
|
||||||
case EPD_CMD_SET_PINS:
|
if (length < 8) return;
|
||||||
if (length < 8) return;
|
|
||||||
|
|
||||||
p_epd->config.mosi_pin = p_data[1];
|
p_epd->config.mosi_pin = p_data[1];
|
||||||
p_epd->config.sclk_pin = p_data[2];
|
p_epd->config.sclk_pin = p_data[2];
|
||||||
p_epd->config.cs_pin = p_data[3];
|
p_epd->config.cs_pin = p_data[3];
|
||||||
p_epd->config.dc_pin = p_data[4];
|
p_epd->config.dc_pin = p_data[4];
|
||||||
p_epd->config.rst_pin = p_data[5];
|
p_epd->config.rst_pin = p_data[5];
|
||||||
p_epd->config.busy_pin = p_data[6];
|
p_epd->config.busy_pin = p_data[6];
|
||||||
p_epd->config.bs_pin = p_data[7];
|
p_epd->config.bs_pin = p_data[7];
|
||||||
if (length > 8)
|
if (length > 8) p_epd->config.en_pin = p_data[8];
|
||||||
p_epd->config.en_pin = p_data[8];
|
epd_config_write(&p_epd->config);
|
||||||
epd_config_write(&p_epd->config);
|
|
||||||
|
|
||||||
EPD_GPIO_Uninit();
|
EPD_GPIO_Uninit();
|
||||||
EPD_GPIO_Load(&p_epd->config);
|
EPD_GPIO_Load(&p_epd->config);
|
||||||
EPD_GPIO_Init();
|
EPD_GPIO_Init();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EPD_CMD_INIT:
|
case EPD_CMD_INIT:
|
||||||
p_epd->epd = epd_init((epd_model_id_t)(length > 1 ? p_data[1] : p_epd->config.model_id));
|
p_epd->epd = epd_init((epd_model_id_t)(length > 1 ? p_data[1] : p_epd->config.model_id));
|
||||||
if (p_epd->epd->id != p_epd->config.model_id) {
|
if (p_epd->epd->id != p_epd->config.model_id) {
|
||||||
p_epd->config.model_id = p_epd->epd->id;
|
p_epd->config.model_id = p_epd->epd->id;
|
||||||
epd_config_write(&p_epd->config);
|
epd_config_write(&p_epd->config);
|
||||||
}
|
}
|
||||||
epd_send_mtu(p_epd);
|
epd_send_mtu(p_epd);
|
||||||
epd_send_time(p_epd);
|
epd_send_time(p_epd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EPD_CMD_CLEAR:
|
case EPD_CMD_CLEAR:
|
||||||
epd_update_display_mode(p_epd, MODE_PICTURE);
|
epd_update_display_mode(p_epd, MODE_PICTURE);
|
||||||
p_epd->epd->drv->clear(p_epd->epd, length > 1 ? p_data[1] : true);
|
p_epd->epd->drv->clear(p_epd->epd, length > 1 ? p_data[1] : true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EPD_CMD_SEND_COMMAND:
|
case EPD_CMD_SEND_COMMAND:
|
||||||
if (length < 2) return;
|
if (length < 2) return;
|
||||||
EPD_WriteCmd(p_data[1]);
|
EPD_WriteCmd(p_data[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EPD_CMD_SEND_DATA:
|
case EPD_CMD_SEND_DATA:
|
||||||
EPD_WriteData(&p_data[1], length - 1);
|
EPD_WriteData(&p_data[1], length - 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EPD_CMD_REFRESH:
|
case EPD_CMD_REFRESH:
|
||||||
epd_update_display_mode(p_epd, MODE_PICTURE);
|
epd_update_display_mode(p_epd, MODE_PICTURE);
|
||||||
p_epd->epd->drv->refresh(p_epd->epd);
|
p_epd->epd->drv->refresh(p_epd->epd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EPD_CMD_SLEEP:
|
case EPD_CMD_SLEEP:
|
||||||
p_epd->epd->drv->sleep(p_epd->epd);
|
p_epd->epd->drv->sleep(p_epd->epd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EPD_CMD_SET_TIME: {
|
case EPD_CMD_SET_TIME: {
|
||||||
if (length < 5) return;
|
if (length < 5) return;
|
||||||
|
|
||||||
NRF_LOG_DEBUG("time: %02x %02x %02x %02x\n", p_data[1], p_data[2], p_data[3], p_data[4]);
|
NRF_LOG_DEBUG("time: %02x %02x %02x %02x\n", p_data[1], p_data[2], p_data[3], p_data[4]);
|
||||||
if (length > 5) NRF_LOG_DEBUG("timezone: %d\n", (int8_t)p_data[5]);
|
if (length > 5) NRF_LOG_DEBUG("timezone: %d\n", (int8_t)p_data[5]);
|
||||||
|
|
||||||
uint32_t timestamp = (p_data[1] << 24) | (p_data[2] << 16) | (p_data[3] << 8) | p_data[4];
|
uint32_t timestamp = (p_data[1] << 24) | (p_data[2] << 16) | (p_data[3] << 8) | p_data[4];
|
||||||
timestamp += (length > 5 ? (int8_t)p_data[5] : 8) * 60 * 60; // timezone
|
timestamp += (length > 5 ? (int8_t)p_data[5] : 8) * 60 * 60; // timezone
|
||||||
set_timestamp(timestamp);
|
set_timestamp(timestamp);
|
||||||
epd_update_display_mode(p_epd, length > 6 ? (display_mode_t)p_data[6] : MODE_CALENDAR);
|
epd_update_display_mode(p_epd, length > 6 ? (display_mode_t)p_data[6] : MODE_CALENDAR);
|
||||||
ble_epd_on_timer(p_epd, timestamp, true);
|
ble_epd_on_timer(p_epd, timestamp, true);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case EPD_CMD_SET_WEEK_START:
|
case EPD_CMD_SET_WEEK_START:
|
||||||
if (length < 2) return;
|
if (length < 2) return;
|
||||||
if (p_data[1] < 7 && p_data[1] != p_epd->config.week_start) {
|
if (p_data[1] < 7 && p_data[1] != p_epd->config.week_start) {
|
||||||
p_epd->config.week_start = p_data[1];
|
p_epd->config.week_start = p_data[1];
|
||||||
epd_config_write(&p_epd->config);
|
epd_config_write(&p_epd->config);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EPD_CMD_WRITE_IMAGE: // MSB=0000: ram begin, LSB=1111: black
|
case EPD_CMD_WRITE_IMAGE: // MSB=0000: ram begin, LSB=1111: black
|
||||||
if (length < 3) return;
|
if (length < 3) return;
|
||||||
p_epd->epd->drv->write_ram(p_epd->epd, p_data[1], &p_data[2], length - 2);
|
p_epd->epd->drv->write_ram(p_epd->epd, p_data[1], &p_data[2], length - 2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EPD_CMD_SET_CONFIG:
|
case EPD_CMD_SET_CONFIG:
|
||||||
if (length < 2) return;
|
if (length < 2) return;
|
||||||
memcpy(&p_epd->config, &p_data[1], (length - 1 > EPD_CONFIG_SIZE) ? EPD_CONFIG_SIZE : length - 1);
|
memcpy(&p_epd->config, &p_data[1], (length - 1 > EPD_CONFIG_SIZE) ? EPD_CONFIG_SIZE : length - 1);
|
||||||
epd_config_write(&p_epd->config);
|
epd_config_write(&p_epd->config);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EPD_CMD_SYS_SLEEP:
|
case EPD_CMD_SYS_SLEEP:
|
||||||
sleep_mode_enter();
|
sleep_mode_enter();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EPD_CMD_SYS_RESET:
|
case EPD_CMD_SYS_RESET:
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
@@ -208,16 +200,16 @@ static void epd_service_on_write(ble_epd_t * p_epd, uint8_t * p_data, uint16_t l
|
|||||||
#else
|
#else
|
||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EPD_CMD_CFG_ERASE:
|
case EPD_CMD_CFG_ERASE:
|
||||||
epd_config_clear(&p_epd->config);
|
epd_config_clear(&p_epd->config);
|
||||||
nrf_delay_ms(100); // required
|
nrf_delay_ms(100); // required
|
||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,60 +218,42 @@ static void epd_service_on_write(ble_epd_t * p_epd, uint8_t * p_data, uint16_t l
|
|||||||
* @param[in] p_epd EPD Service structure.
|
* @param[in] p_epd EPD Service structure.
|
||||||
* @param[in] p_ble_evt Pointer to the event received from BLE stack.
|
* @param[in] p_ble_evt Pointer to the event received from BLE stack.
|
||||||
*/
|
*/
|
||||||
static void on_write(ble_epd_t * p_epd, ble_evt_t * p_ble_evt)
|
static void on_write(ble_epd_t* p_epd, ble_evt_t* p_ble_evt) {
|
||||||
{
|
ble_gatts_evt_write_t* p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
|
||||||
ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
|
|
||||||
|
|
||||||
if (
|
if ((p_evt_write->handle == p_epd->char_handles.cccd_handle) && (p_evt_write->len == 2)) {
|
||||||
(p_evt_write->handle == p_epd->char_handles.cccd_handle)
|
if (ble_srv_is_notification_enabled(p_evt_write->data)) {
|
||||||
&&
|
|
||||||
(p_evt_write->len == 2)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (ble_srv_is_notification_enabled(p_evt_write->data))
|
|
||||||
{
|
|
||||||
NRF_LOG_DEBUG("notification enabled\n");
|
NRF_LOG_DEBUG("notification enabled\n");
|
||||||
p_epd->is_notification_enabled = true;
|
p_epd->is_notification_enabled = true;
|
||||||
static uint16_t length = sizeof(epd_config_t);
|
static uint16_t length = sizeof(epd_config_t);
|
||||||
NRF_LOG_DEBUG("send epd config\n");
|
NRF_LOG_DEBUG("send epd config\n");
|
||||||
uint32_t err_code = ble_epd_string_send(p_epd, (uint8_t *)&p_epd->config, length);
|
uint32_t err_code = ble_epd_string_send(p_epd, (uint8_t*)&p_epd->config, length);
|
||||||
if (err_code != NRF_ERROR_INVALID_STATE)
|
if (err_code != NRF_ERROR_INVALID_STATE) APP_ERROR_CHECK(err_code);
|
||||||
APP_ERROR_CHECK(err_code);
|
} else {
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p_epd->is_notification_enabled = false;
|
p_epd->is_notification_enabled = false;
|
||||||
}
|
}
|
||||||
}
|
} else if (p_evt_write->handle == p_epd->char_handles.value_handle) {
|
||||||
else if (p_evt_write->handle == p_epd->char_handles.value_handle)
|
|
||||||
{
|
|
||||||
epd_service_on_write(p_epd, p_evt_write->data, p_evt_write->len);
|
epd_service_on_write(p_epd, p_evt_write->data, p_evt_write->len);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Do Nothing. This event is not relevant for this service.
|
// Do Nothing. This event is not relevant for this service.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
void ble_epd_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
|
void ble_epd_evt_handler(ble_evt_t const* p_ble_evt, void* p_context) {
|
||||||
{
|
|
||||||
if (p_context == NULL || p_ble_evt == NULL) return;
|
if (p_context == NULL || p_ble_evt == NULL) return;
|
||||||
|
|
||||||
ble_epd_t *p_epd = (ble_epd_t *)p_context;
|
ble_epd_t* p_epd = (ble_epd_t*)p_context;
|
||||||
ble_epd_on_ble_evt(p_epd, (ble_evt_t *)p_ble_evt);
|
ble_epd_on_ble_evt(p_epd, (ble_evt_t*)p_ble_evt);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ble_epd_on_ble_evt(ble_epd_t * p_epd, ble_evt_t * p_ble_evt)
|
void ble_epd_on_ble_evt(ble_epd_t* p_epd, ble_evt_t* p_ble_evt) {
|
||||||
{
|
if ((p_epd == NULL) || (p_ble_evt == NULL)) {
|
||||||
if ((p_epd == NULL) || (p_ble_evt == NULL))
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (p_ble_evt->header.evt_id)
|
switch (p_ble_evt->header.evt_id) {
|
||||||
{
|
|
||||||
case BLE_GAP_EVT_CONNECTED:
|
case BLE_GAP_EVT_CONNECTED:
|
||||||
on_connect(p_epd, p_ble_evt);
|
on_connect(p_epd, p_ble_evt);
|
||||||
break;
|
break;
|
||||||
@@ -298,75 +272,67 @@ void ble_epd_on_ble_evt(ble_epd_t * p_epd, ble_evt_t * p_ble_evt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t epd_service_init(ble_epd_t* p_epd) {
|
||||||
static uint32_t epd_service_init(ble_epd_t * p_epd)
|
ble_uuid_t ble_uuid = {0};
|
||||||
{
|
ble_uuid128_t base_uuid = BLE_UUID_EPD_SVC_BASE;
|
||||||
ble_uuid_t ble_uuid = {0};
|
|
||||||
ble_uuid128_t base_uuid = BLE_UUID_EPD_SVC_BASE;
|
|
||||||
ble_add_char_params_t add_char_params;
|
ble_add_char_params_t add_char_params;
|
||||||
uint8_t app_version = APP_VERSION;
|
uint8_t app_version = APP_VERSION;
|
||||||
|
|
||||||
VERIFY_SUCCESS(sd_ble_uuid_vs_add(&base_uuid, &ble_uuid.type));
|
VERIFY_SUCCESS(sd_ble_uuid_vs_add(&base_uuid, &ble_uuid.type));
|
||||||
|
|
||||||
ble_uuid.type = ble_uuid.type;
|
ble_uuid.type = ble_uuid.type;
|
||||||
ble_uuid.uuid = BLE_UUID_EPD_SVC;
|
ble_uuid.uuid = BLE_UUID_EPD_SVC;
|
||||||
VERIFY_SUCCESS(sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
|
VERIFY_SUCCESS(sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_epd->service_handle));
|
||||||
&ble_uuid,
|
|
||||||
&p_epd->service_handle));
|
|
||||||
|
|
||||||
memset(&add_char_params, 0, sizeof(add_char_params));
|
memset(&add_char_params, 0, sizeof(add_char_params));
|
||||||
add_char_params.uuid = BLE_UUID_EPD_CHAR;
|
add_char_params.uuid = BLE_UUID_EPD_CHAR;
|
||||||
add_char_params.uuid_type = ble_uuid.type;
|
add_char_params.uuid_type = ble_uuid.type;
|
||||||
add_char_params.max_len = BLE_EPD_MAX_DATA_LEN;
|
add_char_params.max_len = BLE_EPD_MAX_DATA_LEN;
|
||||||
add_char_params.init_len = sizeof(uint8_t);
|
add_char_params.init_len = sizeof(uint8_t);
|
||||||
add_char_params.is_var_len = true;
|
add_char_params.is_var_len = true;
|
||||||
add_char_params.char_props.notify = 1;
|
add_char_params.char_props.notify = 1;
|
||||||
add_char_params.char_props.write = 1;
|
add_char_params.char_props.write = 1;
|
||||||
add_char_params.char_props.write_wo_resp = 1;
|
add_char_params.char_props.write_wo_resp = 1;
|
||||||
add_char_params.read_access = SEC_OPEN;
|
add_char_params.read_access = SEC_OPEN;
|
||||||
add_char_params.write_access = SEC_OPEN;
|
add_char_params.write_access = SEC_OPEN;
|
||||||
add_char_params.cccd_write_access = SEC_OPEN;
|
add_char_params.cccd_write_access = SEC_OPEN;
|
||||||
|
|
||||||
VERIFY_SUCCESS(characteristic_add(p_epd->service_handle, &add_char_params, &p_epd->char_handles));
|
VERIFY_SUCCESS(characteristic_add(p_epd->service_handle, &add_char_params, &p_epd->char_handles));
|
||||||
|
|
||||||
memset(&add_char_params, 0, sizeof(add_char_params));
|
memset(&add_char_params, 0, sizeof(add_char_params));
|
||||||
add_char_params.uuid = BLE_UUID_APP_VER;
|
add_char_params.uuid = BLE_UUID_APP_VER;
|
||||||
add_char_params.uuid_type = ble_uuid.type;
|
add_char_params.uuid_type = ble_uuid.type;
|
||||||
add_char_params.max_len = sizeof(uint8_t);
|
add_char_params.max_len = sizeof(uint8_t);
|
||||||
add_char_params.init_len = sizeof(uint8_t);
|
add_char_params.init_len = sizeof(uint8_t);
|
||||||
add_char_params.p_init_value = &app_version;
|
add_char_params.p_init_value = &app_version;
|
||||||
add_char_params.char_props.read = 1;
|
add_char_params.char_props.read = 1;
|
||||||
add_char_params.read_access = SEC_OPEN;
|
add_char_params.read_access = SEC_OPEN;
|
||||||
|
|
||||||
return characteristic_add(p_epd->service_handle, &add_char_params, &p_epd->app_ver_handles);
|
return characteristic_add(p_epd->service_handle, &add_char_params, &p_epd->app_ver_handles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ble_epd_sleep_prepare(ble_epd_t * p_epd)
|
void ble_epd_sleep_prepare(ble_epd_t* p_epd) {
|
||||||
{
|
|
||||||
// Turn off led
|
// Turn off led
|
||||||
EPD_LED_OFF();
|
EPD_LED_OFF();
|
||||||
// Prepare wakeup pin
|
// Prepare wakeup pin
|
||||||
if (p_epd->config.wakeup_pin != 0xFF)
|
if (p_epd->config.wakeup_pin != 0xFF) {
|
||||||
{
|
|
||||||
nrf_gpio_cfg_sense_input(p_epd->config.wakeup_pin, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH);
|
nrf_gpio_cfg_sense_input(p_epd->config.wakeup_pin, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ble_epd_init(ble_epd_t * p_epd)
|
uint32_t ble_epd_init(ble_epd_t* p_epd) {
|
||||||
{
|
|
||||||
if (p_epd == NULL) return NRF_ERROR_NULL;
|
if (p_epd == NULL) return NRF_ERROR_NULL;
|
||||||
|
|
||||||
// Initialize the service structure.
|
// Initialize the service structure.
|
||||||
p_epd->max_data_len = BLE_EPD_MAX_DATA_LEN;
|
p_epd->max_data_len = BLE_EPD_MAX_DATA_LEN;
|
||||||
p_epd->conn_handle = BLE_CONN_HANDLE_INVALID;
|
p_epd->conn_handle = BLE_CONN_HANDLE_INVALID;
|
||||||
p_epd->is_notification_enabled = false;
|
p_epd->is_notification_enabled = false;
|
||||||
|
|
||||||
epd_config_init(&p_epd->config);
|
epd_config_init(&p_epd->config);
|
||||||
epd_config_read(&p_epd->config);
|
epd_config_read(&p_epd->config);
|
||||||
|
|
||||||
// write default config
|
// write default config
|
||||||
if (epd_config_empty(&p_epd->config))
|
if (epd_config_empty(&p_epd->config)) {
|
||||||
{
|
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
if (NRF_FICR->INFO.PART == 0x52810) {
|
if (NRF_FICR->INFO.PART == 0x52810) {
|
||||||
uint8_t cfg[] = EPD_CFG_52810;
|
uint8_t cfg[] = EPD_CFG_52810;
|
||||||
@@ -379,10 +345,8 @@ uint32_t ble_epd_init(ble_epd_t * p_epd)
|
|||||||
uint8_t cfg[] = EPD_CFG_DEFAULT;
|
uint8_t cfg[] = EPD_CFG_DEFAULT;
|
||||||
memcpy(&p_epd->config, cfg, sizeof(cfg));
|
memcpy(&p_epd->config, cfg, sizeof(cfg));
|
||||||
#endif
|
#endif
|
||||||
if (p_epd->config.display_mode == 0xFF)
|
if (p_epd->config.display_mode == 0xFF) p_epd->config.display_mode = MODE_CALENDAR;
|
||||||
p_epd->config.display_mode = MODE_CALENDAR;
|
if (p_epd->config.week_start == 0xFF) p_epd->config.week_start = 0;
|
||||||
if (p_epd->config.week_start == 0xFF)
|
|
||||||
p_epd->config.week_start = 0;
|
|
||||||
epd_config_write(&p_epd->config);
|
epd_config_write(&p_epd->config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,12 +360,10 @@ uint32_t ble_epd_init(ble_epd_t * p_epd)
|
|||||||
return epd_service_init(p_epd);
|
return epd_service_init(p_epd);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ble_epd_string_send(ble_epd_t * p_epd, uint8_t * p_string, uint16_t length)
|
uint32_t ble_epd_string_send(ble_epd_t* p_epd, uint8_t* p_string, uint16_t length) {
|
||||||
{
|
|
||||||
if ((p_epd->conn_handle == BLE_CONN_HANDLE_INVALID) || (!p_epd->is_notification_enabled))
|
if ((p_epd->conn_handle == BLE_CONN_HANDLE_INVALID) || (!p_epd->is_notification_enabled))
|
||||||
return NRF_ERROR_INVALID_STATE;
|
return NRF_ERROR_INVALID_STATE;
|
||||||
if (length > p_epd->max_data_len)
|
if (length > p_epd->max_data_len) return NRF_ERROR_INVALID_PARAM;
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
|
|
||||||
ble_gatts_hvx_params_t hvx_params;
|
ble_gatts_hvx_params_t hvx_params;
|
||||||
|
|
||||||
@@ -409,19 +371,17 @@ uint32_t ble_epd_string_send(ble_epd_t * p_epd, uint8_t * p_string, uint16_t len
|
|||||||
|
|
||||||
hvx_params.handle = p_epd->char_handles.value_handle;
|
hvx_params.handle = p_epd->char_handles.value_handle;
|
||||||
hvx_params.p_data = p_string;
|
hvx_params.p_data = p_string;
|
||||||
hvx_params.p_len = &length;
|
hvx_params.p_len = &length;
|
||||||
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
|
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
|
||||||
|
|
||||||
return sd_ble_gatts_hvx(p_epd->conn_handle, &hvx_params);
|
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)
|
void ble_epd_on_timer(ble_epd_t* p_epd, uint32_t timestamp, bool force_update) {
|
||||||
{
|
|
||||||
// Update calendar on 00:00:00, clock on every minute
|
// Update calendar on 00:00:00, clock on every minute
|
||||||
if (force_update ||
|
if (force_update || (p_epd->config.display_mode == MODE_CALENDAR && timestamp % 86400 == 0) ||
|
||||||
(p_epd->config.display_mode == MODE_CALENDAR && timestamp % 86400 == 0) ||
|
|
||||||
(p_epd->config.display_mode == MODE_CLOCK && timestamp % 60 == 0)) {
|
(p_epd->config.display_mode == MODE_CLOCK && timestamp % 60 == 0)) {
|
||||||
epd_gui_update_event_t event = { p_epd, timestamp };
|
epd_gui_update_event_t event = {p_epd, timestamp};
|
||||||
app_sched_event_put(&event, sizeof(epd_gui_update_event_t), epd_gui_update);
|
app_sched_event_put(&event, sizeof(epd_gui_update_event_t), epd_gui_update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,15 +15,16 @@
|
|||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "ble.h"
|
#include "ble.h"
|
||||||
#include "ble_srv_common.h"
|
#include "ble_srv_common.h"
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
#include "nrf_sdh_ble.h"
|
#include "nrf_sdh_ble.h"
|
||||||
#endif
|
#endif
|
||||||
#include "sdk_config.h"
|
|
||||||
#include "EPD_driver.h"
|
|
||||||
#include "EPD_config.h"
|
#include "EPD_config.h"
|
||||||
|
#include "EPD_driver.h"
|
||||||
#include "GUI.h"
|
#include "GUI.h"
|
||||||
|
#include "sdk_config.h"
|
||||||
|
|
||||||
/**@brief Macro for defining a ble_hts instance.
|
/**@brief Macro for defining a ble_hts instance.
|
||||||
*
|
*
|
||||||
@@ -31,75 +32,75 @@
|
|||||||
* @hideinitializer
|
* @hideinitializer
|
||||||
*/
|
*/
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
void ble_epd_evt_handler(ble_evt_t const * p_ble_evt, void * p_context);
|
void ble_epd_evt_handler(ble_evt_t const* p_ble_evt, void* p_context);
|
||||||
|
|
||||||
#define BLE_EPD_BLE_OBSERVER_PRIO 2
|
#define BLE_EPD_BLE_OBSERVER_PRIO 2
|
||||||
#define BLE_EPD_DEF(_name) \
|
#define BLE_EPD_DEF(_name) \
|
||||||
static ble_epd_t _name; \
|
static ble_epd_t _name; \
|
||||||
NRF_SDH_BLE_OBSERVER(_name ## _obs, \
|
NRF_SDH_BLE_OBSERVER(_name##_obs, BLE_EPD_BLE_OBSERVER_PRIO, ble_epd_evt_handler, &_name)
|
||||||
BLE_EPD_BLE_OBSERVER_PRIO, \
|
|
||||||
ble_epd_evt_handler, &_name)
|
|
||||||
#else
|
#else
|
||||||
#define BLE_EPD_DEF(_name) static ble_epd_t _name;
|
#define BLE_EPD_DEF(_name) static ble_epd_t _name;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define APP_VERSION 0x19
|
#define APP_VERSION 0x19
|
||||||
|
|
||||||
#define BLE_UUID_EPD_SVC_BASE {{0XEC, 0X5A, 0X67, 0X1C, 0XC1, 0XB6, 0X46, 0XFB, \
|
#define BLE_UUID_EPD_SVC_BASE \
|
||||||
0X8D, 0X91, 0X28, 0XD8, 0X22, 0X36, 0X75, 0X62}}
|
{{0XEC, 0X5A, 0X67, 0X1C, 0XC1, 0XB6, 0X46, 0XFB, 0X8D, 0X91, 0X28, 0XD8, 0X22, 0X36, 0X75, 0X62}}
|
||||||
#define BLE_UUID_EPD_SVC 0x0001
|
#define BLE_UUID_EPD_SVC 0x0001
|
||||||
#define BLE_UUID_EPD_CHAR 0x0002
|
#define BLE_UUID_EPD_CHAR 0x0002
|
||||||
#define BLE_UUID_APP_VER 0x0003
|
#define BLE_UUID_APP_VER 0x0003
|
||||||
|
|
||||||
#define EPD_SVC_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN
|
#define EPD_SVC_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN
|
||||||
|
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
#define BLE_EPD_MAX_DATA_LEN (NRF_SDH_BLE_GATT_MAX_MTU_SIZE - 3)
|
#define BLE_EPD_MAX_DATA_LEN (NRF_SDH_BLE_GATT_MAX_MTU_SIZE - 3)
|
||||||
#else
|
#else
|
||||||
#define BLE_EPD_MAX_DATA_LEN (GATT_MTU_SIZE_DEFAULT - 3) /**< Maximum length of data (in bytes) that can be transmitted to the peer. */
|
#define BLE_EPD_MAX_DATA_LEN \
|
||||||
|
(GATT_MTU_SIZE_DEFAULT - 3) /**< Maximum length of data (in bytes) that can be transmitted to the peer. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**< EPD Service command IDs. */
|
/**< EPD Service command IDs. */
|
||||||
enum EPD_CMDS
|
enum EPD_CMDS {
|
||||||
{
|
EPD_CMD_SET_PINS = 0x00, /**< set EPD pin mapping. */
|
||||||
EPD_CMD_SET_PINS = 0x00, /**< set EPD pin mapping. */
|
EPD_CMD_INIT = 0x01, /**< init EPD display driver */
|
||||||
EPD_CMD_INIT = 0x01, /**< init EPD display driver */
|
EPD_CMD_CLEAR = 0x02, /**< clear EPD screen */
|
||||||
EPD_CMD_CLEAR = 0x02, /**< clear EPD screen */
|
EPD_CMD_SEND_COMMAND = 0x03, /**< send command to EPD */
|
||||||
EPD_CMD_SEND_COMMAND = 0x03, /**< send command to EPD */
|
EPD_CMD_SEND_DATA = 0x04, /**< send data to EPD */
|
||||||
EPD_CMD_SEND_DATA = 0x04, /**< send data to EPD */
|
EPD_CMD_REFRESH = 0x05, /**< diaplay EPD ram on screen */
|
||||||
EPD_CMD_REFRESH = 0x05, /**< diaplay EPD ram on screen */
|
EPD_CMD_SLEEP = 0x06, /**< EPD enter sleep mode */
|
||||||
EPD_CMD_SLEEP = 0x06, /**< EPD enter sleep mode */
|
|
||||||
|
|
||||||
EPD_CMD_SET_TIME = 0x20, /** < set time with unix timestamp */
|
EPD_CMD_SET_TIME = 0x20, /** < set time with unix timestamp */
|
||||||
EPD_CMD_SET_WEEK_START = 0x21, /** < set week start day (0: Sunday, 1: Monday, ...) */
|
EPD_CMD_SET_WEEK_START = 0x21, /** < set week start day (0: Sunday, 1: Monday, ...) */
|
||||||
|
|
||||||
EPD_CMD_WRITE_IMAGE = 0x30, /** < write image data to EPD ram */
|
EPD_CMD_WRITE_IMAGE = 0x30, /** < write image data to EPD ram */
|
||||||
|
|
||||||
EPD_CMD_SET_CONFIG = 0x90, /**< set full EPD config */
|
EPD_CMD_SET_CONFIG = 0x90, /**< set full EPD config */
|
||||||
EPD_CMD_SYS_RESET = 0x91, /**< MCU reset */
|
EPD_CMD_SYS_RESET = 0x91, /**< MCU reset */
|
||||||
EPD_CMD_SYS_SLEEP = 0x92, /**< MCU enter sleep mode */
|
EPD_CMD_SYS_SLEEP = 0x92, /**< MCU enter sleep mode */
|
||||||
EPD_CMD_CFG_ERASE = 0x99, /**< Erase config and reset */
|
EPD_CMD_CFG_ERASE = 0x99, /**< Erase config and reset */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**@brief EPD Service structure.
|
/**@brief EPD Service structure.
|
||||||
*
|
*
|
||||||
* @details This structure contains status information related to the service.
|
* @details This structure contains status information related to the service.
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
uint16_t service_handle; /**< Handle of EPD Service (as provided by the S110 SoftDevice). */
|
||||||
uint16_t service_handle; /**< Handle of EPD Service (as provided by the S110 SoftDevice). */
|
ble_gatts_char_handles_t
|
||||||
ble_gatts_char_handles_t char_handles; /**< Handles related to the EPD characteristic (as provided by the SoftDevice). */
|
char_handles; /**< Handles related to the EPD characteristic (as provided by the SoftDevice). */
|
||||||
ble_gatts_char_handles_t app_ver_handles; /**< Handles related to the APP version characteristic (as provided by the SoftDevice). */
|
ble_gatts_char_handles_t
|
||||||
uint16_t conn_handle; /**< Handle of the current connection (as provided by the SoftDevice). BLE_CONN_HANDLE_INVALID if not in a connection. */
|
app_ver_handles; /**< Handles related to the APP version characteristic (as provided by the SoftDevice). */
|
||||||
uint16_t max_data_len; /**< Maximum length of data (in bytes) that can be transmitted to the peer */
|
uint16_t conn_handle; /**< Handle of the current connection (as provided by the SoftDevice). BLE_CONN_HANDLE_INVALID
|
||||||
bool is_notification_enabled; /**< Variable to indicate if the peer has enabled notification of the RX characteristic.*/
|
if not in a connection. */
|
||||||
epd_model_t *epd; /**< current EPD model */
|
uint16_t max_data_len; /**< Maximum length of data (in bytes) that can be transmitted to the peer */
|
||||||
epd_config_t config; /**< EPD config */
|
bool is_notification_enabled; /**< Variable to indicate if the peer has enabled notification of the RX
|
||||||
|
characteristic.*/
|
||||||
|
epd_model_t* epd; /**< current EPD model */
|
||||||
|
epd_config_t config; /**< EPD config */
|
||||||
} ble_epd_t;
|
} ble_epd_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
ble_epd_t* p_epd;
|
||||||
ble_epd_t *p_epd;
|
|
||||||
uint32_t timestamp;
|
uint32_t timestamp;
|
||||||
} epd_gui_update_event_t;
|
} epd_gui_update_event_t;
|
||||||
|
|
||||||
@@ -109,7 +110,7 @@ typedef struct
|
|||||||
*
|
*
|
||||||
* @param[in] p_epd EPD Service structure.
|
* @param[in] p_epd EPD Service structure.
|
||||||
*/
|
*/
|
||||||
void ble_epd_sleep_prepare(ble_epd_t * p_epd);
|
void ble_epd_sleep_prepare(ble_epd_t* p_epd);
|
||||||
|
|
||||||
/**@brief Function for initializing the EPD Service.
|
/**@brief Function for initializing the EPD Service.
|
||||||
*
|
*
|
||||||
@@ -120,7 +121,7 @@ void ble_epd_sleep_prepare(ble_epd_t * p_epd);
|
|||||||
* @retval NRF_SUCCESS If the service was successfully initialized. Otherwise, an error code is returned.
|
* @retval NRF_SUCCESS If the service was successfully initialized. Otherwise, an error code is returned.
|
||||||
* @retval NRF_ERROR_NULL If either of the pointers p_epd or p_epd_init is NULL.
|
* @retval NRF_ERROR_NULL If either of the pointers p_epd or p_epd_init is NULL.
|
||||||
*/
|
*/
|
||||||
uint32_t ble_epd_init(ble_epd_t * p_epd);
|
uint32_t ble_epd_init(ble_epd_t* p_epd);
|
||||||
|
|
||||||
/**@brief Function for handling the EPD Service's BLE events.
|
/**@brief Function for handling the EPD Service's BLE events.
|
||||||
*
|
*
|
||||||
@@ -132,7 +133,7 @@ uint32_t ble_epd_init(ble_epd_t * p_epd);
|
|||||||
* @param[in] p_epd EPD Service structure.
|
* @param[in] p_epd EPD Service structure.
|
||||||
* @param[in] p_ble_evt Event received from the S110 SoftDevice.
|
* @param[in] p_ble_evt Event received from the S110 SoftDevice.
|
||||||
*/
|
*/
|
||||||
void ble_epd_on_ble_evt(ble_epd_t * p_epd, ble_evt_t * p_ble_evt);
|
void ble_epd_on_ble_evt(ble_epd_t* p_epd, ble_evt_t* p_ble_evt);
|
||||||
|
|
||||||
/**@brief Function for sending a string to the peer.
|
/**@brief Function for sending a string to the peer.
|
||||||
*
|
*
|
||||||
@@ -145,10 +146,10 @@ void ble_epd_on_ble_evt(ble_epd_t * p_epd, ble_evt_t * p_ble_evt);
|
|||||||
*
|
*
|
||||||
* @retval NRF_SUCCESS If the string was sent successfully. Otherwise, an error code is returned.
|
* @retval NRF_SUCCESS If the string was sent successfully. Otherwise, an error code is returned.
|
||||||
*/
|
*/
|
||||||
uint32_t ble_epd_string_send(ble_epd_t * p_epd, uint8_t * p_string, uint16_t length);
|
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);
|
void ble_epd_on_timer(ble_epd_t* p_epd, uint32_t timestamp, bool force_update);
|
||||||
|
|
||||||
#endif // EPD_BLE_H__
|
#endif // EPD_BLE_H__
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
@@ -1,51 +1,35 @@
|
|||||||
#include "EPD_driver.h"
|
#include "EPD_driver.h"
|
||||||
#include "nrf_log.h"
|
#include "nrf_log.h"
|
||||||
|
|
||||||
static void SSD16xx_WaitBusy(uint16_t timeout)
|
static void SSD16xx_WaitBusy(uint16_t timeout) { EPD_WaitBusy(HIGH, timeout); }
|
||||||
{
|
|
||||||
EPD_WaitBusy(HIGH, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SSD16xx_Update(uint8_t seq)
|
static void SSD16xx_Update(uint8_t seq) {
|
||||||
{
|
|
||||||
EPD_Write(SSD16xx_DISP_CTRL2, seq);
|
EPD_Write(SSD16xx_DISP_CTRL2, seq);
|
||||||
EPD_WriteCmd(SSD16xx_MASTER_ACTIVATE);
|
EPD_WriteCmd(SSD16xx_MASTER_ACTIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t SSD16xx_Read_Temp(epd_model_t *epd)
|
int8_t SSD16xx_Read_Temp(epd_model_t* epd) {
|
||||||
{
|
|
||||||
SSD16xx_Update(0xB1);
|
SSD16xx_Update(0xB1);
|
||||||
SSD16xx_WaitBusy(500);
|
SSD16xx_WaitBusy(500);
|
||||||
EPD_WriteCmd(SSD16xx_TSENSOR_READ);
|
EPD_WriteCmd(SSD16xx_TSENSOR_READ);
|
||||||
return (int8_t)EPD_ReadByte();
|
return (int8_t)EPD_ReadByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _setPartialRamArea(epd_model_t *epd, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
static void _setPartialRamArea(epd_model_t* epd, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
||||||
{
|
EPD_Write(SSD16xx_ENTRY_MODE, 0x03); // set ram entry mode: x increase, y increase
|
||||||
EPD_Write(SSD16xx_ENTRY_MODE, 0x03); // set ram entry mode: x increase, y increase
|
|
||||||
if (epd->drv->ic == EPD_DRIVER_IC_SSD1677) {
|
if (epd->drv->ic == EPD_DRIVER_IC_SSD1677) {
|
||||||
EPD_Write(SSD16xx_RAM_XPOS,
|
EPD_Write(SSD16xx_RAM_XPOS, x % 256, x / 256, (x + w - 1) % 256, (x + w - 1) / 256);
|
||||||
x % 256, x / 256,
|
|
||||||
(x + w - 1) % 256,
|
|
||||||
(x + w - 1) / 256);
|
|
||||||
EPD_Write(SSD16xx_RAM_XCOUNT, x % 256, x / 256);
|
EPD_Write(SSD16xx_RAM_XCOUNT, x % 256, x / 256);
|
||||||
} else {
|
} else {
|
||||||
EPD_Write(SSD16xx_RAM_XPOS, x / 8, (x + w - 1) / 8);
|
EPD_Write(SSD16xx_RAM_XPOS, x / 8, (x + w - 1) / 8);
|
||||||
EPD_Write(SSD16xx_RAM_YPOS,
|
EPD_Write(SSD16xx_RAM_YPOS, y % 256, y / 256, (y + h - 1) % 256, (y + h - 1) / 256);
|
||||||
y % 256, y / 256,
|
|
||||||
(y + h - 1) % 256,
|
|
||||||
(y + h - 1) / 256);
|
|
||||||
EPD_Write(SSD16xx_RAM_XCOUNT, x / 8);
|
EPD_Write(SSD16xx_RAM_XCOUNT, x / 8);
|
||||||
}
|
}
|
||||||
EPD_Write(SSD16xx_RAM_YPOS,
|
EPD_Write(SSD16xx_RAM_YPOS, y % 256, y / 256, (y + h - 1) % 256, (y + h - 1) / 256);
|
||||||
y % 256, y / 256,
|
|
||||||
(y + h - 1) % 256,
|
|
||||||
(y + h - 1) / 256);
|
|
||||||
EPD_Write(SSD16xx_RAM_YCOUNT, y % 256, y / 256);
|
EPD_Write(SSD16xx_RAM_YCOUNT, y % 256, y / 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSD16xx_Dump_LUT(void)
|
void SSD16xx_Dump_LUT(void) {
|
||||||
{
|
|
||||||
uint8_t lut[128];
|
uint8_t lut[128];
|
||||||
|
|
||||||
EPD_WriteCmd(SSD16xx_READ_LUT);
|
EPD_WriteCmd(SSD16xx_READ_LUT);
|
||||||
@@ -56,8 +40,7 @@ void SSD16xx_Dump_LUT(void)
|
|||||||
NRF_LOG_DEBUG("=== LUT END ===\n");
|
NRF_LOG_DEBUG("=== LUT END ===\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSD16xx_Init(epd_model_t *epd)
|
void SSD16xx_Init(epd_model_t* epd) {
|
||||||
{
|
|
||||||
EPD_Reset(HIGH, 10);
|
EPD_Reset(HIGH, 10);
|
||||||
|
|
||||||
EPD_WriteCmd(SSD16xx_SW_RESET);
|
EPD_WriteCmd(SSD16xx_SW_RESET);
|
||||||
@@ -69,8 +52,7 @@ void SSD16xx_Init(epd_model_t *epd)
|
|||||||
_setPartialRamArea(epd, 0, 0, epd->width, epd->height);
|
_setPartialRamArea(epd, 0, 0, epd->width, epd->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SSD16xx_Refresh(epd_model_t *epd)
|
static void SSD16xx_Refresh(epd_model_t* epd) {
|
||||||
{
|
|
||||||
EPD_Write(SSD16xx_DISP_CTRL1, epd->color == BWR ? 0x80 : 0x40, 0x00);
|
EPD_Write(SSD16xx_DISP_CTRL1, epd->color == BWR ? 0x80 : 0x40, 0x00);
|
||||||
|
|
||||||
NRF_LOG_DEBUG("[EPD]: refresh begin\n");
|
NRF_LOG_DEBUG("[EPD]: refresh begin\n");
|
||||||
@@ -79,14 +61,13 @@ static void SSD16xx_Refresh(epd_model_t *epd)
|
|||||||
SSD16xx_WaitBusy(30000);
|
SSD16xx_WaitBusy(30000);
|
||||||
NRF_LOG_DEBUG("[EPD]: refresh end\n");
|
NRF_LOG_DEBUG("[EPD]: refresh end\n");
|
||||||
|
|
||||||
// SSD16xx_Dump_LUT();
|
// SSD16xx_Dump_LUT();
|
||||||
|
|
||||||
_setPartialRamArea(epd, 0, 0, epd->width, epd->height); // DO NOT REMOVE!
|
_setPartialRamArea(epd, 0, 0, epd->width, epd->height); // DO NOT REMOVE!
|
||||||
SSD16xx_Update(0x83); // power off
|
SSD16xx_Update(0x83); // power off
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSD16xx_Clear(epd_model_t *epd, bool refresh)
|
void SSD16xx_Clear(epd_model_t* epd, bool refresh) {
|
||||||
{
|
|
||||||
uint32_t ram_bytes = ((epd->width + 7) / 8) * epd->height;
|
uint32_t ram_bytes = ((epd->width + 7) / 8) * epd->height;
|
||||||
|
|
||||||
_setPartialRamArea(epd, 0, 0, epd->width, epd->height);
|
_setPartialRamArea(epd, 0, 0, epd->width, epd->height);
|
||||||
@@ -94,30 +75,24 @@ void SSD16xx_Clear(epd_model_t *epd, bool refresh)
|
|||||||
EPD_FillRAM(SSD16xx_WRITE_RAM1, 0xFF, ram_bytes);
|
EPD_FillRAM(SSD16xx_WRITE_RAM1, 0xFF, ram_bytes);
|
||||||
EPD_FillRAM(SSD16xx_WRITE_RAM2, 0xFF, ram_bytes);
|
EPD_FillRAM(SSD16xx_WRITE_RAM2, 0xFF, ram_bytes);
|
||||||
|
|
||||||
if (refresh)
|
if (refresh) SSD16xx_Refresh(epd);
|
||||||
SSD16xx_Refresh(epd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSD16xx_Write_Image(epd_model_t *epd, uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
void SSD16xx_Write_Image(epd_model_t* epd, 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
|
uint16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
|
||||||
x -= x % 8; // byte boundary
|
x -= x % 8; // byte boundary
|
||||||
w = wb * 8; // byte boundary
|
w = wb * 8; // byte boundary
|
||||||
if (x + w > epd->width || y + h > epd->height)
|
if (x + w > epd->width || y + h > epd->height) return;
|
||||||
return;
|
|
||||||
|
|
||||||
_setPartialRamArea(epd, x, y, w, h);
|
_setPartialRamArea(epd, x, y, w, h);
|
||||||
EPD_WriteCmd(SSD16xx_WRITE_RAM1);
|
EPD_WriteCmd(SSD16xx_WRITE_RAM1);
|
||||||
for (uint16_t i = 0; i < h; i++)
|
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);
|
||||||
for (uint16_t j = 0; j < w / 8; j++)
|
|
||||||
EPD_WriteByte(black ? black[j + i * wb] : 0xFF);
|
|
||||||
}
|
}
|
||||||
EPD_WriteCmd(SSD16xx_WRITE_RAM2);
|
EPD_WriteCmd(SSD16xx_WRITE_RAM2);
|
||||||
for (uint16_t i = 0; i < h; i++)
|
for (uint16_t i = 0; i < h; i++) {
|
||||||
{
|
for (uint16_t j = 0; j < w / 8; j++) {
|
||||||
for (uint16_t j = 0; j < w / 8; j++)
|
|
||||||
{
|
|
||||||
if (epd->color == BWR)
|
if (epd->color == BWR)
|
||||||
EPD_WriteByte(color ? color[j + i * wb] : 0xFF);
|
EPD_WriteByte(color ? color[j + i * wb] : 0xFF);
|
||||||
else
|
else
|
||||||
@@ -126,8 +101,7 @@ void SSD16xx_Write_Image(epd_model_t *epd, uint8_t *black, uint8_t *color, uint1
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSD16xx_Write_Ram(epd_model_t *epd, uint8_t cfg, uint8_t *data, uint8_t len)
|
void SSD16xx_Write_Ram(epd_model_t* epd, uint8_t cfg, uint8_t* data, uint8_t len) {
|
||||||
{
|
|
||||||
bool begin = (cfg >> 4) == 0x00;
|
bool begin = (cfg >> 4) == 0x00;
|
||||||
bool black = (cfg & 0x0F) == 0x0F;
|
bool black = (cfg & 0x0F) == 0x0F;
|
||||||
if (begin) {
|
if (begin) {
|
||||||
@@ -139,8 +113,7 @@ void SSD16xx_Write_Ram(epd_model_t *epd, uint8_t cfg, uint8_t *data, uint8_t len
|
|||||||
EPD_WriteData(data, len);
|
EPD_WriteData(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSD16xx_Sleep(epd_model_t *epd)
|
void SSD16xx_Sleep(epd_model_t* epd) {
|
||||||
{
|
|
||||||
EPD_Write(SSD16xx_SLEEP_MODE, 0x01);
|
EPD_Write(SSD16xx_SLEEP_MODE, 0x01);
|
||||||
delay(100);
|
delay(100);
|
||||||
}
|
}
|
||||||
|
|||||||
192
EPD/UC81xx.c
192
EPD/UC81xx.c
@@ -1,55 +1,40 @@
|
|||||||
#include "EPD_driver.h"
|
#include "EPD_driver.h"
|
||||||
#include "nrf_log.h"
|
#include "nrf_log.h"
|
||||||
|
|
||||||
static void UC81xx_WaitBusy(uint16_t timeout)
|
static void UC81xx_WaitBusy(uint16_t timeout) { EPD_WaitBusy(LOW, timeout); }
|
||||||
{
|
|
||||||
EPD_WaitBusy(LOW, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UC81xx_PowerOn(void)
|
static void UC81xx_PowerOn(void) {
|
||||||
{
|
|
||||||
EPD_WriteCmd(UC81xx_PON);
|
EPD_WriteCmd(UC81xx_PON);
|
||||||
UC81xx_WaitBusy(200);
|
UC81xx_WaitBusy(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UC81xx_PowerOff(void)
|
static void UC81xx_PowerOff(void) {
|
||||||
{
|
|
||||||
EPD_WriteCmd(UC81xx_POF);
|
EPD_WriteCmd(UC81xx_POF);
|
||||||
UC81xx_WaitBusy(200);
|
UC81xx_WaitBusy(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read temperature from driver chip
|
// Read temperature from driver chip
|
||||||
int8_t UC81xx_Read_Temp(epd_model_t *epd)
|
int8_t UC81xx_Read_Temp(epd_model_t* epd) {
|
||||||
{
|
|
||||||
EPD_WriteCmd(UC81xx_TSC);
|
EPD_WriteCmd(UC81xx_TSC);
|
||||||
UC81xx_WaitBusy(100);
|
UC81xx_WaitBusy(100);
|
||||||
return (int8_t)EPD_ReadByte();
|
return (int8_t)EPD_ReadByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _setPartialRamArea(epd_model_t *epd, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
static void _setPartialRamArea(epd_model_t* epd, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
||||||
{
|
|
||||||
if (epd->drv->ic == EPD_DRIVER_IC_JD79668 || epd->drv->ic == EPD_DRIVER_IC_JD79665) {
|
if (epd->drv->ic == EPD_DRIVER_IC_JD79668 || epd->drv->ic == EPD_DRIVER_IC_JD79665) {
|
||||||
EPD_Write(0x83, // partial window
|
EPD_Write(0x83, // partial window
|
||||||
x / 256, x % 256,
|
x / 256, x % 256, (x + w - 1) / 256, (x + w - 1) % 256, y / 256, y % 256, (y + h - 1) / 256,
|
||||||
(x + w - 1) / 256, (x + w - 1) % 256,
|
(y + h - 1) % 256, 0x01);
|
||||||
y / 256, y % 256,
|
|
||||||
(y + h - 1) / 256, (y + h - 1) % 256,
|
|
||||||
0x01);
|
|
||||||
} else {
|
} else {
|
||||||
uint16_t xe = (x + w - 1) | 0x0007; // byte boundary inclusive (last byte)
|
uint16_t xe = (x + w - 1) | 0x0007; // byte boundary inclusive (last byte)
|
||||||
uint16_t ye = y + h - 1;
|
uint16_t ye = y + h - 1;
|
||||||
x &= 0xFFF8; // byte boundary
|
x &= 0xFFF8; // byte boundary
|
||||||
EPD_Write(UC81xx_PTL, // partial window
|
EPD_Write(UC81xx_PTL, // partial window
|
||||||
x / 256, x % 256,
|
x / 256, x % 256, xe / 256, xe % 256, y / 256, y % 256, ye / 256, ye % 256, 0x00);
|
||||||
xe / 256, xe % 256,
|
|
||||||
y / 256, y % 256,
|
|
||||||
ye / 256, ye % 256,
|
|
||||||
0x00);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UC81xx_Refresh(epd_model_t *epd)
|
void UC81xx_Refresh(epd_model_t* epd) {
|
||||||
{
|
|
||||||
NRF_LOG_DEBUG("[EPD]: refresh begin\n");
|
NRF_LOG_DEBUG("[EPD]: refresh begin\n");
|
||||||
UC81xx_PowerOn();
|
UC81xx_PowerOn();
|
||||||
|
|
||||||
@@ -63,8 +48,7 @@ void UC81xx_Refresh(epd_model_t *epd)
|
|||||||
NRF_LOG_DEBUG("[EPD]: refresh end\n");
|
NRF_LOG_DEBUG("[EPD]: refresh end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void JD79668_Refresh(epd_model_t *epd)
|
void JD79668_Refresh(epd_model_t* epd) {
|
||||||
{
|
|
||||||
NRF_LOG_DEBUG("[EPD]: refresh begin\n");
|
NRF_LOG_DEBUG("[EPD]: refresh begin\n");
|
||||||
|
|
||||||
_setPartialRamArea(epd, 0, 0, epd->width, epd->height);
|
_setPartialRamArea(epd, 0, 0, epd->width, epd->height);
|
||||||
@@ -76,8 +60,7 @@ void JD79668_Refresh(epd_model_t *epd)
|
|||||||
NRF_LOG_DEBUG("[EPD]: refresh end\n");
|
NRF_LOG_DEBUG("[EPD]: refresh end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void UC81xx_Dump_OTP(void)
|
void UC81xx_Dump_OTP(void) {
|
||||||
{
|
|
||||||
uint8_t data[128];
|
uint8_t data[128];
|
||||||
|
|
||||||
UC81xx_PowerOn();
|
UC81xx_PowerOn();
|
||||||
@@ -93,18 +76,16 @@ void UC81xx_Dump_OTP(void)
|
|||||||
UC81xx_PowerOff();
|
UC81xx_PowerOff();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UC81xx_Init(epd_model_t *epd)
|
void UC81xx_Init(epd_model_t* epd) {
|
||||||
{
|
|
||||||
EPD_Reset(HIGH, 10);
|
EPD_Reset(HIGH, 10);
|
||||||
|
|
||||||
// UC81xx_Dump_OTP();
|
// UC81xx_Dump_OTP();
|
||||||
|
|
||||||
EPD_Write(UC81xx_PSR, epd->color == BWR ? 0x0F : 0x1F);
|
EPD_Write(UC81xx_PSR, epd->color == BWR ? 0x0F : 0x1F);
|
||||||
EPD_Write(UC81xx_CDI, epd->color == BWR ? 0x77 : 0x97);
|
EPD_Write(UC81xx_CDI, epd->color == BWR ? 0x77 : 0x97);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UC8159_Init(epd_model_t *epd)
|
void UC8159_Init(epd_model_t* epd) {
|
||||||
{
|
|
||||||
EPD_Reset(HIGH, 10);
|
EPD_Reset(HIGH, 10);
|
||||||
|
|
||||||
EPD_Write(UC81xx_PWR, 0x37, 0x00);
|
EPD_Write(UC81xx_PWR, 0x37, 0x00);
|
||||||
@@ -114,17 +95,12 @@ void UC8159_Init(epd_model_t *epd)
|
|||||||
EPD_Write(UC81xx_BTST, 0xc7, 0xcc, 0x15);
|
EPD_Write(UC81xx_BTST, 0xc7, 0xcc, 0x15);
|
||||||
EPD_Write(UC81xx_CDI, 0x77);
|
EPD_Write(UC81xx_CDI, 0x77);
|
||||||
EPD_Write(UC81xx_TCON, 0x22);
|
EPD_Write(UC81xx_TCON, 0x22);
|
||||||
EPD_Write(0x65, 0x00); // FLASH CONTROL
|
EPD_Write(0x65, 0x00); // FLASH CONTROL
|
||||||
EPD_Write(0xe5, 0x03); // FLASH MODE
|
EPD_Write(0xe5, 0x03); // FLASH MODE
|
||||||
EPD_Write(UC81xx_TRES,
|
EPD_Write(UC81xx_TRES, epd->width >> 8, epd->width & 0xff, epd->height >> 8, epd->height & 0xff);
|
||||||
epd->width >> 8,
|
|
||||||
epd->width & 0xff,
|
|
||||||
epd->height >> 8,
|
|
||||||
epd->height & 0xff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JD79668_Init(epd_model_t *epd)
|
void JD79668_Init(epd_model_t* epd) {
|
||||||
{
|
|
||||||
EPD_Reset(HIGH, 50);
|
EPD_Reset(HIGH, 50);
|
||||||
|
|
||||||
EPD_Write(0x4D, 0x78);
|
EPD_Write(0x4D, 0x78);
|
||||||
@@ -132,9 +108,7 @@ void JD79668_Init(epd_model_t *epd)
|
|||||||
EPD_Write(UC81xx_BTST, 0x0D, 0x12, 0x24, 0x25, 0x12, 0x29, 0x10);
|
EPD_Write(UC81xx_BTST, 0x0D, 0x12, 0x24, 0x25, 0x12, 0x29, 0x10);
|
||||||
EPD_Write(UC81xx_PLL, 0x08);
|
EPD_Write(UC81xx_PLL, 0x08);
|
||||||
EPD_Write(UC81xx_CDI, 0x37);
|
EPD_Write(UC81xx_CDI, 0x37);
|
||||||
EPD_Write(UC81xx_TRES,
|
EPD_Write(UC81xx_TRES, epd->width / 256, epd->width % 256, epd->height / 256, epd->height % 256);
|
||||||
epd->width / 256, epd->width % 256,
|
|
||||||
epd->height / 256, epd->height % 256);
|
|
||||||
|
|
||||||
EPD_Write(0xAE, 0xCF);
|
EPD_Write(0xAE, 0xCF);
|
||||||
EPD_Write(0xB0, 0x13);
|
EPD_Write(0xB0, 0x13);
|
||||||
@@ -145,19 +119,16 @@ void JD79668_Init(epd_model_t *epd)
|
|||||||
UC81xx_PowerOn();
|
UC81xx_PowerOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UC81xx_Clear(epd_model_t *epd, bool refresh)
|
void UC81xx_Clear(epd_model_t* epd, bool refresh) {
|
||||||
{
|
|
||||||
uint32_t ram_bytes = ((epd->width + 7) / 8) * epd->height;
|
uint32_t ram_bytes = ((epd->width + 7) / 8) * epd->height;
|
||||||
|
|
||||||
EPD_FillRAM(UC81xx_DTM1, 0xFF, ram_bytes);
|
EPD_FillRAM(UC81xx_DTM1, 0xFF, ram_bytes);
|
||||||
EPD_FillRAM(UC81xx_DTM2, 0xFF, ram_bytes);
|
EPD_FillRAM(UC81xx_DTM2, 0xFF, ram_bytes);
|
||||||
|
|
||||||
if (refresh)
|
if (refresh) UC81xx_Refresh(epd);
|
||||||
UC81xx_Refresh(epd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UC8159_Clear(epd_model_t *epd, bool refresh)
|
void UC8159_Clear(epd_model_t* epd, bool refresh) {
|
||||||
{
|
|
||||||
uint32_t wb = (epd->width + 7) / 8;
|
uint32_t wb = (epd->width + 7) / 8;
|
||||||
|
|
||||||
EPD_WriteCmd(UC81xx_DTM1);
|
EPD_WriteCmd(UC81xx_DTM1);
|
||||||
@@ -169,87 +140,81 @@ void UC8159_Clear(epd_model_t *epd, bool refresh)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (refresh)
|
if (refresh) UC81xx_Refresh(epd);
|
||||||
UC81xx_Refresh(epd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JD79668_Clear(epd_model_t *epd, bool refresh)
|
void JD79668_Clear(epd_model_t* epd, bool refresh) {
|
||||||
{
|
|
||||||
uint32_t ram_bytes = ((epd->width + 3) / 4) * epd->height;
|
uint32_t ram_bytes = ((epd->width + 3) / 4) * epd->height;
|
||||||
|
|
||||||
EPD_FillRAM(UC81xx_DTM1, 0x55, ram_bytes);
|
EPD_FillRAM(UC81xx_DTM1, 0x55, ram_bytes);
|
||||||
|
|
||||||
if (refresh)
|
if (refresh) UC81xx_Refresh(epd);
|
||||||
UC81xx_Refresh(epd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UC81xx_Write_Image(epd_model_t *epd, uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
void UC81xx_Write_Image(epd_model_t* epd, 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
|
uint16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
|
||||||
x -= x % 8; // byte boundary
|
x -= x % 8; // byte boundary
|
||||||
w = wb * 8; // byte boundary
|
w = wb * 8; // byte boundary
|
||||||
if (x + w > epd->width || y + h > epd->height)
|
if (x + w > epd->width || y + h > epd->height) return;
|
||||||
return;
|
|
||||||
|
|
||||||
EPD_WriteCmd(UC81xx_PTIN); // partial in
|
EPD_WriteCmd(UC81xx_PTIN); // partial in
|
||||||
_setPartialRamArea(epd, x, y, w, h);
|
_setPartialRamArea(epd, x, y, w, h);
|
||||||
if (epd->color == BWR)
|
if (epd->color == BWR) {
|
||||||
{
|
|
||||||
EPD_WriteCmd(UC81xx_DTM1);
|
EPD_WriteCmd(UC81xx_DTM1);
|
||||||
for (uint16_t i = 0; i < h; i++)
|
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);
|
||||||
for (uint16_t j = 0; j < w / 8; j++)
|
|
||||||
EPD_WriteByte(black ? black[j + i * wb] : 0xFF);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EPD_WriteCmd(UC81xx_DTM2);
|
EPD_WriteCmd(UC81xx_DTM2);
|
||||||
for (uint16_t i = 0; i < h; i++)
|
for (uint16_t i = 0; i < h; i++) {
|
||||||
{
|
for (uint16_t j = 0; j < w / 8; j++) {
|
||||||
for (uint16_t j = 0; j < w / 8; j++)
|
|
||||||
{
|
|
||||||
if (epd->color == BWR)
|
if (epd->color == BWR)
|
||||||
EPD_WriteByte(color ? color[j + i * wb] : 0xFF);
|
EPD_WriteByte(color ? color[j + i * wb] : 0xFF);
|
||||||
else
|
else
|
||||||
EPD_WriteByte(black[j + i * wb]);
|
EPD_WriteByte(black[j + i * wb]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EPD_WriteCmd(UC81xx_PTOUT); // partial out
|
EPD_WriteCmd(UC81xx_PTOUT); // partial out
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UC8159_Send_Pixel(uint8_t black_data, uint8_t color_data) {
|
static void UC8159_Send_Pixel(uint8_t black_data, uint8_t color_data) {
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
for (uint8_t j = 0; j < 8; j++) {
|
for (uint8_t j = 0; j < 8; j++) {
|
||||||
if ((color_data & 0x80) == 0x00) data = 0x04; // red
|
if ((color_data & 0x80) == 0x00)
|
||||||
else if ((black_data & 0x80) == 0x00) data = 0x00; // black
|
data = 0x04; // red
|
||||||
else data = 0x03; // white
|
else if ((black_data & 0x80) == 0x00)
|
||||||
|
data = 0x00; // black
|
||||||
|
else
|
||||||
|
data = 0x03; // white
|
||||||
data = (data << 4) & 0xFF;
|
data = (data << 4) & 0xFF;
|
||||||
black_data = (black_data << 1) & 0xFF;
|
black_data = (black_data << 1) & 0xFF;
|
||||||
color_data = (color_data << 1) & 0xFF;
|
color_data = (color_data << 1) & 0xFF;
|
||||||
j++;
|
j++;
|
||||||
if ((color_data & 0x80) == 0x00) data |= 0x04; // red
|
if ((color_data & 0x80) == 0x00)
|
||||||
else if ((black_data & 0x80) == 0x00) data |= 0x00; // black
|
data |= 0x04; // red
|
||||||
else data |= 0x03; // white
|
else if ((black_data & 0x80) == 0x00)
|
||||||
|
data |= 0x00; // black
|
||||||
|
else
|
||||||
|
data |= 0x03; // white
|
||||||
black_data = (black_data << 1) & 0xFF;
|
black_data = (black_data << 1) & 0xFF;
|
||||||
color_data = (color_data << 1) & 0xFF;
|
color_data = (color_data << 1) & 0xFF;
|
||||||
EPD_WriteByte(data);
|
EPD_WriteByte(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UC8159_Write_Image(epd_model_t *epd, uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
void UC8159_Write_Image(epd_model_t* epd, 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
|
uint16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
|
||||||
x -= x % 8; // byte boundary
|
x -= x % 8; // byte boundary
|
||||||
w = wb * 8; // byte boundary
|
w = wb * 8; // byte boundary
|
||||||
if (x + w > epd->width || y + h > epd->height)
|
if (x + w > epd->width || y + h > epd->height) return;
|
||||||
return;
|
|
||||||
|
|
||||||
EPD_WriteCmd(UC81xx_PTIN); // partial in
|
EPD_WriteCmd(UC81xx_PTIN); // partial in
|
||||||
_setPartialRamArea(epd, x, y, w, h);
|
_setPartialRamArea(epd, x, y, w, h);
|
||||||
EPD_WriteCmd(UC81xx_DTM1);
|
EPD_WriteCmd(UC81xx_DTM1);
|
||||||
for (uint16_t i = 0; i < h; i++)
|
for (uint16_t i = 0; i < h; i++) {
|
||||||
{
|
for (uint16_t j = 0; j < w / 8; j++) {
|
||||||
for (uint16_t j = 0; j < w / 8; j++)
|
|
||||||
{
|
|
||||||
uint8_t black_data = 0xFF;
|
uint8_t black_data = 0xFF;
|
||||||
uint8_t color_data = 0xFF;
|
uint8_t color_data = 0xFF;
|
||||||
if (black) black_data = black[j + i * wb];
|
if (black) black_data = black[j + i * wb];
|
||||||
@@ -257,28 +222,25 @@ void UC8159_Write_Image(epd_model_t *epd, uint8_t *black, uint8_t *color, uint16
|
|||||||
UC8159_Send_Pixel(black_data, color_data);
|
UC8159_Send_Pixel(black_data, color_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EPD_WriteCmd(UC81xx_PTOUT); // partial out
|
EPD_WriteCmd(UC81xx_PTOUT); // partial out
|
||||||
}
|
}
|
||||||
|
|
||||||
void JD79668_Write_Image(epd_model_t *epd, uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
void JD79668_Write_Image(epd_model_t* epd, 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
|
uint16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
|
||||||
x -= x % 8; // byte boundary
|
x -= x % 8; // byte boundary
|
||||||
w = wb * 8; // byte boundary
|
w = wb * 8; // byte boundary
|
||||||
if (x + w > epd->width || y + h > epd->height)
|
if (x + w > epd->width || y + h > epd->height) return;
|
||||||
return;
|
|
||||||
|
|
||||||
_setPartialRamArea(epd, x, y, w, h);
|
_setPartialRamArea(epd, x, y, w, h);
|
||||||
EPD_WriteCmd(UC81xx_DTM1);
|
EPD_WriteCmd(UC81xx_DTM1);
|
||||||
for (uint16_t i = 0; i < h * 2; i++) // 2 bits per pixel
|
for (uint16_t i = 0; i < h * 2; i++) // 2 bits per pixel
|
||||||
{
|
{
|
||||||
for (uint16_t j = 0; j < w / 8; j++)
|
for (uint16_t j = 0; j < w / 8; j++) EPD_WriteByte(black ? black[j + i * wb] : 0x55);
|
||||||
EPD_WriteByte(black ? black[j + i * wb] : 0x55);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UC81xx_Write_Ram(epd_model_t *epd, uint8_t cfg, uint8_t *data, uint8_t len)
|
void UC81xx_Write_Ram(epd_model_t* epd, uint8_t cfg, uint8_t* data, uint8_t len) {
|
||||||
{
|
|
||||||
bool begin = (cfg >> 4) == 0x00;
|
bool begin = (cfg >> 4) == 0x00;
|
||||||
bool black = (cfg & 0x0F) == 0x0F;
|
bool black = (cfg & 0x0F) == 0x0F;
|
||||||
if (begin) {
|
if (begin) {
|
||||||
@@ -291,16 +253,14 @@ void UC81xx_Write_Ram(epd_model_t *epd, uint8_t cfg, uint8_t *data, uint8_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write native data to ram, format should be 2pp or above
|
// Write native data to ram, format should be 2pp or above
|
||||||
void UC81xx_Write_Ram_Native(epd_model_t *epd, uint8_t cfg, uint8_t *data, uint8_t len)
|
void UC81xx_Write_Ram_Native(epd_model_t* epd, uint8_t cfg, uint8_t* data, uint8_t len) {
|
||||||
{
|
|
||||||
bool begin = (cfg >> 4) == 0x00;
|
bool begin = (cfg >> 4) == 0x00;
|
||||||
bool black = (cfg & 0x0F) == 0x0F;
|
bool black = (cfg & 0x0F) == 0x0F;
|
||||||
if (begin && black) EPD_WriteCmd(UC81xx_DTM1);
|
if (begin && black) EPD_WriteCmd(UC81xx_DTM1);
|
||||||
EPD_WriteData(data, len);
|
EPD_WriteData(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UC81xx_Sleep(epd_model_t *epd)
|
void UC81xx_Sleep(epd_model_t* epd) {
|
||||||
{
|
|
||||||
UC81xx_PowerOff();
|
UC81xx_PowerOff();
|
||||||
delay(100);
|
delay(100);
|
||||||
EPD_Write(UC81xx_DSLP, 0xA5);
|
EPD_Write(UC81xx_DSLP, 0xA5);
|
||||||
|
|||||||
1491
GUI/Adafruit_GFX.c
1491
GUI/Adafruit_GFX.c
File diff suppressed because it is too large
Load Diff
@@ -4,99 +4,99 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "u8g2_font.h"
|
#include "u8g2_font.h"
|
||||||
|
|
||||||
#define GFX_BLACK 0x0000
|
#define GFX_BLACK 0x0000
|
||||||
#define GFX_WHITE 0xFFFF
|
#define GFX_WHITE 0xFFFF
|
||||||
#define GFX_RED 0xF800 // 255, 0, 0
|
#define GFX_RED 0xF800 // 255, 0, 0
|
||||||
#define GFX_YELLOW 0xFFE0 // 255, 255, 0
|
#define GFX_YELLOW 0xFFE0 // 255, 255, 0
|
||||||
#define GFX_BLUE 0x001F // 0, 0, 255
|
#define GFX_BLUE 0x001F // 0, 0, 255
|
||||||
#define GFX_GREEN 0x07E0 // 0, 255, 0
|
#define GFX_GREEN 0x07E0 // 0, 255, 0
|
||||||
#define GFX_ORANGE 0xFC00 // 255, 128, 0
|
#define GFX_ORANGE 0xFC00 // 255, 128, 0
|
||||||
|
|
||||||
typedef void (*buffer_callback)(void *user_data, uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
typedef void (*buffer_callback)(void* user_data, uint8_t* black, uint8_t* color, uint16_t x, uint16_t y, uint16_t w,
|
||||||
|
uint16_t h);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GFX_ROTATE_0 = 0,
|
GFX_ROTATE_0 = 0,
|
||||||
GFX_ROTATE_90 = 1,
|
GFX_ROTATE_90 = 1,
|
||||||
GFX_ROTATE_180 = 2,
|
GFX_ROTATE_180 = 2,
|
||||||
GFX_ROTATE_270 = 3,
|
GFX_ROTATE_270 = 3,
|
||||||
} GFX_Rotate;
|
} GFX_Rotate;
|
||||||
|
|
||||||
// GRAPHICS CONTEXT
|
// GRAPHICS CONTEXT
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int16_t WIDTH; // This is the 'raw' display width - never changes
|
int16_t WIDTH; // This is the 'raw' display width - never changes
|
||||||
int16_t HEIGHT; // This is the 'raw' display height - never changes
|
int16_t HEIGHT; // This is the 'raw' display height - never changes
|
||||||
int16_t _width; // Display width as modified by current rotation
|
int16_t _width; // Display width as modified by current rotation
|
||||||
int16_t _height; // Display height as modified by current rotation
|
int16_t _height; // Display height as modified by current rotation
|
||||||
GFX_Rotate rotation; // Display rotation (0 thru 3)
|
GFX_Rotate rotation; // Display rotation (0 thru 3)
|
||||||
|
|
||||||
u8g2_font_t u8g2;
|
u8g2_font_t u8g2;
|
||||||
int16_t tx, ty; // current position for the print command
|
int16_t tx, ty; // current position for the print command
|
||||||
uint16_t encoding; // the unicode, detected by the utf-8 decoder
|
uint16_t encoding; // the unicode, detected by the utf-8 decoder
|
||||||
uint8_t utf8_state; // current state of the utf-8 decoder, contains the remaining bytes for a detected unicode glyph
|
uint8_t
|
||||||
|
utf8_state; // current state of the utf-8 decoder, contains the remaining bytes for a detected unicode glyph
|
||||||
|
|
||||||
uint8_t *buffer; // black pixel buffer
|
uint8_t* buffer; // black pixel buffer
|
||||||
uint8_t *color; // color pixel buffer (3c only)
|
uint8_t* color; // color pixel buffer (3c only)
|
||||||
uint16_t px, py, pw, ph; // partial window offset and size
|
uint16_t px, py, pw, ph; // partial window offset and size
|
||||||
int16_t page_height; // height to be drawn in one page
|
int16_t page_height; // height to be drawn in one page
|
||||||
int16_t current_page; // index of the current drawing page
|
int16_t current_page; // index of the current drawing page
|
||||||
int16_t total_pages; // total number of pages to be drawn
|
int16_t total_pages; // total number of pages to be drawn
|
||||||
} Adafruit_GFX;
|
} Adafruit_GFX;
|
||||||
|
|
||||||
// CONTROL API
|
// CONTROL API
|
||||||
void GFX_begin(Adafruit_GFX *gfx, int16_t w, int16_t h, int16_t buffer_height);
|
void GFX_begin(Adafruit_GFX* gfx, int16_t w, int16_t h, int16_t buffer_height);
|
||||||
void GFX_begin_3c(Adafruit_GFX *gfx, int16_t w, int16_t h, int16_t buffer_height);
|
void GFX_begin_3c(Adafruit_GFX* gfx, int16_t w, int16_t h, int16_t buffer_height);
|
||||||
void GFX_begin_4c(Adafruit_GFX *gfx, int16_t w, int16_t h, int16_t buffer_height);
|
void GFX_begin_4c(Adafruit_GFX* gfx, int16_t w, int16_t h, int16_t buffer_height);
|
||||||
void GFX_setRotation(Adafruit_GFX *gfx, GFX_Rotate r);
|
void GFX_setRotation(Adafruit_GFX* gfx, GFX_Rotate r);
|
||||||
void GFX_setWindow(Adafruit_GFX *gfx, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
void GFX_setWindow(Adafruit_GFX* gfx, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||||||
void GFX_firstPage(Adafruit_GFX *gfx);
|
void GFX_firstPage(Adafruit_GFX* gfx);
|
||||||
bool GFX_nextPage(Adafruit_GFX *gfx, buffer_callback callback, void *user_data);
|
bool GFX_nextPage(Adafruit_GFX* gfx, buffer_callback callback, void* user_data);
|
||||||
void GFX_end(Adafruit_GFX *gfx);
|
void GFX_end(Adafruit_GFX* gfx);
|
||||||
|
|
||||||
// DRAW API
|
// DRAW API
|
||||||
void GFX_drawPixel(Adafruit_GFX *gfx, int16_t x, int16_t y, uint16_t color);
|
void GFX_drawPixel(Adafruit_GFX* gfx, int16_t x, int16_t y, uint16_t color);
|
||||||
void GFX_drawLine(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
|
void GFX_drawLine(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
|
||||||
void GFX_drawDottedLine(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1, int16_t y1,
|
void GFX_drawDottedLine(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color,
|
||||||
uint16_t color, uint8_t dot_len, uint8_t space_len);
|
uint8_t dot_len, uint8_t space_len);
|
||||||
void GFX_drawFastVLine(Adafruit_GFX *gfx, int16_t x, int16_t y, int16_t h, uint16_t color);
|
void GFX_drawFastVLine(Adafruit_GFX* gfx, int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||||
void GFX_drawFastHLine(Adafruit_GFX *gfx, int16_t x, int16_t y, int16_t w, uint16_t color);
|
void GFX_drawFastHLine(Adafruit_GFX* gfx, int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||||
void GFX_fillRect(Adafruit_GFX *gfx, int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
void GFX_fillRect(Adafruit_GFX* gfx, int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
||||||
void GFX_fillScreen(Adafruit_GFX *gfx, uint16_t color);
|
void GFX_fillScreen(Adafruit_GFX* gfx, uint16_t color);
|
||||||
void GFX_drawRect(Adafruit_GFX *gfx, int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
void GFX_drawRect(Adafruit_GFX* gfx, int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
||||||
void GFX_drawCircle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t r, uint16_t color);
|
void GFX_drawCircle(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t r, uint16_t color);
|
||||||
void GFX_drawCircleHelper(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t r, uint8_t cornername,
|
void GFX_drawCircleHelper(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color);
|
||||||
|
void GFX_fillCircle(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t r, uint16_t color);
|
||||||
|
void GFX_fillCircleHelper(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta,
|
||||||
uint16_t color);
|
uint16_t color);
|
||||||
void GFX_fillCircle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t r, uint16_t color);
|
void GFX_drawTriangle(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2,
|
||||||
void GFX_fillCircleHelper(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t r, uint8_t cornername,
|
uint16_t color);
|
||||||
int16_t delta, uint16_t color);
|
void GFX_fillTriangle(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2,
|
||||||
void GFX_drawTriangle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2,
|
uint16_t color);
|
||||||
int16_t y2, uint16_t color);
|
void GFX_drawRoundRect(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
|
||||||
void GFX_fillTriangle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2,
|
void GFX_fillRoundRect(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
|
||||||
int16_t y2, uint16_t color);
|
void GFX_drawBitmap(Adafruit_GFX* gfx, int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h,
|
||||||
void GFX_drawRoundRect(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t w, int16_t h,
|
uint16_t color, bool invert);
|
||||||
int16_t radius, uint16_t color);
|
|
||||||
void GFX_fillRoundRect(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t w, int16_t h,
|
|
||||||
int16_t radius, uint16_t color);
|
|
||||||
void GFX_drawBitmap(Adafruit_GFX *gfx, int16_t x, int16_t y, const uint8_t bitmap[], int16_t w,
|
|
||||||
int16_t h, uint16_t color, bool invert);
|
|
||||||
|
|
||||||
// U8G2 FONT API
|
// U8G2 FONT API
|
||||||
void GFX_setCursor(Adafruit_GFX *gfx, int16_t x, int16_t y);
|
void GFX_setCursor(Adafruit_GFX* gfx, int16_t x, int16_t y);
|
||||||
void GFX_setFont(Adafruit_GFX *gfx, const uint8_t *font);
|
void GFX_setFont(Adafruit_GFX* gfx, const uint8_t* font);
|
||||||
void GFX_setFontMode(Adafruit_GFX *gfx, uint8_t is_transparent);
|
void GFX_setFontMode(Adafruit_GFX* gfx, uint8_t is_transparent);
|
||||||
void GFX_setFontDirection(Adafruit_GFX *gfx, GFX_Rotate d);
|
void GFX_setFontDirection(Adafruit_GFX* gfx, GFX_Rotate d);
|
||||||
void GFX_setTextColor(Adafruit_GFX *gfx, uint16_t fg, uint16_t bg);
|
void GFX_setTextColor(Adafruit_GFX* gfx, uint16_t fg, uint16_t bg);
|
||||||
int8_t GFX_getFontAscent(Adafruit_GFX *gfx);
|
int8_t GFX_getFontAscent(Adafruit_GFX* gfx);
|
||||||
int8_t GFX_getFontDescent(Adafruit_GFX *gfx);
|
int8_t GFX_getFontDescent(Adafruit_GFX* gfx);
|
||||||
int8_t GFX_getFontHeight(Adafruit_GFX *gfx);
|
int8_t GFX_getFontHeight(Adafruit_GFX* gfx);
|
||||||
int16_t GFX_drawGlyph(Adafruit_GFX *gfx, int16_t x, int16_t y, uint16_t e);
|
int16_t GFX_drawGlyph(Adafruit_GFX* gfx, int16_t x, int16_t y, uint16_t e);
|
||||||
int16_t GFX_drawStr(Adafruit_GFX *gfx, int16_t x, int16_t y, const char *s);
|
int16_t GFX_drawStr(Adafruit_GFX* gfx, int16_t x, int16_t y, const char* s);
|
||||||
int16_t GFX_drawUTF8(Adafruit_GFX *gfx, int16_t x, int16_t y, const char *str);
|
int16_t GFX_drawUTF8(Adafruit_GFX* gfx, int16_t x, int16_t y, const char* str);
|
||||||
int16_t GFX_getUTF8Width(Adafruit_GFX *gfx, const char *str);
|
int16_t GFX_getUTF8Width(Adafruit_GFX* gfx, const char* str);
|
||||||
int16_t GFX_getUTF8Widthf(Adafruit_GFX *gfx, const char* format, ...);
|
int16_t GFX_getUTF8Widthf(Adafruit_GFX* gfx, const char* format, ...);
|
||||||
size_t GFX_print(Adafruit_GFX *gfx, const char c);
|
size_t GFX_print(Adafruit_GFX* gfx, const char c);
|
||||||
size_t GFX_write(Adafruit_GFX *gfx, const char *buffer, size_t size);
|
size_t GFX_write(Adafruit_GFX* gfx, const char* buffer, size_t size);
|
||||||
size_t GFX_printf(Adafruit_GFX *gfx, const char* format, ...);
|
size_t GFX_printf(Adafruit_GFX* gfx, const char* format, ...);
|
||||||
|
|
||||||
#endif // _ADAFRUIT_GFX_H
|
#endif // _ADAFRUIT_GFX_H
|
||||||
|
|||||||
140
GUI/GUI.c
140
GUI/GUI.c
@@ -1,65 +1,43 @@
|
|||||||
#include "fonts.h"
|
|
||||||
#include "Lunar.h"
|
|
||||||
#include "GUI.h"
|
#include "GUI.h"
|
||||||
#include <time.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "Lunar.h"
|
||||||
|
#include "fonts.h"
|
||||||
|
|
||||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||||
#define GFX_printf_styled(gfx, fg, bg, font, ...) \
|
#define GFX_printf_styled(gfx, fg, bg, font, ...) \
|
||||||
GFX_setTextColor(gfx, fg, bg); \
|
GFX_setTextColor(gfx, fg, bg); \
|
||||||
GFX_setFont(gfx, font); \
|
GFX_setFont(gfx, font); \
|
||||||
GFX_printf(gfx, __VA_ARGS__);
|
GFX_printf(gfx, __VA_ARGS__);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t month;
|
uint8_t month;
|
||||||
uint8_t day;
|
uint8_t day;
|
||||||
char name[10]; // 3x3+1
|
char name[10]; // 3x3+1
|
||||||
} Festival;
|
} Festival;
|
||||||
|
|
||||||
static const Festival festivals[] = {
|
static const Festival festivals[] = {
|
||||||
{ 1, 1, "元旦节"},
|
{1, 1, "元旦节"}, {2, 14, "情人节"}, {3, 8, "妇女节"}, {3, 12, "植树节"}, {4, 1, "愚人节"},
|
||||||
{ 2, 14, "情人节"},
|
{5, 1, "劳动节"}, {5, 4, "青年节"}, {6, 1, "儿童节"}, {7, 1, "建党节"}, {8, 1, "建军节"},
|
||||||
{ 3, 8, "妇女节"},
|
{9, 10, "教师节"}, {10, 1, "国庆节"}, {11, 1, "万圣节"}, {12, 24, "平安夜"}, {12, 25, "圣诞节"},
|
||||||
{ 3, 12, "植树节"},
|
|
||||||
{ 4, 1, "愚人节"},
|
|
||||||
{ 5, 1, "劳动节"},
|
|
||||||
{ 5, 4, "青年节"},
|
|
||||||
{ 6, 1, "儿童节"},
|
|
||||||
{ 7, 1, "建党节"},
|
|
||||||
{ 8, 1, "建军节"},
|
|
||||||
{ 9, 10, "教师节"},
|
|
||||||
{10, 1, "国庆节"},
|
|
||||||
{11, 1, "万圣节"},
|
|
||||||
{12, 24, "平安夜"},
|
|
||||||
{12, 25, "圣诞节"},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const Festival festivals_lunar[] = {
|
static const Festival festivals_lunar[] = {
|
||||||
{ 1, 1, "春节" },
|
{1, 1, "春节"}, {1, 15, "元宵节"}, {2, 2, "龙抬头"}, {5, 5, "端午节"}, {7, 7, "七夕节"}, {7, 15, "中元节"},
|
||||||
{ 1, 15, "元宵节"},
|
{8, 15, "中秋节"}, {9, 9, "重阳节"}, {10, 1, "寒衣节"}, {12, 8, "腊八节"}, {12, 30, "除夕"},
|
||||||
{ 2, 2, "龙抬头"},
|
|
||||||
{ 5, 5, "端午节"},
|
|
||||||
{ 7, 7, "七夕节"},
|
|
||||||
{ 7, 15, "中元节"},
|
|
||||||
{ 8, 15, "中秋节"},
|
|
||||||
{ 9, 9, "重阳节"},
|
|
||||||
{10, 1, "寒衣节"},
|
|
||||||
{12, 8, "腊八节"},
|
|
||||||
{12, 30, "除夕" },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 放假和调休数据,每年更新
|
// 放假和调休数据,每年更新
|
||||||
#define HOLIDAY_YEAR 2025
|
#define HOLIDAY_YEAR 2025
|
||||||
static const uint16_t holidays[] = {
|
static const uint16_t holidays[] = {
|
||||||
0x0101, 0x111A, 0x011C, 0x011D, 0x011E, 0x011F, 0x0201, 0x0202,
|
0x0101, 0x111A, 0x011C, 0x011D, 0x011E, 0x011F, 0x0201, 0x0202, 0x0202, 0x0203, 0x0204, 0x1208,
|
||||||
0x0202, 0x0203, 0x0204, 0x1208, 0x0404, 0x0405, 0x0406, 0x141B,
|
0x0404, 0x0405, 0x0406, 0x141B, 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x051F, 0x0601, 0x0602,
|
||||||
0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x051F, 0x0601, 0x0602,
|
0x191C, 0x0A01, 0x0A02, 0x0A03, 0x0A04, 0x0A05, 0x0A06, 0x0A07, 0x0A08, 0x1A0B,
|
||||||
0x191C, 0x0A01, 0x0A02, 0x0A03, 0x0A04, 0x0A05, 0x0A06, 0x0A07,
|
|
||||||
0x0A08, 0x1A0B,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool GetHoliday(uint8_t mon, uint8_t day, bool *work)
|
static bool GetHoliday(uint8_t mon, uint8_t day, bool* work) {
|
||||||
{
|
|
||||||
for (uint8_t i = 0; i < ARRAY_SIZE(holidays); i++) {
|
for (uint8_t i = 0; i < ARRAY_SIZE(holidays); i++) {
|
||||||
if (((holidays[i] >> 8) & 0xF) == mon && (holidays[i] & 0xFF) == day) {
|
if (((holidays[i] >> 8) & 0xF) == mon && (holidays[i] & 0xFF) == day) {
|
||||||
*work = ((holidays[i] >> 12) & 0xF) > 0;
|
*work = ((holidays[i] >> 12) & 0xF) > 0;
|
||||||
@@ -69,9 +47,8 @@ static bool GetHoliday(uint8_t mon, uint8_t day, bool *work)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GetFestival(uint16_t year, uint8_t mon, uint8_t day, uint8_t week,
|
static bool GetFestival(uint16_t year, uint8_t mon, uint8_t day, uint8_t week, struct Lunar_Date* Lunar,
|
||||||
struct Lunar_Date *Lunar, char *festival)
|
char* festival) {
|
||||||
{
|
|
||||||
// 农历节日
|
// 农历节日
|
||||||
for (uint8_t i = 0; i < ARRAY_SIZE(festivals_lunar); i++) {
|
for (uint8_t i = 0; i < ARRAY_SIZE(festivals_lunar); i++) {
|
||||||
if (Lunar->Month == festivals_lunar[i].month && Lunar->Date == festivals_lunar[i].day) {
|
if (Lunar->Month == festivals_lunar[i].month && Lunar->Date == festivals_lunar[i].day) {
|
||||||
@@ -121,19 +98,18 @@ static bool GetFestival(uint16_t year, uint8_t mon, uint8_t day, uint8_t week,
|
|||||||
uint8_t JQ = (mon - 1) * 2;
|
uint8_t JQ = (mon - 1) * 2;
|
||||||
if (day >= 15) JQ++;
|
if (day >= 15) JQ++;
|
||||||
strcpy(festival, JieQiStr[JQ]);
|
strcpy(festival, JieQiStr[JQ]);
|
||||||
if (JQ == 6) // 清明
|
if (JQ == 6) // 清明
|
||||||
strcat(festival, "节");
|
strcat(festival, "节");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawTimeSyncTip(Adafruit_GFX *gfx, gui_data_t *data)
|
static void DrawTimeSyncTip(Adafruit_GFX* gfx, gui_data_t* data) {
|
||||||
{
|
const char* title = "SYNC TIME!";
|
||||||
const char *title = "SYNC TIME!";
|
const char* url = "https://tsl0922.github.io/EPD-nRF5";
|
||||||
const char *url = "https://tsl0922.github.io/EPD-nRF5";
|
|
||||||
|
|
||||||
GFX_setFont(gfx, u8g2_font_wqy9_t_lunar);
|
GFX_setFont(gfx, u8g2_font_wqy9_t_lunar);
|
||||||
|
|
||||||
@@ -153,8 +129,7 @@ static void DrawTimeSyncTip(Adafruit_GFX *gfx, gui_data_t *data)
|
|||||||
GFX_printf(gfx, url);
|
GFX_printf(gfx, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawBattery(Adafruit_GFX *gfx, int16_t x, int16_t y, uint8_t iw, float voltage)
|
static void DrawBattery(Adafruit_GFX* gfx, int16_t x, int16_t y, uint8_t iw, float voltage) {
|
||||||
{
|
|
||||||
x -= iw;
|
x -= iw;
|
||||||
uint8_t level = (uint8_t)(voltage * 100 / 3.6f);
|
uint8_t level = (uint8_t)(voltage * 100 / 3.6f);
|
||||||
GFX_setFont(gfx, u8g2_font_wqy9_t_lunar);
|
GFX_setFont(gfx, u8g2_font_wqy9_t_lunar);
|
||||||
@@ -166,8 +141,7 @@ static void DrawBattery(Adafruit_GFX *gfx, int16_t x, int16_t y, uint8_t iw, flo
|
|||||||
GFX_fillRect(gfx, x + 2, y + 2, 16 * level / 100, 6, GFX_BLACK);
|
GFX_fillRect(gfx, x + 2, y + 2, 16 * level / 100, 6, GFX_BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t GetWeekOfYear(uint8_t year, uint8_t mon, uint8_t mday, uint8_t wday)
|
static uint8_t GetWeekOfYear(uint8_t year, uint8_t mon, uint8_t mday, uint8_t wday) {
|
||||||
{
|
|
||||||
struct tm tm = {0};
|
struct tm tm = {0};
|
||||||
tm.tm_year = year;
|
tm.tm_year = year;
|
||||||
tm.tm_mon = mon;
|
tm.tm_mon = mon;
|
||||||
@@ -180,8 +154,8 @@ static uint8_t GetWeekOfYear(uint8_t year, uint8_t mon, uint8_t mday, uint8_t wd
|
|||||||
return atoi(buffer);
|
return atoi(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawDateHeader(Adafruit_GFX *gfx, int16_t x, int16_t y, tm_t *tm, struct Lunar_Date *Lunar, gui_data_t *data)
|
static void DrawDateHeader(Adafruit_GFX* gfx, int16_t x, int16_t y, tm_t* tm, struct Lunar_Date* Lunar,
|
||||||
{
|
gui_data_t* data) {
|
||||||
GFX_setCursor(gfx, x, y - 2);
|
GFX_setCursor(gfx, x, y - 2);
|
||||||
GFX_printf_styled(gfx, GFX_RED, GFX_WHITE, u8g2_font_helvB18_tn, "%d", tm->tm_year + YEAR0);
|
GFX_printf_styled(gfx, GFX_RED, GFX_WHITE, u8g2_font_helvB18_tn, "%d", tm->tm_year + YEAR0);
|
||||||
GFX_printf_styled(gfx, GFX_BLACK, GFX_WHITE, u8g2_font_wqy12_t_lunar, "年");
|
GFX_printf_styled(gfx, GFX_BLACK, GFX_WHITE, u8g2_font_wqy12_t_lunar, "年");
|
||||||
@@ -195,10 +169,10 @@ static void DrawDateHeader(Adafruit_GFX *gfx, int16_t x, int16_t y, tm_t *tm, st
|
|||||||
GFX_setCursor(gfx, tx, ty);
|
GFX_setCursor(gfx, tx, ty);
|
||||||
if (Lunar->IsLeap) GFX_printf(gfx, " ");
|
if (Lunar->IsLeap) GFX_printf(gfx, " ");
|
||||||
GFX_printf(gfx, "%s%s%s", Lunar_MonthLeapString[Lunar->IsLeap], Lunar_MonthString[Lunar->Month],
|
GFX_printf(gfx, "%s%s%s", Lunar_MonthLeapString[Lunar->IsLeap], Lunar_MonthString[Lunar->Month],
|
||||||
Lunar_DateString[Lunar->Date]);
|
Lunar_DateString[Lunar->Date]);
|
||||||
GFX_setTextColor(gfx, GFX_RED, GFX_WHITE);
|
GFX_setTextColor(gfx, GFX_RED, GFX_WHITE);
|
||||||
GFX_printf(gfx, " [%d周]", GetWeekOfYear(tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday));
|
GFX_printf(gfx, " [%d周]", GetWeekOfYear(tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday));
|
||||||
|
|
||||||
GFX_setCursor(gfx, tx, ty - 14);
|
GFX_setCursor(gfx, tx, ty - 14);
|
||||||
GFX_setTextColor(gfx, GFX_BLACK, GFX_WHITE);
|
GFX_setTextColor(gfx, GFX_BLACK, GFX_WHITE);
|
||||||
GFX_printf(gfx, " %s%s年", Lunar_StemStrig[LUNAR_GetStem(Lunar)], Lunar_BranchStrig[LUNAR_GetBranch(Lunar)]);
|
GFX_printf(gfx, " %s%s年", Lunar_StemStrig[LUNAR_GetStem(Lunar)], Lunar_BranchStrig[LUNAR_GetBranch(Lunar)]);
|
||||||
@@ -211,8 +185,7 @@ static void DrawDateHeader(Adafruit_GFX *gfx, int16_t x, int16_t y, tm_t *tm, st
|
|||||||
GFX_printf(gfx, "%s", data->ssid);
|
GFX_printf(gfx, "%s", data->ssid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawWeekHeader(Adafruit_GFX *gfx, int16_t x, int16_t y, gui_data_t *data)
|
static void DrawWeekHeader(Adafruit_GFX* gfx, int16_t x, int16_t y, gui_data_t* data) {
|
||||||
{
|
|
||||||
GFX_setFont(gfx, data->height > 300 ? u8g2_font_wqy12_t_lunar : u8g2_font_wqy9_t_lunar);
|
GFX_setFont(gfx, data->height > 300 ? u8g2_font_wqy12_t_lunar : u8g2_font_wqy9_t_lunar);
|
||||||
uint8_t w = (data->width - 2 * x) / 7;
|
uint8_t w = (data->width - 2 * x) / 7;
|
||||||
uint8_t h = data->height > 300 ? 32 : 24;
|
uint8_t h = data->height > 300 ? 32 : 24;
|
||||||
@@ -229,8 +202,8 @@ static void DrawWeekHeader(Adafruit_GFX *gfx, int16_t x, int16_t y, gui_data_t *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawMonthDays(Adafruit_GFX *gfx, int16_t x, int16_t y, tm_t *tm, struct Lunar_Date *Lunar, gui_data_t *data)
|
static void DrawMonthDays(Adafruit_GFX* gfx, int16_t x, int16_t y, tm_t* tm, struct Lunar_Date* Lunar,
|
||||||
{
|
gui_data_t* data) {
|
||||||
uint8_t firstDayWeek = get_first_day_week(tm->tm_year + YEAR0, tm->tm_mon + 1);
|
uint8_t firstDayWeek = get_first_day_week(tm->tm_year + YEAR0, tm->tm_mon + 1);
|
||||||
int8_t adjustedFirstDay = (firstDayWeek - data->week_start + 7) % 7;
|
int8_t adjustedFirstDay = (firstDayWeek - data->week_start + 7) % 7;
|
||||||
uint8_t monthMaxDays = thisMonthMaxDays(tm->tm_year + YEAR0, tm->tm_mon + 1);
|
uint8_t monthMaxDays = thisMonthMaxDays(tm->tm_year + YEAR0, tm->tm_mon + 1);
|
||||||
@@ -254,7 +227,7 @@ static void DrawMonthDays(Adafruit_GFX *gfx, int16_t x, int16_t y, tm_t *tm, str
|
|||||||
|
|
||||||
int16_t actualWeek = (firstDayWeek + i) % 7;
|
int16_t actualWeek = (firstDayWeek + i) % 7;
|
||||||
int16_t displayWeek = (adjustedFirstDay + i) % 7;
|
int16_t displayWeek = (adjustedFirstDay + i) % 7;
|
||||||
bool weekend = (actualWeek == 0) || (actualWeek == 6);
|
bool weekend = (actualWeek == 0) || (actualWeek == 6);
|
||||||
|
|
||||||
LUNAR_SolarToLunar(Lunar, year, month, day);
|
LUNAR_SolarToLunar(Lunar, year, month, day);
|
||||||
|
|
||||||
@@ -272,15 +245,16 @@ static void DrawMonthDays(Adafruit_GFX *gfx, int16_t x, int16_t y, tm_t *tm, str
|
|||||||
GFX_setFont(gfx, large ? u8g2_font_helvB18_tn : u8g2_font_helvB14_tn);
|
GFX_setFont(gfx, large ? u8g2_font_helvB18_tn : u8g2_font_helvB14_tn);
|
||||||
GFX_setCursor(gfx, bx + (2 * cr - GFX_getUTF8Widthf(gfx, "%d", day)) / 2, by - (cr - GFX_getFontHeight(gfx)));
|
GFX_setCursor(gfx, bx + (2 * cr - GFX_getUTF8Widthf(gfx, "%d", day)) / 2, by - (cr - GFX_getFontHeight(gfx)));
|
||||||
GFX_printf(gfx, "%d", day);
|
GFX_printf(gfx, "%d", day);
|
||||||
|
|
||||||
char festival[10] = {0};
|
char festival[10] = {0};
|
||||||
GFX_setFont(gfx, large ? u8g2_font_wqy12_t_lunar : u8g2_font_wqy9_t_lunar);
|
GFX_setFont(gfx, large ? u8g2_font_wqy12_t_lunar : u8g2_font_wqy9_t_lunar);
|
||||||
GFX_setFontMode(gfx, 1); // transparent
|
GFX_setFontMode(gfx, 1); // transparent
|
||||||
if (GetFestival(year, month, day, actualWeek, Lunar, festival)) {
|
if (GetFestival(year, month, day, actualWeek, Lunar, festival)) {
|
||||||
if (day != tm->tm_mday) GFX_setTextColor(gfx, GFX_RED, GFX_WHITE);
|
if (day != tm->tm_mday) GFX_setTextColor(gfx, GFX_RED, GFX_WHITE);
|
||||||
} else {
|
} else {
|
||||||
if (Lunar->Date == 1)
|
if (Lunar->Date == 1)
|
||||||
snprintf(festival, sizeof(festival), "%s%s", Lunar_MonthLeapString[Lunar->IsLeap], Lunar_MonthString[Lunar->Month]);
|
snprintf(festival, sizeof(festival), "%s%s", Lunar_MonthLeapString[Lunar->IsLeap],
|
||||||
|
Lunar_MonthString[Lunar->Month]);
|
||||||
else
|
else
|
||||||
snprintf(festival, sizeof(festival), "%s", Lunar_DateString[Lunar->Date]);
|
snprintf(festival, sizeof(festival), "%s", Lunar_DateString[Lunar->Date]);
|
||||||
}
|
}
|
||||||
@@ -304,14 +278,14 @@ static void DrawMonthDays(Adafruit_GFX *gfx, int16_t x, int16_t y, tm_t *tm, str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawCalendar(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar, gui_data_t *data)
|
static void DrawCalendar(Adafruit_GFX* gfx, tm_t* tm, struct Lunar_Date* Lunar, gui_data_t* data) {
|
||||||
{
|
|
||||||
bool large = data->height > 300;
|
bool large = data->height > 300;
|
||||||
DrawDateHeader(gfx, 10, large ? 38 : 28, tm, Lunar, data);
|
DrawDateHeader(gfx, 10, large ? 38 : 28, tm, Lunar, data);
|
||||||
DrawWeekHeader(gfx, 10, large ? 44 : 32, data);
|
DrawWeekHeader(gfx, 10, large ? 44 : 32, data);
|
||||||
DrawMonthDays(gfx, 10, large ? 84 : 64, tm, Lunar, data);
|
DrawMonthDays(gfx, 10, large ? 84 : 64, tm, Lunar, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
/* Routine to Draw Large 7-Segment formated number
|
/* Routine to Draw Large 7-Segment formated number
|
||||||
Contributed by William Zaggle.
|
Contributed by William Zaggle.
|
||||||
|
|
||||||
@@ -341,19 +315,18 @@ static void Draw7Number(Adafruit_GFX *gfx, int n, unsigned int xLoc, unsigned in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
static void DrawTime(Adafruit_GFX *gfx, tm_t *tm, int16_t x, int16_t y, uint16_t cS, uint16_t nD)
|
static void DrawTime(Adafruit_GFX* gfx, tm_t* tm, int16_t x, int16_t y, uint16_t cS, uint16_t nD) {
|
||||||
{
|
|
||||||
Draw7Number(gfx, tm->tm_hour, x, y, cS, GFX_BLACK, GFX_WHITE, nD);
|
Draw7Number(gfx, tm->tm_hour, x, y, cS, GFX_BLACK, GFX_WHITE, nD);
|
||||||
x += (nD*(11*cS+2)-2*cS) + 2*cS;
|
x += (nD * (11 * cS + 2) - 2 * cS) + 2 * cS;
|
||||||
GFX_fillRect(gfx, x, y + 4.5*cS+1, 2*cS, 2*cS, GFX_BLACK);
|
GFX_fillRect(gfx, x, y + 4.5 * cS + 1, 2 * cS, 2 * cS, GFX_BLACK);
|
||||||
GFX_fillRect(gfx, x, y + 13.5*cS+3, 2*cS, 2*cS, GFX_BLACK);
|
GFX_fillRect(gfx, x, y + 13.5 * cS + 3, 2 * cS, 2 * cS, GFX_BLACK);
|
||||||
x += 4*cS;
|
x += 4 * cS;
|
||||||
Draw7Number(gfx, tm->tm_min, x, y, cS, GFX_BLACK, GFX_WHITE, nD);
|
Draw7Number(gfx, tm->tm_min, x, y, cS, GFX_BLACK, GFX_WHITE, nD);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawClock(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar, gui_data_t *data)
|
static void DrawClock(Adafruit_GFX* gfx, tm_t* tm, struct Lunar_Date* Lunar, gui_data_t* data) {
|
||||||
{
|
|
||||||
uint8_t padding = data->height > 300 ? 100 : 40;
|
uint8_t padding = data->height > 300 ? 100 : 40;
|
||||||
GFX_setCursor(gfx, padding, 36);
|
GFX_setCursor(gfx, padding, 36);
|
||||||
GFX_printf_styled(gfx, GFX_RED, GFX_WHITE, u8g2_font_helvB18_tn, "%d", tm->tm_year + YEAR0);
|
GFX_printf_styled(gfx, GFX_RED, GFX_WHITE, u8g2_font_helvB18_tn, "%d", tm->tm_year + YEAR0);
|
||||||
@@ -368,7 +341,7 @@ static void DrawClock(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar, gui
|
|||||||
GFX_printf(gfx, "星期%s", Lunar_DayString[tm->tm_wday]);
|
GFX_printf(gfx, "星期%s", Lunar_DayString[tm->tm_wday]);
|
||||||
GFX_setCursor(gfx, 138, 58);
|
GFX_setCursor(gfx, 138, 58);
|
||||||
GFX_printf(gfx, "%s%s%s", Lunar_MonthLeapString[Lunar->IsLeap], Lunar_MonthString[Lunar->Month],
|
GFX_printf(gfx, "%s%s%s", Lunar_MonthLeapString[Lunar->IsLeap], Lunar_MonthString[Lunar->Month],
|
||||||
Lunar_DateString[Lunar->Date]);
|
Lunar_DateString[Lunar->Date]);
|
||||||
|
|
||||||
DrawBattery(gfx, data->width - padding, 25, 20, data->voltage);
|
DrawBattery(gfx, data->width - padding, 25, 20, data->voltage);
|
||||||
|
|
||||||
@@ -381,7 +354,7 @@ static void DrawClock(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar, gui
|
|||||||
GFX_printf(gfx, "%d℃[%s]", data->temperature, ssid);
|
GFX_printf(gfx, "%d℃[%s]", data->temperature, ssid);
|
||||||
|
|
||||||
GFX_drawFastHLine(gfx, padding - 10, 68, data->width - 2 * (padding - 10), GFX_BLACK);
|
GFX_drawFastHLine(gfx, padding - 10, 68, data->width - 2 * (padding - 10), GFX_BLACK);
|
||||||
|
|
||||||
uint16_t cS = data->height / 45;
|
uint16_t cS = data->height / 45;
|
||||||
uint16_t nD = 2;
|
uint16_t nD = 2;
|
||||||
uint16_t time_width = 2 * (nD * (11 * cS + 2) - 2 * cS) + 4 * cS;
|
uint16_t time_width = 2 * (nD * (11 * cS + 2) - 2 * cS) + 4 * cS;
|
||||||
@@ -389,7 +362,7 @@ static void DrawClock(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar, gui
|
|||||||
int16_t time_x = (data->width - time_width) / 2;
|
int16_t time_x = (data->width - time_width) / 2;
|
||||||
int16_t time_y = (68 + (data->height - 68)) / 2 - time_height / 2;
|
int16_t time_y = (68 + (data->height - 68)) / 2 - time_height / 2;
|
||||||
DrawTime(gfx, tm, time_x, time_y, cS, nD);
|
DrawTime(gfx, tm, time_x, time_y, cS, nD);
|
||||||
|
|
||||||
GFX_drawFastHLine(gfx, padding - 10, data->height - 68, data->width - 2 * (padding - 10), GFX_BLACK);
|
GFX_drawFastHLine(gfx, padding - 10, data->height - 68, data->width - 2 * (padding - 10), GFX_BLACK);
|
||||||
|
|
||||||
GFX_setCursor(gfx, padding, data->height - 68 + 30);
|
GFX_setCursor(gfx, padding, data->height - 68 + 30);
|
||||||
@@ -422,8 +395,7 @@ static void DrawClock(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar, gui
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawGUI(gui_data_t *data, buffer_callback callback, void *callback_data)
|
void DrawGUI(gui_data_t* data, buffer_callback callback, void* callback_data) {
|
||||||
{
|
|
||||||
if (data->week_start > 6) data->week_start = 0;
|
if (data->week_start > 6) data->week_start = 0;
|
||||||
|
|
||||||
tm_t tm = {0};
|
tm_t tm = {0};
|
||||||
@@ -435,11 +407,11 @@ void DrawGUI(gui_data_t *data, buffer_callback callback, void *callback_data)
|
|||||||
int16_t ph = (__HEAP_SIZE - 512) / (data->width / 8);
|
int16_t ph = (__HEAP_SIZE - 512) / (data->width / 8);
|
||||||
|
|
||||||
if (data->color == 2)
|
if (data->color == 2)
|
||||||
GFX_begin_3c(&gfx, data->width, data->height, ph);
|
GFX_begin_3c(&gfx, data->width, data->height, ph);
|
||||||
else if (data->color == 3)
|
else if (data->color == 3)
|
||||||
GFX_begin_4c(&gfx, data->width, data->height, ph);
|
GFX_begin_4c(&gfx, data->width, data->height, ph);
|
||||||
else
|
else
|
||||||
GFX_begin(&gfx, data->width, data->height, ph);
|
GFX_begin(&gfx, data->width, data->height, ph);
|
||||||
|
|
||||||
GFX_firstPage(&gfx);
|
GFX_firstPage(&gfx);
|
||||||
do {
|
do {
|
||||||
@@ -461,7 +433,7 @@ void DrawGUI(gui_data_t *data, buffer_callback callback, void *callback_data)
|
|||||||
(tm.tm_year + YEAR0 == 2025 && tm.tm_mon + 1 == 1)) {
|
(tm.tm_year + YEAR0 == 2025 && tm.tm_mon + 1 == 1)) {
|
||||||
DrawTimeSyncTip(&gfx, data);
|
DrawTimeSyncTip(&gfx, data);
|
||||||
}
|
}
|
||||||
} while(GFX_nextPage(&gfx, callback, callback_data));
|
} while (GFX_nextPage(&gfx, callback, callback_data));
|
||||||
|
|
||||||
GFX_end(&gfx);
|
GFX_end(&gfx);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ typedef struct {
|
|||||||
uint16_t width;
|
uint16_t width;
|
||||||
uint16_t height;
|
uint16_t height;
|
||||||
uint32_t timestamp;
|
uint32_t timestamp;
|
||||||
uint8_t week_start; // 0: Sunday, 1: Monday
|
uint8_t week_start; // 0: Sunday, 1: Monday
|
||||||
int8_t temperature;
|
int8_t temperature;
|
||||||
float voltage;
|
float voltage;
|
||||||
char ssid[20];
|
char ssid[20];
|
||||||
} gui_data_t;
|
} gui_data_t;
|
||||||
|
|
||||||
void DrawGUI(gui_data_t *data, buffer_callback callback, void *callback_data);
|
void DrawGUI(gui_data_t* data, buffer_callback callback, void* callback_data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
364
GUI/Lunar.c
364
GUI/Lunar.c
@@ -1,32 +1,22 @@
|
|||||||
#include "Lunar.h"
|
#include "Lunar.h"
|
||||||
|
|
||||||
const char Lunar_MonthString[13][7] = {
|
const char Lunar_MonthString[13][7] = {"----", "正月", "二月", "三月", "四月", "五月", "六月",
|
||||||
"----",
|
"七月", "八月", "九月", "十月", "冬月", "腊月"};
|
||||||
"正月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月",
|
|
||||||
"冬月", "腊月"};
|
|
||||||
|
|
||||||
const char Lunar_MonthLeapString[2][4] = {
|
const char Lunar_MonthLeapString[2][4] = {" ", "闰"};
|
||||||
" ",
|
|
||||||
"闰"};
|
|
||||||
|
|
||||||
const char Lunar_DateString[31][7] = {
|
const char Lunar_DateString[31][7] = {"----", "初一", "初二", "初三", "初四", "初五", "初六", "初七",
|
||||||
"----",
|
"初八", "初九", "初十", "十一", "十二", "十三", "十四", "十五",
|
||||||
"初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十",
|
"十六", "十七", "十八", "十九", "二十", "廿一", "廿二", "廿三",
|
||||||
"十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十",
|
"廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十"};
|
||||||
"廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十"};
|
|
||||||
|
|
||||||
const char Lunar_DayString[7][4] = {
|
const char Lunar_DayString[7][4] = {"日", "一", "二", "三", "四", "五", "六"};
|
||||||
"日",
|
|
||||||
"一", "二", "三", "四", "五", "六"};
|
|
||||||
|
|
||||||
const char Lunar_ZodiacString[12][4] = {
|
const char Lunar_ZodiacString[12][4] = {"猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊"};
|
||||||
"猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊"};
|
|
||||||
|
|
||||||
const char Lunar_StemStrig[10][4] = {
|
const char Lunar_StemStrig[10][4] = {"庚", "辛", "壬", "癸", "甲", "乙", "丙", "丁", "戊", "己"};
|
||||||
"庚", "辛", "壬", "癸", "甲", "乙", "丙", "丁", "戊", "己"};
|
|
||||||
|
|
||||||
const char Lunar_BranchStrig[12][4] = {
|
const char Lunar_BranchStrig[12][4] = {"申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未"};
|
||||||
"申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未"};
|
|
||||||
|
|
||||||
/* 2000 ~ 2199 */
|
/* 2000 ~ 2199 */
|
||||||
const uint32_t lunar_month_days[] = {
|
const uint32_t lunar_month_days[] = {
|
||||||
@@ -82,28 +72,24 @@ const uint32_t solar_1_1[] = {
|
|||||||
0x00111648, 0x0011183C, 0x00111A4F, 0x00111C45, 0x00111E39, 0x0011204D, 0x00112242, 0x00112436, 0x0011264A,
|
0x00111648, 0x0011183C, 0x00111A4F, 0x00111C45, 0x00111E39, 0x0011204D, 0x00112242, 0x00112436, 0x0011264A,
|
||||||
0x0011283E, 0x00112A51, 0x00112C46, 0x00112E3B, 0x0011304F*/};
|
0x0011283E, 0x00112A51, 0x00112C46, 0x00112E3B, 0x0011304F*/};
|
||||||
|
|
||||||
static uint32_t GetBitInt(uint32_t data, uint8_t length, uint8_t shift)
|
static uint32_t GetBitInt(uint32_t data, uint8_t length, uint8_t shift) {
|
||||||
{
|
|
||||||
return (data & (((1 << length) - 1) << shift)) >> shift;
|
return (data & (((1 << length) - 1) << shift)) >> shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
// WARNING: Dates before Oct. 1582 are inaccurate
|
// WARNING: Dates before Oct. 1582 are inaccurate
|
||||||
static uint16_t SolarToInt(uint16_t y, uint8_t m, uint8_t d)
|
static uint16_t SolarToInt(uint16_t y, uint8_t m, uint8_t d) {
|
||||||
{
|
|
||||||
m = (m + 9) % 12;
|
m = (m + 9) % 12;
|
||||||
y = y - m / 10;
|
y = y - m / 10;
|
||||||
return 365 * y + y / 4 - y / 100 + y / 400 + (m * 306 + 5) / 10 + (d - 1);
|
return 365 * y + y / 4 - y / 100 + y / 400 + (m * 306 + 5) / 10 + (d - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LUNAR_SolarToLunar(struct Lunar_Date *lunar, uint16_t solar_year, uint8_t solar_month, uint8_t solar_date)
|
void LUNAR_SolarToLunar(struct Lunar_Date* lunar, uint16_t solar_year, uint8_t solar_month, uint8_t solar_date) {
|
||||||
{
|
|
||||||
uint8_t i, lunarM, m, d, leap, dm;
|
uint8_t i, lunarM, m, d, leap, dm;
|
||||||
uint16_t year_index, lunarY, y, offset;
|
uint16_t year_index, lunarY, y, offset;
|
||||||
uint32_t solar_data, solar11, days;
|
uint32_t solar_data, solar11, days;
|
||||||
|
|
||||||
if (solar_month < 1 || solar_month > 12 || solar_date < 1 || solar_date > 31 ||
|
if (solar_month < 1 || solar_month > 12 || solar_date < 1 || solar_date > 31 || (solar_year - solar_1_1[0] < 3) ||
|
||||||
(solar_year - solar_1_1[0] < 3) || ((solar_year - solar_1_1[0]) > (sizeof(solar_1_1) / sizeof(uint32_t) - 2)))
|
((solar_year - solar_1_1[0]) > (sizeof(solar_1_1) / sizeof(uint32_t) - 2))) {
|
||||||
{
|
|
||||||
lunar->Year = 0;
|
lunar->Year = 0;
|
||||||
lunar->Month = 0;
|
lunar->Month = 0;
|
||||||
lunar->Date = 0;
|
lunar->Date = 0;
|
||||||
@@ -113,8 +99,7 @@ void LUNAR_SolarToLunar(struct Lunar_Date *lunar, uint16_t solar_year, uint8_t s
|
|||||||
|
|
||||||
year_index = solar_year - solar_1_1[0];
|
year_index = solar_year - solar_1_1[0];
|
||||||
solar_data = ((uint32_t)solar_year << 9) | ((uint32_t)solar_month << 5) | ((uint32_t)solar_date);
|
solar_data = ((uint32_t)solar_year << 9) | ((uint32_t)solar_month << 5) | ((uint32_t)solar_date);
|
||||||
if (solar_1_1[year_index] > solar_data)
|
if (solar_1_1[year_index] > solar_data) {
|
||||||
{
|
|
||||||
year_index -= 1;
|
year_index -= 1;
|
||||||
}
|
}
|
||||||
solar11 = solar_1_1[year_index];
|
solar11 = solar_1_1[year_index];
|
||||||
@@ -129,31 +114,22 @@ void LUNAR_SolarToLunar(struct Lunar_Date *lunar, uint16_t solar_year, uint8_t s
|
|||||||
lunarY = year_index + solar_1_1[0];
|
lunarY = year_index + solar_1_1[0];
|
||||||
lunarM = 1;
|
lunarM = 1;
|
||||||
offset += 1;
|
offset += 1;
|
||||||
for (i = 0; i < 13; i++)
|
for (i = 0; i < 13; i++) {
|
||||||
{
|
if (GetBitInt(days, 1, 12 - i) == 1) {
|
||||||
if (GetBitInt(days, 1, 12 - i) == 1)
|
|
||||||
{
|
|
||||||
dm = 30;
|
dm = 30;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
dm = 29;
|
dm = 29;
|
||||||
}
|
}
|
||||||
if (offset > dm)
|
if (offset > dm) {
|
||||||
{
|
|
||||||
lunarM += 1;
|
lunarM += 1;
|
||||||
offset -= dm;
|
offset -= dm;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lunar->IsLeap = 0;
|
lunar->IsLeap = 0;
|
||||||
if (leap != 0 && lunarM > leap)
|
if (leap != 0 && lunarM > leap) {
|
||||||
{
|
if (lunarM == leap + 1) {
|
||||||
if (lunarM == leap + 1)
|
|
||||||
{
|
|
||||||
lunar->IsLeap = 1;
|
lunar->IsLeap = 1;
|
||||||
}
|
}
|
||||||
lunarM -= 1;
|
lunarM -= 1;
|
||||||
@@ -163,20 +139,11 @@ void LUNAR_SolarToLunar(struct Lunar_Date *lunar, uint16_t solar_year, uint8_t s
|
|||||||
lunar->Year = lunarY;
|
lunar->Year = lunarY;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t LUNAR_GetZodiac(const struct Lunar_Date *lunar)
|
uint8_t LUNAR_GetZodiac(const struct Lunar_Date* lunar) { return lunar->Year % 12; }
|
||||||
{
|
|
||||||
return lunar->Year % 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t LUNAR_GetStem(const struct Lunar_Date *lunar)
|
uint8_t LUNAR_GetStem(const struct Lunar_Date* lunar) { return lunar->Year % 10; }
|
||||||
{
|
|
||||||
return lunar->Year % 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t LUNAR_GetBranch(const struct Lunar_Date *lunar)
|
uint8_t LUNAR_GetBranch(const struct Lunar_Date* lunar) { return lunar->Year % 12; }
|
||||||
{
|
|
||||||
return lunar->Year % 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
/*********************************************************************************************************
|
||||||
** 以下为24节气计算相关程序
|
** 以下为24节气计算相关程序
|
||||||
@@ -188,113 +155,78 @@ uint8_t LUNAR_GetBranch(const struct Lunar_Date *lunar)
|
|||||||
有兴趣的朋友可按照上面给的原理添加其它年份的表格
|
有兴趣的朋友可按照上面给的原理添加其它年份的表格
|
||||||
不是很清楚的朋友可给我发EMAIL
|
不是很清楚的朋友可给我发EMAIL
|
||||||
*/
|
*/
|
||||||
static const uint8_t YearMonthBit[160] =
|
static const uint8_t YearMonthBit[160] = {
|
||||||
{
|
0x4E, 0xA6, 0x99, // 2000
|
||||||
0x4E, 0xA6, 0x99, // 2000
|
0x9C, 0xA2, 0x98, // 2001
|
||||||
0x9C, 0xA2, 0x98, // 2001
|
0x80, 0x00, 0x18, // 2002
|
||||||
0x80, 0x00, 0x18, // 2002
|
0x00, 0x10, 0x24, // 2003
|
||||||
0x00, 0x10, 0x24, // 2003
|
0x4E, 0xA6, 0x99, // 2004
|
||||||
0x4E, 0xA6, 0x99, // 2004
|
0x9C, 0xA2, 0x98, // 2005
|
||||||
0x9C, 0xA2, 0x98, // 2005
|
0x80, 0x82, 0x18, // 2006
|
||||||
0x80, 0x82, 0x18, // 2006
|
0x00, 0x10, 0x24, // 2007
|
||||||
0x00, 0x10, 0x24, // 2007
|
0x4E, 0xA6, 0xD9, // 2008
|
||||||
0x4E, 0xA6, 0xD9, // 2008
|
0x9E, 0xA2, 0x98, // 2009
|
||||||
0x9E, 0xA2, 0x98, // 2009
|
|
||||||
|
|
||||||
0x80, 0x82, 0x18, // 2010
|
0x80, 0x82, 0x18, // 2010
|
||||||
0x00, 0x10, 0x04, // 2011
|
0x00, 0x10, 0x04, // 2011
|
||||||
0x4E, 0xE6, 0xD9, // 2012
|
0x4E, 0xE6, 0xD9, // 2012
|
||||||
0x9E, 0xA6, 0xA8, // 2013
|
0x9E, 0xA6, 0xA8, // 2013
|
||||||
0x80, 0x82, 0x18, // 2014
|
0x80, 0x82, 0x18, // 2014
|
||||||
0x00, 0x10, 0x00, // 2015
|
0x00, 0x10, 0x00, // 2015
|
||||||
0x0F, 0xE6, 0xD9, // 2016
|
0x0F, 0xE6, 0xD9, // 2016
|
||||||
0xBE, 0xA6, 0x98, // 2017
|
0xBE, 0xA6, 0x98, // 2017
|
||||||
0x88, 0x82, 0x18, // 2018
|
0x88, 0x82, 0x18, // 2018
|
||||||
0x80, 0x00, 0x00, // 2019
|
0x80, 0x00, 0x00, // 2019
|
||||||
|
|
||||||
0x0F, 0xEF, 0xD9, // 2020
|
0x0F, 0xEF, 0xD9, // 2020
|
||||||
0xBE, 0xA6, 0x99, // 2021
|
0xBE, 0xA6, 0x99, // 2021
|
||||||
0x8C, 0x82, 0x98, // 2022
|
0x8C, 0x82, 0x98, // 2022
|
||||||
0x80, 0x00, 0x00, // 2023
|
0x80, 0x00, 0x00, // 2023
|
||||||
0x0F, 0xEF, 0xDB, // 2024
|
0x0F, 0xEF, 0xDB, // 2024
|
||||||
0xBE, 0xA6, 0x99, // 2025
|
0xBE, 0xA6, 0x99, // 2025
|
||||||
0x9C, 0xA2, 0x98, // 2026
|
0x9C, 0xA2, 0x98, // 2026
|
||||||
0x80, 0x00, 0x18, // 2027
|
0x80, 0x00, 0x18, // 2027
|
||||||
0x0F, 0xEF, 0xDB, // 2028
|
0x0F, 0xEF, 0xDB, // 2028
|
||||||
0xBE, 0xA6, 0x99, // 2029
|
0xBE, 0xA6, 0x99, // 2029
|
||||||
|
|
||||||
0x9C, 0xA2, 0x98, // 2030
|
0x9C, 0xA2, 0x98, // 2030
|
||||||
0x80, 0x00, 0x18, // 2031
|
0x80, 0x00, 0x18, // 2031
|
||||||
0x0F, 0xEF, 0xDB, // 2032
|
0x0F, 0xEF, 0xDB, // 2032
|
||||||
0xBE, 0xA2, 0x99, // 2033
|
0xBE, 0xA2, 0x99, // 2033
|
||||||
0x8C, 0xA0, 0x98, // 2034
|
0x8C, 0xA0, 0x98, // 2034
|
||||||
0x80, 0x82, 0x18, // 2035
|
0x80, 0x82, 0x18, // 2035
|
||||||
0x0B, 0xEF, 0xDB, // 2036
|
0x0B, 0xEF, 0xDB, // 2036
|
||||||
0xBE, 0xA6, 0x99, // 2037
|
0xBE, 0xA6, 0x99, // 2037
|
||||||
0x8C, 0xA2, 0x98, // 2038
|
0x8C, 0xA2, 0x98, // 2038
|
||||||
0x80, 0x82, 0x18, // 2039
|
0x80, 0x82, 0x18, // 2039
|
||||||
|
|
||||||
0x0F, 0xEF, 0xDB, // 2040
|
0x0F, 0xEF, 0xDB, // 2040
|
||||||
0xBE, 0xE6, 0xD9, // 2041
|
0xBE, 0xE6, 0xD9, // 2041
|
||||||
0x9E, 0xA2, 0x98, // 2042
|
0x9E, 0xA2, 0x98, // 2042
|
||||||
0x80, 0x82, 0x18, // 2043
|
0x80, 0x82, 0x18, // 2043
|
||||||
0x0F, 0xEF, 0xFB, // 2044
|
0x0F, 0xEF, 0xFB, // 2044
|
||||||
0xBF, 0xE6, 0xD9, // 2045
|
0xBF, 0xE6, 0xD9, // 2045
|
||||||
0x9E, 0xA6, 0x98, // 2046
|
0x9E, 0xA6, 0x98, // 2046
|
||||||
0x80, 0x82, 0x18, // 2047
|
0x80, 0x82, 0x18, // 2047
|
||||||
0x0F, 0xFF, 0xFF, // 2048
|
0x0F, 0xFF, 0xFF, // 2048
|
||||||
0xFC, 0xEF, 0xD9, // 2049
|
0xFC, 0xEF, 0xD9, // 2049
|
||||||
0xBE, 0xA6, 0x18, // 2050
|
0xBE, 0xA6, 0x18, // 2050
|
||||||
};
|
};
|
||||||
static const uint8_t days[24] =
|
static const uint8_t days[24] = {
|
||||||
{
|
6, 20, 4, 19, 6, 21, // 一月到三月 的节气基本日期
|
||||||
6, 20, 4, 19, 6, 21, // 一月到三月 的节气基本日期
|
5, 20, 6, 21, 6, 21, // 四月到六月 的节气基本日期
|
||||||
5, 20, 6, 21, 6, 21, // 四月到六月 的节气基本日期
|
7, 23, 8, 23, 8, 23, // 七月到九月 的节气基本日期
|
||||||
7, 23, 8, 23, 8, 23, // 七月到九月 的节气基本日期
|
8, 24, 8, 22, 7, 22, // 十月到十二月的节气基本日期
|
||||||
8, 24, 8, 22, 7, 22, // 十月到十二月的节气基本日期
|
|
||||||
};
|
};
|
||||||
/*立春、雨水、惊蛰、春分、清明、谷雨、立夏、小满、芒种、夏至、小暑、大暑、立秋、处暑、白露、秋分、寒露、霜降、立冬、小雪、大雪、冬至、小寒、大寒
|
/*立春、雨水、惊蛰、春分、清明、谷雨、立夏、小满、芒种、夏至、小暑、大暑、立秋、处暑、白露、秋分、寒露、霜降、立冬、小雪、大雪、冬至、小寒、大寒
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const char JieQiStr[24][7] = {
|
const char JieQiStr[24][7] = {
|
||||||
"小寒",
|
"小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至",
|
||||||
"大寒",
|
"小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至",
|
||||||
"立春",
|
|
||||||
"雨水",
|
|
||||||
"惊蛰",
|
|
||||||
"春分",
|
|
||||||
"清明",
|
|
||||||
"谷雨",
|
|
||||||
"立夏",
|
|
||||||
"小满",
|
|
||||||
"芒种",
|
|
||||||
"夏至",
|
|
||||||
"小暑",
|
|
||||||
"大暑",
|
|
||||||
"立秋",
|
|
||||||
"处暑",
|
|
||||||
"白露",
|
|
||||||
"秋分",
|
|
||||||
"寒露",
|
|
||||||
"霜降",
|
|
||||||
"立冬",
|
|
||||||
"小雪",
|
|
||||||
"大雪",
|
|
||||||
"冬至",
|
|
||||||
};
|
};
|
||||||
const uint8_t MonthDayMax[12] = {
|
const uint8_t MonthDayMax[12] = {
|
||||||
31,
|
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
|
||||||
28,
|
|
||||||
31,
|
|
||||||
30,
|
|
||||||
31,
|
|
||||||
30,
|
|
||||||
31,
|
|
||||||
31,
|
|
||||||
30,
|
|
||||||
31,
|
|
||||||
30,
|
|
||||||
31,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*********************************************************************************************************
|
/*********************************************************************************************************
|
||||||
@@ -314,24 +246,19 @@ const uint8_t MonthDayMax[12] = {
|
|||||||
** 日 期:
|
** 日 期:
|
||||||
**------------------------------------------------------------------------------------------------------
|
**------------------------------------------------------------------------------------------------------
|
||||||
********************************************************************************************************/
|
********************************************************************************************************/
|
||||||
uint8_t GetJieQi(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t *JQdate)
|
uint8_t GetJieQi(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t* JQdate) {
|
||||||
{
|
|
||||||
uint8_t bak1, value, JQ;
|
uint8_t bak1, value, JQ;
|
||||||
|
|
||||||
if ((myear < 2000) || (myear > 2050))
|
if ((myear < 2000) || (myear > 2050)) return 0;
|
||||||
return 0;
|
if ((mmonth == 0) || (mmonth > 12)) return 0;
|
||||||
if ((mmonth == 0) || (mmonth > 12))
|
JQ = (mmonth - 1) * 2; // 获得节气顺序标号(0~23
|
||||||
return 0;
|
if (mday >= 15) JQ++; // 判断是否是上半月
|
||||||
JQ = (mmonth - 1) * 2; // 获得节气顺序标号(0~23
|
|
||||||
if (mday >= 15)
|
|
||||||
JQ++; // 判断是否是上半月
|
|
||||||
|
|
||||||
bak1 = YearMonthBit[(myear - 2000) * 3 + JQ / 8]; // 获得节气日期相对值所在字节
|
bak1 = YearMonthBit[(myear - 2000) * 3 + JQ / 8]; // 获得节气日期相对值所在字节
|
||||||
value = ((bak1 << (JQ % 8)) & 0x80); // 获得节气日期相对值状态
|
value = ((bak1 << (JQ % 8)) & 0x80); // 获得节气日期相对值状态
|
||||||
|
|
||||||
*JQdate = days[JQ];
|
*JQdate = days[JQ];
|
||||||
if (value != 0)
|
if (value != 0) {
|
||||||
{
|
|
||||||
// 判断年份,以决定节气相对值1代表1,还是-1。
|
// 判断年份,以决定节气相对值1代表1,还是-1。
|
||||||
if ((JQ == 1 || JQ == 11 || JQ == 18 || JQ == 21) && myear < 2044)
|
if ((JQ == 1 || JQ == 11 || JQ == 18 || JQ == 21) && myear < 2044)
|
||||||
(*JQdate)++;
|
(*JQdate)++;
|
||||||
@@ -357,19 +284,16 @@ uint8_t GetJieQi(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t *JQdate)
|
|||||||
** 日 期:
|
** 日 期:
|
||||||
**------------------------------------------------------------------------------------------------------
|
**------------------------------------------------------------------------------------------------------
|
||||||
********************************************************************************************************/
|
********************************************************************************************************/
|
||||||
uint8_t GetJieQiStr(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t *day)
|
uint8_t GetJieQiStr(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t* day) {
|
||||||
{
|
|
||||||
uint8_t JQdate, JQ, MaxDay;
|
uint8_t JQdate, JQ, MaxDay;
|
||||||
|
|
||||||
if (GetJieQi(myear, mmonth, mday, &JQdate) == 0)
|
if (GetJieQi(myear, mmonth, mday, &JQdate) == 0) return 0xFF;
|
||||||
return 0xFF;
|
|
||||||
|
|
||||||
JQ = (mmonth - 1) * 2; // 获得节气顺序标号(0~23
|
JQ = (mmonth - 1) * 2; // 获得节气顺序标号(0~23
|
||||||
|
|
||||||
if (mday >= 15)
|
if (mday >= 15) JQ++; // 判断是否是上半月
|
||||||
JQ++; // 判断是否是上半月
|
|
||||||
|
|
||||||
if (mday == JQdate) // 今天正是一个节气日
|
if (mday == JQdate) // 今天正是一个节气日
|
||||||
{
|
{
|
||||||
*day = 0;
|
*day = 0;
|
||||||
return JQ;
|
return JQ;
|
||||||
@@ -377,30 +301,24 @@ uint8_t GetJieQiStr(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t *day)
|
|||||||
// 今天不是一个节气日
|
// 今天不是一个节气日
|
||||||
// StrCopy(str, (uint8_t *)"离小寒还有??天", 15);
|
// StrCopy(str, (uint8_t *)"离小寒还有??天", 15);
|
||||||
|
|
||||||
if (mday < JQdate) // 如果今天日期小于本月的节气日期
|
if (mday < JQdate) // 如果今天日期小于本月的节气日期
|
||||||
{
|
{
|
||||||
|
|
||||||
mday = JQdate - mday;
|
mday = JQdate - mday;
|
||||||
}
|
} else // 如果今天日期大于本月的节气日期
|
||||||
else // 如果今天日期大于本月的节气日期
|
|
||||||
{
|
{
|
||||||
JQ++;
|
JQ++;
|
||||||
|
|
||||||
if (mday < 15)
|
if (mday < 15) {
|
||||||
{
|
|
||||||
GetJieQi(myear, mmonth, 15, &JQdate);
|
GetJieQi(myear, mmonth, 15, &JQdate);
|
||||||
mday = JQdate - mday;
|
mday = JQdate - mday;
|
||||||
}
|
} else // 翻月
|
||||||
else // 翻月
|
|
||||||
{
|
{
|
||||||
MaxDay = MonthDayMax[mmonth - 1];
|
MaxDay = MonthDayMax[mmonth - 1];
|
||||||
if (mmonth == 2) // 润月问题
|
if (mmonth == 2) // 润月问题
|
||||||
{
|
{
|
||||||
if ((myear % 4 == 0) && ((myear % 100 != 0) || (myear % 400 == 0)))
|
if ((myear % 4 == 0) && ((myear % 100 != 0) || (myear % 400 == 0))) MaxDay++;
|
||||||
MaxDay++;
|
|
||||||
}
|
}
|
||||||
if (++mmonth == 13)
|
if (++mmonth == 13) mmonth = 1;
|
||||||
mmonth = 1;
|
|
||||||
GetJieQi(myear, mmonth, 1, &JQdate);
|
GetJieQi(myear, mmonth, 1, &JQdate);
|
||||||
mday = MaxDay - mday + JQdate;
|
mday = MaxDay - mday + JQdate;
|
||||||
}
|
}
|
||||||
@@ -409,14 +327,12 @@ uint8_t GetJieQiStr(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t *day)
|
|||||||
return JQ;
|
return JQ;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t SEC_PER_YR[2] = {31536000, 31622400}; // 闰年和非闰年的秒数
|
uint32_t SEC_PER_YR[2] = {31536000, 31622400}; // 闰年和非闰年的秒数
|
||||||
uint32_t SEC_PER_MT[2][12] = {
|
uint32_t SEC_PER_MT[2][12] = {
|
||||||
{2678400, 2419200, 2678400, 2592000, 2678400, 2592000,
|
{2678400, 2419200, 2678400, 2592000, 2678400, 2592000, 2678400, 2678400, 2592000, 2678400, 2592000, 2678400},
|
||||||
2678400, 2678400, 2592000, 2678400, 2592000, 2678400},
|
{2678400, 2505600, 2678400, 2592000, 2678400, 2592000, 2678400, 2678400, 2592000, 2678400, 2592000, 2678400},
|
||||||
{2678400, 2505600, 2678400, 2592000, 2678400, 2592000,
|
|
||||||
2678400, 2678400, 2592000, 2678400, 2592000, 2678400},
|
|
||||||
};
|
};
|
||||||
#define SECOND_OF_DAY 86400 // 一天多少秒
|
#define SECOND_OF_DAY 86400 // 一天多少秒
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Name : static int is_leap(int yr)
|
* @Name : static int is_leap(int yr)
|
||||||
@@ -427,8 +343,7 @@ uint32_t SEC_PER_MT[2][12] = {
|
|||||||
* @Out : 1:是闰年 0:非闰年
|
* @Out : 1:是闰年 0:非闰年
|
||||||
* @Author : Denis
|
* @Author : Denis
|
||||||
*/
|
*/
|
||||||
int is_leap(int yr)
|
int is_leap(int yr) {
|
||||||
{
|
|
||||||
if (0 == (yr % 100))
|
if (0 == (yr % 100))
|
||||||
return (yr % 400 == 0) ? 1 : 0;
|
return (yr % 400 == 0) ? 1 : 0;
|
||||||
else
|
else
|
||||||
@@ -443,27 +358,22 @@ int is_leap(int yr)
|
|||||||
* @Out : 星期几
|
* @Out : 星期几
|
||||||
* @Author : Denis
|
* @Author : Denis
|
||||||
*/
|
*/
|
||||||
unsigned char day_of_week_get(unsigned char month, unsigned char day,
|
unsigned char day_of_week_get(unsigned char month, unsigned char day, unsigned short year) {
|
||||||
unsigned short year)
|
|
||||||
{
|
|
||||||
/* Month should be a number 0 to 11, Day should be a number 1 to 31 */
|
/* Month should be a number 0 to 11, Day should be a number 1 to 31 */
|
||||||
static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
|
static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
|
||||||
year -= (uint8_t)(month < 3);
|
year -= (uint8_t)(month < 3);
|
||||||
return (year + year / 4 - year / 100 + year / 400 + t[month - 1] + day) % 7;
|
return (year + year / 4 - year / 100 + year / 400 + t[month - 1] + day) % 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
void transformTime(uint32_t unix_time, struct devtm *result)
|
void transformTime(uint32_t unix_time, struct devtm* result) {
|
||||||
{
|
|
||||||
int leapyr = 0;
|
int leapyr = 0;
|
||||||
uint32_t ltime = unix_time;
|
uint32_t ltime = unix_time;
|
||||||
|
|
||||||
memset(result, 0, sizeof(struct devtm));
|
memset(result, 0, sizeof(struct devtm));
|
||||||
result->tm_year = EPOCH_YR;
|
result->tm_year = EPOCH_YR;
|
||||||
|
|
||||||
while (1)
|
while (1) {
|
||||||
{
|
if (ltime < SEC_PER_YR[is_leap(result->tm_year)]) {
|
||||||
if (ltime < SEC_PER_YR[is_leap(result->tm_year)])
|
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ltime -= SEC_PER_YR[is_leap(result->tm_year)];
|
ltime -= SEC_PER_YR[is_leap(result->tm_year)];
|
||||||
@@ -472,10 +382,8 @@ void transformTime(uint32_t unix_time, struct devtm *result)
|
|||||||
|
|
||||||
leapyr = is_leap(result->tm_year);
|
leapyr = is_leap(result->tm_year);
|
||||||
|
|
||||||
while (1)
|
while (1) {
|
||||||
{
|
if (ltime < SEC_PER_MT[leapyr][result->tm_mon]) break;
|
||||||
if (ltime < SEC_PER_MT[leapyr][result->tm_mon])
|
|
||||||
break;
|
|
||||||
ltime -= SEC_PER_MT[leapyr][result->tm_mon];
|
ltime -= SEC_PER_MT[leapyr][result->tm_mon];
|
||||||
++(result->tm_mon);
|
++(result->tm_mon);
|
||||||
}
|
}
|
||||||
@@ -490,9 +398,7 @@ void transformTime(uint32_t unix_time, struct devtm *result)
|
|||||||
result->tm_min = ltime / 60;
|
result->tm_min = ltime / 60;
|
||||||
result->tm_sec = ltime % 60;
|
result->tm_sec = ltime % 60;
|
||||||
|
|
||||||
result->tm_wday =
|
result->tm_wday = day_of_week_get(result->tm_mon + 1, result->tm_mday, result->tm_year);
|
||||||
day_of_week_get(result->tm_mon + 1, result->tm_mday,
|
|
||||||
result->tm_year);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The number of years since YEAR0"
|
* The number of years since YEAR0"
|
||||||
@@ -505,10 +411,8 @@ uint8_t map[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
|||||||
/*
|
/*
|
||||||
获取一个月最后一天值
|
获取一个月最后一天值
|
||||||
*/
|
*/
|
||||||
uint8_t get_last_day(uint16_t year, uint8_t month)
|
uint8_t get_last_day(uint16_t year, uint8_t month) {
|
||||||
{
|
if (month % 12 == 1) {
|
||||||
if (month % 12 == 1)
|
|
||||||
{
|
|
||||||
return map[month % 12] + is_leap(year);
|
return map[month % 12] + is_leap(year);
|
||||||
}
|
}
|
||||||
return map[month % 12];
|
return map[month % 12];
|
||||||
@@ -517,32 +421,26 @@ uint8_t get_last_day(uint16_t year, uint8_t month)
|
|||||||
/*
|
/*
|
||||||
获取一个月第一天星期值
|
获取一个月第一天星期值
|
||||||
*/
|
*/
|
||||||
uint8_t get_first_day_week(uint16_t year, uint8_t month)
|
uint8_t get_first_day_week(uint16_t year, uint8_t month) { return day_of_week_get(month, 1, year); }
|
||||||
{
|
|
||||||
return day_of_week_get(month, 1, year);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 时间结构体转时间戳
|
// 时间结构体转时间戳
|
||||||
uint32_t transformTimeStruct(struct devtm *result)
|
uint32_t transformTimeStruct(struct devtm* result) {
|
||||||
{
|
|
||||||
uint32_t Cyear = 0;
|
uint32_t Cyear = 0;
|
||||||
for (uint16_t i = 1970; i < result->tm_year; i++)
|
for (uint16_t i = 1970; i < result->tm_year; i++) {
|
||||||
{
|
if (is_leap(i) == 1) Cyear++;
|
||||||
if (is_leap(i) == 1)
|
|
||||||
Cyear++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t CountDay = Cyear * (uint32_t)366 + (uint32_t)(result->tm_year - 1970 - Cyear) * (uint32_t)365 + result->tm_mday - 1;
|
uint32_t CountDay =
|
||||||
for (uint8_t i = 0; i < result->tm_mon - 1; i++)
|
Cyear * (uint32_t)366 + (uint32_t)(result->tm_year - 1970 - Cyear) * (uint32_t)365 + result->tm_mday - 1;
|
||||||
{
|
for (uint8_t i = 0; i < result->tm_mon - 1; i++) {
|
||||||
CountDay += get_last_day(result->tm_year, i);
|
CountDay += get_last_day(result->tm_year, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (CountDay * SECOND_OF_DAY + (uint32_t)result->tm_sec + (uint32_t)result->tm_min * 60 + (uint32_t)result->tm_hour * 3600);
|
return (CountDay * SECOND_OF_DAY + (uint32_t)result->tm_sec + (uint32_t)result->tm_min * 60 +
|
||||||
|
(uint32_t)result->tm_hour * 3600);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t thisMonthMaxDays(uint8_t year, uint8_t month)
|
uint8_t thisMonthMaxDays(uint8_t year, uint8_t month) {
|
||||||
{
|
|
||||||
if (year % 4 == 0 && month == 2)
|
if (year % 4 == 0 && month == 2)
|
||||||
return MonthDayMax[month - 1] + 1;
|
return MonthDayMax[month - 1] + 1;
|
||||||
else
|
else
|
||||||
|
|||||||
30
GUI/Lunar.h
30
GUI/Lunar.h
@@ -3,13 +3,12 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define YEAR0 (1900) /* The first year */
|
#define YEAR0 (1900) /* The first year */
|
||||||
#define EPOCH_YR (1970) /* EPOCH = Jan 1 1970 00:00:00 */
|
#define EPOCH_YR (1970) /* EPOCH = Jan 1 1970 00:00:00 */
|
||||||
#define SEC_PER_DY (86400) // 一天的秒数
|
#define SEC_PER_DY (86400) // 一天的秒数
|
||||||
#define SEC_PER_HR (3600) // 一小时的秒数
|
#define SEC_PER_HR (3600) // 一小时的秒数
|
||||||
|
|
||||||
typedef struct devtm
|
typedef struct devtm {
|
||||||
{
|
|
||||||
uint16_t tm_year;
|
uint16_t tm_year;
|
||||||
uint8_t tm_mon;
|
uint8_t tm_mon;
|
||||||
uint8_t tm_mday;
|
uint8_t tm_mday;
|
||||||
@@ -19,8 +18,7 @@ typedef struct devtm
|
|||||||
uint8_t tm_wday;
|
uint8_t tm_wday;
|
||||||
} tm_t;
|
} tm_t;
|
||||||
|
|
||||||
struct Lunar_Date
|
struct Lunar_Date {
|
||||||
{
|
|
||||||
uint8_t IsLeap;
|
uint8_t IsLeap;
|
||||||
uint8_t Date;
|
uint8_t Date;
|
||||||
uint8_t Month;
|
uint8_t Month;
|
||||||
@@ -36,15 +34,15 @@ extern const char Lunar_StemStrig[10][4];
|
|||||||
extern const char Lunar_BranchStrig[12][4];
|
extern const char Lunar_BranchStrig[12][4];
|
||||||
extern const char JieQiStr[24][7];
|
extern const char JieQiStr[24][7];
|
||||||
|
|
||||||
void LUNAR_SolarToLunar(struct Lunar_Date *lunar, uint16_t solar_year, uint8_t solar_month, uint8_t solar_date);
|
void LUNAR_SolarToLunar(struct Lunar_Date* lunar, uint16_t solar_year, uint8_t solar_month, uint8_t solar_date);
|
||||||
uint8_t LUNAR_GetZodiac(const struct Lunar_Date *lunar);
|
uint8_t LUNAR_GetZodiac(const struct Lunar_Date* lunar);
|
||||||
uint8_t LUNAR_GetStem(const struct Lunar_Date *lunar);
|
uint8_t LUNAR_GetStem(const struct Lunar_Date* lunar);
|
||||||
uint8_t LUNAR_GetBranch(const struct Lunar_Date *lunar);
|
uint8_t LUNAR_GetBranch(const struct Lunar_Date* lunar);
|
||||||
uint8_t GetJieQiStr(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t *day);
|
uint8_t GetJieQiStr(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t* day);
|
||||||
uint8_t GetJieQi(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t *JQdate);
|
uint8_t GetJieQi(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t* JQdate);
|
||||||
|
|
||||||
void transformTime(uint32_t unix_time, struct devtm *result);
|
void transformTime(uint32_t unix_time, struct devtm* result);
|
||||||
uint32_t transformTimeStruct(struct devtm *result);
|
uint32_t transformTimeStruct(struct devtm* result);
|
||||||
uint8_t get_first_day_week(uint16_t year, uint8_t month);
|
uint8_t get_first_day_week(uint16_t year, uint8_t month);
|
||||||
uint8_t get_last_day(uint16_t year, uint8_t month);
|
uint8_t get_last_day(uint16_t year, uint8_t month);
|
||||||
unsigned char day_of_week_get(unsigned char month, unsigned char day, unsigned short year);
|
unsigned char day_of_week_get(unsigned char month, unsigned char day, unsigned short year);
|
||||||
|
|||||||
430
GUI/u8g2_font.c
430
GUI/u8g2_font.c
@@ -1,154 +1,135 @@
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
U8g2_for_Adafruit_GFX.cpp
|
U8g2_for_Adafruit_GFX.cpp
|
||||||
|
|
||||||
Add unicode support and U8g2 fonts to Adafruit GFX libraries.
|
Add unicode support and U8g2 fonts to Adafruit GFX libraries.
|
||||||
|
|
||||||
U8g2 for Adafruit GFX Lib (https://github.com/olikraus/U8g2_for_Adafruit_GFX)
|
U8g2 for Adafruit GFX Lib (https://github.com/olikraus/U8g2_for_Adafruit_GFX)
|
||||||
|
|
||||||
Copyright (c) 2018, olikraus@gmail.com
|
Copyright (c) 2018, olikraus@gmail.com
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
are permitted provided that the following conditions are met:
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this list
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
of conditions and the following disclaimer.
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
list of conditions and the following disclaimer in the documentation and/or other
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
materials provided with the distribution.
|
materials provided with the distribution.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include "u8g2_font.h"
|
#include "u8g2_font.h"
|
||||||
|
|
||||||
static uint8_t u8g2_font_get_byte(const uint8_t *font, uint8_t offset)
|
#include <stddef.h>
|
||||||
{
|
|
||||||
|
static uint8_t u8g2_font_get_byte(const uint8_t* font, uint8_t offset) {
|
||||||
font += offset;
|
font += offset;
|
||||||
return u8x8_pgm_read( font );
|
return u8x8_pgm_read(font);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t u8g2_font_get_word(const uint8_t *font, uint8_t offset) U8X8_NOINLINE;
|
static uint16_t u8g2_font_get_word(const uint8_t* font, uint8_t offset) U8X8_NOINLINE;
|
||||||
static uint16_t u8g2_font_get_word(const uint8_t *font, uint8_t offset)
|
static uint16_t u8g2_font_get_word(const uint8_t* font, uint8_t offset) {
|
||||||
{
|
uint16_t pos;
|
||||||
uint16_t pos;
|
font += offset;
|
||||||
font += offset;
|
pos = u8x8_pgm_read(font);
|
||||||
pos = u8x8_pgm_read( font );
|
font++;
|
||||||
font++;
|
pos <<= 8;
|
||||||
pos <<= 8;
|
pos += u8x8_pgm_read(font);
|
||||||
pos += u8x8_pgm_read( font);
|
return pos;
|
||||||
return pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*========================================================================*/
|
/*========================================================================*/
|
||||||
/* new font format */
|
/* new font format */
|
||||||
void u8g2_read_font_info(u8g2_font_info_t *font_info, const uint8_t *font)
|
void u8g2_read_font_info(u8g2_font_info_t* font_info, const uint8_t* font) {
|
||||||
{
|
|
||||||
/* offset 0 */
|
/* offset 0 */
|
||||||
font_info->glyph_cnt = u8g2_font_get_byte(font, 0);
|
font_info->glyph_cnt = u8g2_font_get_byte(font, 0);
|
||||||
font_info->bbx_mode = u8g2_font_get_byte(font, 1);
|
font_info->bbx_mode = u8g2_font_get_byte(font, 1);
|
||||||
font_info->bits_per_0 = u8g2_font_get_byte(font, 2);
|
font_info->bits_per_0 = u8g2_font_get_byte(font, 2);
|
||||||
font_info->bits_per_1 = u8g2_font_get_byte(font, 3);
|
font_info->bits_per_1 = u8g2_font_get_byte(font, 3);
|
||||||
|
|
||||||
/* offset 4 */
|
/* offset 4 */
|
||||||
font_info->bits_per_char_width = u8g2_font_get_byte(font, 4);
|
font_info->bits_per_char_width = u8g2_font_get_byte(font, 4);
|
||||||
font_info->bits_per_char_height = u8g2_font_get_byte(font, 5);
|
font_info->bits_per_char_height = u8g2_font_get_byte(font, 5);
|
||||||
font_info->bits_per_char_x = u8g2_font_get_byte(font, 6);
|
font_info->bits_per_char_x = u8g2_font_get_byte(font, 6);
|
||||||
font_info->bits_per_char_y = u8g2_font_get_byte(font, 7);
|
font_info->bits_per_char_y = u8g2_font_get_byte(font, 7);
|
||||||
font_info->bits_per_delta_x = u8g2_font_get_byte(font, 8);
|
font_info->bits_per_delta_x = u8g2_font_get_byte(font, 8);
|
||||||
|
|
||||||
/* offset 9 */
|
/* offset 9 */
|
||||||
font_info->max_char_width = u8g2_font_get_byte(font, 9);
|
font_info->max_char_width = u8g2_font_get_byte(font, 9);
|
||||||
font_info->max_char_height = u8g2_font_get_byte(font, 10);
|
font_info->max_char_height = u8g2_font_get_byte(font, 10);
|
||||||
font_info->x_offset = u8g2_font_get_byte(font, 11);
|
font_info->x_offset = u8g2_font_get_byte(font, 11);
|
||||||
font_info->y_offset = u8g2_font_get_byte(font, 12);
|
font_info->y_offset = u8g2_font_get_byte(font, 12);
|
||||||
|
|
||||||
/* offset 13 */
|
/* offset 13 */
|
||||||
font_info->ascent_A = u8g2_font_get_byte(font, 13);
|
font_info->ascent_A = u8g2_font_get_byte(font, 13);
|
||||||
font_info->descent_g = u8g2_font_get_byte(font, 14);
|
font_info->descent_g = u8g2_font_get_byte(font, 14);
|
||||||
font_info->ascent_para = u8g2_font_get_byte(font, 15);
|
font_info->ascent_para = u8g2_font_get_byte(font, 15);
|
||||||
font_info->descent_para = u8g2_font_get_byte(font, 16);
|
font_info->descent_para = u8g2_font_get_byte(font, 16);
|
||||||
|
|
||||||
/* offset 17 */
|
/* offset 17 */
|
||||||
font_info->start_pos_upper_A = u8g2_font_get_word(font, 17);
|
font_info->start_pos_upper_A = u8g2_font_get_word(font, 17);
|
||||||
font_info->start_pos_lower_a = u8g2_font_get_word(font, 19);
|
font_info->start_pos_lower_a = u8g2_font_get_word(font, 19);
|
||||||
|
|
||||||
/* offset 21 */
|
/* offset 21 */
|
||||||
font_info->start_pos_unicode = u8g2_font_get_word(font, 21);
|
font_info->start_pos_unicode = u8g2_font_get_word(font, 21);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t u8g2_GetFontBBXWidth(u8g2_font_t *u8g2)
|
uint8_t u8g2_GetFontBBXWidth(u8g2_font_t* u8g2) { return u8g2->font_info.max_char_width; /* new font info structure */ }
|
||||||
{
|
|
||||||
return u8g2->font_info.max_char_width; /* new font info structure */
|
uint8_t u8g2_GetFontBBXHeight(u8g2_font_t* u8g2) {
|
||||||
|
return u8g2->font_info.max_char_height; /* new font info structure */
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t u8g2_GetFontBBXHeight(u8g2_font_t *u8g2)
|
int8_t u8g2_GetFontBBXOffX(u8g2_font_t* u8g2) { return u8g2->font_info.x_offset; /* new font info structure */ }
|
||||||
{
|
|
||||||
return u8g2->font_info.max_char_height; /* new font info structure */
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t u8g2_GetFontBBXOffX(u8g2_font_t *u8g2)
|
int8_t u8g2_GetFontBBXOffY(u8g2_font_t* u8g2) { return u8g2->font_info.y_offset; /* new font info structure */ }
|
||||||
{
|
|
||||||
return u8g2->font_info.x_offset; /* new font info structure */
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t u8g2_GetFontBBXOffY(u8g2_font_t *u8g2)
|
uint8_t u8g2_GetFontCapitalAHeight(u8g2_font_t* u8g2) { return u8g2->font_info.ascent_A; /* new font info structure */ }
|
||||||
{
|
|
||||||
return u8g2->font_info.y_offset; /* new font info structure */
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t u8g2_GetFontCapitalAHeight(u8g2_font_t *u8g2)
|
static uint8_t u8g2_font_decode_get_unsigned_bits(u8g2_font_decode_t* f, uint8_t cnt) U8X8_NOINLINE;
|
||||||
{
|
static uint8_t u8g2_font_decode_get_unsigned_bits(u8g2_font_decode_t* f, uint8_t cnt) {
|
||||||
return u8g2->font_info.ascent_A; /* new font info structure */
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t u8g2_font_decode_get_unsigned_bits(u8g2_font_decode_t *f, uint8_t cnt) U8X8_NOINLINE;
|
|
||||||
static uint8_t u8g2_font_decode_get_unsigned_bits(u8g2_font_decode_t *f, uint8_t cnt)
|
|
||||||
{
|
|
||||||
uint8_t val;
|
uint8_t val;
|
||||||
uint8_t bit_pos = f->decode_bit_pos;
|
uint8_t bit_pos = f->decode_bit_pos;
|
||||||
uint8_t bit_pos_plus_cnt;
|
uint8_t bit_pos_plus_cnt;
|
||||||
|
|
||||||
//val = *(f->decode_ptr);
|
// val = *(f->decode_ptr);
|
||||||
val = u8x8_pgm_read( f->decode_ptr );
|
val = u8x8_pgm_read(f->decode_ptr);
|
||||||
|
|
||||||
val >>= bit_pos;
|
val >>= bit_pos;
|
||||||
bit_pos_plus_cnt = bit_pos;
|
bit_pos_plus_cnt = bit_pos;
|
||||||
bit_pos_plus_cnt += cnt;
|
bit_pos_plus_cnt += cnt;
|
||||||
if ( bit_pos_plus_cnt >= 8 )
|
if (bit_pos_plus_cnt >= 8) {
|
||||||
{
|
|
||||||
uint8_t s = 8;
|
uint8_t s = 8;
|
||||||
s -= bit_pos;
|
s -= bit_pos;
|
||||||
f->decode_ptr++;
|
f->decode_ptr++;
|
||||||
//val |= *(f->decode_ptr) << (8-bit_pos);
|
// val |= *(f->decode_ptr) << (8-bit_pos);
|
||||||
val |= u8x8_pgm_read( f->decode_ptr ) << (s);
|
val |= u8x8_pgm_read(f->decode_ptr) << (s);
|
||||||
//bit_pos -= 8;
|
// bit_pos -= 8;
|
||||||
bit_pos_plus_cnt -= 8;
|
bit_pos_plus_cnt -= 8;
|
||||||
}
|
}
|
||||||
val &= (1U<<cnt)-1;
|
val &= (1U << cnt) - 1;
|
||||||
//bit_pos += cnt;
|
// bit_pos += cnt;
|
||||||
|
|
||||||
f->decode_bit_pos = bit_pos_plus_cnt;
|
f->decode_bit_pos = bit_pos_plus_cnt;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
2 bit --> cnt = 2
|
2 bit --> cnt = 2
|
||||||
-2,-1,0. 1
|
-2,-1,0. 1
|
||||||
@@ -164,9 +145,8 @@ static uint8_t u8g2_font_decode_get_unsigned_bits(u8g2_font_decode_t *f, uint8_t
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
/* optimized */
|
/* optimized */
|
||||||
static int8_t u8g2_font_decode_get_signed_bits(u8g2_font_decode_t *f, uint8_t cnt) U8X8_NOINLINE;
|
static int8_t u8g2_font_decode_get_signed_bits(u8g2_font_decode_t* f, uint8_t cnt) U8X8_NOINLINE;
|
||||||
static int8_t u8g2_font_decode_get_signed_bits(u8g2_font_decode_t *f, uint8_t cnt)
|
static int8_t u8g2_font_decode_get_signed_bits(u8g2_font_decode_t* f, uint8_t cnt) {
|
||||||
{
|
|
||||||
int8_t v, d;
|
int8_t v, d;
|
||||||
v = (int8_t)u8g2_font_decode_get_unsigned_bits(f, cnt);
|
v = (int8_t)u8g2_font_decode_get_unsigned_bits(f, cnt);
|
||||||
d = 1;
|
d = 1;
|
||||||
@@ -174,15 +154,12 @@ static int8_t u8g2_font_decode_get_signed_bits(u8g2_font_decode_t *f, uint8_t cn
|
|||||||
d <<= cnt;
|
d <<= cnt;
|
||||||
v -= d;
|
v -= d;
|
||||||
return v;
|
return v;
|
||||||
//return (int8_t)u8g2_font_decode_get_unsigned_bits(f, cnt) - ((1<<cnt)>>1);
|
// return (int8_t)u8g2_font_decode_get_unsigned_bits(f, cnt) - ((1<<cnt)>>1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int16_t u8g2_add_vector_y(int16_t dy, int8_t x, int8_t y, uint8_t dir) U8X8_NOINLINE;
|
static int16_t u8g2_add_vector_y(int16_t dy, int8_t x, int8_t y, uint8_t dir) U8X8_NOINLINE;
|
||||||
static int16_t u8g2_add_vector_y(int16_t dy, int8_t x, int8_t y, uint8_t dir)
|
static int16_t u8g2_add_vector_y(int16_t dy, int8_t x, int8_t y, uint8_t dir) {
|
||||||
{
|
switch (dir) {
|
||||||
switch(dir)
|
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
dy += y;
|
dy += y;
|
||||||
break;
|
break;
|
||||||
@@ -194,16 +171,14 @@ static int16_t u8g2_add_vector_y(int16_t dy, int8_t x, int8_t y, uint8_t dir)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dy -= x;
|
dy -= x;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return dy;
|
return dy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int16_t u8g2_add_vector_x(int16_t dx, int8_t x, int8_t y, uint8_t dir) U8X8_NOINLINE;
|
static int16_t u8g2_add_vector_x(int16_t dx, int8_t x, int8_t y, uint8_t dir) U8X8_NOINLINE;
|
||||||
static int16_t u8g2_add_vector_x(int16_t dx, int8_t x, int8_t y, uint8_t dir)
|
static int16_t u8g2_add_vector_x(int16_t dx, int8_t x, int8_t y, uint8_t dir) {
|
||||||
{
|
switch (dir) {
|
||||||
switch(dir)
|
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
dx += x;
|
dx += x;
|
||||||
break;
|
break;
|
||||||
@@ -215,7 +190,7 @@ static int16_t u8g2_add_vector_x(int16_t dx, int8_t x, int8_t y, uint8_t dir)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dx += y;
|
dx += y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return dx;
|
return dx;
|
||||||
}
|
}
|
||||||
@@ -238,42 +213,38 @@ static int16_t u8g2_add_vector_x(int16_t dx, int8_t x, int8_t y, uint8_t dir)
|
|||||||
u8g2_font_decode_glyph()
|
u8g2_font_decode_glyph()
|
||||||
*/
|
*/
|
||||||
/* optimized */
|
/* optimized */
|
||||||
static void u8g2_font_decode_len(u8g2_font_t *u8g2, uint8_t len, uint8_t is_foreground)
|
static void u8g2_font_decode_len(u8g2_font_t* u8g2, uint8_t len, uint8_t is_foreground) {
|
||||||
{
|
uint8_t cnt; /* total number of remaining pixels, which have to be drawn */
|
||||||
uint8_t cnt; /* total number of remaining pixels, which have to be drawn */
|
uint8_t rem; /* remaining pixel to the right edge of the glyph */
|
||||||
uint8_t rem; /* remaining pixel to the right edge of the glyph */
|
uint8_t current; /* number of pixels, which need to be drawn for the draw procedure */
|
||||||
uint8_t current; /* number of pixels, which need to be drawn for the draw procedure */
|
/* current is either equal to cnt or equal to rem */
|
||||||
/* current is either equal to cnt or equal to rem */
|
|
||||||
|
|
||||||
/* local coordinates of the glyph */
|
/* local coordinates of the glyph */
|
||||||
uint8_t lx,ly;
|
uint8_t lx, ly;
|
||||||
|
|
||||||
/* target position on the screen */
|
/* target position on the screen */
|
||||||
int16_t x, y;
|
int16_t x, y;
|
||||||
|
|
||||||
u8g2_font_decode_t *decode = &(u8g2->font_decode);
|
u8g2_font_decode_t* decode = &(u8g2->font_decode);
|
||||||
|
|
||||||
cnt = len;
|
cnt = len;
|
||||||
|
|
||||||
/* get the local position */
|
/* get the local position */
|
||||||
lx = decode->x;
|
lx = decode->x;
|
||||||
ly = decode->y;
|
ly = decode->y;
|
||||||
|
|
||||||
for(;;)
|
for (;;) {
|
||||||
{
|
|
||||||
/* calculate the number of pixel to the right edge of the glyph */
|
/* calculate the number of pixel to the right edge of the glyph */
|
||||||
rem = decode->glyph_width;
|
rem = decode->glyph_width;
|
||||||
rem -= lx;
|
rem -= lx;
|
||||||
|
|
||||||
/* calculate how many pixel to draw. This is either to the right edge */
|
/* calculate how many pixel to draw. This is either to the right edge */
|
||||||
/* or lesser, if not enough pixel are left */
|
/* or lesser, if not enough pixel are left */
|
||||||
current = rem;
|
current = rem;
|
||||||
if ( cnt < rem )
|
if (cnt < rem) current = cnt;
|
||||||
current = cnt;
|
|
||||||
|
|
||||||
|
|
||||||
/* now draw the line, but apply the rotation around the glyph target position */
|
/* now draw the line, but apply the rotation around the glyph target position */
|
||||||
//u8g2_font_decode_draw_pixel(u8g2, lx,ly,current, is_foreground);
|
// u8g2_font_decode_draw_pixel(u8g2, lx,ly,current, is_foreground);
|
||||||
|
|
||||||
/* get target position */
|
/* get target position */
|
||||||
x = decode->target_x;
|
x = decode->target_x;
|
||||||
@@ -282,51 +253,43 @@ static void u8g2_font_decode_len(u8g2_font_t *u8g2, uint8_t len, uint8_t is_fore
|
|||||||
/* apply rotation */
|
/* apply rotation */
|
||||||
x = u8g2_add_vector_x(x, lx, ly, decode->dir);
|
x = u8g2_add_vector_x(x, lx, ly, decode->dir);
|
||||||
y = u8g2_add_vector_y(y, lx, ly, decode->dir);
|
y = u8g2_add_vector_y(y, lx, ly, decode->dir);
|
||||||
|
|
||||||
/* draw foreground and background (if required) */
|
/* draw foreground and background (if required) */
|
||||||
if ( current > 0 ) /* avoid drawing zero length lines, issue #4 */
|
if (current > 0) /* avoid drawing zero length lines, issue #4 */
|
||||||
{
|
{
|
||||||
if ( is_foreground )
|
if (is_foreground) {
|
||||||
{
|
|
||||||
u8g2->draw_hv_line(u8g2, x, y, current, decode->dir, decode->fg_color);
|
u8g2->draw_hv_line(u8g2, x, y, current, decode->dir, decode->fg_color);
|
||||||
}
|
} else if (decode->is_transparent == 0) {
|
||||||
else if ( decode->is_transparent == 0 )
|
|
||||||
{
|
|
||||||
u8g2->draw_hv_line(u8g2, x, y, current, decode->dir, decode->bg_color);
|
u8g2->draw_hv_line(u8g2, x, y, current, decode->dir, decode->bg_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check, whether the end of the run length code has been reached */
|
/* check, whether the end of the run length code has been reached */
|
||||||
if ( cnt < rem )
|
if (cnt < rem) break;
|
||||||
break;
|
|
||||||
cnt -= rem;
|
cnt -= rem;
|
||||||
lx = 0;
|
lx = 0;
|
||||||
ly++;
|
ly++;
|
||||||
}
|
}
|
||||||
lx += cnt;
|
lx += cnt;
|
||||||
|
|
||||||
decode->x = lx;
|
decode->x = lx;
|
||||||
decode->y = ly;
|
decode->y = ly;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void u8g2_font_setup_decode(u8g2_font_t *u8g2, const uint8_t *glyph_data)
|
static void u8g2_font_setup_decode(u8g2_font_t* u8g2, const uint8_t* glyph_data) {
|
||||||
{
|
u8g2_font_decode_t* decode = &(u8g2->font_decode);
|
||||||
u8g2_font_decode_t *decode = &(u8g2->font_decode);
|
|
||||||
decode->decode_ptr = glyph_data;
|
decode->decode_ptr = glyph_data;
|
||||||
decode->decode_bit_pos = 0;
|
decode->decode_bit_pos = 0;
|
||||||
|
|
||||||
/* 8 Nov 2015, this is already done in the glyph data search procedure */
|
/* 8 Nov 2015, this is already done in the glyph data search procedure */
|
||||||
/*
|
/*
|
||||||
decode->decode_ptr += 1;
|
decode->decode_ptr += 1;
|
||||||
decode->decode_ptr += 1;
|
decode->decode_ptr += 1;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
decode->glyph_width = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_char_width);
|
|
||||||
decode->glyph_height = u8g2_font_decode_get_unsigned_bits(decode,u8g2->font_info.bits_per_char_height);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
decode->glyph_width = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_char_width);
|
||||||
|
decode->glyph_height = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_char_height);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Description:
|
Description:
|
||||||
@@ -342,48 +305,40 @@ static void u8g2_font_setup_decode(u8g2_font_t *u8g2, const uint8_t *glyph_data)
|
|||||||
u8g2_font_decode_len()
|
u8g2_font_decode_len()
|
||||||
*/
|
*/
|
||||||
/* optimized */
|
/* optimized */
|
||||||
static int8_t u8g2_font_decode_glyph(u8g2_font_t *u8g2, const uint8_t *glyph_data)
|
static int8_t u8g2_font_decode_glyph(u8g2_font_t* u8g2, const uint8_t* glyph_data) {
|
||||||
{
|
|
||||||
uint8_t a, b;
|
uint8_t a, b;
|
||||||
int8_t x, y;
|
int8_t x, y;
|
||||||
int8_t d;
|
int8_t d;
|
||||||
int8_t h;
|
int8_t h;
|
||||||
u8g2_font_decode_t *decode = &(u8g2->font_decode);
|
u8g2_font_decode_t* decode = &(u8g2->font_decode);
|
||||||
|
|
||||||
u8g2_font_setup_decode(u8g2, glyph_data);
|
u8g2_font_setup_decode(u8g2, glyph_data);
|
||||||
h = u8g2->font_decode.glyph_height;
|
h = u8g2->font_decode.glyph_height;
|
||||||
|
|
||||||
x = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_x);
|
x = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_x);
|
||||||
y = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_y);
|
y = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_y);
|
||||||
d = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_delta_x);
|
d = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_delta_x);
|
||||||
|
|
||||||
|
if (decode->glyph_width > 0) {
|
||||||
if ( decode->glyph_width > 0 )
|
decode->target_x = u8g2_add_vector_x(decode->target_x, x, -(h + y), decode->dir);
|
||||||
{
|
decode->target_y = u8g2_add_vector_y(decode->target_y, x, -(h + y), decode->dir);
|
||||||
decode->target_x = u8g2_add_vector_x(decode->target_x, x, -(h+y), decode->dir);
|
// u8g2_add_vector(&(decode->target_x), &(decode->target_y), x, -(h+y), decode->dir);
|
||||||
decode->target_y = u8g2_add_vector_y(decode->target_y, x, -(h+y), decode->dir);
|
|
||||||
//u8g2_add_vector(&(decode->target_x), &(decode->target_y), x, -(h+y), decode->dir);
|
|
||||||
|
|
||||||
|
|
||||||
/* reset local x/y position */
|
/* reset local x/y position */
|
||||||
decode->x = 0;
|
decode->x = 0;
|
||||||
decode->y = 0;
|
decode->y = 0;
|
||||||
|
|
||||||
/* decode glyph */
|
/* decode glyph */
|
||||||
for(;;)
|
for (;;) {
|
||||||
{
|
|
||||||
a = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_0);
|
a = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_0);
|
||||||
b = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_1);
|
b = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_1);
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
u8g2_font_decode_len(u8g2, a, 0);
|
u8g2_font_decode_len(u8g2, a, 0);
|
||||||
u8g2_font_decode_len(u8g2, b, 1);
|
u8g2_font_decode_len(u8g2, b, 1);
|
||||||
} while( u8g2_font_decode_get_unsigned_bits(decode, 1) != 0 );
|
} while (u8g2_font_decode_get_unsigned_bits(decode, 1) != 0);
|
||||||
|
|
||||||
if ( decode->y >= h )
|
if (decode->y >= h) break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
@@ -396,140 +351,107 @@ static int8_t u8g2_font_decode_glyph(u8g2_font_t *u8g2, const uint8_t *glyph_dat
|
|||||||
Return:
|
Return:
|
||||||
Address of the glyph data or NULL, if the encoding is not avialable in the font.
|
Address of the glyph data or NULL, if the encoding is not avialable in the font.
|
||||||
*/
|
*/
|
||||||
const uint8_t *u8g2_font_get_glyph_data(u8g2_font_t *u8g2, uint16_t encoding)
|
const uint8_t* u8g2_font_get_glyph_data(u8g2_font_t* u8g2, uint16_t encoding) {
|
||||||
{
|
const uint8_t* font = u8g2->font;
|
||||||
const uint8_t *font = u8g2->font;
|
|
||||||
font += 23;
|
font += 23;
|
||||||
|
|
||||||
|
if (encoding <= 255) {
|
||||||
if ( encoding <= 255 )
|
if (encoding >= 'a') {
|
||||||
{
|
|
||||||
if ( encoding >= 'a' )
|
|
||||||
{
|
|
||||||
font += u8g2->font_info.start_pos_lower_a;
|
font += u8g2->font_info.start_pos_lower_a;
|
||||||
}
|
} else if (encoding >= 'A') {
|
||||||
else if ( encoding >= 'A' )
|
|
||||||
{
|
|
||||||
font += u8g2->font_info.start_pos_upper_A;
|
font += u8g2->font_info.start_pos_upper_A;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(;;)
|
for (;;) {
|
||||||
{
|
if (u8x8_pgm_read(font + 1) == 0) break;
|
||||||
if ( u8x8_pgm_read( font + 1 ) == 0 )
|
if (u8x8_pgm_read(font) == encoding) {
|
||||||
break;
|
return font + 2; /* skip encoding and glyph size */
|
||||||
if ( u8x8_pgm_read( font ) == encoding )
|
|
||||||
{
|
|
||||||
return font+2; /* skip encoding and glyph size */
|
|
||||||
}
|
}
|
||||||
font += u8x8_pgm_read( font + 1 );
|
font += u8x8_pgm_read(font + 1);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
uint16_t e;
|
uint16_t e;
|
||||||
const uint8_t *unicode_lookup_table;
|
const uint8_t* unicode_lookup_table;
|
||||||
/* support for the new unicode lookup table */
|
/* support for the new unicode lookup table */
|
||||||
|
|
||||||
font += u8g2->font_info.start_pos_unicode;
|
font += u8g2->font_info.start_pos_unicode;
|
||||||
unicode_lookup_table = font;
|
unicode_lookup_table = font;
|
||||||
|
|
||||||
/* u8g2 issue 596: search for the glyph start in the unicode lookup table */
|
/* u8g2 issue 596: search for the glyph start in the unicode lookup table */
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
font += u8g2_font_get_word(unicode_lookup_table, 0);
|
font += u8g2_font_get_word(unicode_lookup_table, 0);
|
||||||
e = u8g2_font_get_word(unicode_lookup_table, 2);
|
e = u8g2_font_get_word(unicode_lookup_table, 2);
|
||||||
unicode_lookup_table+=4;
|
unicode_lookup_table += 4;
|
||||||
} while( e < encoding );
|
} while (e < encoding);
|
||||||
|
|
||||||
/* variable "font" is now updated according to the lookup table */
|
/* variable "font" is now updated according to the lookup table */
|
||||||
|
|
||||||
for(;;)
|
for (;;) {
|
||||||
{
|
e = u8x8_pgm_read(font);
|
||||||
e = u8x8_pgm_read( font );
|
|
||||||
e <<= 8;
|
e <<= 8;
|
||||||
e |= u8x8_pgm_read( font + 1 );
|
e |= u8x8_pgm_read(font + 1);
|
||||||
if ( e == 0 )
|
if (e == 0) break;
|
||||||
break;
|
if (e == encoding) {
|
||||||
if ( e == encoding )
|
return font + 3; /* skip encoding and glyph size */
|
||||||
{
|
|
||||||
return font+3; /* skip encoding and glyph size */
|
|
||||||
}
|
}
|
||||||
font += u8x8_pgm_read( font + 2 );
|
font += u8x8_pgm_read(font + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int16_t u8g2_font_draw_glyph(u8g2_font_t *u8g2, int16_t x, int16_t y, uint16_t encoding)
|
static int16_t u8g2_font_draw_glyph(u8g2_font_t* u8g2, int16_t x, int16_t y, uint16_t encoding) {
|
||||||
{
|
|
||||||
int16_t dx = 0;
|
int16_t dx = 0;
|
||||||
u8g2->font_decode.target_x = x;
|
u8g2->font_decode.target_x = x;
|
||||||
u8g2->font_decode.target_y = y;
|
u8g2->font_decode.target_y = y;
|
||||||
//u8g2->font_decode.is_transparent = is_transparent; this is already set
|
// u8g2->font_decode.is_transparent = is_transparent; this is already set
|
||||||
//u8g2->font_decode.dir = dir;
|
// u8g2->font_decode.dir = dir;
|
||||||
const uint8_t *glyph_data = u8g2_font_get_glyph_data(u8g2, encoding);
|
const uint8_t* glyph_data = u8g2_font_get_glyph_data(u8g2, encoding);
|
||||||
if ( glyph_data != NULL )
|
if (glyph_data != NULL) {
|
||||||
{
|
|
||||||
dx = u8g2_font_decode_glyph(u8g2, glyph_data);
|
dx = u8g2_font_decode_glyph(u8g2, glyph_data);
|
||||||
}
|
}
|
||||||
return dx;
|
return dx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//========================================================
|
//========================================================
|
||||||
|
|
||||||
uint8_t u8g2_IsGlyph(u8g2_font_t *u8g2, uint16_t requested_encoding)
|
uint8_t u8g2_IsGlyph(u8g2_font_t* u8g2, uint16_t requested_encoding) {
|
||||||
{
|
|
||||||
/* updated to new code */
|
/* updated to new code */
|
||||||
if ( u8g2_font_get_glyph_data(u8g2, requested_encoding) != NULL )
|
if (u8g2_font_get_glyph_data(u8g2, requested_encoding) != NULL) return 1;
|
||||||
return 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* side effect: updates u8g2->font_decode and u8g2->glyph_x_offset */
|
/* side effect: updates u8g2->font_decode and u8g2->glyph_x_offset */
|
||||||
/* actually u8g2_GetGlyphWidth returns the glyph delta x and glyph width itself is set as side effect */
|
/* actually u8g2_GetGlyphWidth returns the glyph delta x and glyph width itself is set as side effect */
|
||||||
int8_t u8g2_GetGlyphWidth(u8g2_font_t *u8g2, uint16_t requested_encoding)
|
int8_t u8g2_GetGlyphWidth(u8g2_font_t* u8g2, uint16_t requested_encoding) {
|
||||||
{
|
const uint8_t* glyph_data = u8g2_font_get_glyph_data(u8g2, requested_encoding);
|
||||||
const uint8_t *glyph_data = u8g2_font_get_glyph_data(u8g2, requested_encoding);
|
if (glyph_data == NULL) return 0;
|
||||||
if ( glyph_data == NULL )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
u8g2_font_setup_decode(u8g2, glyph_data);
|
u8g2_font_setup_decode(u8g2, glyph_data);
|
||||||
u8g2->glyph_x_offset = u8g2_font_decode_get_signed_bits(&(u8g2->font_decode), u8g2->font_info.bits_per_char_x);
|
u8g2->glyph_x_offset = u8g2_font_decode_get_signed_bits(&(u8g2->font_decode), u8g2->font_info.bits_per_char_x);
|
||||||
u8g2_font_decode_get_signed_bits(&(u8g2->font_decode), u8g2->font_info.bits_per_char_y);
|
u8g2_font_decode_get_signed_bits(&(u8g2->font_decode), u8g2->font_info.bits_per_char_y);
|
||||||
|
|
||||||
/* glyph width is here: u8g2->font_decode.glyph_width */
|
/* glyph width is here: u8g2->font_decode.glyph_width */
|
||||||
return u8g2_font_decode_get_signed_bits(&(u8g2->font_decode), u8g2->font_info.bits_per_delta_x);
|
return u8g2_font_decode_get_signed_bits(&(u8g2->font_decode), u8g2->font_info.bits_per_delta_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void u8g2_SetFontMode(u8g2_font_t* u8g2, uint8_t is_transparent) {
|
||||||
void u8g2_SetFontMode(u8g2_font_t *u8g2, uint8_t is_transparent)
|
u8g2->font_decode.is_transparent = is_transparent; // new font procedures
|
||||||
{
|
|
||||||
u8g2->font_decode.is_transparent = is_transparent; // new font procedures
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void u8g2_SetFontDirection(u8g2_font_t *u8g2, uint8_t dir)
|
void u8g2_SetFontDirection(u8g2_font_t* u8g2, uint8_t dir) { u8g2->font_decode.dir = dir; }
|
||||||
{
|
|
||||||
u8g2->font_decode.dir = dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
int16_t u8g2_DrawGlyph(u8g2_font_t* u8g2, int16_t x, int16_t y, uint16_t encoding) {
|
||||||
|
|
||||||
int16_t u8g2_DrawGlyph(u8g2_font_t *u8g2, int16_t x, int16_t y, uint16_t encoding)
|
|
||||||
{
|
|
||||||
return u8g2_font_draw_glyph(u8g2, x, y, encoding);
|
return u8g2_font_draw_glyph(u8g2, x, y, encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t u8g2_DrawStr(u8g2_font_t *u8g2, int16_t x, int16_t y, const char *s)
|
int16_t u8g2_DrawStr(u8g2_font_t* u8g2, int16_t x, int16_t y, const char* s) {
|
||||||
{
|
|
||||||
int16_t sum, delta;
|
int16_t sum, delta;
|
||||||
sum = 0;
|
sum = 0;
|
||||||
|
|
||||||
while( *s != '\0' )
|
while (*s != '\0') {
|
||||||
{
|
|
||||||
delta = u8g2_DrawGlyph(u8g2, x, y, *s);
|
delta = u8g2_DrawGlyph(u8g2, x, y, *s);
|
||||||
switch(u8g2->font_decode.dir)
|
switch (u8g2->font_decode.dir) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
x += delta;
|
x += delta;
|
||||||
break;
|
break;
|
||||||
@@ -543,31 +465,21 @@ int16_t u8g2_DrawStr(u8g2_font_t *u8g2, int16_t x, int16_t y, const char *s)
|
|||||||
y -= delta;
|
y -= delta;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sum += delta;
|
sum += delta;
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void u8g2_SetFont(u8g2_font_t* u8g2, const uint8_t* font) {
|
||||||
|
if (u8g2->font != font) {
|
||||||
void u8g2_SetFont(u8g2_font_t *u8g2, const uint8_t *font)
|
|
||||||
{
|
|
||||||
if ( u8g2->font != font )
|
|
||||||
{
|
|
||||||
u8g2->font = font;
|
u8g2->font = font;
|
||||||
u8g2->font_decode.is_transparent = 0;
|
u8g2->font_decode.is_transparent = 0;
|
||||||
|
|
||||||
u8g2_read_font_info(&(u8g2->font_info), font);
|
u8g2_read_font_info(&(u8g2->font_info), font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void u8g2_SetForegroundColor(u8g2_font_t *u8g2, uint16_t fg)
|
void u8g2_SetForegroundColor(u8g2_font_t* u8g2, uint16_t fg) { u8g2->font_decode.fg_color = fg; }
|
||||||
{
|
|
||||||
u8g2->font_decode.fg_color = fg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void u8g2_SetBackgroundColor(u8g2_font_t *u8g2, uint16_t bg)
|
void u8g2_SetBackgroundColor(u8g2_font_t* u8g2, uint16_t bg) { u8g2->font_decode.bg_color = bg; }
|
||||||
{
|
|
||||||
u8g2->font_decode.bg_color = bg;
|
|
||||||
}
|
|
||||||
|
|||||||
133
GUI/u8g2_font.h
133
GUI/u8g2_font.h
@@ -1,37 +1,36 @@
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
U8g2_for_Adafruit_GFX.h
|
U8g2_for_Adafruit_GFX.h
|
||||||
|
|
||||||
Add unicode support and U8g2 fonts to Adafruit GFX libraries.
|
Add unicode support and U8g2 fonts to Adafruit GFX libraries.
|
||||||
|
|
||||||
U8g2 for Adafruit GFX Lib (https://github.com/olikraus/U8g2_for_Adafruit_GFX)
|
U8g2 for Adafruit GFX Lib (https://github.com/olikraus/U8g2_for_Adafruit_GFX)
|
||||||
|
|
||||||
Copyright (c) 2018, olikraus@gmail.com
|
Copyright (c) 2018, olikraus@gmail.com
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
are permitted provided that the following conditions are met:
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this list
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
of conditions and the following disclaimer.
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
list of conditions and the following disclaimer in the documentation and/or other
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
materials provided with the distribution.
|
materials provided with the distribution.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#ifndef __U8G2_H
|
#ifndef __U8G2_H
|
||||||
@@ -40,45 +39,44 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
# define U8X8_NOINLINE __attribute__((noinline))
|
#define U8X8_NOINLINE __attribute__((noinline))
|
||||||
# define U8X8_SECTION(name) __attribute__ ((section (name)))
|
#define U8X8_SECTION(name) __attribute__((section(name)))
|
||||||
# define U8X8_UNUSED __attribute__((unused))
|
#define U8X8_UNUSED __attribute__((unused))
|
||||||
#else
|
#else
|
||||||
# define U8X8_SECTION(name)
|
#define U8X8_SECTION(name)
|
||||||
# define U8X8_NOINLINE
|
#define U8X8_NOINLINE
|
||||||
# define U8X8_UNUSED
|
#define U8X8_UNUSED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__GNUC__) && defined(__AVR__)
|
#if defined(__GNUC__) && defined(__AVR__)
|
||||||
# define U8X8_FONT_SECTION(name) U8X8_SECTION(".progmem." name)
|
#define U8X8_FONT_SECTION(name) U8X8_SECTION(".progmem." name)
|
||||||
# define u8x8_pgm_read(adr) pgm_read_byte_near(adr)
|
#define u8x8_pgm_read(adr) pgm_read_byte_near(adr)
|
||||||
# define U8X8_PROGMEM PROGMEM
|
#define U8X8_PROGMEM PROGMEM
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef U8X8_FONT_SECTION
|
#ifndef U8X8_FONT_SECTION
|
||||||
# define U8X8_FONT_SECTION(name)
|
#define U8X8_FONT_SECTION(name)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef u8x8_pgm_read
|
#ifndef u8x8_pgm_read
|
||||||
# define u8x8_pgm_read(adr) (*(const uint8_t *)(adr))
|
#define u8x8_pgm_read(adr) (*(const uint8_t*)(adr))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef U8X8_PROGMEM
|
#ifndef U8X8_PROGMEM
|
||||||
# define U8X8_PROGMEM
|
#define U8X8_PROGMEM
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define U8G2_FONT_SECTION(name) U8X8_FONT_SECTION(name)
|
#define U8G2_FONT_SECTION(name) U8X8_FONT_SECTION(name)
|
||||||
|
|
||||||
/* the macro U8G2_USE_LARGE_FONTS enables large fonts (>32K) */
|
/* the macro U8G2_USE_LARGE_FONTS enables large fonts (>32K) */
|
||||||
/* it can be enabled for those uC supporting larger arrays */
|
/* it can be enabled for those uC supporting larger arrays */
|
||||||
#if defined(unix) || defined(__arm__) || defined(__arc__) || defined(ESP8266) || defined(ESP_PLATFORM)
|
#if defined(unix) || defined(__arm__) || defined(__arc__) || defined(ESP8266) || defined(ESP_PLATFORM)
|
||||||
#ifndef U8G2_USE_LARGE_FONTS
|
#ifndef U8G2_USE_LARGE_FONTS
|
||||||
#define U8G2_USE_LARGE_FONTS
|
#define U8G2_USE_LARGE_FONTS
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct _u8g2_font_info_t
|
typedef struct _u8g2_font_info_t {
|
||||||
{
|
|
||||||
/* offset 0 */
|
/* offset 0 */
|
||||||
uint8_t glyph_cnt;
|
uint8_t glyph_cnt;
|
||||||
uint8_t bbx_mode;
|
uint8_t bbx_mode;
|
||||||
@@ -87,7 +85,7 @@ typedef struct _u8g2_font_info_t
|
|||||||
|
|
||||||
/* offset 4 */
|
/* offset 4 */
|
||||||
uint8_t bits_per_char_width;
|
uint8_t bits_per_char_width;
|
||||||
uint8_t bits_per_char_height;
|
uint8_t bits_per_char_height;
|
||||||
uint8_t bits_per_char_x;
|
uint8_t bits_per_char_x;
|
||||||
uint8_t bits_per_char_y;
|
uint8_t bits_per_char_y;
|
||||||
uint8_t bits_per_delta_x;
|
uint8_t bits_per_delta_x;
|
||||||
@@ -99,59 +97,56 @@ typedef struct _u8g2_font_info_t
|
|||||||
int8_t y_offset;
|
int8_t y_offset;
|
||||||
|
|
||||||
/* offset 13 */
|
/* offset 13 */
|
||||||
int8_t ascent_A;
|
int8_t ascent_A;
|
||||||
int8_t descent_g; /* usually a negative value */
|
int8_t descent_g; /* usually a negative value */
|
||||||
int8_t ascent_para;
|
int8_t ascent_para;
|
||||||
int8_t descent_para;
|
int8_t descent_para;
|
||||||
|
|
||||||
/* offset 17 */
|
/* offset 17 */
|
||||||
uint16_t start_pos_upper_A;
|
uint16_t start_pos_upper_A;
|
||||||
uint16_t start_pos_lower_a;
|
uint16_t start_pos_lower_a;
|
||||||
|
|
||||||
/* offset 21 */
|
/* offset 21 */
|
||||||
uint16_t start_pos_unicode;
|
uint16_t start_pos_unicode;
|
||||||
} u8g2_font_info_t;
|
} u8g2_font_info_t;
|
||||||
|
|
||||||
typedef struct _u8g2_font_decode_t
|
typedef struct _u8g2_font_decode_t {
|
||||||
{
|
const uint8_t* decode_ptr; /* pointer to the compressed data */
|
||||||
const uint8_t *decode_ptr; /* pointer to the compressed data */
|
|
||||||
|
|
||||||
int16_t target_x;
|
int16_t target_x;
|
||||||
int16_t target_y;
|
int16_t target_y;
|
||||||
uint16_t fg_color;
|
uint16_t fg_color;
|
||||||
uint16_t bg_color;
|
uint16_t bg_color;
|
||||||
|
|
||||||
int8_t x; /* local coordinates, (0,0) is upper left */
|
int8_t x; /* local coordinates, (0,0) is upper left */
|
||||||
int8_t y;
|
int8_t y;
|
||||||
int8_t glyph_width;
|
int8_t glyph_width;
|
||||||
int8_t glyph_height;
|
int8_t glyph_height;
|
||||||
|
|
||||||
uint8_t decode_bit_pos; /* bitpos inside a byte of the compressed data */
|
uint8_t decode_bit_pos; /* bitpos inside a byte of the compressed data */
|
||||||
uint8_t is_transparent;
|
uint8_t is_transparent;
|
||||||
uint8_t dir; /* direction */
|
uint8_t dir; /* direction */
|
||||||
} u8g2_font_decode_t;
|
} u8g2_font_decode_t;
|
||||||
|
|
||||||
typedef struct _u8g2_font_t
|
typedef struct _u8g2_font_t {
|
||||||
{
|
const uint8_t* font; /* current font for all text procedures */
|
||||||
const uint8_t *font; /* current font for all text procedures */
|
|
||||||
|
|
||||||
u8g2_font_decode_t font_decode; /* new font decode structure */
|
u8g2_font_decode_t font_decode; /* new font decode structure */
|
||||||
u8g2_font_info_t font_info; /* new font info structure */
|
u8g2_font_info_t font_info; /* new font info structure */
|
||||||
|
|
||||||
int8_t glyph_x_offset; /* set by u8g2_GetGlyphWidth as a side effect */
|
int8_t glyph_x_offset; /* set by u8g2_GetGlyphWidth as a side effect */
|
||||||
|
|
||||||
void (*draw_hv_line)(struct _u8g2_font_t *u8g2, int16_t x, int16_t y,
|
void (*draw_hv_line)(struct _u8g2_font_t* u8g2, int16_t x, int16_t y, int16_t len, uint8_t dir, uint16_t color);
|
||||||
int16_t len, uint8_t dir, uint16_t color);
|
|
||||||
} u8g2_font_t;
|
} u8g2_font_t;
|
||||||
|
|
||||||
uint8_t u8g2_IsGlyph(u8g2_font_t *u8g2, uint16_t requested_encoding);
|
uint8_t u8g2_IsGlyph(u8g2_font_t* u8g2, uint16_t requested_encoding);
|
||||||
int8_t u8g2_GetGlyphWidth(u8g2_font_t *u8g2, uint16_t requested_encoding);
|
int8_t u8g2_GetGlyphWidth(u8g2_font_t* u8g2, uint16_t requested_encoding);
|
||||||
void u8g2_SetFontMode(u8g2_font_t *u8g2, uint8_t is_transparent);
|
void u8g2_SetFontMode(u8g2_font_t* u8g2, uint8_t is_transparent);
|
||||||
void u8g2_SetFontDirection(u8g2_font_t *u8g2, uint8_t dir);
|
void u8g2_SetFontDirection(u8g2_font_t* u8g2, uint8_t dir);
|
||||||
int16_t u8g2_DrawGlyph(u8g2_font_t *u8g2, int16_t x, int16_t y, uint16_t encoding);
|
int16_t u8g2_DrawGlyph(u8g2_font_t* u8g2, int16_t x, int16_t y, uint16_t encoding);
|
||||||
int16_t u8g2_DrawStr(u8g2_font_t *u8g2, int16_t x, int16_t y, const char *s);
|
int16_t u8g2_DrawStr(u8g2_font_t* u8g2, int16_t x, int16_t y, const char* s);
|
||||||
void u8g2_SetFont(u8g2_font_t *u8g2, const uint8_t *font);
|
void u8g2_SetFont(u8g2_font_t* u8g2, const uint8_t* font);
|
||||||
void u8g2_SetForegroundColor(u8g2_font_t *u8g2, uint16_t fg);
|
void u8g2_SetForegroundColor(u8g2_font_t* u8g2, uint16_t fg);
|
||||||
void u8g2_SetBackgroundColor(u8g2_font_t *u8g2, uint16_t bg);
|
void u8g2_SetBackgroundColor(u8g2_font_t* u8g2, uint16_t bg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
202
emulator.c
202
emulator.c
@@ -1,53 +1,54 @@
|
|||||||
// GUI emulator for Windows
|
// GUI emulator for Windows
|
||||||
// This code is a simple Windows GUI application that emulates the display of an e-paper device.
|
// This code is a simple Windows GUI application that emulates the display of an e-paper device.
|
||||||
#include <windows.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <time.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
#include "GUI.h"
|
#include "GUI.h"
|
||||||
|
|
||||||
#define BITMAP_WIDTH 400
|
#define BITMAP_WIDTH 400
|
||||||
#define BITMAP_HEIGHT 300
|
#define BITMAP_HEIGHT 300
|
||||||
#define WINDOW_WIDTH 450
|
#define WINDOW_WIDTH 450
|
||||||
#define WINDOW_HEIGHT 380
|
#define WINDOW_HEIGHT 380
|
||||||
|
|
||||||
// Global variables
|
// Global variables
|
||||||
HINSTANCE g_hInstance;
|
HINSTANCE g_hInstance;
|
||||||
HWND g_hwnd;
|
HWND g_hwnd;
|
||||||
HDC g_paintHDC = NULL;
|
HDC g_paintHDC = NULL;
|
||||||
display_mode_t g_display_mode = MODE_CALENDAR; // Default to calendar mode
|
display_mode_t g_display_mode = MODE_CALENDAR; // Default to calendar mode
|
||||||
BOOL g_bwr_mode = TRUE; // Default to BWR mode
|
BOOL g_bwr_mode = TRUE; // Default to BWR mode
|
||||||
uint8_t g_week_start = 0; // Default week start (0=Sunday, 1=Monday, etc.)
|
uint8_t g_week_start = 0; // Default week start (0=Sunday, 1=Monday, etc.)
|
||||||
time_t g_display_time;
|
time_t g_display_time;
|
||||||
struct tm g_tm_time;
|
struct tm g_tm_time;
|
||||||
|
|
||||||
// Implementation of the buffer_callback function
|
// Implementation of the buffer_callback function
|
||||||
void DrawBitmap(void *user_data, uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
void DrawBitmap(void* user_data, uint8_t* black, uint8_t* color, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
||||||
HDC hdc = g_paintHDC;
|
HDC hdc = g_paintHDC;
|
||||||
if (!hdc) return;
|
if (!hdc) return;
|
||||||
|
|
||||||
RECT clientRect;
|
RECT clientRect;
|
||||||
int scale = 1;
|
int scale = 1;
|
||||||
|
|
||||||
// Get client area for positioning
|
// Get client area for positioning
|
||||||
GetClientRect(g_hwnd, &clientRect);
|
GetClientRect(g_hwnd, &clientRect);
|
||||||
|
|
||||||
// Calculate position to center the entire bitmap in the window
|
// Calculate position to center the entire bitmap in the window
|
||||||
int drawX = (clientRect.right - BITMAP_WIDTH * scale) / 2;
|
int drawX = (clientRect.right - BITMAP_WIDTH * scale) / 2;
|
||||||
int drawY = (clientRect.bottom - BITMAP_HEIGHT * scale) / 2;
|
int drawY = (clientRect.bottom - BITMAP_HEIGHT * scale) / 2;
|
||||||
|
|
||||||
// Use 4-bit approach (16 colors, but we only use 3)
|
// Use 4-bit approach (16 colors, but we only use 3)
|
||||||
BITMAPINFO bmi;
|
BITMAPINFO bmi;
|
||||||
ZeroMemory(&bmi, sizeof(BITMAPINFO));
|
ZeroMemory(&bmi, sizeof(BITMAPINFO));
|
||||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
bmi.bmiHeader.biWidth = w;
|
bmi.bmiHeader.biWidth = w;
|
||||||
bmi.bmiHeader.biHeight = -h; // Negative for top-down bitmap
|
bmi.bmiHeader.biHeight = -h; // Negative for top-down bitmap
|
||||||
bmi.bmiHeader.biPlanes = 1;
|
bmi.bmiHeader.biPlanes = 1;
|
||||||
bmi.bmiHeader.biBitCount = 4; // 4 bits per pixel
|
bmi.bmiHeader.biBitCount = 4; // 4 bits per pixel
|
||||||
bmi.bmiHeader.biCompression = BI_RGB;
|
bmi.bmiHeader.biCompression = BI_RGB;
|
||||||
bmi.bmiHeader.biClrUsed = 16; // 16 colors (2^4)
|
bmi.bmiHeader.biClrUsed = 16; // 16 colors (2^4)
|
||||||
|
|
||||||
// Initialize all 16 palette entries to white first
|
// Initialize all 16 palette entries to white first
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
bmi.bmiColors[i].rgbBlue = 255;
|
bmi.bmiColors[i].rgbBlue = 255;
|
||||||
@@ -55,23 +56,23 @@ void DrawBitmap(void *user_data, uint8_t *black, uint8_t *color, uint16_t x, uin
|
|||||||
bmi.bmiColors[i].rgbRed = 255;
|
bmi.bmiColors[i].rgbRed = 255;
|
||||||
bmi.bmiColors[i].rgbReserved = 0;
|
bmi.bmiColors[i].rgbReserved = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set specific colors for our pixel values
|
// Set specific colors for our pixel values
|
||||||
// Color 0: White
|
// Color 0: White
|
||||||
bmi.bmiColors[0].rgbBlue = 255;
|
bmi.bmiColors[0].rgbBlue = 255;
|
||||||
bmi.bmiColors[0].rgbGreen = 255;
|
bmi.bmiColors[0].rgbGreen = 255;
|
||||||
bmi.bmiColors[0].rgbRed = 255;
|
bmi.bmiColors[0].rgbRed = 255;
|
||||||
|
|
||||||
// Color 1: Black
|
// Color 1: Black
|
||||||
bmi.bmiColors[1].rgbBlue = 0;
|
bmi.bmiColors[1].rgbBlue = 0;
|
||||||
bmi.bmiColors[1].rgbGreen = 0;
|
bmi.bmiColors[1].rgbGreen = 0;
|
||||||
bmi.bmiColors[1].rgbRed = 0;
|
bmi.bmiColors[1].rgbRed = 0;
|
||||||
|
|
||||||
// Color 2: Red
|
// Color 2: Red
|
||||||
bmi.bmiColors[2].rgbBlue = 0;
|
bmi.bmiColors[2].rgbBlue = 0;
|
||||||
bmi.bmiColors[2].rgbGreen = 0;
|
bmi.bmiColors[2].rgbGreen = 0;
|
||||||
bmi.bmiColors[2].rgbRed = 255;
|
bmi.bmiColors[2].rgbRed = 255;
|
||||||
|
|
||||||
// Create 4-bit bitmap data
|
// Create 4-bit bitmap data
|
||||||
// Each byte contains 2 pixels (4 bits each)
|
// Each byte contains 2 pixels (4 bits each)
|
||||||
int pixelsPerByte = 2;
|
int pixelsPerByte = 2;
|
||||||
@@ -79,31 +80,31 @@ void DrawBitmap(void *user_data, uint8_t *black, uint8_t *color, uint16_t x, uin
|
|||||||
// Align to DWORD boundary (4 bytes)
|
// Align to DWORD boundary (4 bytes)
|
||||||
bytesPerRow = ((bytesPerRow + 3) / 4) * 4;
|
bytesPerRow = ((bytesPerRow + 3) / 4) * 4;
|
||||||
int totalSize = bytesPerRow * h;
|
int totalSize = bytesPerRow * h;
|
||||||
|
|
||||||
uint8_t *bitmap4bit = (uint8_t*)malloc(totalSize);
|
uint8_t* bitmap4bit = (uint8_t*)malloc(totalSize);
|
||||||
if (!bitmap4bit) {
|
if (!bitmap4bit) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memset(bitmap4bit, 0, totalSize); // Initialize to white (0)
|
memset(bitmap4bit, 0, totalSize); // Initialize to white (0)
|
||||||
|
|
||||||
int ePaperBytesPerRow = (w + 7) / 8;
|
int ePaperBytesPerRow = (w + 7) / 8;
|
||||||
for (int row = 0; row < h; row++) {
|
for (int row = 0; row < h; row++) {
|
||||||
for (int col = 0; col < w; col++) {
|
for (int col = 0; col < w; col++) {
|
||||||
int bytePos = row * ePaperBytesPerRow + col / 8;
|
int bytePos = row * ePaperBytesPerRow + col / 8;
|
||||||
int bitPos = 7 - (col % 8);
|
int bitPos = 7 - (col % 8);
|
||||||
|
|
||||||
int blackBit = !((black[bytePos] >> bitPos) & 0x01);
|
int blackBit = !((black[bytePos] >> bitPos) & 0x01);
|
||||||
int colorBit = color ? !((color[bytePos] >> bitPos) & 0x01) : 0;
|
int colorBit = color ? !((color[bytePos] >> bitPos) & 0x01) : 0;
|
||||||
|
|
||||||
// Determine pixel value: 0=white, 1=black, 2=red
|
// Determine pixel value: 0=white, 1=black, 2=red
|
||||||
uint8_t pixelValue = colorBit ? 2 : (blackBit ? 1 : 0);
|
uint8_t pixelValue = colorBit ? 2 : (blackBit ? 1 : 0);
|
||||||
|
|
||||||
// Pack into 4-bit format
|
// Pack into 4-bit format
|
||||||
// Each byte stores 2 pixels: [pixel0][pixel1]
|
// Each byte stores 2 pixels: [pixel0][pixel1]
|
||||||
// High nibble = first pixel, low nibble = second pixel
|
// High nibble = first pixel, low nibble = second pixel
|
||||||
int bitmap4bitBytePos = row * bytesPerRow + col / pixelsPerByte;
|
int bitmap4bitBytePos = row * bytesPerRow + col / pixelsPerByte;
|
||||||
int isHighNibble = (col % pixelsPerByte) == 0;
|
int isHighNibble = (col % pixelsPerByte) == 0;
|
||||||
|
|
||||||
if (isHighNibble) {
|
if (isHighNibble) {
|
||||||
// Clear high nibble and set new value
|
// Clear high nibble and set new value
|
||||||
bitmap4bit[bitmap4bitBytePos] &= 0x0F;
|
bitmap4bit[bitmap4bitBytePos] &= 0x0F;
|
||||||
@@ -115,15 +116,11 @@ void DrawBitmap(void *user_data, uint8_t *black, uint8_t *color, uint16_t x, uin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the bitmap
|
// Draw the bitmap
|
||||||
StretchDIBits(hdc,
|
StretchDIBits(hdc, drawX + x * scale, drawY + y * scale, w * scale, h * scale, 0, 0, w, h, bitmap4bit, &bmi,
|
||||||
drawX + x * scale, drawY + y * scale,
|
DIB_RGB_COLORS, SRCCOPY);
|
||||||
w * scale, h * scale,
|
|
||||||
0, 0, w, h,
|
|
||||||
bitmap4bit, &bmi,
|
|
||||||
DIB_RGB_COLORS, SRCCOPY);
|
|
||||||
|
|
||||||
free(bitmap4bit);
|
free(bitmap4bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,14 +129,14 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
switch (message) {
|
switch (message) {
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
// Initialize the display time
|
// Initialize the display time
|
||||||
g_display_time = time(NULL) + 8*3600;
|
g_display_time = time(NULL) + 8 * 3600;
|
||||||
// Set a timer to update the CLOCK periodically (every second)
|
// Set a timer to update the CLOCK periodically (every second)
|
||||||
SetTimer(hwnd, 1, 1000, NULL);
|
SetTimer(hwnd, 1, 1000, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case WM_TIMER:
|
case WM_TIMER:
|
||||||
if (g_display_mode == MODE_CLOCK) {
|
if (g_display_mode == MODE_CLOCK) {
|
||||||
g_display_time = time(NULL) + 8*3600;
|
g_display_time = time(NULL) + 8 * 3600;
|
||||||
if (g_display_time % 60 == 0) {
|
if (g_display_time % 60 == 0) {
|
||||||
InvalidateRect(hwnd, NULL, FALSE);
|
InvalidateRect(hwnd, NULL, FALSE);
|
||||||
}
|
}
|
||||||
@@ -149,10 +146,10 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
case WM_PAINT: {
|
case WM_PAINT: {
|
||||||
PAINTSTRUCT ps;
|
PAINTSTRUCT ps;
|
||||||
HDC hdc = BeginPaint(hwnd, &ps);
|
HDC hdc = BeginPaint(hwnd, &ps);
|
||||||
|
|
||||||
// Set the global HDC for DrawBitmap to use
|
// Set the global HDC for DrawBitmap to use
|
||||||
g_paintHDC = hdc;
|
g_paintHDC = hdc;
|
||||||
|
|
||||||
// Get client rect for calculations
|
// Get client rect for calculations
|
||||||
RECT clientRect;
|
RECT clientRect;
|
||||||
GetClientRect(hwnd, &clientRect);
|
GetClientRect(hwnd, &clientRect);
|
||||||
@@ -161,94 +158,87 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
HBRUSH bgBrush = CreateSolidBrush(RGB(240, 240, 240));
|
HBRUSH bgBrush = CreateSolidBrush(RGB(240, 240, 240));
|
||||||
FillRect(hdc, &clientRect, bgBrush);
|
FillRect(hdc, &clientRect, bgBrush);
|
||||||
DeleteObject(bgBrush);
|
DeleteObject(bgBrush);
|
||||||
|
|
||||||
// Calculate border position (same as bitmap position)
|
// Calculate border position (same as bitmap position)
|
||||||
int scale = 1;
|
int scale = 1;
|
||||||
int drawX = (clientRect.right - BITMAP_WIDTH * scale) / 2;
|
int drawX = (clientRect.right - BITMAP_WIDTH * scale) / 2;
|
||||||
int drawY = (clientRect.bottom - BITMAP_HEIGHT * scale) / 2;
|
int drawY = (clientRect.bottom - BITMAP_HEIGHT * scale) / 2;
|
||||||
|
|
||||||
// Draw border around the bitmap area
|
// Draw border around the bitmap area
|
||||||
HPEN borderPen = CreatePen(PS_DOT, 1, RGB(0, 0, 255));
|
HPEN borderPen = CreatePen(PS_DOT, 1, RGB(0, 0, 255));
|
||||||
HPEN oldPen = SelectObject(hdc, borderPen);
|
HPEN oldPen = SelectObject(hdc, borderPen);
|
||||||
HBRUSH oldBrush = SelectObject(hdc, GetStockObject(NULL_BRUSH)); // No fill
|
HBRUSH oldBrush = SelectObject(hdc, GetStockObject(NULL_BRUSH)); // No fill
|
||||||
|
|
||||||
Rectangle(hdc, drawX - 1, drawY - 1,
|
Rectangle(hdc, drawX - 1, drawY - 1, drawX + BITMAP_WIDTH * scale + 1, drawY + BITMAP_HEIGHT * scale + 1);
|
||||||
drawX + BITMAP_WIDTH * scale + 1,
|
|
||||||
drawY + BITMAP_HEIGHT * scale + 1);
|
|
||||||
|
|
||||||
SelectObject(hdc, oldPen);
|
SelectObject(hdc, oldPen);
|
||||||
SelectObject(hdc, oldBrush);
|
SelectObject(hdc, oldBrush);
|
||||||
DeleteObject(borderPen);
|
DeleteObject(borderPen);
|
||||||
|
|
||||||
// Display current mode at the top of the bitmap
|
// Display current mode at the top of the bitmap
|
||||||
const wchar_t* modeText = (g_display_mode == MODE_CLOCK) ? L"时钟模式" : L"日历模式";
|
const wchar_t* modeText = (g_display_mode == MODE_CLOCK) ? L"时钟模式" : L"日历模式";
|
||||||
int modeTextY = drawY - 20; // Above the bitmap
|
int modeTextY = drawY - 20; // Above the bitmap
|
||||||
SetTextColor(hdc, RGB(50, 50, 50));
|
SetTextColor(hdc, RGB(50, 50, 50));
|
||||||
SetBkMode(hdc, TRANSPARENT);
|
SetBkMode(hdc, TRANSPARENT);
|
||||||
|
|
||||||
// Create a font for mode text
|
// Create a font for mode text
|
||||||
HFONT modeFont = CreateFont(
|
HFONT modeFont = CreateFont(16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
||||||
16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
|
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial");
|
||||||
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
|
||||||
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial"
|
|
||||||
);
|
|
||||||
HFONT oldFont = SelectObject(hdc, modeFont);
|
HFONT oldFont = SelectObject(hdc, modeFont);
|
||||||
|
|
||||||
// Calculate text width for centering mode text
|
// Calculate text width for centering mode text
|
||||||
SIZE modeTextSize;
|
SIZE modeTextSize;
|
||||||
GetTextExtentPoint32W(hdc, modeText, wcslen(modeText), &modeTextSize);
|
GetTextExtentPoint32W(hdc, modeText, wcslen(modeText), &modeTextSize);
|
||||||
int modeCenteredX = drawX + (BITMAP_WIDTH - modeTextSize.cx) / 2;
|
int modeCenteredX = drawX + (BITMAP_WIDTH - modeTextSize.cx) / 2;
|
||||||
|
|
||||||
TextOutW(hdc, modeCenteredX, modeTextY, modeText, wcslen(modeText));
|
TextOutW(hdc, modeCenteredX, modeTextY, modeText, wcslen(modeText));
|
||||||
|
|
||||||
// Draw help text below the bitmap
|
// Draw help text below the bitmap
|
||||||
const wchar_t helpText[] = L"空格 - 切换模式 | R - 切换颜色 | W - 星期起点 | 方向键 - 调整日期/月份";
|
const wchar_t helpText[] = L"空格 - 切换模式 | R - 切换颜色 | W - 星期起点 | 方向键 - 调整日期/月份";
|
||||||
int helpTextY = drawY + BITMAP_HEIGHT * scale + 5;
|
int helpTextY = drawY + BITMAP_HEIGHT * scale + 5;
|
||||||
SetTextColor(hdc, RGB(80, 80, 80));
|
SetTextColor(hdc, RGB(80, 80, 80));
|
||||||
|
|
||||||
// Create a smaller font for help text
|
// Create a smaller font for help text
|
||||||
HFONT helpFont = CreateFont(
|
HFONT helpFont =
|
||||||
14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
|
CreateFont(14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
||||||
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial");
|
||||||
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial"
|
|
||||||
);
|
|
||||||
SelectObject(hdc, modeFont);
|
SelectObject(hdc, modeFont);
|
||||||
DeleteObject(modeFont);
|
DeleteObject(modeFont);
|
||||||
SelectObject(hdc, helpFont);
|
SelectObject(hdc, helpFont);
|
||||||
|
|
||||||
// Calculate text width for centering help text
|
// Calculate text width for centering help text
|
||||||
SIZE textSize;
|
SIZE textSize;
|
||||||
GetTextExtentPoint32W(hdc, helpText, wcslen(helpText), &textSize);
|
GetTextExtentPoint32W(hdc, helpText, wcslen(helpText), &textSize);
|
||||||
int centeredX = drawX + (BITMAP_WIDTH - textSize.cx) / 2;
|
int centeredX = drawX + (BITMAP_WIDTH - textSize.cx) / 2;
|
||||||
|
|
||||||
TextOutW(hdc, centeredX, helpTextY, helpText, wcslen(helpText));
|
TextOutW(hdc, centeredX, helpTextY, helpText, wcslen(helpText));
|
||||||
|
|
||||||
SelectObject(hdc, oldFont);
|
SelectObject(hdc, oldFont);
|
||||||
DeleteObject(helpFont);
|
DeleteObject(helpFont);
|
||||||
|
|
||||||
// Use the stored timestamp
|
// Use the stored timestamp
|
||||||
gui_data_t data = {
|
gui_data_t data = {
|
||||||
.mode = g_display_mode,
|
.mode = g_display_mode,
|
||||||
.color = g_bwr_mode ? 2 : 1,
|
.color = g_bwr_mode ? 2 : 1,
|
||||||
.width = BITMAP_WIDTH,
|
.width = BITMAP_WIDTH,
|
||||||
.height = BITMAP_HEIGHT,
|
.height = BITMAP_HEIGHT,
|
||||||
.timestamp = g_display_time,
|
.timestamp = g_display_time,
|
||||||
.week_start = g_week_start,
|
.week_start = g_week_start,
|
||||||
.temperature = 25,
|
.temperature = 25,
|
||||||
.voltage = 3.2f,
|
.voltage = 3.2f,
|
||||||
.ssid = "NRF_EPD_84AC",
|
.ssid = "NRF_EPD_84AC",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Call DrawGUI to render the interface
|
// Call DrawGUI to render the interface
|
||||||
DrawGUI(&data, DrawBitmap, NULL);
|
DrawGUI(&data, DrawBitmap, NULL);
|
||||||
|
|
||||||
// Clear the global HDC
|
// Clear the global HDC
|
||||||
g_paintHDC = NULL;
|
g_paintHDC = NULL;
|
||||||
|
|
||||||
EndPaint(hwnd, &ps);
|
EndPaint(hwnd, &ps);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
// Toggle display mode with spacebar
|
// Toggle display mode with spacebar
|
||||||
if (wParam == VK_SPACE) {
|
if (wParam == VK_SPACE) {
|
||||||
@@ -256,7 +246,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
g_display_mode = MODE_CALENDAR;
|
g_display_mode = MODE_CALENDAR;
|
||||||
else
|
else
|
||||||
g_display_mode = MODE_CLOCK;
|
g_display_mode = MODE_CLOCK;
|
||||||
|
|
||||||
InvalidateRect(hwnd, NULL, TRUE);
|
InvalidateRect(hwnd, NULL, TRUE);
|
||||||
}
|
}
|
||||||
// Toggle BWR mode with R key
|
// Toggle BWR mode with R key
|
||||||
@@ -267,14 +257,14 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
// Increase week start with W key
|
// Increase week start with W key
|
||||||
else if (wParam == 'W') {
|
else if (wParam == 'W') {
|
||||||
g_week_start++;
|
g_week_start++;
|
||||||
if (g_week_start > 6) g_week_start = 0; // Wrap around
|
if (g_week_start > 6) g_week_start = 0; // Wrap around
|
||||||
InvalidateRect(hwnd, NULL, TRUE);
|
InvalidateRect(hwnd, NULL, TRUE);
|
||||||
}
|
}
|
||||||
// Handle arrow keys for month/day adjustment
|
// Handle arrow keys for month/day adjustment
|
||||||
else if (wParam == VK_UP || wParam == VK_DOWN || wParam == VK_LEFT || wParam == VK_RIGHT) {
|
else if (wParam == VK_UP || wParam == VK_DOWN || wParam == VK_LEFT || wParam == VK_RIGHT) {
|
||||||
// Get the current time structure
|
// Get the current time structure
|
||||||
g_tm_time = *localtime(&g_display_time);
|
g_tm_time = *localtime(&g_display_time);
|
||||||
|
|
||||||
// Up/Down adjusts month
|
// Up/Down adjusts month
|
||||||
if (wParam == VK_UP) {
|
if (wParam == VK_UP) {
|
||||||
g_tm_time.tm_mon++;
|
g_tm_time.tm_mon++;
|
||||||
@@ -282,8 +272,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
g_tm_time.tm_mon = 0;
|
g_tm_time.tm_mon = 0;
|
||||||
g_tm_time.tm_year++;
|
g_tm_time.tm_year++;
|
||||||
}
|
}
|
||||||
}
|
} else if (wParam == VK_DOWN) {
|
||||||
else if (wParam == VK_DOWN) {
|
|
||||||
g_tm_time.tm_mon--;
|
g_tm_time.tm_mon--;
|
||||||
if (g_tm_time.tm_mon < 0) {
|
if (g_tm_time.tm_mon < 0) {
|
||||||
g_tm_time.tm_mon = 11;
|
g_tm_time.tm_mon = 11;
|
||||||
@@ -293,24 +282,23 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
// Left/Right adjusts day
|
// Left/Right adjusts day
|
||||||
else if (wParam == VK_RIGHT) {
|
else if (wParam == VK_RIGHT) {
|
||||||
g_tm_time.tm_mday++;
|
g_tm_time.tm_mday++;
|
||||||
}
|
} else if (wParam == VK_LEFT) {
|
||||||
else if (wParam == VK_LEFT) {
|
|
||||||
g_tm_time.tm_mday--;
|
g_tm_time.tm_mday--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert back to time_t
|
// Convert back to time_t
|
||||||
g_display_time = mktime(&g_tm_time);
|
g_display_time = mktime(&g_tm_time);
|
||||||
|
|
||||||
// Force redraw
|
// Force redraw
|
||||||
InvalidateRect(hwnd, NULL, TRUE);
|
InvalidateRect(hwnd, NULL, TRUE);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
KillTimer(hwnd, 1);
|
KillTimer(hwnd, 1);
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return DefWindowProcW(hwnd, message, wParam, lParam);
|
return DefWindowProcW(hwnd, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
@@ -319,46 +307,40 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
// Main entry point
|
// Main entry point
|
||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
|
||||||
g_hInstance = hInstance;
|
g_hInstance = hInstance;
|
||||||
|
|
||||||
// Register window class
|
// Register window class
|
||||||
WNDCLASSW wc = {0};
|
WNDCLASSW wc = {0};
|
||||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
wc.lpfnWndProc = WndProc;
|
wc.lpfnWndProc = WndProc;
|
||||||
wc.hInstance = hInstance;
|
wc.hInstance = hInstance;
|
||||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
||||||
wc.lpszClassName = L"Emurator";
|
wc.lpszClassName = L"Emurator";
|
||||||
|
|
||||||
if (!RegisterClassW(&wc)) {
|
if (!RegisterClassW(&wc)) {
|
||||||
MessageBoxW(NULL, L"Window Registration Failed!", L"Error", MB_ICONEXCLAMATION | MB_OK);
|
MessageBoxW(NULL, L"Window Registration Failed!", L"Error", MB_ICONEXCLAMATION | MB_OK);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the window
|
// Create the window
|
||||||
g_hwnd = CreateWindowW(
|
g_hwnd = CreateWindowW(L"Emurator", L"模拟器", WS_POPUPWINDOW | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
|
||||||
L"Emurator",
|
CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);
|
||||||
L"模拟器",
|
|
||||||
WS_POPUPWINDOW | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
|
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
|
||||||
WINDOW_WIDTH, WINDOW_HEIGHT,
|
|
||||||
NULL, NULL, hInstance, NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!g_hwnd) {
|
if (!g_hwnd) {
|
||||||
MessageBoxW(NULL, L"Window Creation Failed!", L"Error", MB_ICONEXCLAMATION | MB_OK);
|
MessageBoxW(NULL, L"Window Creation Failed!", L"Error", MB_ICONEXCLAMATION | MB_OK);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show window
|
// Show window
|
||||||
ShowWindow(g_hwnd, nCmdShow);
|
ShowWindow(g_hwnd, nCmdShow);
|
||||||
UpdateWindow(g_hwnd);
|
UpdateWindow(g_hwnd);
|
||||||
|
|
||||||
// Main message loop
|
// Main message loop
|
||||||
MSG msg;
|
MSG msg;
|
||||||
while (GetMessage(&msg, NULL, 0, 0)) {
|
while (GetMessage(&msg, NULL, 0, 0)) {
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)msg.wParam;
|
return (int)msg.wParam;
|
||||||
}
|
}
|
||||||
291
main.c
291
main.c
@@ -12,41 +12,42 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "nordic_common.h"
|
|
||||||
#include "nrf.h"
|
|
||||||
#include "ble.h"
|
#include "ble.h"
|
||||||
#include "ble_hci.h"
|
|
||||||
#include "ble_srv_common.h"
|
|
||||||
#include "ble_advdata.h"
|
#include "ble_advdata.h"
|
||||||
#include "ble_advertising.h"
|
#include "ble_advertising.h"
|
||||||
#include "ble_conn_params.h"
|
#include "ble_conn_params.h"
|
||||||
#include "ble_dfu.h"
|
#include "ble_dfu.h"
|
||||||
|
#include "ble_hci.h"
|
||||||
|
#include "ble_srv_common.h"
|
||||||
|
#include "nordic_common.h"
|
||||||
|
#include "nrf.h"
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
#include "nrf_sdh.h"
|
|
||||||
#include "nrf_sdh_soc.h"
|
|
||||||
#include "nrf_sdh_ble.h"
|
|
||||||
#include "nrf_ble_gatt.h"
|
#include "nrf_ble_gatt.h"
|
||||||
#include "nrf_bootloader_info.h"
|
#include "nrf_bootloader_info.h"
|
||||||
|
#include "nrf_sdh.h"
|
||||||
|
#include "nrf_sdh_ble.h"
|
||||||
|
#include "nrf_sdh_soc.h"
|
||||||
#else
|
#else
|
||||||
#include "fstorage.h"
|
#include "fstorage.h"
|
||||||
#include "softdevice_handler.h"
|
#include "softdevice_handler.h"
|
||||||
#endif
|
#endif
|
||||||
#include "nrf_power.h"
|
#include "EPD_service.h"
|
||||||
#include "app_error.h"
|
#include "app_error.h"
|
||||||
#include "app_timer.h"
|
|
||||||
#include "app_scheduler.h"
|
#include "app_scheduler.h"
|
||||||
|
#include "app_timer.h"
|
||||||
|
#include "main.h"
|
||||||
#include "nrf_drv_gpiote.h"
|
#include "nrf_drv_gpiote.h"
|
||||||
#include "nrf_drv_wdt.h"
|
#include "nrf_drv_wdt.h"
|
||||||
#include "nrf_pwr_mgmt.h"
|
|
||||||
#include "EPD_service.h"
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
#include "nrf_log.h"
|
#include "nrf_log.h"
|
||||||
#include "nrf_log_ctrl.h"
|
#include "nrf_log_ctrl.h"
|
||||||
|
#include "nrf_power.h"
|
||||||
|
#include "nrf_pwr_mgmt.h"
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
#include "nrf_log_default_backends.h"
|
#include "nrf_log_default_backends.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
#define CENTRAL_LINK_COUNT 0 /**< Number of central links used by the application. When changing this number remember to adjust the RAM settings*/
|
#define CENTRAL_LINK_COUNT 0 /**< Number of central links used by the application. When changing this number remember to adjust the RAM settings*/
|
||||||
#define PERIPHERAL_LINK_COUNT 1 /**< Number of peripheral links used by the application. When changing this number remember to adjust the RAM settings*/
|
#define PERIPHERAL_LINK_COUNT 1 /**< Number of peripheral links used by the application. When changing this number remember to adjust the RAM settings*/
|
||||||
|
|
||||||
@@ -100,6 +101,7 @@ APP_TIMER_DEF(m_clock_timer_id);
|
|||||||
static nrf_drv_wdt_channel_id m_wdt_channel_id;
|
static nrf_drv_wdt_channel_id m_wdt_channel_id;
|
||||||
static uint32_t m_wdt_last_feed_time = 0;
|
static uint32_t m_wdt_last_feed_time = 0;
|
||||||
static uint32_t m_resetreas;
|
static uint32_t m_resetreas;
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
/**@brief Callback function for asserts in the SoftDevice.
|
/**@brief Callback function for asserts in the SoftDevice.
|
||||||
*
|
*
|
||||||
@@ -112,28 +114,22 @@ static uint32_t m_resetreas;
|
|||||||
* @param[in] line_num Line number of the failing ASSERT call.
|
* @param[in] line_num Line number of the failing ASSERT call.
|
||||||
* @param[in] file_name File name of the failing ASSERT call.
|
* @param[in] file_name File name of the failing ASSERT call.
|
||||||
*/
|
*/
|
||||||
void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
|
void assert_nrf_callback(uint16_t line_num, const uint8_t* p_file_name) {
|
||||||
{
|
|
||||||
app_error_handler(DEAD_BEEF, line_num, p_file_name);
|
app_error_handler(DEAD_BEEF, line_num, p_file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return current timestamp
|
// return current timestamp
|
||||||
uint32_t timestamp(void)
|
uint32_t timestamp(void) { return m_timestamp; }
|
||||||
{
|
|
||||||
return m_timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the timestamp
|
// set the timestamp
|
||||||
void set_timestamp(uint32_t timestamp)
|
void set_timestamp(uint32_t timestamp) {
|
||||||
{
|
|
||||||
app_timer_stop(m_clock_timer_id);
|
app_timer_stop(m_clock_timer_id);
|
||||||
m_timestamp = timestamp;
|
m_timestamp = timestamp;
|
||||||
app_timer_start(m_clock_timer_id, CLOCK_TIMER_INTERVAL, NULL);
|
app_timer_start(m_clock_timer_id, CLOCK_TIMER_INTERVAL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reload the wdt channel
|
// reload the wdt channel
|
||||||
void app_feed_wdt(void)
|
void app_feed_wdt(void) {
|
||||||
{
|
|
||||||
if (m_timestamp - m_wdt_last_feed_time >= 30) {
|
if (m_timestamp - m_wdt_last_feed_time >= 30) {
|
||||||
NRF_LOG_DEBUG("Feed WDT\n");
|
NRF_LOG_DEBUG("Feed WDT\n");
|
||||||
nrf_drv_wdt_channel_feed(m_wdt_channel_id);
|
nrf_drv_wdt_channel_feed(m_wdt_channel_id);
|
||||||
@@ -142,39 +138,32 @@ void app_feed_wdt(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void * p_context)
|
static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void* p_context) {
|
||||||
{
|
if (state == NRF_SDH_EVT_STATE_DISABLED) {
|
||||||
if (state == NRF_SDH_EVT_STATE_DISABLED)
|
|
||||||
{
|
|
||||||
// Softdevice was disabled before going into reset. Inform bootloader to skip CRC on next boot.
|
// Softdevice was disabled before going into reset. Inform bootloader to skip CRC on next boot.
|
||||||
nrf_power_gpregret2_set(BOOTLOADER_DFU_SKIP_CRC);
|
nrf_power_gpregret2_set(BOOTLOADER_DFU_SKIP_CRC);
|
||||||
|
|
||||||
//Go to system off.
|
// Go to system off.
|
||||||
nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
|
nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nrf_sdh state observer. */
|
/* nrf_sdh state observer. */
|
||||||
NRF_SDH_STATE_OBSERVER(m_buttonless_dfu_state_obs, 0) =
|
NRF_SDH_STATE_OBSERVER(m_buttonless_dfu_state_obs, 0) = {
|
||||||
{
|
|
||||||
.handler = buttonless_dfu_sdh_state_observer,
|
.handler = buttonless_dfu_sdh_state_observer,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void advertising_config_get(ble_adv_modes_config_t * p_config)
|
static void advertising_config_get(ble_adv_modes_config_t* p_config) {
|
||||||
{
|
|
||||||
memset(p_config, 0, sizeof(ble_adv_modes_config_t));
|
memset(p_config, 0, sizeof(ble_adv_modes_config_t));
|
||||||
|
|
||||||
p_config->ble_adv_fast_enabled = true;
|
p_config->ble_adv_fast_enabled = true;
|
||||||
p_config->ble_adv_fast_interval = APP_ADV_INTERVAL;
|
p_config->ble_adv_fast_interval = APP_ADV_INTERVAL;
|
||||||
p_config->ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS * 100;
|
p_config->ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event)
|
static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event) {
|
||||||
{
|
switch (event) {
|
||||||
switch (event)
|
case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE: {
|
||||||
{
|
|
||||||
case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
|
|
||||||
{
|
|
||||||
NRF_LOG_INFO("Device is preparing to enter bootloader mode.");
|
NRF_LOG_INFO("Device is preparing to enter bootloader mode.");
|
||||||
|
|
||||||
// Prevent device from advertising on disconnect.
|
// Prevent device from advertising on disconnect.
|
||||||
@@ -210,10 +199,8 @@ static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void ble_dfu_evt_handler(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
|
static void ble_dfu_evt_handler(ble_dfu_t* p_dfu, ble_dfu_evt_t* p_evt) {
|
||||||
{
|
switch (p_evt->type) {
|
||||||
switch (p_evt->type)
|
|
||||||
{
|
|
||||||
case BLE_DFU_EVT_INDICATION_DISABLED:
|
case BLE_DFU_EVT_INDICATION_DISABLED:
|
||||||
NRF_LOG_INFO("Indication for BLE_DFU is disabled\r\n");
|
NRF_LOG_INFO("Indication for BLE_DFU is disabled\r\n");
|
||||||
break;
|
break;
|
||||||
@@ -232,8 +219,7 @@ static void ble_dfu_evt_handler(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void clock_timer_timeout_handler(void * p_context)
|
static void clock_timer_timeout_handler(void* p_context) {
|
||||||
{
|
|
||||||
UNUSED_PARAMETER(p_context);
|
UNUSED_PARAMETER(p_context);
|
||||||
|
|
||||||
m_timestamp++;
|
m_timestamp++;
|
||||||
@@ -243,17 +229,13 @@ static void clock_timer_timeout_handler(void * p_context)
|
|||||||
|
|
||||||
/**@brief Function for the Event Scheduler initialization.
|
/**@brief Function for the Event Scheduler initialization.
|
||||||
*/
|
*/
|
||||||
static void scheduler_init(void)
|
static void scheduler_init(void) { APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE); }
|
||||||
{
|
|
||||||
APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Function for the Timer initialization.
|
/**@brief Function for the Timer initialization.
|
||||||
*
|
*
|
||||||
* @details Initializes the timer module. This creates and starts application timers.
|
* @details Initializes the timer module. This creates and starts application timers.
|
||||||
*/
|
*/
|
||||||
static void timers_init(void)
|
static void timers_init(void) {
|
||||||
{
|
|
||||||
// Initialize timer module.
|
// Initialize timer module.
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
APP_ERROR_CHECK(app_timer_init());
|
APP_ERROR_CHECK(app_timer_init());
|
||||||
@@ -261,15 +243,12 @@ static void timers_init(void)
|
|||||||
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
|
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
|
||||||
#endif
|
#endif
|
||||||
// Create timers.
|
// Create timers.
|
||||||
APP_ERROR_CHECK(app_timer_create(&m_clock_timer_id,
|
APP_ERROR_CHECK(app_timer_create(&m_clock_timer_id, APP_TIMER_MODE_REPEATED, clock_timer_timeout_handler));
|
||||||
APP_TIMER_MODE_REPEATED,
|
|
||||||
clock_timer_timeout_handler));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**@brief Function for starting application timers.
|
/**@brief Function for starting application timers.
|
||||||
*/
|
*/
|
||||||
static void application_timers_start(void)
|
static void application_timers_start(void) {
|
||||||
{
|
|
||||||
// Start application timers.
|
// Start application timers.
|
||||||
APP_ERROR_CHECK(app_timer_start(m_clock_timer_id, CLOCK_TIMER_INTERVAL, NULL));
|
APP_ERROR_CHECK(app_timer_start(m_clock_timer_id, CLOCK_TIMER_INTERVAL, NULL));
|
||||||
}
|
}
|
||||||
@@ -278,8 +257,7 @@ static void application_timers_start(void)
|
|||||||
*
|
*
|
||||||
* @note This function will not return.
|
* @note This function will not return.
|
||||||
*/
|
*/
|
||||||
void sleep_mode_enter(void)
|
void sleep_mode_enter(void) {
|
||||||
{
|
|
||||||
NRF_LOG_DEBUG("Entering deep sleep mode\n");
|
NRF_LOG_DEBUG("Entering deep sleep mode\n");
|
||||||
NRF_LOG_FINAL_FLUSH();
|
NRF_LOG_FINAL_FLUSH();
|
||||||
nrf_delay_ms(100);
|
nrf_delay_ms(100);
|
||||||
@@ -290,8 +268,7 @@ void sleep_mode_enter(void)
|
|||||||
|
|
||||||
/**@brief Function for initializing services that will be used by the application.
|
/**@brief Function for initializing services that will be used by the application.
|
||||||
*/
|
*/
|
||||||
static void services_init(void)
|
static void services_init(void) {
|
||||||
{
|
|
||||||
// Initialize EPD Service.
|
// Initialize EPD Service.
|
||||||
memset(&m_epd, 0, sizeof(ble_epd_t));
|
memset(&m_epd, 0, sizeof(ble_epd_t));
|
||||||
APP_ERROR_CHECK(ble_epd_init(&m_epd));
|
APP_ERROR_CHECK(ble_epd_init(&m_epd));
|
||||||
@@ -304,9 +281,9 @@ static void services_init(void)
|
|||||||
// Initialize the Device Firmware Update Service.
|
// Initialize the Device Firmware Update Service.
|
||||||
ble_dfu_init_t dfus_init;
|
ble_dfu_init_t dfus_init;
|
||||||
memset(&dfus_init, 0, sizeof(dfus_init));
|
memset(&dfus_init, 0, sizeof(dfus_init));
|
||||||
dfus_init.evt_handler = ble_dfu_evt_handler;
|
dfus_init.evt_handler = ble_dfu_evt_handler;
|
||||||
dfus_init.ctrl_point_security_req_write_perm = SEC_SIGNED;
|
dfus_init.ctrl_point_security_req_write_perm = SEC_SIGNED;
|
||||||
dfus_init.ctrl_point_security_req_cccd_write_perm = SEC_SIGNED;
|
dfus_init.ctrl_point_security_req_cccd_write_perm = SEC_SIGNED;
|
||||||
APP_ERROR_CHECK(ble_dfu_init(&m_dfus, &dfus_init));
|
APP_ERROR_CHECK(ble_dfu_init(&m_dfus, &dfus_init));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -316,11 +293,10 @@ static void services_init(void)
|
|||||||
* @details This function will set up all the necessary GAP (Generic Access Profile) parameters of
|
* @details This function will set up all the necessary GAP (Generic Access Profile) parameters of
|
||||||
* the device. It also sets the permissions and appearance.
|
* the device. It also sets the permissions and appearance.
|
||||||
*/
|
*/
|
||||||
static void gap_params_init(void)
|
static void gap_params_init(void) {
|
||||||
{
|
char device_name[20];
|
||||||
char device_name[20];
|
ble_gap_addr_t addr;
|
||||||
ble_gap_addr_t addr;
|
ble_gap_conn_params_t gap_conn_params;
|
||||||
ble_gap_conn_params_t gap_conn_params;
|
|
||||||
ble_gap_conn_sec_mode_t sec_mode;
|
ble_gap_conn_sec_mode_t sec_mode;
|
||||||
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
|
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
|
||||||
@@ -330,21 +306,18 @@ static void gap_params_init(void)
|
|||||||
APP_ERROR_CHECK(sd_ble_gap_address_get(&addr));
|
APP_ERROR_CHECK(sd_ble_gap_address_get(&addr));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NRF_LOG_INFO("Bluetooth MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
NRF_LOG_INFO("Bluetooth MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n", addr.addr[5], addr.addr[4], addr.addr[3],
|
||||||
addr.addr[5], addr.addr[4], addr.addr[3],
|
addr.addr[2], addr.addr[1], addr.addr[0]);
|
||||||
addr.addr[2], addr.addr[1], addr.addr[0]);
|
|
||||||
|
|
||||||
snprintf(device_name, 20, "%s_%02X%02X", DEVICE_NAME, addr.addr[1],addr.addr[0]);
|
snprintf(device_name, 20, "%s_%02X%02X", DEVICE_NAME, addr.addr[1], addr.addr[0]);
|
||||||
APP_ERROR_CHECK(sd_ble_gap_device_name_set(&sec_mode,
|
APP_ERROR_CHECK(sd_ble_gap_device_name_set(&sec_mode, (const uint8_t*)device_name, strlen(device_name)));
|
||||||
(const uint8_t *)device_name,
|
|
||||||
strlen(device_name)));
|
|
||||||
|
|
||||||
memset(&gap_conn_params, 0, sizeof(gap_conn_params));
|
memset(&gap_conn_params, 0, sizeof(gap_conn_params));
|
||||||
|
|
||||||
gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
|
gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
|
||||||
gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
|
gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
|
||||||
gap_conn_params.slave_latency = SLAVE_LATENCY;
|
gap_conn_params.slave_latency = SLAVE_LATENCY;
|
||||||
gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;
|
gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;
|
||||||
|
|
||||||
APP_ERROR_CHECK(sd_ble_gap_ppcp_set(&gap_conn_params));
|
APP_ERROR_CHECK(sd_ble_gap_ppcp_set(&gap_conn_params));
|
||||||
}
|
}
|
||||||
@@ -360,48 +333,38 @@ static void gap_params_init(void)
|
|||||||
*
|
*
|
||||||
* @param[in] p_evt Event received from the Connection Parameters Module.
|
* @param[in] p_evt Event received from the Connection Parameters Module.
|
||||||
*/
|
*/
|
||||||
static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
|
static void on_conn_params_evt(ble_conn_params_evt_t* p_evt) {
|
||||||
{
|
if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED) {
|
||||||
if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
|
|
||||||
{
|
|
||||||
APP_ERROR_CHECK(sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE));
|
APP_ERROR_CHECK(sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for handling errors from the Connection Parameters module.
|
/**@brief Function for handling errors from the Connection Parameters module.
|
||||||
*
|
*
|
||||||
* @param[in] nrf_error Error code containing information about what went wrong.
|
* @param[in] nrf_error Error code containing information about what went wrong.
|
||||||
*/
|
*/
|
||||||
static void conn_params_error_handler(uint32_t nrf_error)
|
static void conn_params_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); }
|
||||||
{
|
|
||||||
APP_ERROR_HANDLER(nrf_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for initializing the Connection Parameters module.
|
/**@brief Function for initializing the Connection Parameters module.
|
||||||
*/
|
*/
|
||||||
static void conn_params_init(void)
|
static void conn_params_init(void) {
|
||||||
{
|
|
||||||
ble_conn_params_init_t cp_init;
|
ble_conn_params_init_t cp_init;
|
||||||
|
|
||||||
memset(&cp_init, 0, sizeof(cp_init));
|
memset(&cp_init, 0, sizeof(cp_init));
|
||||||
|
|
||||||
cp_init.p_conn_params = NULL;
|
cp_init.p_conn_params = NULL;
|
||||||
cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
|
cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
|
||||||
cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;
|
cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;
|
||||||
cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;
|
cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;
|
||||||
cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;
|
cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;
|
||||||
cp_init.disconnect_on_fail = false;
|
cp_init.disconnect_on_fail = false;
|
||||||
cp_init.evt_handler = on_conn_params_evt;
|
cp_init.evt_handler = on_conn_params_evt;
|
||||||
cp_init.error_handler = conn_params_error_handler;
|
cp_init.error_handler = conn_params_error_handler;
|
||||||
|
|
||||||
APP_ERROR_CHECK(ble_conn_params_init(&cp_init));
|
APP_ERROR_CHECK(ble_conn_params_init(&cp_init));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void advertising_start(void) {
|
||||||
static void advertising_start(void)
|
|
||||||
{
|
|
||||||
NRF_LOG_INFO("advertising start\n");
|
NRF_LOG_INFO("advertising start\n");
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
APP_ERROR_CHECK(ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST));
|
APP_ERROR_CHECK(ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST));
|
||||||
@@ -432,17 +395,14 @@ static void setup_wakeup_pin(nrf_drv_gpiote_pin_t pin) {
|
|||||||
nrf_drv_gpiote_in_event_enable(pin, true);
|
nrf_drv_gpiote_in_event_enable(pin, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for handling advertising events.
|
/**@brief Function for handling advertising events.
|
||||||
*
|
*
|
||||||
* @details This function will be called for advertising events which are passed to the application.
|
* @details This function will be called for advertising events which are passed to the application.
|
||||||
*
|
*
|
||||||
* @param[in] ble_adv_evt Advertising event.
|
* @param[in] ble_adv_evt Advertising event.
|
||||||
*/
|
*/
|
||||||
static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
|
static void on_adv_evt(ble_adv_evt_t ble_adv_evt) {
|
||||||
{
|
switch (ble_adv_evt) {
|
||||||
switch (ble_adv_evt)
|
|
||||||
{
|
|
||||||
case BLE_ADV_EVT_FAST:
|
case BLE_ADV_EVT_FAST:
|
||||||
break;
|
break;
|
||||||
case BLE_ADV_EVT_IDLE:
|
case BLE_ADV_EVT_IDLE:
|
||||||
@@ -465,10 +425,8 @@ static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
|
|||||||
*
|
*
|
||||||
* @param[in] p_ble_evt SoftDevice event.
|
* @param[in] p_ble_evt SoftDevice event.
|
||||||
*/
|
*/
|
||||||
static void on_ble_evt(ble_evt_t * p_ble_evt)
|
static void on_ble_evt(ble_evt_t* p_ble_evt) {
|
||||||
{
|
switch (p_ble_evt->header.evt_id) {
|
||||||
switch (p_ble_evt->header.evt_id)
|
|
||||||
{
|
|
||||||
case BLE_GAP_EVT_CONNECTED:
|
case BLE_GAP_EVT_CONNECTED:
|
||||||
NRF_LOG_INFO("CONNECTED\n");
|
NRF_LOG_INFO("CONNECTED\n");
|
||||||
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
|
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
|
||||||
@@ -482,11 +440,9 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
|
case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
|
||||||
{
|
|
||||||
NRF_LOG_DEBUG("PHY update request.");
|
NRF_LOG_DEBUG("PHY update request.");
|
||||||
ble_gap_phys_t const phys =
|
ble_gap_phys_t const phys = {
|
||||||
{
|
|
||||||
.rx_phys = BLE_GAP_PHY_AUTO,
|
.rx_phys = BLE_GAP_PHY_AUTO,
|
||||||
.tx_phys = BLE_GAP_PHY_AUTO,
|
.tx_phys = BLE_GAP_PHY_AUTO,
|
||||||
};
|
};
|
||||||
@@ -496,24 +452,25 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
|
|||||||
|
|
||||||
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
|
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
|
||||||
// Pairing not supported
|
// Pairing not supported
|
||||||
APP_ERROR_CHECK(sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL));
|
APP_ERROR_CHECK(
|
||||||
|
sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLE_GATTS_EVT_SYS_ATTR_MISSING:
|
case BLE_GATTS_EVT_SYS_ATTR_MISSING:
|
||||||
// No system attributes have been stored.
|
// No system attributes have been stored.
|
||||||
APP_ERROR_CHECK(sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0));
|
APP_ERROR_CHECK(sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLE_GATTC_EVT_TIMEOUT:
|
case BLE_GATTC_EVT_TIMEOUT:
|
||||||
// Disconnect on GATT Client timeout event.
|
// Disconnect on GATT Client timeout event.
|
||||||
APP_ERROR_CHECK(sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
|
APP_ERROR_CHECK(
|
||||||
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
|
sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLE_GATTS_EVT_TIMEOUT:
|
case BLE_GATTS_EVT_TIMEOUT:
|
||||||
// Disconnect on GATT Server timeout event.
|
// Disconnect on GATT Server timeout event.
|
||||||
APP_ERROR_CHECK(sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
|
APP_ERROR_CHECK(
|
||||||
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
|
sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -522,18 +479,16 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
/**@brief Function for handling BLE events.
|
/**@brief Function for handling BLE events.
|
||||||
*
|
*
|
||||||
* @param[in] p_ble_evt Bluetooth stack event.
|
* @param[in] p_ble_evt Bluetooth stack event.
|
||||||
* @param[in] p_context Unused.
|
* @param[in] p_context Unused.
|
||||||
*/
|
*/
|
||||||
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
|
static void ble_evt_handler(ble_evt_t const* p_ble_evt, void* p_context) {
|
||||||
{
|
|
||||||
UNUSED_PARAMETER(p_context);
|
UNUSED_PARAMETER(p_context);
|
||||||
|
|
||||||
on_ble_evt((ble_evt_t *)p_ble_evt);
|
on_ble_evt((ble_evt_t*)p_ble_evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -545,8 +500,7 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
|
|||||||
*
|
*
|
||||||
* @param[in] p_ble_evt SoftDevice event.
|
* @param[in] p_ble_evt SoftDevice event.
|
||||||
*/
|
*/
|
||||||
static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
|
static void ble_evt_dispatch(ble_evt_t* p_ble_evt) {
|
||||||
{
|
|
||||||
ble_conn_params_on_ble_evt(p_ble_evt);
|
ble_conn_params_on_ble_evt(p_ble_evt);
|
||||||
ble_epd_on_ble_evt(&m_epd, p_ble_evt);
|
ble_epd_on_ble_evt(&m_epd, p_ble_evt);
|
||||||
on_ble_evt(p_ble_evt);
|
on_ble_evt(p_ble_evt);
|
||||||
@@ -554,7 +508,6 @@ static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
|
|||||||
ble_dfu_on_ble_evt(&m_dfus, p_ble_evt);
|
ble_dfu_on_ble_evt(&m_dfus, p_ble_evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for dispatching a system event to interested modules.
|
/**@brief Function for dispatching a system event to interested modules.
|
||||||
*
|
*
|
||||||
* @details This function is called from the System event interrupt handler after a system
|
* @details This function is called from the System event interrupt handler after a system
|
||||||
@@ -562,8 +515,7 @@ static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
|
|||||||
*
|
*
|
||||||
* @param[in] sys_evt System stack event.
|
* @param[in] sys_evt System stack event.
|
||||||
*/
|
*/
|
||||||
static void sys_evt_dispatch(uint32_t sys_evt)
|
static void sys_evt_dispatch(uint32_t sys_evt) {
|
||||||
{
|
|
||||||
// Dispatch the system event to the fstorage module, where it will be
|
// Dispatch the system event to the fstorage module, where it will be
|
||||||
// dispatched to the Flash Data Storage (FDS) module.
|
// dispatched to the Flash Data Storage (FDS) module.
|
||||||
fs_sys_event_handler(sys_evt);
|
fs_sys_event_handler(sys_evt);
|
||||||
@@ -579,8 +531,7 @@ static void sys_evt_dispatch(uint32_t sys_evt)
|
|||||||
*
|
*
|
||||||
* @details This function initializes the SoftDevice and the BLE event interrupt.
|
* @details This function initializes the SoftDevice and the BLE event interrupt.
|
||||||
*/
|
*/
|
||||||
static void ble_stack_init(void)
|
static void ble_stack_init(void) {
|
||||||
{
|
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
APP_ERROR_CHECK(nrf_sdh_enable_request());
|
APP_ERROR_CHECK(nrf_sdh_enable_request());
|
||||||
|
|
||||||
@@ -595,20 +546,19 @@ static void ble_stack_init(void)
|
|||||||
// Register a handler for BLE events.
|
// Register a handler for BLE events.
|
||||||
NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
|
NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
|
||||||
#else
|
#else
|
||||||
nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;
|
nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;
|
||||||
|
|
||||||
// Initialize the SoftDevice handler module.
|
// Initialize the SoftDevice handler module.
|
||||||
SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);
|
SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);
|
||||||
|
|
||||||
ble_enable_params_t ble_enable_params;
|
ble_enable_params_t ble_enable_params;
|
||||||
APP_ERROR_CHECK(softdevice_enable_get_default_config(CENTRAL_LINK_COUNT,
|
APP_ERROR_CHECK(
|
||||||
PERIPHERAL_LINK_COUNT,
|
softdevice_enable_get_default_config(CENTRAL_LINK_COUNT, PERIPHERAL_LINK_COUNT, &ble_enable_params));
|
||||||
&ble_enable_params));
|
|
||||||
ble_enable_params.common_enable_params.vs_uuid_count = 2;
|
ble_enable_params.common_enable_params.vs_uuid_count = 2;
|
||||||
|
|
||||||
// Check the ram settings against the used number of links
|
// Check the ram settings against the used number of links
|
||||||
CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT,PERIPHERAL_LINK_COUNT);
|
CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT, PERIPHERAL_LINK_COUNT);
|
||||||
|
|
||||||
// Enable BLE stack.
|
// Enable BLE stack.
|
||||||
APP_ERROR_CHECK(softdevice_enable(&ble_enable_params));
|
APP_ERROR_CHECK(softdevice_enable(&ble_enable_params));
|
||||||
|
|
||||||
@@ -622,29 +572,23 @@ static void ble_stack_init(void)
|
|||||||
|
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
/**@brief Function for handling events from the GATT library. */
|
/**@brief Function for handling events from the GATT library. */
|
||||||
void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
|
void gatt_evt_handler(nrf_ble_gatt_t* p_gatt, nrf_ble_gatt_evt_t const* p_evt) {
|
||||||
{
|
if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)) {
|
||||||
if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
|
|
||||||
{
|
|
||||||
m_epd.max_data_len = p_evt->params.att_mtu_effective - 3;
|
m_epd.max_data_len = p_evt->params.att_mtu_effective - 3;
|
||||||
NRF_LOG_INFO("Data len is set to 0x%X(%d)", m_epd.max_data_len, m_epd.max_data_len);
|
NRF_LOG_INFO("Data len is set to 0x%X(%d)", m_epd.max_data_len, m_epd.max_data_len);
|
||||||
}
|
}
|
||||||
NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x",
|
NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x", p_gatt->att_mtu_desired_central,
|
||||||
p_gatt->att_mtu_desired_central,
|
|
||||||
p_gatt->att_mtu_desired_periph);
|
p_gatt->att_mtu_desired_periph);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for initializing the GATT library. */
|
/**@brief Function for initializing the GATT library. */
|
||||||
void gatt_init(void)
|
void gatt_init(void) {
|
||||||
{
|
|
||||||
APP_ERROR_CHECK(nrf_ble_gatt_init(&m_gatt, gatt_evt_handler));
|
APP_ERROR_CHECK(nrf_ble_gatt_init(&m_gatt, gatt_evt_handler));
|
||||||
APP_ERROR_CHECK(nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE));
|
APP_ERROR_CHECK(nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Set BW Config to HIGH.
|
// Set BW Config to HIGH.
|
||||||
static void ble_options_set(void)
|
static void ble_options_set(void) {
|
||||||
{
|
|
||||||
ble_opt_t ble_opt;
|
ble_opt_t ble_opt;
|
||||||
|
|
||||||
memset(&ble_opt, 0, sizeof(ble_opt));
|
memset(&ble_opt, 0, sizeof(ble_opt));
|
||||||
@@ -659,47 +603,46 @@ static void ble_options_set(void)
|
|||||||
|
|
||||||
/**@brief Function for initializing the Advertising functionality.
|
/**@brief Function for initializing the Advertising functionality.
|
||||||
*/
|
*/
|
||||||
static void advertising_init(void)
|
static void advertising_init(void) {
|
||||||
{
|
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
ble_advertising_init_t init;
|
ble_advertising_init_t init;
|
||||||
|
|
||||||
memset(&init, 0, sizeof(init));
|
memset(&init, 0, sizeof(init));
|
||||||
|
|
||||||
init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
|
init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
|
||||||
init.advdata.include_appearance = false;
|
init.advdata.include_appearance = false;
|
||||||
init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
|
init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
|
||||||
|
|
||||||
init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
|
init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
|
||||||
init.srdata.uuids_complete.p_uuids = m_adv_uuids;
|
init.srdata.uuids_complete.p_uuids = m_adv_uuids;
|
||||||
|
|
||||||
init.config.ble_adv_fast_enabled = true;
|
init.config.ble_adv_fast_enabled = true;
|
||||||
init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
|
init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
|
||||||
init.config.ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS * 100;
|
init.config.ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS * 100;
|
||||||
init.evt_handler = on_adv_evt;
|
init.evt_handler = on_adv_evt;
|
||||||
|
|
||||||
APP_ERROR_CHECK(ble_advertising_init(&m_advertising, &init));
|
APP_ERROR_CHECK(ble_advertising_init(&m_advertising, &init));
|
||||||
|
|
||||||
ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
|
ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
|
||||||
#else
|
#else
|
||||||
ble_advdata_t advdata;
|
ble_advdata_t advdata;
|
||||||
ble_advdata_t scanrsp;
|
ble_advdata_t scanrsp;
|
||||||
ble_adv_modes_config_t options;
|
ble_adv_modes_config_t options;
|
||||||
|
|
||||||
// Build advertising data struct to pass into @ref ble_advertising_init.
|
// Build advertising data struct to pass into @ref ble_advertising_init.
|
||||||
memset(&advdata, 0, sizeof(advdata));
|
memset(&advdata, 0, sizeof(advdata));
|
||||||
advdata.name_type = BLE_ADVDATA_FULL_NAME;
|
advdata.name_type = BLE_ADVDATA_FULL_NAME;
|
||||||
advdata.include_appearance = false;
|
advdata.include_appearance = false;
|
||||||
advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
|
advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
|
||||||
|
|
||||||
memset(&scanrsp, 0, sizeof(scanrsp));
|
memset(&scanrsp, 0, sizeof(scanrsp));
|
||||||
scanrsp.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
|
scanrsp.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
|
||||||
scanrsp.uuids_complete.p_uuids = m_adv_uuids;
|
scanrsp.uuids_complete.p_uuids = m_adv_uuids;
|
||||||
|
|
||||||
memset(&options, 0, sizeof(options));
|
memset(&options, 0, sizeof(options));
|
||||||
options.ble_adv_fast_enabled = true;
|
options.ble_adv_fast_enabled = true;
|
||||||
options.ble_adv_fast_interval = APP_ADV_INTERVAL;
|
options.ble_adv_fast_interval = APP_ADV_INTERVAL;
|
||||||
options.ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS;
|
options.ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS;
|
||||||
|
|
||||||
APP_ERROR_CHECK(ble_advertising_init(&advdata, &scanrsp, &options, on_adv_evt, NULL));
|
APP_ERROR_CHECK(ble_advertising_init(&advdata, &scanrsp, &options, on_adv_evt, NULL));
|
||||||
#endif
|
#endif
|
||||||
@@ -707,8 +650,7 @@ static void advertising_init(void)
|
|||||||
|
|
||||||
/**@brief Function for initializing the nrf log module.
|
/**@brief Function for initializing the nrf log module.
|
||||||
*/
|
*/
|
||||||
static void log_init(void)
|
static void log_init(void) {
|
||||||
{
|
|
||||||
APP_ERROR_CHECK(NRF_LOG_INIT(timestamp));
|
APP_ERROR_CHECK(NRF_LOG_INIT(timestamp));
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
NRF_LOG_DEFAULT_BACKENDS_INIT();
|
NRF_LOG_DEFAULT_BACKENDS_INIT();
|
||||||
@@ -717,8 +659,7 @@ static void log_init(void)
|
|||||||
|
|
||||||
/**@brief Function for initializing power management.
|
/**@brief Function for initializing power management.
|
||||||
*/
|
*/
|
||||||
static void power_management_init(void)
|
static void power_management_init(void) {
|
||||||
{
|
|
||||||
#if defined(S112)
|
#if defined(S112)
|
||||||
APP_ERROR_CHECK(nrf_pwr_mgmt_init());
|
APP_ERROR_CHECK(nrf_pwr_mgmt_init());
|
||||||
#else
|
#else
|
||||||
@@ -730,28 +671,25 @@ static void power_management_init(void)
|
|||||||
*
|
*
|
||||||
* @details If there is no pending log operation, then sleep until next the next event occurs.
|
* @details If there is no pending log operation, then sleep until next the next event occurs.
|
||||||
*/
|
*/
|
||||||
static void idle_state_handle(void)
|
static void idle_state_handle(void) {
|
||||||
{
|
|
||||||
app_feed_wdt();
|
app_feed_wdt();
|
||||||
|
|
||||||
if (NRF_LOG_PROCESS() == false)
|
if (NRF_LOG_PROCESS() == false) nrf_pwr_mgmt_run();
|
||||||
nrf_pwr_mgmt_run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief WDT events handler.
|
* @brief WDT events handler.
|
||||||
*/
|
*/
|
||||||
void wdt_event_handler(void)
|
void wdt_event_handler(void) {
|
||||||
{
|
// NOTE: The max amount of time we can spend in WDT interrupt is two cycles of 32768[Hz] clock - after that, reset
|
||||||
//NOTE: The max amount of time we can spend in WDT interrupt is two cycles of 32768[Hz] clock - after that, reset occurs
|
// occurs
|
||||||
NRF_LOG_ERROR("WDT Rest!\r\n");
|
NRF_LOG_ERROR("WDT Rest!\r\n");
|
||||||
NRF_LOG_FINAL_FLUSH();
|
NRF_LOG_FINAL_FLUSH();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**@brief Function for application main entry.
|
/**@brief Function for application main entry.
|
||||||
*/
|
*/
|
||||||
int main(void)
|
int main(void) {
|
||||||
{
|
|
||||||
log_init();
|
log_init();
|
||||||
|
|
||||||
// Save reset reason.
|
// Save reset reason.
|
||||||
@@ -798,8 +736,7 @@ int main(void)
|
|||||||
ble_epd_on_timer(&m_epd, m_timestamp, true);
|
ble_epd_on_timer(&m_epd, m_timestamp, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;) {
|
||||||
{
|
|
||||||
app_sched_execute();
|
app_sched_execute();
|
||||||
idle_state_handle();
|
idle_state_handle();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user