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 <string.h>
|
||||
|
||||
#include "app_scheduler.h"
|
||||
#include "fds.h"
|
||||
#include "nordic_common.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
#define CONFIG_FILE_ID 0x0000
|
||||
#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);
|
||||
}
|
||||
|
||||
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");
|
||||
fds_gc();
|
||||
}
|
||||
|
||||
void epd_config_init(epd_config_t *cfg)
|
||||
{
|
||||
void epd_config_init(epd_config_t* cfg) {
|
||||
ret_code_t ret;
|
||||
|
||||
ret = fds_register(fds_evt_handler);
|
||||
@@ -38,8 +37,7 @@ void epd_config_init(epd_config_t *cfg)
|
||||
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_record_desc_t record_desc;
|
||||
fds_find_token_t ftok;
|
||||
@@ -64,8 +62,7 @@ void epd_config_read(epd_config_t *cfg)
|
||||
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;
|
||||
fds_record_t record;
|
||||
fds_record_desc_t record_desc;
|
||||
@@ -93,13 +90,11 @@ void epd_config_write(epd_config_t *cfg)
|
||||
|
||||
if (ret != NRF_SUCCESS) {
|
||||
NRF_LOG_ERROR("epd_config_save: record write/update failed, code=%d\n", ret);
|
||||
if (ret == FDS_ERR_NO_SPACE_IN_FLASH)
|
||||
app_sched_event_put(NULL, 0, run_fds_gc);
|
||||
if (ret == FDS_ERR_NO_SPACE_IN_FLASH) 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;
|
||||
fds_record_desc_t record_desc;
|
||||
fds_find_token_t ftok;
|
||||
@@ -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++) {
|
||||
if (((uint8_t *)cfg)[i] != 0xFF)
|
||||
return false;
|
||||
if (((uint8_t*)cfg)[i] != 0xFF) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint8_t mosi_pin;
|
||||
uint8_t sclk_pin;
|
||||
uint8_t cs_pin;
|
||||
|
||||
118
EPD/EPD_driver.c
118
EPD/EPD_driver.c
@@ -1,6 +1,7 @@
|
||||
#include "EPD_driver.h"
|
||||
|
||||
#include "app_error.h"
|
||||
#include "nrf_drv_spi.h"
|
||||
#include "EPD_driver.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
@@ -24,19 +25,15 @@ static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI i
|
||||
#define HAL_SPI_INSTANCE spi.u.spi.p_reg
|
||||
#else
|
||||
#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);
|
||||
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
|
||||
|
||||
// Arduino like function wrappers
|
||||
void pinMode(uint32_t pin, uint32_t mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
void pinMode(uint32_t pin, uint32_t mode) {
|
||||
switch (mode) {
|
||||
case INPUT:
|
||||
nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_NOPULL);
|
||||
break;
|
||||
@@ -59,8 +56,7 @@ void pinMode(uint32_t pin, uint32_t mode)
|
||||
// GPIO
|
||||
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;
|
||||
EPD_MOSI_PIN = cfg->mosi_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;
|
||||
}
|
||||
|
||||
void EPD_GPIO_Init(void)
|
||||
{
|
||||
void EPD_GPIO_Init(void) {
|
||||
if (m_driver_refs++ > 0) return;
|
||||
|
||||
pinMode(EPD_DC_PIN, OUTPUT);
|
||||
@@ -103,14 +98,12 @@ void EPD_GPIO_Init(void)
|
||||
digitalWrite(EPD_DC_PIN, LOW);
|
||||
digitalWrite(EPD_RST_PIN, HIGH);
|
||||
|
||||
if (EPD_LED_PIN != 0xFF)
|
||||
pinMode(EPD_LED_PIN, OUTPUT);
|
||||
if (EPD_LED_PIN != 0xFF) pinMode(EPD_LED_PIN, OUTPUT);
|
||||
|
||||
EPD_LED_ON();
|
||||
}
|
||||
|
||||
void EPD_GPIO_Uninit(void)
|
||||
{
|
||||
void EPD_GPIO_Uninit(void) {
|
||||
if (--m_driver_refs > 0) return;
|
||||
|
||||
EPD_LED_OFF();
|
||||
@@ -120,8 +113,7 @@ void EPD_GPIO_Uninit(void)
|
||||
digitalWrite(EPD_DC_PIN, LOW);
|
||||
digitalWrite(EPD_CS_PIN, LOW);
|
||||
digitalWrite(EPD_RST_PIN, LOW);
|
||||
if (EPD_EN_PIN != 0xFF)
|
||||
digitalWrite(EPD_EN_PIN, LOW);
|
||||
if (EPD_EN_PIN != 0xFF) digitalWrite(EPD_EN_PIN, LOW);
|
||||
|
||||
// reset pin state
|
||||
pinMode(EPD_MOSI_PIN, DEFAULT);
|
||||
@@ -136,8 +128,7 @@ void EPD_GPIO_Uninit(void)
|
||||
}
|
||||
|
||||
// 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);
|
||||
if (dir != NRF_GPIO_PIN_DIR_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));
|
||||
}
|
||||
|
||||
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);
|
||||
if (dir != NRF_GPIO_PIN_DIR_INPUT) {
|
||||
pinMode(EPD_MOSI_PIN, INPUT);
|
||||
@@ -157,43 +147,36 @@ void EPD_SPI_Read(uint8_t *value, uint8_t len)
|
||||
}
|
||||
|
||||
// EPD
|
||||
void EPD_WriteCmd(uint8_t cmd)
|
||||
{
|
||||
void EPD_WriteCmd(uint8_t cmd) {
|
||||
digitalWrite(EPD_DC_PIN, LOW);
|
||||
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);
|
||||
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);
|
||||
EPD_SPI_Read(value, len);
|
||||
}
|
||||
|
||||
void EPD_WriteByte(uint8_t value)
|
||||
{
|
||||
void EPD_WriteByte(uint8_t value) {
|
||||
digitalWrite(EPD_DC_PIN, HIGH);
|
||||
EPD_SPI_Write(&value, 1);
|
||||
}
|
||||
|
||||
uint8_t EPD_ReadByte(void)
|
||||
{
|
||||
uint8_t EPD_ReadByte(void) {
|
||||
uint8_t value;
|
||||
digitalWrite(EPD_DC_PIN, HIGH);
|
||||
EPD_SPI_Read(&value, 1);
|
||||
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];
|
||||
for (uint8_t i = 0; i < BUFFER_SIZE; i++)
|
||||
buffer[i] = value;
|
||||
for (uint8_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = value;
|
||||
|
||||
EPD_WriteCmd(cmd);
|
||||
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);
|
||||
delay(duration);
|
||||
digitalWrite(EPD_RST_PIN, (value == LOW) ? HIGH : LOW);
|
||||
@@ -214,8 +196,7 @@ void EPD_Reset(uint32_t value, uint16_t 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);
|
||||
|
||||
NRF_LOG_DEBUG("[EPD]: check busy\n");
|
||||
@@ -238,26 +219,19 @@ void EPD_WaitBusy(uint32_t value, uint16_t timeout)
|
||||
}
|
||||
|
||||
// lED
|
||||
void EPD_LED_ON(void)
|
||||
{
|
||||
if (EPD_LED_PIN != 0xFF)
|
||||
digitalWrite(EPD_LED_PIN, LOW);
|
||||
void EPD_LED_ON(void) {
|
||||
if (EPD_LED_PIN != 0xFF) digitalWrite(EPD_LED_PIN, LOW);
|
||||
}
|
||||
|
||||
void EPD_LED_OFF(void)
|
||||
{
|
||||
if (EPD_LED_PIN != 0xFF)
|
||||
digitalWrite(EPD_LED_PIN, HIGH);
|
||||
void EPD_LED_OFF(void) {
|
||||
if (EPD_LED_PIN != 0xFF) digitalWrite(EPD_LED_PIN, HIGH);
|
||||
}
|
||||
|
||||
void EPD_LED_Toggle(void)
|
||||
{
|
||||
if (EPD_LED_PIN != 0xFF)
|
||||
nrf_gpio_pin_toggle(EPD_LED_PIN);
|
||||
void EPD_LED_Toggle(void) {
|
||||
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) {
|
||||
pinMode(EPD_LED_PIN, OUTPUT);
|
||||
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)
|
||||
volatile int16_t value = 0;
|
||||
NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_10bit;
|
||||
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)
|
||||
| ((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk)
|
||||
| ((SAADC_CH_CONFIG_GAIN_Gain1_6 << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk)
|
||||
| ((SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_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].CONFIG =
|
||||
((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos) & SAADC_CH_CONFIG_RESP_Msk) |
|
||||
((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk) |
|
||||
((SAADC_CH_CONFIG_GAIN_Gain1_6 << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk) |
|
||||
((SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_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].PSELP = SAADC_CH_PSELP_PSELP_VDD;
|
||||
NRF_SAADC->RESULT.PTR = (uint32_t)&value;
|
||||
@@ -328,22 +302,12 @@ extern epd_model_t epd_jd79668_420_bwry;
|
||||
extern epd_model_t epd_jd79668_750_bwry;
|
||||
|
||||
static epd_model_t* epd_models[] = {
|
||||
&epd_uc8176_420_bw,
|
||||
&epd_uc8176_420_bwr,
|
||||
&epd_uc8159_750_bw,
|
||||
&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_uc8176_420_bw, &epd_uc8176_420_bwr, &epd_uc8159_750_bw, &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;
|
||||
for (uint8_t i = 0; i < ARRAY_SIZE(epd_models); i++) {
|
||||
if (epd_models[i]->id == id) {
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "EPD_config.h"
|
||||
#include "nrf_delay.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "EPD_config.h"
|
||||
|
||||
// EPD driver IC types
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
EPD_DRIVER_IC_UC8159 = 0x10,
|
||||
EPD_DRIVER_IC_UC8176 = 0x11,
|
||||
EPD_DRIVER_IC_UC8179 = 0x12,
|
||||
@@ -120,16 +120,14 @@ enum {
|
||||
SSD16xx_NOP = 0x7F, // NOP
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
BW = 1,
|
||||
BWR = 2,
|
||||
BWRY = 3,
|
||||
} epd_color_t;
|
||||
|
||||
// Do not change the existing IDs!
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
EPD_UC8176_420_BW = 1,
|
||||
EPD_UC8176_420_BWR = 3,
|
||||
EPD_SSD1619_420_BWR = 2,
|
||||
@@ -146,8 +144,7 @@ typedef enum
|
||||
|
||||
struct epd_driver;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
epd_model_id_t id;
|
||||
epd_color_t color;
|
||||
struct epd_driver* drv;
|
||||
@@ -159,12 +156,12 @@ typedef struct
|
||||
*
|
||||
* @details This structure contains epd driver functions.
|
||||
*/
|
||||
typedef struct epd_driver
|
||||
{
|
||||
typedef struct epd_driver {
|
||||
epd_driver_ic_t ic; /**< EPD driver IC type */
|
||||
void (*init)(epd_model_t* epd); /**< Initialize the e-Paper register */
|
||||
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, uint16_t h); /**< write image */
|
||||
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 */
|
||||
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 (*sleep)(epd_model_t* epd); /**< Enter sleep mode */
|
||||
|
||||
@@ -10,16 +10,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EPD_service.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "sdk_macros.h"
|
||||
|
||||
#include "app_scheduler.h"
|
||||
#include "ble_srv_common.h"
|
||||
#include "main.h"
|
||||
#include "nrf_delay.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_pwr_mgmt.h"
|
||||
#include "sdk_macros.h"
|
||||
|
||||
#if defined(S112)
|
||||
#define EPD_CFG_52811 {0x14, 0x13, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02, 0xFF, 0x12, 0x07}
|
||||
@@ -29,8 +31,7 @@
|
||||
// #define EPD_CFG_DEFAULT {0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x01, 0x07}
|
||||
#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;
|
||||
ble_epd_t* p_epd = event->p_epd;
|
||||
|
||||
@@ -49,8 +50,7 @@ static void epd_gui_update(void * p_event_data, uint16_t event_size)
|
||||
|
||||
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);
|
||||
if (err_code == NRF_SUCCESS && dev_name_len > 0)
|
||||
data.ssid[dev_name_len] = '\0';
|
||||
if (err_code == NRF_SUCCESS && dev_name_len > 0) data.ssid[dev_name_len] = '\0';
|
||||
|
||||
DrawGUI(&data, (buffer_callback)epd->drv->write_image, 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_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;
|
||||
EPD_GPIO_Init();
|
||||
}
|
||||
@@ -75,8 +74,7 @@ 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_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);
|
||||
p_epd->conn_handle = BLE_CONN_HANDLE_INVALID;
|
||||
p_epd->epd->drv->sleep(p_epd->epd);
|
||||
@@ -84,36 +82,31 @@ static void on_disconnect(ble_epd_t * p_epd, ble_evt_t * p_ble_evt)
|
||||
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) {
|
||||
p_epd->config.display_mode = mode;
|
||||
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};
|
||||
snprintf(buf, 20, "t=%" PRIu32, timestamp());
|
||||
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};
|
||||
snprintf(buf, sizeof(buf), "mtu=%d", p_epd->max_data_len);
|
||||
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_HEXDUMP_DEBUG(p_data, length);
|
||||
if (p_data == NULL || length <= 0) return;
|
||||
|
||||
switch (p_data[0])
|
||||
{
|
||||
switch (p_data[0]) {
|
||||
case EPD_CMD_SET_PINS:
|
||||
if (length < 8) return;
|
||||
|
||||
@@ -124,8 +117,7 @@ static void epd_service_on_write(ble_epd_t * p_epd, uint8_t * p_data, uint16_t l
|
||||
p_epd->config.rst_pin = p_data[5];
|
||||
p_epd->config.busy_pin = p_data[6];
|
||||
p_epd->config.bs_pin = p_data[7];
|
||||
if (length > 8)
|
||||
p_epd->config.en_pin = p_data[8];
|
||||
if (length > 8) p_epd->config.en_pin = p_data[8];
|
||||
epd_config_write(&p_epd->config);
|
||||
|
||||
EPD_GPIO_Uninit();
|
||||
@@ -226,44 +218,29 @@ 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_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;
|
||||
|
||||
if (
|
||||
(p_evt_write->handle == p_epd->char_handles.cccd_handle)
|
||||
&&
|
||||
(p_evt_write->len == 2)
|
||||
)
|
||||
{
|
||||
if (ble_srv_is_notification_enabled(p_evt_write->data))
|
||||
{
|
||||
if ((p_evt_write->handle == p_epd->char_handles.cccd_handle) && (p_evt_write->len == 2)) {
|
||||
if (ble_srv_is_notification_enabled(p_evt_write->data)) {
|
||||
NRF_LOG_DEBUG("notification enabled\n");
|
||||
p_epd->is_notification_enabled = true;
|
||||
static uint16_t length = sizeof(epd_config_t);
|
||||
NRF_LOG_DEBUG("send epd config\n");
|
||||
uint32_t err_code = ble_epd_string_send(p_epd, (uint8_t*)&p_epd->config, length);
|
||||
if (err_code != NRF_ERROR_INVALID_STATE)
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (err_code != NRF_ERROR_INVALID_STATE) APP_ERROR_CHECK(err_code);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Do Nothing. This event is not relevant for this service.
|
||||
}
|
||||
}
|
||||
|
||||
#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;
|
||||
|
||||
ble_epd_t* p_epd = (ble_epd_t*)p_context;
|
||||
@@ -271,15 +248,12 @@ void ble_epd_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
|
||||
}
|
||||
#endif
|
||||
|
||||
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))
|
||||
{
|
||||
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)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (p_ble_evt->header.evt_id)
|
||||
{
|
||||
switch (p_ble_evt->header.evt_id) {
|
||||
case BLE_GAP_EVT_CONNECTED:
|
||||
on_connect(p_epd, p_ble_evt);
|
||||
break;
|
||||
@@ -298,9 +272,7 @@ 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_add_char_params_t add_char_params;
|
||||
@@ -310,9 +282,7 @@ static uint32_t epd_service_init(ble_epd_t * p_epd)
|
||||
|
||||
ble_uuid.type = ble_uuid.type;
|
||||
ble_uuid.uuid = BLE_UUID_EPD_SVC;
|
||||
VERIFY_SUCCESS(sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
|
||||
&ble_uuid,
|
||||
&p_epd->service_handle));
|
||||
VERIFY_SUCCESS(sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_epd->service_handle));
|
||||
|
||||
memset(&add_char_params, 0, sizeof(add_char_params));
|
||||
add_char_params.uuid = BLE_UUID_EPD_CHAR;
|
||||
@@ -341,19 +311,16 @@ static uint32_t epd_service_init(ble_epd_t * p_epd)
|
||||
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
|
||||
EPD_LED_OFF();
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// Initialize the service structure.
|
||||
@@ -365,8 +332,7 @@ uint32_t ble_epd_init(ble_epd_t * p_epd)
|
||||
epd_config_read(&p_epd->config);
|
||||
|
||||
// write default config
|
||||
if (epd_config_empty(&p_epd->config))
|
||||
{
|
||||
if (epd_config_empty(&p_epd->config)) {
|
||||
#if defined(S112)
|
||||
if (NRF_FICR->INFO.PART == 0x52810) {
|
||||
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;
|
||||
memcpy(&p_epd->config, cfg, sizeof(cfg));
|
||||
#endif
|
||||
if (p_epd->config.display_mode == 0xFF)
|
||||
p_epd->config.display_mode = MODE_CALENDAR;
|
||||
if (p_epd->config.week_start == 0xFF)
|
||||
p_epd->config.week_start = 0;
|
||||
if (p_epd->config.display_mode == 0xFF) p_epd->config.display_mode = MODE_CALENDAR;
|
||||
if (p_epd->config.week_start == 0xFF) p_epd->config.week_start = 0;
|
||||
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);
|
||||
}
|
||||
|
||||
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))
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
if (length > p_epd->max_data_len)
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
if (length > p_epd->max_data_len) return NRF_ERROR_INVALID_PARAM;
|
||||
|
||||
ble_gatts_hvx_params_t hvx_params;
|
||||
|
||||
@@ -415,11 +377,9 @@ uint32_t ble_epd_string_send(ble_epd_t * p_epd, uint8_t * p_string, uint16_t len
|
||||
return sd_ble_gatts_hvx(p_epd->conn_handle, &hvx_params);
|
||||
}
|
||||
|
||||
void ble_epd_on_timer(ble_epd_t * p_epd, uint32_t timestamp, bool force_update)
|
||||
{
|
||||
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
|
||||
if (force_update ||
|
||||
(p_epd->config.display_mode == MODE_CALENDAR && timestamp % 86400 == 0) ||
|
||||
if (force_update || (p_epd->config.display_mode == MODE_CALENDAR && timestamp % 86400 == 0) ||
|
||||
(p_epd->config.display_mode == MODE_CLOCK && timestamp % 60 == 0)) {
|
||||
epd_gui_update_event_t event = {p_epd, timestamp};
|
||||
app_sched_event_put(&event, sizeof(epd_gui_update_event_t), epd_gui_update);
|
||||
|
||||
@@ -15,15 +15,16 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "ble.h"
|
||||
#include "ble_srv_common.h"
|
||||
#if defined(S112)
|
||||
#include "nrf_sdh_ble.h"
|
||||
#endif
|
||||
#include "sdk_config.h"
|
||||
#include "EPD_driver.h"
|
||||
#include "EPD_config.h"
|
||||
#include "EPD_driver.h"
|
||||
#include "GUI.h"
|
||||
#include "sdk_config.h"
|
||||
|
||||
/**@brief Macro for defining a ble_hts instance.
|
||||
*
|
||||
@@ -36,17 +37,15 @@ 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_DEF(_name) \
|
||||
static ble_epd_t _name; \
|
||||
NRF_SDH_BLE_OBSERVER(_name ## _obs, \
|
||||
BLE_EPD_BLE_OBSERVER_PRIO, \
|
||||
ble_epd_evt_handler, &_name)
|
||||
NRF_SDH_BLE_OBSERVER(_name##_obs, BLE_EPD_BLE_OBSERVER_PRIO, ble_epd_evt_handler, &_name)
|
||||
#else
|
||||
#define BLE_EPD_DEF(_name) static ble_epd_t _name;
|
||||
#endif
|
||||
|
||||
#define APP_VERSION 0x19
|
||||
|
||||
#define BLE_UUID_EPD_SVC_BASE {{0XEC, 0X5A, 0X67, 0X1C, 0XC1, 0XB6, 0X46, 0XFB, \
|
||||
0X8D, 0X91, 0X28, 0XD8, 0X22, 0X36, 0X75, 0X62}}
|
||||
#define BLE_UUID_EPD_SVC_BASE \
|
||||
{{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_CHAR 0x0002
|
||||
#define BLE_UUID_APP_VER 0x0003
|
||||
@@ -56,12 +55,12 @@ void ble_epd_evt_handler(ble_evt_t const * p_ble_evt, void * p_context);
|
||||
#if defined(S112)
|
||||
#define BLE_EPD_MAX_DATA_LEN (NRF_SDH_BLE_GATT_MAX_MTU_SIZE - 3)
|
||||
#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
|
||||
|
||||
/**< EPD Service command IDs. */
|
||||
enum EPD_CMDS
|
||||
{
|
||||
enum EPD_CMDS {
|
||||
EPD_CMD_SET_PINS = 0x00, /**< set EPD pin mapping. */
|
||||
EPD_CMD_INIT = 0x01, /**< init EPD display driver */
|
||||
EPD_CMD_CLEAR = 0x02, /**< clear EPD screen */
|
||||
@@ -85,20 +84,22 @@ enum EPD_CMDS
|
||||
*
|
||||
* @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). */
|
||||
ble_gatts_char_handles_t 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). */
|
||||
uint16_t conn_handle; /**< Handle of the current connection (as provided by the SoftDevice). BLE_CONN_HANDLE_INVALID if not in a connection. */
|
||||
ble_gatts_char_handles_t
|
||||
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). */
|
||||
uint16_t conn_handle; /**< Handle of the current connection (as provided by the SoftDevice). BLE_CONN_HANDLE_INVALID
|
||||
if not in a connection. */
|
||||
uint16_t max_data_len; /**< Maximum length of data (in bytes) that can be transmitted to the peer */
|
||||
bool is_notification_enabled; /**< Variable to indicate if the peer has enabled notification of the RX characteristic.*/
|
||||
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;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
ble_epd_t* p_epd;
|
||||
uint32_t timestamp;
|
||||
} epd_gui_update_event_t;
|
||||
|
||||
@@ -1,51 +1,35 @@
|
||||
#include "EPD_driver.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
static void SSD16xx_WaitBusy(uint16_t timeout)
|
||||
{
|
||||
EPD_WaitBusy(HIGH, timeout);
|
||||
}
|
||||
static void SSD16xx_WaitBusy(uint16_t 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_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_WaitBusy(500);
|
||||
EPD_WriteCmd(SSD16xx_TSENSOR_READ);
|
||||
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
|
||||
if (epd->drv->ic == EPD_DRIVER_IC_SSD1677) {
|
||||
EPD_Write(SSD16xx_RAM_XPOS,
|
||||
x % 256, x / 256,
|
||||
(x + w - 1) % 256,
|
||||
(x + w - 1) / 256);
|
||||
EPD_Write(SSD16xx_RAM_XPOS, x % 256, x / 256, (x + w - 1) % 256, (x + w - 1) / 256);
|
||||
EPD_Write(SSD16xx_RAM_XCOUNT, x % 256, x / 256);
|
||||
} else {
|
||||
EPD_Write(SSD16xx_RAM_XPOS, x / 8, (x + w - 1) / 8);
|
||||
EPD_Write(SSD16xx_RAM_YPOS,
|
||||
y % 256, y / 256,
|
||||
(y + h - 1) % 256,
|
||||
(y + h - 1) / 256);
|
||||
EPD_Write(SSD16xx_RAM_YPOS, y % 256, y / 256, (y + h - 1) % 256, (y + h - 1) / 256);
|
||||
EPD_Write(SSD16xx_RAM_XCOUNT, x / 8);
|
||||
}
|
||||
EPD_Write(SSD16xx_RAM_YPOS,
|
||||
y % 256, y / 256,
|
||||
(y + h - 1) % 256,
|
||||
(y + h - 1) / 256);
|
||||
EPD_Write(SSD16xx_RAM_YPOS, y % 256, y / 256, (y + h - 1) % 256, (y + h - 1) / 256);
|
||||
EPD_Write(SSD16xx_RAM_YCOUNT, y % 256, y / 256);
|
||||
}
|
||||
|
||||
void SSD16xx_Dump_LUT(void)
|
||||
{
|
||||
void SSD16xx_Dump_LUT(void) {
|
||||
uint8_t lut[128];
|
||||
|
||||
EPD_WriteCmd(SSD16xx_READ_LUT);
|
||||
@@ -56,8 +40,7 @@ void SSD16xx_Dump_LUT(void)
|
||||
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_WriteCmd(SSD16xx_SW_RESET);
|
||||
@@ -69,8 +52,7 @@ void SSD16xx_Init(epd_model_t *epd)
|
||||
_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);
|
||||
|
||||
NRF_LOG_DEBUG("[EPD]: refresh begin\n");
|
||||
@@ -85,8 +67,7 @@ static void SSD16xx_Refresh(epd_model_t *epd)
|
||||
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;
|
||||
|
||||
_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_RAM2, 0xFF, ram_bytes);
|
||||
|
||||
if (refresh)
|
||||
SSD16xx_Refresh(epd);
|
||||
if (refresh) 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
|
||||
x -= x % 8; // byte boundary
|
||||
w = wb * 8; // byte boundary
|
||||
if (x + w > epd->width || y + h > epd->height)
|
||||
return;
|
||||
if (x + w > epd->width || y + h > epd->height) return;
|
||||
|
||||
_setPartialRamArea(epd, x, y, w, h);
|
||||
EPD_WriteCmd(SSD16xx_WRITE_RAM1);
|
||||
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 i = 0; i < h; i++) {
|
||||
for (uint16_t j = 0; j < w / 8; j++) EPD_WriteByte(black ? black[j + i * wb] : 0xFF);
|
||||
}
|
||||
EPD_WriteCmd(SSD16xx_WRITE_RAM2);
|
||||
for (uint16_t i = 0; i < h; i++)
|
||||
{
|
||||
for (uint16_t j = 0; j < w / 8; j++)
|
||||
{
|
||||
for (uint16_t i = 0; i < h; i++) {
|
||||
for (uint16_t j = 0; j < w / 8; j++) {
|
||||
if (epd->color == BWR)
|
||||
EPD_WriteByte(color ? color[j + i * wb] : 0xFF);
|
||||
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 black = (cfg & 0x0F) == 0x0F;
|
||||
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);
|
||||
}
|
||||
|
||||
void SSD16xx_Sleep(epd_model_t *epd)
|
||||
{
|
||||
void SSD16xx_Sleep(epd_model_t* epd) {
|
||||
EPD_Write(SSD16xx_SLEEP_MODE, 0x01);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
148
EPD/UC81xx.c
148
EPD/UC81xx.c
@@ -1,55 +1,40 @@
|
||||
#include "EPD_driver.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
static void UC81xx_WaitBusy(uint16_t timeout)
|
||||
{
|
||||
EPD_WaitBusy(LOW, timeout);
|
||||
}
|
||||
static void UC81xx_WaitBusy(uint16_t timeout) { EPD_WaitBusy(LOW, timeout); }
|
||||
|
||||
static void UC81xx_PowerOn(void)
|
||||
{
|
||||
static void UC81xx_PowerOn(void) {
|
||||
EPD_WriteCmd(UC81xx_PON);
|
||||
UC81xx_WaitBusy(200);
|
||||
}
|
||||
|
||||
static void UC81xx_PowerOff(void)
|
||||
{
|
||||
static void UC81xx_PowerOff(void) {
|
||||
EPD_WriteCmd(UC81xx_POF);
|
||||
UC81xx_WaitBusy(200);
|
||||
}
|
||||
|
||||
// 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);
|
||||
UC81xx_WaitBusy(100);
|
||||
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) {
|
||||
EPD_Write(0x83, // partial window
|
||||
x / 256, x % 256,
|
||||
(x + w - 1) / 256, (x + w - 1) % 256,
|
||||
y / 256, y % 256,
|
||||
(y + h - 1) / 256, (y + h - 1) % 256,
|
||||
0x01);
|
||||
x / 256, x % 256, (x + w - 1) / 256, (x + w - 1) % 256, y / 256, y % 256, (y + h - 1) / 256,
|
||||
(y + h - 1) % 256, 0x01);
|
||||
} else {
|
||||
uint16_t xe = (x + w - 1) | 0x0007; // byte boundary inclusive (last byte)
|
||||
uint16_t ye = y + h - 1;
|
||||
x &= 0xFFF8; // byte boundary
|
||||
EPD_Write(UC81xx_PTL, // partial window
|
||||
x / 256, x % 256,
|
||||
xe / 256, xe % 256,
|
||||
y / 256, y % 256,
|
||||
ye / 256, ye % 256,
|
||||
0x00);
|
||||
x / 256, x % 256, 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");
|
||||
UC81xx_PowerOn();
|
||||
|
||||
@@ -63,8 +48,7 @@ void UC81xx_Refresh(epd_model_t *epd)
|
||||
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");
|
||||
|
||||
_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");
|
||||
}
|
||||
|
||||
void UC81xx_Dump_OTP(void)
|
||||
{
|
||||
void UC81xx_Dump_OTP(void) {
|
||||
uint8_t data[128];
|
||||
|
||||
UC81xx_PowerOn();
|
||||
@@ -93,8 +76,7 @@ void UC81xx_Dump_OTP(void)
|
||||
UC81xx_PowerOff();
|
||||
}
|
||||
|
||||
void UC81xx_Init(epd_model_t *epd)
|
||||
{
|
||||
void UC81xx_Init(epd_model_t* epd) {
|
||||
EPD_Reset(HIGH, 10);
|
||||
|
||||
// UC81xx_Dump_OTP();
|
||||
@@ -103,8 +85,7 @@ void UC81xx_Init(epd_model_t *epd)
|
||||
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_Write(UC81xx_PWR, 0x37, 0x00);
|
||||
@@ -116,15 +97,10 @@ void UC8159_Init(epd_model_t *epd)
|
||||
EPD_Write(UC81xx_TCON, 0x22);
|
||||
EPD_Write(0x65, 0x00); // FLASH CONTROL
|
||||
EPD_Write(0xe5, 0x03); // FLASH MODE
|
||||
EPD_Write(UC81xx_TRES,
|
||||
epd->width >> 8,
|
||||
epd->width & 0xff,
|
||||
epd->height >> 8,
|
||||
epd->height & 0xff);
|
||||
EPD_Write(UC81xx_TRES, 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_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_PLL, 0x08);
|
||||
EPD_Write(UC81xx_CDI, 0x37);
|
||||
EPD_Write(UC81xx_TRES,
|
||||
epd->width / 256, epd->width % 256,
|
||||
epd->height / 256, epd->height % 256);
|
||||
EPD_Write(UC81xx_TRES, epd->width / 256, epd->width % 256, epd->height / 256, epd->height % 256);
|
||||
|
||||
EPD_Write(0xAE, 0xCF);
|
||||
EPD_Write(0xB0, 0x13);
|
||||
@@ -145,19 +119,16 @@ void JD79668_Init(epd_model_t *epd)
|
||||
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;
|
||||
|
||||
EPD_FillRAM(UC81xx_DTM1, 0xFF, ram_bytes);
|
||||
EPD_FillRAM(UC81xx_DTM2, 0xFF, ram_bytes);
|
||||
|
||||
if (refresh)
|
||||
UC81xx_Refresh(epd);
|
||||
if (refresh) 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;
|
||||
|
||||
EPD_WriteCmd(UC81xx_DTM1);
|
||||
@@ -169,44 +140,35 @@ void UC8159_Clear(epd_model_t *epd, bool refresh)
|
||||
}
|
||||
}
|
||||
|
||||
if (refresh)
|
||||
UC81xx_Refresh(epd);
|
||||
if (refresh) 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;
|
||||
|
||||
EPD_FillRAM(UC81xx_DTM1, 0x55, ram_bytes);
|
||||
|
||||
if (refresh)
|
||||
UC81xx_Refresh(epd);
|
||||
if (refresh) 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
|
||||
x -= x % 8; // byte boundary
|
||||
w = wb * 8; // byte boundary
|
||||
if (x + w > epd->width || y + h > epd->height)
|
||||
return;
|
||||
if (x + w > epd->width || y + h > epd->height) return;
|
||||
|
||||
EPD_WriteCmd(UC81xx_PTIN); // partial in
|
||||
_setPartialRamArea(epd, x, y, w, h);
|
||||
if (epd->color == BWR)
|
||||
{
|
||||
if (epd->color == BWR) {
|
||||
EPD_WriteCmd(UC81xx_DTM1);
|
||||
for (uint16_t i = 0; i < h; i++)
|
||||
{
|
||||
for (uint16_t j = 0; j < w / 8; j++)
|
||||
EPD_WriteByte(black ? black[j + i * wb] : 0xFF);
|
||||
for (uint16_t i = 0; i < h; i++) {
|
||||
for (uint16_t j = 0; j < w / 8; j++) EPD_WriteByte(black ? black[j + i * wb] : 0xFF);
|
||||
}
|
||||
}
|
||||
EPD_WriteCmd(UC81xx_DTM2);
|
||||
for (uint16_t i = 0; i < h; i++)
|
||||
{
|
||||
for (uint16_t j = 0; j < w / 8; j++)
|
||||
{
|
||||
for (uint16_t i = 0; i < h; i++) {
|
||||
for (uint16_t j = 0; j < w / 8; j++) {
|
||||
if (epd->color == BWR)
|
||||
EPD_WriteByte(color ? color[j + i * wb] : 0xFF);
|
||||
else
|
||||
@@ -219,37 +181,40 @@ void UC81xx_Write_Image(epd_model_t *epd, uint8_t *black, uint8_t *color, uint16
|
||||
static void UC8159_Send_Pixel(uint8_t black_data, uint8_t color_data) {
|
||||
uint8_t data;
|
||||
for (uint8_t j = 0; j < 8; j++) {
|
||||
if ((color_data & 0x80) == 0x00) data = 0x04; // red
|
||||
else if ((black_data & 0x80) == 0x00) data = 0x00; // black
|
||||
else data = 0x03; // white
|
||||
if ((color_data & 0x80) == 0x00)
|
||||
data = 0x04; // red
|
||||
else if ((black_data & 0x80) == 0x00)
|
||||
data = 0x00; // black
|
||||
else
|
||||
data = 0x03; // white
|
||||
data = (data << 4) & 0xFF;
|
||||
black_data = (black_data << 1) & 0xFF;
|
||||
color_data = (color_data << 1) & 0xFF;
|
||||
j++;
|
||||
if ((color_data & 0x80) == 0x00) data |= 0x04; // red
|
||||
else if ((black_data & 0x80) == 0x00) data |= 0x00; // black
|
||||
else data |= 0x03; // white
|
||||
if ((color_data & 0x80) == 0x00)
|
||||
data |= 0x04; // red
|
||||
else if ((black_data & 0x80) == 0x00)
|
||||
data |= 0x00; // black
|
||||
else
|
||||
data |= 0x03; // white
|
||||
black_data = (black_data << 1) & 0xFF;
|
||||
color_data = (color_data << 1) & 0xFF;
|
||||
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
|
||||
x -= x % 8; // byte boundary
|
||||
w = wb * 8; // byte boundary
|
||||
if (x + w > epd->width || y + h > epd->height)
|
||||
return;
|
||||
if (x + w > epd->width || y + h > epd->height) return;
|
||||
|
||||
EPD_WriteCmd(UC81xx_PTIN); // partial in
|
||||
_setPartialRamArea(epd, x, y, w, h);
|
||||
EPD_WriteCmd(UC81xx_DTM1);
|
||||
for (uint16_t i = 0; i < h; i++)
|
||||
{
|
||||
for (uint16_t j = 0; j < w / 8; j++)
|
||||
{
|
||||
for (uint16_t i = 0; i < h; i++) {
|
||||
for (uint16_t j = 0; j < w / 8; j++) {
|
||||
uint8_t black_data = 0xFF;
|
||||
uint8_t color_data = 0xFF;
|
||||
if (black) black_data = black[j + i * wb];
|
||||
@@ -260,25 +225,22 @@ void UC8159_Write_Image(epd_model_t *epd, uint8_t *black, uint8_t *color, uint16
|
||||
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
|
||||
x -= x % 8; // byte boundary
|
||||
w = wb * 8; // byte boundary
|
||||
if (x + w > epd->width || y + h > epd->height)
|
||||
return;
|
||||
if (x + w > epd->width || y + h > epd->height) return;
|
||||
|
||||
_setPartialRamArea(epd, x, y, w, h);
|
||||
EPD_WriteCmd(UC81xx_DTM1);
|
||||
for (uint16_t i = 0; i < h * 2; i++) // 2 bits per pixel
|
||||
{
|
||||
for (uint16_t j = 0; j < w / 8; j++)
|
||||
EPD_WriteByte(black ? black[j + i * wb] : 0x55);
|
||||
for (uint16_t j = 0; j < w / 8; j++) 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 black = (cfg & 0x0F) == 0x0F;
|
||||
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
|
||||
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 black = (cfg & 0x0F) == 0x0F;
|
||||
if (begin && black) EPD_WriteCmd(UC81xx_DTM1);
|
||||
EPD_WriteData(data, len);
|
||||
}
|
||||
|
||||
void UC81xx_Sleep(epd_model_t *epd)
|
||||
{
|
||||
void UC81xx_Sleep(epd_model_t* epd) {
|
||||
UC81xx_PowerOff();
|
||||
delay(100);
|
||||
EPD_Write(UC81xx_DSLP, 0xA5);
|
||||
|
||||
@@ -31,12 +31,13 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Adafruit_GFX.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "Adafruit_GFX.h"
|
||||
|
||||
#ifndef ABS
|
||||
#define ABS(x) ((x) > 0 ? (x) : -(x))
|
||||
@@ -45,15 +46,18 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef SWAP
|
||||
#define SWAP(a, b, T) do { T t = a; a = b; b = t; } while (0)
|
||||
#define SWAP(a, b, T) \
|
||||
do { \
|
||||
T t = a; \
|
||||
a = b; \
|
||||
b = t; \
|
||||
} while (0)
|
||||
#endif
|
||||
#ifndef CONTAINER_OF
|
||||
#define CONTAINER_OF(ptr, type, member) (type*)((char*)ptr - offsetof(type, member))
|
||||
#endif
|
||||
|
||||
static void GFX_u8g2_draw_hv_line(u8g2_font_t *u8g2, int16_t x, int16_t y,
|
||||
int16_t len, uint8_t dir, uint16_t color)
|
||||
{
|
||||
static void GFX_u8g2_draw_hv_line(u8g2_font_t* u8g2, int16_t x, int16_t y, int16_t len, uint8_t dir, uint16_t color) {
|
||||
Adafruit_GFX* gfx = CONTAINER_OF(u8g2, Adafruit_GFX, u8g2);
|
||||
switch (dir) {
|
||||
case 0:
|
||||
@@ -182,8 +186,7 @@ void GFX_setRotation(Adafruit_GFX *gfx, GFX_Rotate r) {
|
||||
this is an addressing limitation of the e-paper controllers
|
||||
*/
|
||||
/**************************************************************************/
|
||||
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) {
|
||||
gfx->px = MIN(x, gfx->_width);
|
||||
gfx->py = MIN(y, gfx->_height);
|
||||
gfx->pw = MIN(w, gfx->_width - gfx->px);
|
||||
@@ -218,28 +221,50 @@ static uint8_t color4(uint16_t color) {
|
||||
static uint8_t _prev_color4 = 0x00; // black
|
||||
if (color == _prev_color) return _prev_color4;
|
||||
uint8_t cv4 = 0x00;
|
||||
switch (color)
|
||||
{
|
||||
case GFX_BLACK: cv4 = 0x00; break;
|
||||
case GFX_WHITE: cv4 = 0x01; break;
|
||||
case GFX_GREEN: cv4 = 0x02; break; // use yellow?
|
||||
case GFX_BLUE: cv4 = 0x00; break; // use black
|
||||
case GFX_RED: cv4 = 0x03; break;
|
||||
case GFX_YELLOW: cv4 = 0x02; break;
|
||||
case GFX_ORANGE: cv4 = 0x02; break; // use yellow?
|
||||
switch (color) {
|
||||
case GFX_BLACK:
|
||||
cv4 = 0x00;
|
||||
break;
|
||||
case GFX_WHITE:
|
||||
cv4 = 0x01;
|
||||
break;
|
||||
case GFX_GREEN:
|
||||
cv4 = 0x02;
|
||||
break; // use yellow?
|
||||
case GFX_BLUE:
|
||||
cv4 = 0x00;
|
||||
break; // use black
|
||||
case GFX_RED:
|
||||
cv4 = 0x03;
|
||||
break;
|
||||
case GFX_YELLOW:
|
||||
cv4 = 0x02;
|
||||
break;
|
||||
case GFX_ORANGE:
|
||||
cv4 = 0x02;
|
||||
break; // use yellow?
|
||||
default: {
|
||||
uint16_t red = color & 0xF800;
|
||||
uint16_t green = (color & 0x07E0) << 5;
|
||||
uint16_t blue = (color & 0x001F) << 11;
|
||||
if ((red < 0x8000) && (green < 0x8000) && (blue < 0x8000)) cv4 = 0x00; // black
|
||||
else if ((red >= 0x8000) && (green >= 0x8000) && (blue >= 0x8000)) cv4 = 0x01; // white
|
||||
else if ((red >= 0x8000) && (blue >= 0x8000)) cv4 = 0x03; // red, blue > red
|
||||
else if ((green >= 0x8000) && (blue >= 0x8000)) cv4 = 0x01; // green, blue > white
|
||||
else if ((red >= 0x8000) && (green >= 0xC000)) cv4 = 0x02; // yellow
|
||||
else if ((red >= 0x8000) && (green >= 0x4000)) cv4 = 0x03; // orange > red
|
||||
else if (red >= 0x8000) cv4 = 0x03; // red
|
||||
else if (green >= 0x8000) cv4 = 0x00; // green > black
|
||||
else cv4 = 0x03; // blue
|
||||
if ((red < 0x8000) && (green < 0x8000) && (blue < 0x8000))
|
||||
cv4 = 0x00; // black
|
||||
else if ((red >= 0x8000) && (green >= 0x8000) && (blue >= 0x8000))
|
||||
cv4 = 0x01; // white
|
||||
else if ((red >= 0x8000) && (blue >= 0x8000))
|
||||
cv4 = 0x03; // red, blue > red
|
||||
else if ((green >= 0x8000) && (blue >= 0x8000))
|
||||
cv4 = 0x01; // green, blue > white
|
||||
else if ((red >= 0x8000) && (green >= 0xC000))
|
||||
cv4 = 0x02; // yellow
|
||||
else if ((red >= 0x8000) && (green >= 0x4000))
|
||||
cv4 = 0x03; // orange > red
|
||||
else if (red >= 0x8000)
|
||||
cv4 = 0x03; // red
|
||||
else if (green >= 0x8000)
|
||||
cv4 = 0x00; // green > black
|
||||
else
|
||||
cv4 = 0x03; // blue
|
||||
} break;
|
||||
}
|
||||
_prev_color = color;
|
||||
@@ -288,10 +313,18 @@ void GFX_drawPixel(Adafruit_GFX *gfx, int16_t x, int16_t y, uint16_t color) {
|
||||
uint32_t i = x / 4 + ((uint32_t)y) * (gfx->pw / 4);
|
||||
uint8_t pv = color4(color);
|
||||
switch (x % 4) {
|
||||
case 0: gfx->buffer[i] = (gfx->buffer[i] & 0x3F) | (pv << 6); break;
|
||||
case 1: gfx->buffer[i] = (gfx->buffer[i] & 0xCF) | (pv << 4); break;
|
||||
case 2: gfx->buffer[i] = (gfx->buffer[i] & 0xF3) | (pv << 2); break;
|
||||
case 3: gfx->buffer[i] = (gfx->buffer[i] & 0xFC) | pv; break;
|
||||
case 0:
|
||||
gfx->buffer[i] = (gfx->buffer[i] & 0x3F) | (pv << 6);
|
||||
break;
|
||||
case 1:
|
||||
gfx->buffer[i] = (gfx->buffer[i] & 0xCF) | (pv << 4);
|
||||
break;
|
||||
case 2:
|
||||
gfx->buffer[i] = (gfx->buffer[i] & 0xF3) | (pv << 2);
|
||||
break;
|
||||
case 3:
|
||||
gfx->buffer[i] = (gfx->buffer[i] & 0xFC) | pv;
|
||||
break;
|
||||
}
|
||||
} else if (gfx->color != NULL) { // 3c
|
||||
uint16_t i = x / 8 + y * (gfx->pw / 8);
|
||||
@@ -320,8 +353,7 @@ void GFX_drawPixel(Adafruit_GFX *gfx, int16_t x, int16_t y, uint16_t color) {
|
||||
@param color 16-bit 5-6-5 Color to draw with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
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) {
|
||||
int16_t steep = ABS(y1 - y0) > ABS(x1 - x0);
|
||||
if (steep) {
|
||||
SWAP(x0, y0, int16_t);
|
||||
@@ -370,8 +402,8 @@ void GFX_drawLine(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1, int16_t
|
||||
@param color 16-bit 5-6-5 Color to draw with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFX_drawDottedLine(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1, int16_t y1,
|
||||
uint16_t color, uint8_t dot_len, uint8_t space_len) {
|
||||
void GFX_drawDottedLine(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color,
|
||||
uint8_t dot_len, uint8_t space_len) {
|
||||
int16_t steep = ABS(y1 - y0) > ABS(x1 - x0);
|
||||
if (steep) {
|
||||
SWAP(x0, y0, int16_t);
|
||||
@@ -434,8 +466,7 @@ void GFX_drawDottedLine(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1, i
|
||||
@param color 16-bit 5-6-5 Color to fill with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
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) {
|
||||
GFX_drawLine(gfx, x, y, x, y + h - 1, color);
|
||||
}
|
||||
|
||||
@@ -448,8 +479,7 @@ void GFX_drawFastVLine(Adafruit_GFX *gfx, int16_t x, int16_t y, int16_t h,
|
||||
@param color 16-bit 5-6-5 Color to fill with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
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) {
|
||||
GFX_drawLine(gfx, x, y, x + w - 1, y, color);
|
||||
}
|
||||
|
||||
@@ -463,8 +493,7 @@ void GFX_drawFastHLine(Adafruit_GFX *gfx, int16_t x, int16_t y, int16_t w,
|
||||
@param color 16-bit 5-6-5 Color to fill with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
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) {
|
||||
for (int16_t i = x; i < x + w; i++) {
|
||||
GFX_drawFastVLine(gfx, i, y, h, color);
|
||||
}
|
||||
@@ -483,8 +512,7 @@ void GFX_fillScreen(Adafruit_GFX *gfx, uint16_t color) {
|
||||
memset(gfx->buffer, pv, size * 2);
|
||||
} else {
|
||||
memset(gfx->buffer, color == GFX_WHITE ? 0xFF : 0x00, size);
|
||||
if (gfx->color != NULL)
|
||||
memset(gfx->color, color == GFX_RED ? 0x00 : 0xFF, size);
|
||||
if (gfx->color != NULL) memset(gfx->color, color == GFX_RED ? 0x00 : 0xFF, size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,8 +525,7 @@ void GFX_fillScreen(Adafruit_GFX *gfx, uint16_t color) {
|
||||
@param color 16-bit 5-6-5 Color to draw with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
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) {
|
||||
int16_t f = 1 - r;
|
||||
int16_t ddF_x = 1;
|
||||
int16_t ddF_y = -2 * r;
|
||||
@@ -542,8 +569,7 @@ void GFX_drawCircle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t r,
|
||||
@param color 16-bit 5-6-5 Color to draw with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFX_drawCircleHelper(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t r,
|
||||
uint8_t cornername, uint16_t color) {
|
||||
void GFX_drawCircleHelper(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color) {
|
||||
int16_t f = 1 - r;
|
||||
int16_t ddF_x = 1;
|
||||
int16_t ddF_y = -2 * r;
|
||||
@@ -587,8 +613,7 @@ void GFX_drawCircleHelper(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t r,
|
||||
@param color 16-bit 5-6-5 Color to fill with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFX_fillCircle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t r,
|
||||
uint16_t color) {
|
||||
void GFX_fillCircle(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t r, uint16_t color) {
|
||||
GFX_drawFastVLine(gfx, x0, y0 - r, 2 * r + 1, color);
|
||||
GFX_fillCircleHelper(gfx, x0, y0, r, 3, 0, color);
|
||||
}
|
||||
@@ -604,9 +629,8 @@ void GFX_fillCircle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t r,
|
||||
@param color 16-bit 5-6-5 Color to fill with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFX_fillCircleHelper(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t r,
|
||||
uint8_t corners, int16_t delta, uint16_t color) {
|
||||
|
||||
void GFX_fillCircleHelper(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t r, uint8_t corners, int16_t delta,
|
||||
uint16_t color) {
|
||||
int16_t f = 1 - r;
|
||||
int16_t ddF_x = 1;
|
||||
int16_t ddF_y = -2 * r;
|
||||
@@ -629,16 +653,12 @@ void GFX_fillCircleHelper(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t r,
|
||||
// These checks avoid double-drawing certain lines, important
|
||||
// for the SSD1306 library which has an INVERT drawing mode.
|
||||
if (x < (y + 1)) {
|
||||
if (corners & 1)
|
||||
GFX_drawFastVLine(gfx, x0 + x, y0 - y, 2 * y + delta, color);
|
||||
if (corners & 2)
|
||||
GFX_drawFastVLine(gfx, x0 - x, y0 - y, 2 * y + delta, color);
|
||||
if (corners & 1) GFX_drawFastVLine(gfx, x0 + x, y0 - y, 2 * y + delta, color);
|
||||
if (corners & 2) GFX_drawFastVLine(gfx, x0 - x, y0 - y, 2 * y + delta, color);
|
||||
}
|
||||
if (y != py) {
|
||||
if (corners & 1)
|
||||
GFX_drawFastVLine(gfx, x0 + py, y0 - px, 2 * px + delta, color);
|
||||
if (corners & 2)
|
||||
GFX_drawFastVLine(gfx, x0 - py, y0 - px, 2 * px + delta, color);
|
||||
if (corners & 1) GFX_drawFastVLine(gfx, x0 + py, y0 - px, 2 * px + delta, color);
|
||||
if (corners & 2) GFX_drawFastVLine(gfx, x0 - py, y0 - px, 2 * px + delta, color);
|
||||
py = y;
|
||||
}
|
||||
px = x;
|
||||
@@ -655,8 +675,7 @@ void GFX_fillCircleHelper(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t r,
|
||||
@param color 16-bit 5-6-5 Color to draw with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
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) {
|
||||
GFX_drawFastHLine(gfx, x, y, w, color);
|
||||
GFX_drawFastHLine(gfx, x, y + h - 1, w, color);
|
||||
GFX_drawFastVLine(gfx, x, y, h, color);
|
||||
@@ -674,11 +693,9 @@ void GFX_drawRect(Adafruit_GFX *gfx, int16_t x, int16_t y, int16_t w, int16_t h,
|
||||
@param color 16-bit 5-6-5 Color to draw with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFX_drawRoundRect(Adafruit_GFX *gfx, int16_t x, int16_t y, int16_t w,
|
||||
int16_t h, int16_t r, uint16_t color) {
|
||||
void GFX_drawRoundRect(Adafruit_GFX* gfx, int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color) {
|
||||
int16_t max_radius = ((w < h) ? w : h) / 2; // 1/2 minor axis
|
||||
if (r > max_radius)
|
||||
r = max_radius;
|
||||
if (r > max_radius) r = max_radius;
|
||||
// smarter version
|
||||
GFX_drawFastHLine(gfx, x + r, y, w - 2 * r, color); // Top
|
||||
GFX_drawFastHLine(gfx, x + r, y + h - 1, w - 2 * r, color); // Bottom
|
||||
@@ -702,11 +719,9 @@ void GFX_drawRoundRect(Adafruit_GFX *gfx, int16_t x, int16_t y, int16_t w,
|
||||
@param color 16-bit 5-6-5 Color to draw/fill with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFX_fillRoundRect(Adafruit_GFX *gfx, int16_t x, int16_t y, int16_t w,
|
||||
int16_t h, int16_t r, uint16_t color) {
|
||||
void GFX_fillRoundRect(Adafruit_GFX* gfx, int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color) {
|
||||
int16_t max_radius = ((w < h) ? w : h) / 2; // 1/2 minor axis
|
||||
if (r > max_radius)
|
||||
r = max_radius;
|
||||
if (r > max_radius) r = max_radius;
|
||||
// smarter version
|
||||
GFX_fillRect(gfx, x + r, y, w - 2 * r, h, color);
|
||||
// draw four corners
|
||||
@@ -726,8 +741,8 @@ void GFX_fillRoundRect(Adafruit_GFX *gfx, int16_t x, int16_t y, int16_t w,
|
||||
@param color 16-bit 5-6-5 Color to draw with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFX_drawTriangle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1,
|
||||
int16_t y1, int16_t x2, int16_t y2, 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,
|
||||
uint16_t color) {
|
||||
GFX_drawLine(gfx, x0, y0, x1, y1, color);
|
||||
GFX_drawLine(gfx, x1, y1, x2, y2, color);
|
||||
GFX_drawLine(gfx, x2, y2, x0, y0, color);
|
||||
@@ -745,9 +760,8 @@ void GFX_drawTriangle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1,
|
||||
@param color 16-bit 5-6-5 Color to fill/draw with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFX_fillTriangle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1,
|
||||
int16_t y1, int16_t x2, int16_t y2, 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,
|
||||
uint16_t color) {
|
||||
int16_t a, b, y, last;
|
||||
|
||||
// Sort coordinates by Y order (y2 >= y1 >= y0)
|
||||
@@ -778,8 +792,7 @@ void GFX_fillTriangle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1,
|
||||
return;
|
||||
}
|
||||
|
||||
int16_t dx01 = x1 - x0, dy01 = y1 - y0, dx02 = x2 - x0, dy02 = y2 - y0,
|
||||
dx12 = x2 - x1, dy12 = y2 - y1;
|
||||
int16_t dx01 = x1 - x0, dy01 = y1 - y0, dx02 = x2 - x0, dy02 = y2 - y0, dx12 = x2 - x1, dy12 = y2 - y1;
|
||||
int32_t sa = 0, sb = 0;
|
||||
|
||||
// For upper part of triangle, find scanline crossings for segments
|
||||
@@ -802,8 +815,7 @@ void GFX_fillTriangle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1,
|
||||
a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
|
||||
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
|
||||
*/
|
||||
if (a > b)
|
||||
SWAP(a, b, int16_t);
|
||||
if (a > b) SWAP(a, b, int16_t);
|
||||
GFX_drawFastHLine(gfx, a, y, b - a + 1, color);
|
||||
}
|
||||
|
||||
@@ -820,8 +832,7 @@ void GFX_fillTriangle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1,
|
||||
a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
|
||||
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
|
||||
*/
|
||||
if (a > b)
|
||||
SWAP(a, b, int16_t);
|
||||
if (a > b) SWAP(a, b, int16_t);
|
||||
GFX_drawFastHLine(gfx, a, y, b - a + 1, color);
|
||||
}
|
||||
}
|
||||
@@ -839,9 +850,8 @@ void GFX_fillTriangle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1,
|
||||
@param invert When true, will invert the bitmap
|
||||
*/
|
||||
/**************************************************************************/
|
||||
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) {
|
||||
|
||||
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) {
|
||||
int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte
|
||||
uint8_t byte = 0;
|
||||
|
||||
@@ -851,8 +861,7 @@ void GFX_drawBitmap(Adafruit_GFX *gfx, int16_t x, int16_t y, const uint8_t bitma
|
||||
byte <<= 1;
|
||||
else
|
||||
byte = bitmap[j * byteWidth + i / 8];
|
||||
if (((byte & 0x80) == 0x80) ^ invert)
|
||||
GFX_drawPixel(gfx, x + i, y + j, color);
|
||||
if (((byte & 0x80) == 0x80) ^ invert) GFX_drawPixel(gfx, x + i, y + j, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -900,34 +909,22 @@ void GFX_setCursor(Adafruit_GFX *gfx, int16_t x, int16_t y) {
|
||||
gfx->utf8_state = 0;
|
||||
}
|
||||
|
||||
void GFX_setFont(Adafruit_GFX *gfx, const uint8_t *font) {
|
||||
u8g2_SetFont(&gfx->u8g2, font);
|
||||
}
|
||||
void GFX_setFont(Adafruit_GFX* gfx, const uint8_t* font) { u8g2_SetFont(&gfx->u8g2, font); }
|
||||
|
||||
void GFX_setFontMode(Adafruit_GFX *gfx, uint8_t is_transparent) {
|
||||
u8g2_SetFontMode(&gfx->u8g2, is_transparent);
|
||||
}
|
||||
void GFX_setFontMode(Adafruit_GFX* gfx, uint8_t is_transparent) { u8g2_SetFontMode(&gfx->u8g2, is_transparent); }
|
||||
|
||||
void GFX_setFontDirection(Adafruit_GFX *gfx, GFX_Rotate d) {
|
||||
u8g2_SetFontDirection(&gfx->u8g2, (uint8_t)d);
|
||||
}
|
||||
void GFX_setFontDirection(Adafruit_GFX* gfx, GFX_Rotate d) { u8g2_SetFontDirection(&gfx->u8g2, (uint8_t)d); }
|
||||
|
||||
void GFX_setTextColor(Adafruit_GFX* gfx, uint16_t fg, uint16_t bg) {
|
||||
u8g2_SetForegroundColor(&gfx->u8g2, fg);
|
||||
u8g2_SetBackgroundColor(&gfx->u8g2, bg);
|
||||
}
|
||||
|
||||
int8_t GFX_getFontAscent(Adafruit_GFX *gfx) {
|
||||
return gfx->u8g2.font_info.ascent_A;
|
||||
}
|
||||
int8_t GFX_getFontAscent(Adafruit_GFX* gfx) { return gfx->u8g2.font_info.ascent_A; }
|
||||
|
||||
int8_t GFX_getFontDescent(Adafruit_GFX *gfx) {
|
||||
return gfx->u8g2.font_info.descent_g;
|
||||
}
|
||||
int8_t GFX_getFontDescent(Adafruit_GFX* gfx) { return gfx->u8g2.font_info.descent_g; }
|
||||
|
||||
int8_t GFX_getFontHeight(Adafruit_GFX *gfx) {
|
||||
return gfx->u8g2.font_info.ascent_A - gfx->u8g2.font_info.descent_g;
|
||||
}
|
||||
int8_t GFX_getFontHeight(Adafruit_GFX* gfx) { return gfx->u8g2.font_info.ascent_A - gfx->u8g2.font_info.descent_g; }
|
||||
|
||||
int16_t GFX_drawGlyph(Adafruit_GFX* gfx, int16_t x, int16_t y, uint16_t e) {
|
||||
return u8g2_DrawGlyph(&gfx->u8g2, x, y, e);
|
||||
@@ -937,77 +934,57 @@ int16_t GFX_drawStr(Adafruit_GFX *gfx, int16_t x, int16_t y, const char *s) {
|
||||
return u8g2_DrawStr(&gfx->u8g2, x, y, s);
|
||||
}
|
||||
|
||||
static uint16_t utf8_next(Adafruit_GFX *gfx, uint8_t b)
|
||||
{
|
||||
static uint16_t utf8_next(Adafruit_GFX* gfx, uint8_t b) {
|
||||
if (b == 0) /* '\n' terminates the string to support the string list procedures */
|
||||
return 0x0ffff; /* end of string detected, pending UTF8 is discarded */
|
||||
if ( gfx->utf8_state == 0 )
|
||||
{
|
||||
if (gfx->utf8_state == 0) {
|
||||
if (b >= 0xfc) /* 6 byte sequence */
|
||||
{
|
||||
gfx->utf8_state = 5;
|
||||
b &= 1;
|
||||
}
|
||||
else if ( b >= 0xf8 )
|
||||
{
|
||||
} else if (b >= 0xf8) {
|
||||
gfx->utf8_state = 4;
|
||||
b &= 3;
|
||||
}
|
||||
else if ( b >= 0xf0 )
|
||||
{
|
||||
} else if (b >= 0xf0) {
|
||||
gfx->utf8_state = 3;
|
||||
b &= 7;
|
||||
}
|
||||
else if ( b >= 0xe0 )
|
||||
{
|
||||
} else if (b >= 0xe0) {
|
||||
gfx->utf8_state = 2;
|
||||
b &= 15;
|
||||
}
|
||||
else if ( b >= 0xc0 )
|
||||
{
|
||||
} else if (b >= 0xc0) {
|
||||
gfx->utf8_state = 1;
|
||||
b &= 0x01f;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* do nothing, just use the value as encoding */
|
||||
return b;
|
||||
}
|
||||
gfx->encoding = b;
|
||||
return 0x0fffe;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
gfx->utf8_state--;
|
||||
/* The case b < 0x080 (an illegal UTF8 encoding) is not checked here. */
|
||||
gfx->encoding <<= 6;
|
||||
b &= 0x03f;
|
||||
gfx->encoding |= b;
|
||||
if ( gfx->utf8_state != 0 )
|
||||
return 0x0fffe; /* nothing to do yet */
|
||||
if (gfx->utf8_state != 0) return 0x0fffe; /* nothing to do yet */
|
||||
}
|
||||
return gfx->encoding;
|
||||
}
|
||||
|
||||
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) {
|
||||
uint16_t e;
|
||||
int16_t delta, sum;
|
||||
|
||||
gfx->utf8_state = 0;
|
||||
sum = 0;
|
||||
for(;;)
|
||||
{
|
||||
for (;;) {
|
||||
e = utf8_next(gfx, (uint8_t)*str);
|
||||
if ( e == 0x0ffff )
|
||||
break;
|
||||
if (e == 0x0ffff) break;
|
||||
str++;
|
||||
if ( e != 0x0fffe )
|
||||
{
|
||||
if (e != 0x0fffe) {
|
||||
delta = u8g2_DrawGlyph(&gfx->u8g2, x, y, e);
|
||||
|
||||
switch(gfx->u8g2.font_decode.dir)
|
||||
{
|
||||
switch (gfx->u8g2.font_decode.dir) {
|
||||
case 0:
|
||||
x += delta;
|
||||
break;
|
||||
@@ -1028,8 +1005,7 @@ int16_t GFX_drawUTF8(Adafruit_GFX *gfx, int16_t x, int16_t y, const char *str)
|
||||
return sum;
|
||||
}
|
||||
|
||||
int16_t GFX_getUTF8Width(Adafruit_GFX *gfx, const char *str)
|
||||
{
|
||||
int16_t GFX_getUTF8Width(Adafruit_GFX* gfx, const char* str) {
|
||||
uint16_t e;
|
||||
int16_t dx, w;
|
||||
|
||||
@@ -1037,21 +1013,17 @@ int16_t GFX_getUTF8Width(Adafruit_GFX *gfx, const char *str)
|
||||
gfx->utf8_state = 0;
|
||||
w = 0;
|
||||
dx = 0;
|
||||
for(;;)
|
||||
{
|
||||
for (;;) {
|
||||
e = utf8_next(gfx, (uint8_t)*str);
|
||||
if ( e == 0x0ffff )
|
||||
break;
|
||||
if (e == 0x0ffff) break;
|
||||
str++;
|
||||
if ( e != 0x0fffe )
|
||||
{
|
||||
if (e != 0x0fffe) {
|
||||
dx = u8g2_GetGlyphWidth(&gfx->u8g2, e);
|
||||
w += dx;
|
||||
}
|
||||
}
|
||||
/* adjust the last glyph, check for issue #16: do not adjust if width is 0 */
|
||||
if ( gfx->u8g2.font_decode.glyph_width != 0 )
|
||||
{
|
||||
if (gfx->u8g2.font_decode.glyph_width != 0) {
|
||||
w -= dx;
|
||||
w += gfx->u8g2.font_decode.glyph_width; /* the real pixel width of the glyph, sideeffect of GetGlyphWidth */
|
||||
/* issue #46: we have to add the x offset also */
|
||||
@@ -1061,8 +1033,7 @@ int16_t GFX_getUTF8Width(Adafruit_GFX *gfx, const char *str)
|
||||
return w;
|
||||
}
|
||||
|
||||
int16_t GFX_getUTF8Widthf(Adafruit_GFX *gfx, const char* format, ...)
|
||||
{
|
||||
int16_t GFX_getUTF8Widthf(Adafruit_GFX* gfx, const char* format, ...) {
|
||||
char buf[64] = {0};
|
||||
char* str = buf;
|
||||
size_t len;
|
||||
@@ -1072,11 +1043,9 @@ int16_t GFX_getUTF8Widthf(Adafruit_GFX *gfx, const char* format, ...)
|
||||
len = vsnprintf(buf, sizeof(buf), format, va);
|
||||
va_end(va);
|
||||
|
||||
if (len > sizeof(buf) - 1)
|
||||
{
|
||||
if (len > sizeof(buf) - 1) {
|
||||
str = malloc(len + 1);
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
if (str == NULL) return 0;
|
||||
va_start(va, format);
|
||||
vsnprintf(str, len + 1, format, va);
|
||||
va_end(va);
|
||||
@@ -1084,8 +1053,7 @@ int16_t GFX_getUTF8Widthf(Adafruit_GFX *gfx, const char* format, ...)
|
||||
|
||||
int16_t w = GFX_getUTF8Width(gfx, str);
|
||||
|
||||
if (str != buf)
|
||||
free(str);
|
||||
if (str != buf) free(str);
|
||||
|
||||
return w;
|
||||
}
|
||||
@@ -1093,20 +1061,14 @@ int16_t GFX_getUTF8Widthf(Adafruit_GFX *gfx, const char* format, ...)
|
||||
size_t GFX_print(Adafruit_GFX* gfx, const char c) {
|
||||
int16_t delta;
|
||||
uint16_t e = utf8_next(gfx, (uint8_t)c);
|
||||
if ( e == '\n' )
|
||||
{
|
||||
if (e == '\n') {
|
||||
gfx->tx = 0;
|
||||
gfx->ty += gfx->u8g2.font_info.ascent_para - gfx->u8g2.font_info.descent_para;
|
||||
}
|
||||
else if ( e == '\r' )
|
||||
{
|
||||
} else if (e == '\r') {
|
||||
gfx->tx = 0;
|
||||
}
|
||||
else if ( e < 0x0fffe )
|
||||
{
|
||||
} else if (e < 0x0fffe) {
|
||||
delta = u8g2_DrawGlyph(&gfx->u8g2, gfx->tx, gfx->ty, e);
|
||||
switch(gfx->u8g2.font_decode.dir)
|
||||
{
|
||||
switch (gfx->u8g2.font_decode.dir) {
|
||||
case 0:
|
||||
gfx->tx += delta;
|
||||
break;
|
||||
@@ -1143,19 +1105,16 @@ size_t GFX_printf(Adafruit_GFX *gfx, const char* format, ...) {
|
||||
len = vsnprintf(tmp, sizeof(tmp), format, va);
|
||||
va_end(va);
|
||||
|
||||
if (len > sizeof(tmp) - 1)
|
||||
{
|
||||
if (len > sizeof(tmp) - 1) {
|
||||
buf = malloc(len + 1);
|
||||
if (buf == NULL)
|
||||
return 0;
|
||||
if (buf == NULL) return 0;
|
||||
va_start(va, format);
|
||||
vsnprintf(buf, len + 1, format, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
len = GFX_write(gfx, buf, len);
|
||||
if (buf != tmp)
|
||||
free(buf);
|
||||
if (buf != tmp) free(buf);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "u8g2_font.h"
|
||||
|
||||
#define GFX_BLACK 0x0000
|
||||
@@ -14,7 +15,8 @@
|
||||
#define GFX_GREEN 0x07E0 // 0, 255, 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 {
|
||||
GFX_ROTATE_0 = 0,
|
||||
@@ -34,7 +36,8 @@ typedef struct {
|
||||
u8g2_font_t u8g2;
|
||||
int16_t tx, ty; // current position for the print command
|
||||
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* color; // color pixel buffer (3c only)
|
||||
@@ -57,29 +60,26 @@ void GFX_end(Adafruit_GFX *gfx);
|
||||
// DRAW API
|
||||
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_drawDottedLine(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1, int16_t y1,
|
||||
uint16_t color, uint8_t dot_len, uint8_t space_len);
|
||||
void GFX_drawDottedLine(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color,
|
||||
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_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_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_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,
|
||||
uint16_t color);
|
||||
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);
|
||||
void GFX_drawTriangle(Adafruit_GFX *gfx, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2,
|
||||
int16_t y2, 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, 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_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);
|
||||
void GFX_fillCircleHelper(Adafruit_GFX* gfx, int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta,
|
||||
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,
|
||||
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,
|
||||
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_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
|
||||
void GFX_setCursor(Adafruit_GFX* gfx, int16_t x, int16_t y);
|
||||
|
||||
92
GUI/GUI.c
92
GUI/GUI.c
@@ -1,8 +1,10 @@
|
||||
#include "fonts.h"
|
||||
#include "Lunar.h"
|
||||
#include "GUI.h"
|
||||
#include <time.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "Lunar.h"
|
||||
#include "fonts.h"
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#define GFX_printf_styled(gfx, fg, bg, font, ...) \
|
||||
@@ -17,49 +19,25 @@ typedef struct {
|
||||
} Festival;
|
||||
|
||||
static const Festival festivals[] = {
|
||||
{ 1, 1, "元旦节"},
|
||||
{ 2, 14, "情人节"},
|
||||
{ 3, 8, "妇女节"},
|
||||
{ 3, 12, "植树节"},
|
||||
{ 4, 1, "愚人节"},
|
||||
{ 5, 1, "劳动节"},
|
||||
{ 5, 4, "青年节"},
|
||||
{ 6, 1, "儿童节"},
|
||||
{ 7, 1, "建党节"},
|
||||
{ 8, 1, "建军节"},
|
||||
{ 9, 10, "教师节"},
|
||||
{10, 1, "国庆节"},
|
||||
{11, 1, "万圣节"},
|
||||
{12, 24, "平安夜"},
|
||||
{12, 25, "圣诞节"},
|
||||
{1, 1, "元旦节"}, {2, 14, "情人节"}, {3, 8, "妇女节"}, {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[] = {
|
||||
{ 1, 1, "春节" },
|
||||
{ 1, 15, "元宵节"},
|
||||
{ 2, 2, "龙抬头"},
|
||||
{ 5, 5, "端午节"},
|
||||
{ 7, 7, "七夕节"},
|
||||
{ 7, 15, "中元节"},
|
||||
{ 8, 15, "中秋节"},
|
||||
{ 9, 9, "重阳节"},
|
||||
{10, 1, "寒衣节"},
|
||||
{12, 8, "腊八节"},
|
||||
{12, 30, "除夕" },
|
||||
{1, 1, "春节"}, {1, 15, "元宵节"}, {2, 2, "龙抬头"}, {5, 5, "端午节"}, {7, 7, "七夕节"}, {7, 15, "中元节"},
|
||||
{8, 15, "中秋节"}, {9, 9, "重阳节"}, {10, 1, "寒衣节"}, {12, 8, "腊八节"}, {12, 30, "除夕"},
|
||||
};
|
||||
|
||||
// 放假和调休数据,每年更新
|
||||
#define HOLIDAY_YEAR 2025
|
||||
static const uint16_t holidays[] = {
|
||||
0x0101, 0x111A, 0x011C, 0x011D, 0x011E, 0x011F, 0x0201, 0x0202,
|
||||
0x0202, 0x0203, 0x0204, 0x1208, 0x0404, 0x0405, 0x0406, 0x141B,
|
||||
0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x051F, 0x0601, 0x0602,
|
||||
0x191C, 0x0A01, 0x0A02, 0x0A03, 0x0A04, 0x0A05, 0x0A06, 0x0A07,
|
||||
0x0A08, 0x1A0B,
|
||||
0x0101, 0x111A, 0x011C, 0x011D, 0x011E, 0x011F, 0x0201, 0x0202, 0x0202, 0x0203, 0x0204, 0x1208,
|
||||
0x0404, 0x0405, 0x0406, 0x141B, 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x051F, 0x0601, 0x0602,
|
||||
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++) {
|
||||
if (((holidays[i] >> 8) & 0xF) == mon && (holidays[i] & 0xFF) == day) {
|
||||
*work = ((holidays[i] >> 12) & 0xF) > 0;
|
||||
@@ -69,9 +47,8 @@ static bool GetHoliday(uint8_t mon, uint8_t day, bool *work)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool GetFestival(uint16_t year, uint8_t mon, uint8_t day, uint8_t week,
|
||||
struct Lunar_Date *Lunar, char *festival)
|
||||
{
|
||||
static bool GetFestival(uint16_t year, uint8_t mon, uint8_t day, uint8_t week, struct Lunar_Date* Lunar,
|
||||
char* festival) {
|
||||
// 农历节日
|
||||
for (uint8_t i = 0; i < ARRAY_SIZE(festivals_lunar); i++) {
|
||||
if (Lunar->Month == festivals_lunar[i].month && Lunar->Date == festivals_lunar[i].day) {
|
||||
@@ -130,8 +107,7 @@ static bool GetFestival(uint16_t year, uint8_t mon, uint8_t day, uint8_t week,
|
||||
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* url = "https://tsl0922.github.io/EPD-nRF5";
|
||||
|
||||
@@ -153,8 +129,7 @@ static void DrawTimeSyncTip(Adafruit_GFX *gfx, gui_data_t *data)
|
||||
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;
|
||||
uint8_t level = (uint8_t)(voltage * 100 / 3.6f);
|
||||
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);
|
||||
}
|
||||
|
||||
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};
|
||||
tm.tm_year = year;
|
||||
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);
|
||||
}
|
||||
|
||||
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_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, "年");
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
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);
|
||||
uint8_t w = (data->width - 2 * x) / 7;
|
||||
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);
|
||||
int8_t adjustedFirstDay = (firstDayWeek - data->week_start + 7) % 7;
|
||||
uint8_t monthMaxDays = thisMonthMaxDays(tm->tm_year + YEAR0, tm->tm_mon + 1);
|
||||
@@ -280,7 +253,8 @@ static void DrawMonthDays(Adafruit_GFX *gfx, int16_t x, int16_t y, tm_t *tm, str
|
||||
if (day != tm->tm_mday) GFX_setTextColor(gfx, GFX_RED, GFX_WHITE);
|
||||
} else {
|
||||
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
|
||||
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;
|
||||
DrawDateHeader(gfx, 10, large ? 38 : 28, tm, Lunar, data);
|
||||
DrawWeekHeader(gfx, 10, large ? 44 : 32, data);
|
||||
DrawMonthDays(gfx, 10, large ? 84 : 64, tm, Lunar, data);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
/* Routine to Draw Large 7-Segment formated number
|
||||
Contributed by William Zaggle.
|
||||
|
||||
@@ -341,9 +315,9 @@ 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);
|
||||
x += (nD * (11 * cS + 2) - 2 * cS) + 2 * cS;
|
||||
GFX_fillRect(gfx, x, y + 4.5 * cS + 1, 2 * cS, 2 * cS, GFX_BLACK);
|
||||
@@ -352,8 +326,7 @@ static void DrawTime(Adafruit_GFX *gfx, tm_t *tm, int16_t x, int16_t y, uint16_t
|
||||
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;
|
||||
GFX_setCursor(gfx, padding, 36);
|
||||
GFX_printf_styled(gfx, GFX_RED, GFX_WHITE, u8g2_font_helvB18_tn, "%d", tm->tm_year + YEAR0);
|
||||
@@ -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;
|
||||
|
||||
tm_t tm = {0};
|
||||
|
||||
236
GUI/Lunar.c
236
GUI/Lunar.c
@@ -1,32 +1,22 @@
|
||||
#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 */
|
||||
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,
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
y = y - m / 10;
|
||||
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;
|
||||
uint16_t year_index, lunarY, y, offset;
|
||||
uint32_t solar_data, solar11, days;
|
||||
|
||||
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]) > (sizeof(solar_1_1) / sizeof(uint32_t) - 2)))
|
||||
{
|
||||
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]) > (sizeof(solar_1_1) / sizeof(uint32_t) - 2))) {
|
||||
lunar->Year = 0;
|
||||
lunar->Month = 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];
|
||||
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;
|
||||
}
|
||||
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];
|
||||
lunarM = 1;
|
||||
offset += 1;
|
||||
for (i = 0; i < 13; i++)
|
||||
{
|
||||
if (GetBitInt(days, 1, 12 - i) == 1)
|
||||
{
|
||||
for (i = 0; i < 13; i++) {
|
||||
if (GetBitInt(days, 1, 12 - i) == 1) {
|
||||
dm = 30;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
dm = 29;
|
||||
}
|
||||
if (offset > dm)
|
||||
{
|
||||
if (offset > dm) {
|
||||
lunarM += 1;
|
||||
offset -= dm;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
lunar->IsLeap = 0;
|
||||
if (leap != 0 && lunarM > leap)
|
||||
{
|
||||
if (lunarM == leap + 1)
|
||||
{
|
||||
if (leap != 0 && lunarM > leap) {
|
||||
if (lunarM == leap + 1) {
|
||||
lunar->IsLeap = 1;
|
||||
}
|
||||
lunarM -= 1;
|
||||
@@ -163,20 +139,11 @@ void LUNAR_SolarToLunar(struct Lunar_Date *lunar, uint16_t solar_year, uint8_t s
|
||||
lunar->Year = lunarY;
|
||||
}
|
||||
|
||||
uint8_t LUNAR_GetZodiac(const struct Lunar_Date *lunar)
|
||||
{
|
||||
return lunar->Year % 12;
|
||||
}
|
||||
uint8_t LUNAR_GetZodiac(const struct Lunar_Date* lunar) { return lunar->Year % 12; }
|
||||
|
||||
uint8_t LUNAR_GetStem(const struct Lunar_Date *lunar)
|
||||
{
|
||||
return lunar->Year % 10;
|
||||
}
|
||||
uint8_t LUNAR_GetStem(const struct Lunar_Date* lunar) { return lunar->Year % 10; }
|
||||
|
||||
uint8_t LUNAR_GetBranch(const struct Lunar_Date *lunar)
|
||||
{
|
||||
return lunar->Year % 12;
|
||||
}
|
||||
uint8_t LUNAR_GetBranch(const struct Lunar_Date* lunar) { return lunar->Year % 12; }
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 以下为24节气计算相关程序
|
||||
@@ -188,8 +155,7 @@ uint8_t LUNAR_GetBranch(const struct Lunar_Date *lunar)
|
||||
有兴趣的朋友可按照上面给的原理添加其它年份的表格
|
||||
不是很清楚的朋友可给我发EMAIL
|
||||
*/
|
||||
static const uint8_t YearMonthBit[160] =
|
||||
{
|
||||
static const uint8_t YearMonthBit[160] = {
|
||||
0x4E, 0xA6, 0x99, // 2000
|
||||
0x9C, 0xA2, 0x98, // 2001
|
||||
0x80, 0x00, 0x18, // 2002
|
||||
@@ -246,8 +212,7 @@ static const uint8_t YearMonthBit[160] =
|
||||
0xFC, 0xEF, 0xD9, // 2049
|
||||
0xBE, 0xA6, 0x18, // 2050
|
||||
};
|
||||
static const uint8_t days[24] =
|
||||
{
|
||||
static const uint8_t days[24] = {
|
||||
6, 20, 4, 19, 6, 21, // 一月到三月 的节气基本日期
|
||||
5, 20, 6, 21, 6, 21, // 四月到六月 的节气基本日期
|
||||
7, 23, 8, 23, 8, 23, // 七月到九月 的节气基本日期
|
||||
@@ -257,44 +222,11 @@ static const uint8_t days[24] =
|
||||
*
|
||||
*/
|
||||
const char JieQiStr[24][7] = {
|
||||
"小寒",
|
||||
"大寒",
|
||||
"立春",
|
||||
"雨水",
|
||||
"惊蛰",
|
||||
"春分",
|
||||
"清明",
|
||||
"谷雨",
|
||||
"立夏",
|
||||
"小满",
|
||||
"芒种",
|
||||
"夏至",
|
||||
"小暑",
|
||||
"大暑",
|
||||
"立秋",
|
||||
"处暑",
|
||||
"白露",
|
||||
"秋分",
|
||||
"寒露",
|
||||
"霜降",
|
||||
"立冬",
|
||||
"小雪",
|
||||
"大雪",
|
||||
"冬至",
|
||||
"小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至",
|
||||
"小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至",
|
||||
};
|
||||
const uint8_t MonthDayMax[12] = {
|
||||
31,
|
||||
28,
|
||||
31,
|
||||
30,
|
||||
31,
|
||||
30,
|
||||
31,
|
||||
31,
|
||||
30,
|
||||
31,
|
||||
30,
|
||||
31,
|
||||
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;
|
||||
|
||||
if ((myear < 2000) || (myear > 2050))
|
||||
return 0;
|
||||
if ((mmonth == 0) || (mmonth > 12))
|
||||
return 0;
|
||||
if ((myear < 2000) || (myear > 2050)) return 0;
|
||||
if ((mmonth == 0) || (mmonth > 12)) return 0;
|
||||
JQ = (mmonth - 1) * 2; // 获得节气顺序标号(0~23
|
||||
if (mday >= 15)
|
||||
JQ++; // 判断是否是上半月
|
||||
if (mday >= 15) JQ++; // 判断是否是上半月
|
||||
|
||||
bak1 = YearMonthBit[(myear - 2000) * 3 + JQ / 8]; // 获得节气日期相对值所在字节
|
||||
value = ((bak1 << (JQ % 8)) & 0x80); // 获得节气日期相对值状态
|
||||
|
||||
*JQdate = days[JQ];
|
||||
if (value != 0)
|
||||
{
|
||||
if (value != 0) {
|
||||
// 判断年份,以决定节气相对值1代表1,还是-1。
|
||||
if ((JQ == 1 || JQ == 11 || JQ == 18 || JQ == 21) && myear < 2044)
|
||||
(*JQdate)++;
|
||||
@@ -357,17 +284,14 @@ 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;
|
||||
|
||||
if (GetJieQi(myear, mmonth, mday, &JQdate) == 0)
|
||||
return 0xFF;
|
||||
if (GetJieQi(myear, mmonth, mday, &JQdate) == 0) return 0xFF;
|
||||
|
||||
JQ = (mmonth - 1) * 2; // 获得节气顺序标号(0~23
|
||||
|
||||
if (mday >= 15)
|
||||
JQ++; // 判断是否是上半月
|
||||
if (mday >= 15) JQ++; // 判断是否是上半月
|
||||
|
||||
if (mday == JQdate) // 今天正是一个节气日
|
||||
{
|
||||
@@ -379,28 +303,22 @@ uint8_t GetJieQiStr(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t *day)
|
||||
|
||||
if (mday < JQdate) // 如果今天日期小于本月的节气日期
|
||||
{
|
||||
|
||||
mday = JQdate - mday;
|
||||
}
|
||||
else // 如果今天日期大于本月的节气日期
|
||||
} else // 如果今天日期大于本月的节气日期
|
||||
{
|
||||
JQ++;
|
||||
|
||||
if (mday < 15)
|
||||
{
|
||||
if (mday < 15) {
|
||||
GetJieQi(myear, mmonth, 15, &JQdate);
|
||||
mday = JQdate - mday;
|
||||
}
|
||||
else // 翻月
|
||||
} else // 翻月
|
||||
{
|
||||
MaxDay = MonthDayMax[mmonth - 1];
|
||||
if (mmonth == 2) // 润月问题
|
||||
{
|
||||
if ((myear % 4 == 0) && ((myear % 100 != 0) || (myear % 400 == 0)))
|
||||
MaxDay++;
|
||||
if ((myear % 4 == 0) && ((myear % 100 != 0) || (myear % 400 == 0))) MaxDay++;
|
||||
}
|
||||
if (++mmonth == 13)
|
||||
mmonth = 1;
|
||||
if (++mmonth == 13) mmonth = 1;
|
||||
GetJieQi(myear, mmonth, 1, &JQdate);
|
||||
mday = MaxDay - mday + JQdate;
|
||||
}
|
||||
@@ -411,10 +329,8 @@ uint8_t GetJieQiStr(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t *day)
|
||||
|
||||
uint32_t SEC_PER_YR[2] = {31536000, 31622400}; // 闰年和非闰年的秒数
|
||||
uint32_t SEC_PER_MT[2][12] = {
|
||||
{2678400, 2419200, 2678400, 2592000, 2678400, 2592000,
|
||||
2678400, 2678400, 2592000, 2678400, 2592000, 2678400},
|
||||
{2678400, 2505600, 2678400, 2592000, 2678400, 2592000,
|
||||
2678400, 2678400, 2592000, 2678400, 2592000, 2678400},
|
||||
{2678400, 2419200, 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 // 一天多少秒
|
||||
|
||||
@@ -427,8 +343,7 @@ uint32_t SEC_PER_MT[2][12] = {
|
||||
* @Out : 1:是闰年 0:非闰年
|
||||
* @Author : Denis
|
||||
*/
|
||||
int is_leap(int yr)
|
||||
{
|
||||
int is_leap(int yr) {
|
||||
if (0 == (yr % 100))
|
||||
return (yr % 400 == 0) ? 1 : 0;
|
||||
else
|
||||
@@ -443,27 +358,22 @@ int is_leap(int yr)
|
||||
* @Out : 星期几
|
||||
* @Author : Denis
|
||||
*/
|
||||
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) {
|
||||
/* 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};
|
||||
year -= (uint8_t)(month < 3);
|
||||
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;
|
||||
uint32_t ltime = unix_time;
|
||||
|
||||
memset(result, 0, sizeof(struct devtm));
|
||||
result->tm_year = EPOCH_YR;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (ltime < SEC_PER_YR[is_leap(result->tm_year)])
|
||||
{
|
||||
while (1) {
|
||||
if (ltime < SEC_PER_YR[is_leap(result->tm_year)]) {
|
||||
break;
|
||||
}
|
||||
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);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (ltime < SEC_PER_MT[leapyr][result->tm_mon])
|
||||
break;
|
||||
while (1) {
|
||||
if (ltime < SEC_PER_MT[leapyr][result->tm_mon]) break;
|
||||
ltime -= SEC_PER_MT[leapyr][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_sec = ltime % 60;
|
||||
|
||||
result->tm_wday =
|
||||
day_of_week_get(result->tm_mon + 1, result->tm_mday,
|
||||
result->tm_year);
|
||||
result->tm_wday = day_of_week_get(result->tm_mon + 1, result->tm_mday, result->tm_year);
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
if (month % 12 == 1)
|
||||
{
|
||||
uint8_t get_last_day(uint16_t year, uint8_t month) {
|
||||
if (month % 12 == 1) {
|
||||
return map[month % 12] + is_leap(year);
|
||||
}
|
||||
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)
|
||||
{
|
||||
return day_of_week_get(month, 1, year);
|
||||
}
|
||||
uint8_t get_first_day_week(uint16_t year, uint8_t month) { return day_of_week_get(month, 1, year); }
|
||||
|
||||
// 时间结构体转时间戳
|
||||
uint32_t transformTimeStruct(struct devtm *result)
|
||||
{
|
||||
uint32_t transformTimeStruct(struct devtm* result) {
|
||||
uint32_t Cyear = 0;
|
||||
for (uint16_t i = 1970; i < result->tm_year; i++)
|
||||
{
|
||||
if (is_leap(i) == 1)
|
||||
Cyear++;
|
||||
for (uint16_t i = 1970; i < result->tm_year; i++) {
|
||||
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;
|
||||
for (uint8_t i = 0; i < result->tm_mon - 1; i++)
|
||||
{
|
||||
uint32_t CountDay =
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
return MonthDayMax[month - 1] + 1;
|
||||
else
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
#define SEC_PER_DY (86400) // 一天的秒数
|
||||
#define SEC_PER_HR (3600) // 一小时的秒数
|
||||
|
||||
typedef struct devtm
|
||||
{
|
||||
typedef struct devtm {
|
||||
uint16_t tm_year;
|
||||
uint8_t tm_mon;
|
||||
uint8_t tm_mday;
|
||||
@@ -19,8 +18,7 @@ typedef struct devtm
|
||||
uint8_t tm_wday;
|
||||
} tm_t;
|
||||
|
||||
struct Lunar_Date
|
||||
{
|
||||
struct Lunar_Date {
|
||||
uint8_t IsLeap;
|
||||
uint8_t Date;
|
||||
uint8_t Month;
|
||||
|
||||
202
GUI/u8g2_font.c
202
GUI/u8g2_font.c
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
|
||||
U8g2_for_Adafruit_GFX.cpp
|
||||
|
||||
Add unicode support and U8g2 fonts to Adafruit GFX libraries.
|
||||
@@ -35,18 +34,17 @@
|
||||
|
||||
*/
|
||||
|
||||
#include <stddef.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;
|
||||
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)
|
||||
{
|
||||
static uint16_t u8g2_font_get_word(const uint8_t* font, uint8_t offset) {
|
||||
uint16_t pos;
|
||||
font += offset;
|
||||
pos = u8x8_pgm_read(font);
|
||||
@@ -58,8 +56,7 @@ static uint16_t u8g2_font_get_word(const uint8_t *font, uint8_t offset)
|
||||
|
||||
/*========================================================================*/
|
||||
/* 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 */
|
||||
font_info->glyph_cnt = u8g2_font_get_byte(font, 0);
|
||||
font_info->bbx_mode = u8g2_font_get_byte(font, 1);
|
||||
@@ -93,34 +90,20 @@ void u8g2_read_font_info(u8g2_font_info_t *font_info, const uint8_t *font)
|
||||
font_info->start_pos_unicode = u8g2_font_get_word(font, 21);
|
||||
}
|
||||
|
||||
uint8_t u8g2_GetFontBBXWidth(u8g2_font_t *u8g2)
|
||||
{
|
||||
return u8g2->font_info.max_char_width; /* new font info structure */
|
||||
}
|
||||
uint8_t u8g2_GetFontBBXWidth(u8g2_font_t* u8g2) { return u8g2->font_info.max_char_width; /* new font info structure */ }
|
||||
|
||||
uint8_t u8g2_GetFontBBXHeight(u8g2_font_t *u8g2)
|
||||
{
|
||||
uint8_t u8g2_GetFontBBXHeight(u8g2_font_t* u8g2) {
|
||||
return u8g2->font_info.max_char_height; /* new font info structure */
|
||||
}
|
||||
|
||||
int8_t u8g2_GetFontBBXOffX(u8g2_font_t *u8g2)
|
||||
{
|
||||
return u8g2->font_info.x_offset; /* new font info structure */
|
||||
}
|
||||
int8_t u8g2_GetFontBBXOffX(u8g2_font_t* u8g2) { return u8g2->font_info.x_offset; /* new font info structure */ }
|
||||
|
||||
int8_t u8g2_GetFontBBXOffY(u8g2_font_t *u8g2)
|
||||
{
|
||||
return u8g2->font_info.y_offset; /* new font info structure */
|
||||
}
|
||||
int8_t u8g2_GetFontBBXOffY(u8g2_font_t* u8g2) { return u8g2->font_info.y_offset; /* new font info structure */ }
|
||||
|
||||
uint8_t u8g2_GetFontCapitalAHeight(u8g2_font_t *u8g2)
|
||||
{
|
||||
return u8g2->font_info.ascent_A; /* new font info structure */
|
||||
}
|
||||
uint8_t u8g2_GetFontCapitalAHeight(u8g2_font_t* u8g2) { 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)
|
||||
{
|
||||
static uint8_t u8g2_font_decode_get_unsigned_bits(u8g2_font_decode_t* f, uint8_t cnt) {
|
||||
uint8_t val;
|
||||
uint8_t bit_pos = f->decode_bit_pos;
|
||||
uint8_t bit_pos_plus_cnt;
|
||||
@@ -131,8 +114,7 @@ static uint8_t u8g2_font_decode_get_unsigned_bits(u8g2_font_decode_t *f, uint8_t
|
||||
val >>= bit_pos;
|
||||
bit_pos_plus_cnt = bit_pos;
|
||||
bit_pos_plus_cnt += cnt;
|
||||
if ( bit_pos_plus_cnt >= 8 )
|
||||
{
|
||||
if (bit_pos_plus_cnt >= 8) {
|
||||
uint8_t s = 8;
|
||||
s -= bit_pos;
|
||||
f->decode_ptr++;
|
||||
@@ -148,7 +130,6 @@ static uint8_t u8g2_font_decode_get_unsigned_bits(u8g2_font_decode_t *f, uint8_t
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
2 bit --> cnt = 2
|
||||
-2,-1,0. 1
|
||||
@@ -165,8 +146,7 @@ static uint8_t u8g2_font_decode_get_unsigned_bits(u8g2_font_decode_t *f, uint8_t
|
||||
*/
|
||||
/* 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)
|
||||
{
|
||||
static int8_t u8g2_font_decode_get_signed_bits(u8g2_font_decode_t* f, uint8_t cnt) {
|
||||
int8_t v, d;
|
||||
v = (int8_t)u8g2_font_decode_get_unsigned_bits(f, cnt);
|
||||
d = 1;
|
||||
@@ -177,12 +157,9 @@ static int8_t u8g2_font_decode_get_signed_bits(u8g2_font_decode_t *f, uint8_t cn
|
||||
// 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)
|
||||
{
|
||||
switch(dir)
|
||||
{
|
||||
static int16_t u8g2_add_vector_y(int16_t dy, int8_t x, int8_t y, uint8_t dir) {
|
||||
switch (dir) {
|
||||
case 0:
|
||||
dy += y;
|
||||
break;
|
||||
@@ -200,10 +177,8 @@ 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_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)
|
||||
{
|
||||
switch(dir)
|
||||
{
|
||||
static int16_t u8g2_add_vector_x(int16_t dx, int8_t x, int8_t y, uint8_t dir) {
|
||||
switch (dir) {
|
||||
case 0:
|
||||
dx += x;
|
||||
break;
|
||||
@@ -238,8 +213,7 @@ static int16_t u8g2_add_vector_x(int16_t dx, int8_t x, int8_t y, uint8_t dir)
|
||||
u8g2_font_decode_glyph()
|
||||
*/
|
||||
/* 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 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 */
|
||||
@@ -259,8 +233,7 @@ static void u8g2_font_decode_len(u8g2_font_t *u8g2, uint8_t len, uint8_t is_fore
|
||||
lx = decode->x;
|
||||
ly = decode->y;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
for (;;) {
|
||||
/* calculate the number of pixel to the right edge of the glyph */
|
||||
rem = decode->glyph_width;
|
||||
rem -= lx;
|
||||
@@ -268,9 +241,7 @@ static void u8g2_font_decode_len(u8g2_font_t *u8g2, uint8_t len, uint8_t is_fore
|
||||
/* calculate how many pixel to draw. This is either to the right edge */
|
||||
/* or lesser, if not enough pixel are left */
|
||||
current = rem;
|
||||
if ( cnt < rem )
|
||||
current = cnt;
|
||||
|
||||
if (cnt < rem) current = cnt;
|
||||
|
||||
/* now draw the line, but apply the rotation around the glyph target position */
|
||||
// u8g2_font_decode_draw_pixel(u8g2, lx,ly,current, is_foreground);
|
||||
@@ -286,19 +257,15 @@ static void u8g2_font_decode_len(u8g2_font_t *u8g2, uint8_t len, uint8_t is_fore
|
||||
/* draw foreground and background (if required) */
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* check, whether the end of the run length code has been reached */
|
||||
if ( cnt < rem )
|
||||
break;
|
||||
if (cnt < rem) break;
|
||||
cnt -= rem;
|
||||
lx = 0;
|
||||
ly++;
|
||||
@@ -307,11 +274,9 @@ static void u8g2_font_decode_len(u8g2_font_t *u8g2, uint8_t len, uint8_t is_fore
|
||||
|
||||
decode->x = lx;
|
||||
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);
|
||||
decode->decode_ptr = glyph_data;
|
||||
decode->decode_bit_pos = 0;
|
||||
@@ -324,10 +289,8 @@ static void u8g2_font_setup_decode(u8g2_font_t *u8g2, const uint8_t *glyph_data)
|
||||
|
||||
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:
|
||||
Decode and draw a glyph.
|
||||
@@ -342,8 +305,7 @@ static void u8g2_font_setup_decode(u8g2_font_t *u8g2, const uint8_t *glyph_data)
|
||||
u8g2_font_decode_len()
|
||||
*/
|
||||
/* 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;
|
||||
int8_t x, y;
|
||||
int8_t d;
|
||||
@@ -357,33 +319,26 @@ static int8_t u8g2_font_decode_glyph(u8g2_font_t *u8g2, const uint8_t *glyph_dat
|
||||
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);
|
||||
|
||||
|
||||
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);
|
||||
// u8g2_add_vector(&(decode->target_x), &(decode->target_y), x, -(h+y), decode->dir);
|
||||
|
||||
|
||||
/* reset local x/y position */
|
||||
decode->x = 0;
|
||||
decode->y = 0;
|
||||
|
||||
/* decode glyph */
|
||||
for(;;)
|
||||
{
|
||||
for (;;) {
|
||||
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);
|
||||
do
|
||||
{
|
||||
do {
|
||||
u8g2_font_decode_len(u8g2, a, 0);
|
||||
u8g2_font_decode_len(u8g2, b, 1);
|
||||
} while (u8g2_font_decode_get_unsigned_bits(decode, 1) != 0);
|
||||
|
||||
if ( decode->y >= h )
|
||||
break;
|
||||
if (decode->y >= h) break;
|
||||
}
|
||||
|
||||
}
|
||||
return d;
|
||||
}
|
||||
@@ -396,36 +351,25 @@ static int8_t u8g2_font_decode_glyph(u8g2_font_t *u8g2, const uint8_t *glyph_dat
|
||||
Return:
|
||||
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;
|
||||
font += 23;
|
||||
|
||||
|
||||
if ( encoding <= 255 )
|
||||
{
|
||||
if ( encoding >= 'a' )
|
||||
{
|
||||
if (encoding <= 255) {
|
||||
if (encoding >= '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;
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if ( u8x8_pgm_read( font + 1 ) == 0 )
|
||||
break;
|
||||
if ( u8x8_pgm_read( font ) == encoding )
|
||||
{
|
||||
for (;;) {
|
||||
if (u8x8_pgm_read(font + 1) == 0) break;
|
||||
if (u8x8_pgm_read(font) == encoding) {
|
||||
return font + 2; /* skip encoding and glyph size */
|
||||
}
|
||||
font += u8x8_pgm_read(font + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
uint16_t e;
|
||||
const uint8_t* unicode_lookup_table;
|
||||
/* support for the new unicode lookup table */
|
||||
@@ -434,8 +378,7 @@ const uint8_t *u8g2_font_get_glyph_data(u8g2_font_t *u8g2, uint16_t encoding)
|
||||
unicode_lookup_table = font;
|
||||
|
||||
/* u8g2 issue 596: search for the glyph start in the unicode lookup table */
|
||||
do
|
||||
{
|
||||
do {
|
||||
font += u8g2_font_get_word(unicode_lookup_table, 0);
|
||||
e = u8g2_font_get_word(unicode_lookup_table, 2);
|
||||
unicode_lookup_table += 4;
|
||||
@@ -443,15 +386,12 @@ const uint8_t *u8g2_font_get_glyph_data(u8g2_font_t *u8g2, uint16_t encoding)
|
||||
|
||||
/* variable "font" is now updated according to the lookup table */
|
||||
|
||||
for(;;)
|
||||
{
|
||||
for (;;) {
|
||||
e = u8x8_pgm_read(font);
|
||||
e <<= 8;
|
||||
e |= u8x8_pgm_read(font + 1);
|
||||
if ( e == 0 )
|
||||
break;
|
||||
if ( e == encoding )
|
||||
{
|
||||
if (e == 0) break;
|
||||
if (e == encoding) {
|
||||
return font + 3; /* skip encoding and glyph size */
|
||||
}
|
||||
font += u8x8_pgm_read(font + 2);
|
||||
@@ -460,39 +400,32 @@ const uint8_t *u8g2_font_get_glyph_data(u8g2_font_t *u8g2, uint16_t encoding)
|
||||
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;
|
||||
u8g2->font_decode.target_x = x;
|
||||
u8g2->font_decode.target_y = y;
|
||||
// u8g2->font_decode.is_transparent = is_transparent; this is already set
|
||||
// u8g2->font_decode.dir = dir;
|
||||
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);
|
||||
}
|
||||
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 */
|
||||
if ( u8g2_font_get_glyph_data(u8g2, requested_encoding) != NULL )
|
||||
return 1;
|
||||
if (u8g2_font_get_glyph_data(u8g2, requested_encoding) != NULL) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
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);
|
||||
if ( glyph_data == NULL )
|
||||
return 0;
|
||||
if (glyph_data == NULL) return 0;
|
||||
|
||||
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);
|
||||
@@ -502,34 +435,23 @@ int8_t u8g2_GetGlyphWidth(u8g2_font_t *u8g2, uint16_t requested_encoding)
|
||||
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
|
||||
}
|
||||
|
||||
void u8g2_SetFontDirection(u8g2_font_t *u8g2, uint8_t dir)
|
||||
{
|
||||
u8g2->font_decode.dir = dir;
|
||||
}
|
||||
void u8g2_SetFontDirection(u8g2_font_t* u8g2, uint8_t 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);
|
||||
}
|
||||
|
||||
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;
|
||||
sum = 0;
|
||||
|
||||
while( *s != '\0' )
|
||||
{
|
||||
while (*s != '\0') {
|
||||
delta = u8g2_DrawGlyph(u8g2, x, y, *s);
|
||||
switch(u8g2->font_decode.dir)
|
||||
{
|
||||
switch (u8g2->font_decode.dir) {
|
||||
case 0:
|
||||
x += delta;
|
||||
break;
|
||||
@@ -549,12 +471,8 @@ int16_t u8g2_DrawStr(u8g2_font_t *u8g2, int16_t x, int16_t y, const char *s)
|
||||
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_decode.is_transparent = 0;
|
||||
|
||||
@@ -562,12 +480,6 @@ void u8g2_SetFont(u8g2_font_t *u8g2, const uint8_t *font)
|
||||
}
|
||||
}
|
||||
|
||||
void u8g2_SetForegroundColor(u8g2_font_t *u8g2, uint16_t fg)
|
||||
{
|
||||
u8g2->font_decode.fg_color = fg;
|
||||
}
|
||||
void u8g2_SetForegroundColor(u8g2_font_t* u8g2, uint16_t fg) { u8g2->font_decode.fg_color = fg; }
|
||||
|
||||
void u8g2_SetBackgroundColor(u8g2_font_t *u8g2, uint16_t bg)
|
||||
{
|
||||
u8g2->font_decode.bg_color = bg;
|
||||
}
|
||||
void u8g2_SetBackgroundColor(u8g2_font_t* u8g2, uint16_t bg) { u8g2->font_decode.bg_color = bg; }
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
|
||||
U8g2_for_Adafruit_GFX.h
|
||||
|
||||
Add unicode support and U8g2 fonts to Adafruit GFX libraries.
|
||||
@@ -77,8 +76,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct _u8g2_font_info_t
|
||||
{
|
||||
typedef struct _u8g2_font_info_t {
|
||||
/* offset 0 */
|
||||
uint8_t glyph_cnt;
|
||||
uint8_t bbx_mode;
|
||||
@@ -112,8 +110,7 @@ typedef struct _u8g2_font_info_t
|
||||
uint16_t start_pos_unicode;
|
||||
} 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 */
|
||||
|
||||
int16_t target_x;
|
||||
@@ -131,8 +128,7 @@ typedef struct _u8g2_font_decode_t
|
||||
uint8_t dir; /* direction */
|
||||
} u8g2_font_decode_t;
|
||||
|
||||
typedef struct _u8g2_font_t
|
||||
{
|
||||
typedef struct _u8g2_font_t {
|
||||
const uint8_t* font; /* current font for all text procedures */
|
||||
|
||||
u8g2_font_decode_t font_decode; /* new font decode structure */
|
||||
@@ -140,8 +136,7 @@ typedef struct _u8g2_font_t
|
||||
|
||||
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,
|
||||
int16_t len, uint8_t dir, uint16_t color);
|
||||
void (*draw_hv_line)(struct _u8g2_font_t* u8g2, int16_t x, int16_t y, int16_t len, uint8_t dir, uint16_t color);
|
||||
} u8g2_font_t;
|
||||
|
||||
uint8_t u8g2_IsGlyph(u8g2_font_t* u8g2, uint16_t requested_encoding);
|
||||
|
||||
46
emulator.c
46
emulator.c
@@ -1,10 +1,11 @@
|
||||
// GUI emulator for Windows
|
||||
// This code is a simple Windows GUI application that emulates the display of an e-paper device.
|
||||
#include <windows.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <wchar.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "GUI.h"
|
||||
|
||||
#define BITMAP_WIDTH 400
|
||||
@@ -117,11 +118,7 @@ void DrawBitmap(void *user_data, uint8_t *black, uint8_t *color, uint16_t x, uin
|
||||
}
|
||||
|
||||
// Draw the bitmap
|
||||
StretchDIBits(hdc,
|
||||
drawX + x * scale, drawY + y * scale,
|
||||
w * scale, h * scale,
|
||||
0, 0, w, h,
|
||||
bitmap4bit, &bmi,
|
||||
StretchDIBits(hdc, drawX + x * scale, drawY + y * scale, w * scale, h * scale, 0, 0, w, h, bitmap4bit, &bmi,
|
||||
DIB_RGB_COLORS, SRCCOPY);
|
||||
|
||||
free(bitmap4bit);
|
||||
@@ -172,9 +169,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
HPEN oldPen = SelectObject(hdc, borderPen);
|
||||
HBRUSH oldBrush = SelectObject(hdc, GetStockObject(NULL_BRUSH)); // No fill
|
||||
|
||||
Rectangle(hdc, drawX - 1, drawY - 1,
|
||||
drawX + BITMAP_WIDTH * scale + 1,
|
||||
drawY + BITMAP_HEIGHT * scale + 1);
|
||||
Rectangle(hdc, drawX - 1, drawY - 1, drawX + BITMAP_WIDTH * scale + 1, drawY + BITMAP_HEIGHT * scale + 1);
|
||||
|
||||
SelectObject(hdc, oldPen);
|
||||
SelectObject(hdc, oldBrush);
|
||||
@@ -187,11 +182,8 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
SetBkMode(hdc, TRANSPARENT);
|
||||
|
||||
// Create a font for mode text
|
||||
HFONT modeFont = CreateFont(
|
||||
16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
|
||||
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
||||
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial"
|
||||
);
|
||||
HFONT modeFont = CreateFont(16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial");
|
||||
HFONT oldFont = SelectObject(hdc, modeFont);
|
||||
|
||||
// Calculate text width for centering mode text
|
||||
@@ -207,11 +199,9 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
SetTextColor(hdc, RGB(80, 80, 80));
|
||||
|
||||
// Create a smaller font for help text
|
||||
HFONT helpFont = CreateFont(
|
||||
14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
|
||||
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
||||
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial"
|
||||
);
|
||||
HFONT helpFont =
|
||||
CreateFont(14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial");
|
||||
SelectObject(hdc, modeFont);
|
||||
DeleteObject(modeFont);
|
||||
SelectObject(hdc, helpFont);
|
||||
@@ -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_year++;
|
||||
}
|
||||
}
|
||||
else if (wParam == VK_DOWN) {
|
||||
} else if (wParam == VK_DOWN) {
|
||||
g_tm_time.tm_mon--;
|
||||
if (g_tm_time.tm_mon < 0) {
|
||||
g_tm_time.tm_mon = 11;
|
||||
@@ -293,8 +282,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
// Left/Right adjusts day
|
||||
else if (wParam == VK_RIGHT) {
|
||||
g_tm_time.tm_mday++;
|
||||
}
|
||||
else if (wParam == VK_LEFT) {
|
||||
} else if (wParam == VK_LEFT) {
|
||||
g_tm_time.tm_mday--;
|
||||
}
|
||||
|
||||
@@ -335,14 +323,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
}
|
||||
|
||||
// Create the window
|
||||
g_hwnd = CreateWindowW(
|
||||
L"Emurator",
|
||||
L"模拟器",
|
||||
WS_POPUPWINDOW | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
WINDOW_WIDTH, WINDOW_HEIGHT,
|
||||
NULL, NULL, hInstance, NULL
|
||||
);
|
||||
g_hwnd = CreateWindowW(L"Emurator", L"模拟器", WS_POPUPWINDOW | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);
|
||||
|
||||
if (!g_hwnd) {
|
||||
MessageBoxW(NULL, L"Window Creation Failed!", L"Error", MB_ICONEXCLAMATION | MB_OK);
|
||||
|
||||
215
main.c
215
main.c
@@ -12,41 +12,42 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "nordic_common.h"
|
||||
#include "nrf.h"
|
||||
|
||||
#include "ble.h"
|
||||
#include "ble_hci.h"
|
||||
#include "ble_srv_common.h"
|
||||
#include "ble_advdata.h"
|
||||
#include "ble_advertising.h"
|
||||
#include "ble_conn_params.h"
|
||||
#include "ble_dfu.h"
|
||||
#include "ble_hci.h"
|
||||
#include "ble_srv_common.h"
|
||||
#include "nordic_common.h"
|
||||
#include "nrf.h"
|
||||
#if defined(S112)
|
||||
#include "nrf_sdh.h"
|
||||
#include "nrf_sdh_soc.h"
|
||||
#include "nrf_sdh_ble.h"
|
||||
#include "nrf_ble_gatt.h"
|
||||
#include "nrf_bootloader_info.h"
|
||||
#include "nrf_sdh.h"
|
||||
#include "nrf_sdh_ble.h"
|
||||
#include "nrf_sdh_soc.h"
|
||||
#else
|
||||
#include "fstorage.h"
|
||||
#include "softdevice_handler.h"
|
||||
#endif
|
||||
#include "nrf_power.h"
|
||||
#include "EPD_service.h"
|
||||
#include "app_error.h"
|
||||
#include "app_timer.h"
|
||||
#include "app_scheduler.h"
|
||||
#include "app_timer.h"
|
||||
#include "main.h"
|
||||
#include "nrf_drv_gpiote.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_ctrl.h"
|
||||
#include "nrf_power.h"
|
||||
#include "nrf_pwr_mgmt.h"
|
||||
#if defined(S112)
|
||||
#include "nrf_log_default_backends.h"
|
||||
#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 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 uint32_t m_wdt_last_feed_time = 0;
|
||||
static uint32_t m_resetreas;
|
||||
// clang-format on
|
||||
|
||||
/**@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] 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);
|
||||
}
|
||||
|
||||
// return current timestamp
|
||||
uint32_t timestamp(void)
|
||||
{
|
||||
return m_timestamp;
|
||||
}
|
||||
uint32_t timestamp(void) { return m_timestamp; }
|
||||
|
||||
// set the timestamp
|
||||
void set_timestamp(uint32_t timestamp)
|
||||
{
|
||||
void set_timestamp(uint32_t timestamp) {
|
||||
app_timer_stop(m_clock_timer_id);
|
||||
m_timestamp = timestamp;
|
||||
app_timer_start(m_clock_timer_id, CLOCK_TIMER_INTERVAL, NULL);
|
||||
}
|
||||
|
||||
// reload the wdt channel
|
||||
void app_feed_wdt(void)
|
||||
{
|
||||
void app_feed_wdt(void) {
|
||||
if (m_timestamp - m_wdt_last_feed_time >= 30) {
|
||||
NRF_LOG_DEBUG("Feed WDT\n");
|
||||
nrf_drv_wdt_channel_feed(m_wdt_channel_id);
|
||||
@@ -142,10 +138,8 @@ void app_feed_wdt(void)
|
||||
}
|
||||
|
||||
#if defined(S112)
|
||||
static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void * p_context)
|
||||
{
|
||||
if (state == NRF_SDH_EVT_STATE_DISABLED)
|
||||
{
|
||||
static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void* p_context) {
|
||||
if (state == NRF_SDH_EVT_STATE_DISABLED) {
|
||||
// Softdevice was disabled before going into reset. Inform bootloader to skip CRC on next boot.
|
||||
nrf_power_gpregret2_set(BOOTLOADER_DFU_SKIP_CRC);
|
||||
|
||||
@@ -155,13 +149,11 @@ static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void *
|
||||
}
|
||||
|
||||
/* 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,
|
||||
};
|
||||
|
||||
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));
|
||||
|
||||
p_config->ble_adv_fast_enabled = true;
|
||||
@@ -169,12 +161,9 @@ static void advertising_config_get(ble_adv_modes_config_t * p_config)
|
||||
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)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
|
||||
{
|
||||
static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event) {
|
||||
switch (event) {
|
||||
case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE: {
|
||||
NRF_LOG_INFO("Device is preparing to enter bootloader mode.");
|
||||
|
||||
// Prevent device from advertising on disconnect.
|
||||
@@ -210,10 +199,8 @@ static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event)
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void ble_dfu_evt_handler(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
|
||||
{
|
||||
switch (p_evt->type)
|
||||
{
|
||||
static void ble_dfu_evt_handler(ble_dfu_t* p_dfu, ble_dfu_evt_t* p_evt) {
|
||||
switch (p_evt->type) {
|
||||
case BLE_DFU_EVT_INDICATION_DISABLED:
|
||||
NRF_LOG_INFO("Indication for BLE_DFU is disabled\r\n");
|
||||
break;
|
||||
@@ -232,8 +219,7 @@ static void ble_dfu_evt_handler(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void clock_timer_timeout_handler(void * p_context)
|
||||
{
|
||||
static void clock_timer_timeout_handler(void* p_context) {
|
||||
UNUSED_PARAMETER(p_context);
|
||||
|
||||
m_timestamp++;
|
||||
@@ -243,17 +229,13 @@ static void clock_timer_timeout_handler(void * p_context)
|
||||
|
||||
/**@brief Function for the Event Scheduler initialization.
|
||||
*/
|
||||
static void scheduler_init(void)
|
||||
{
|
||||
APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
|
||||
}
|
||||
static void scheduler_init(void) { APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE); }
|
||||
|
||||
/**@brief Function for the Timer initialization.
|
||||
*
|
||||
* @details Initializes the timer module. This creates and starts application timers.
|
||||
*/
|
||||
static void timers_init(void)
|
||||
{
|
||||
static void timers_init(void) {
|
||||
// Initialize timer module.
|
||||
#if defined(S112)
|
||||
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);
|
||||
#endif
|
||||
// Create timers.
|
||||
APP_ERROR_CHECK(app_timer_create(&m_clock_timer_id,
|
||||
APP_TIMER_MODE_REPEATED,
|
||||
clock_timer_timeout_handler));
|
||||
APP_ERROR_CHECK(app_timer_create(&m_clock_timer_id, APP_TIMER_MODE_REPEATED, clock_timer_timeout_handler));
|
||||
}
|
||||
|
||||
/**@brief Function for starting application timers.
|
||||
*/
|
||||
static void application_timers_start(void)
|
||||
{
|
||||
static void application_timers_start(void) {
|
||||
// Start application timers.
|
||||
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.
|
||||
*/
|
||||
void sleep_mode_enter(void)
|
||||
{
|
||||
void sleep_mode_enter(void) {
|
||||
NRF_LOG_DEBUG("Entering deep sleep mode\n");
|
||||
NRF_LOG_FINAL_FLUSH();
|
||||
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.
|
||||
*/
|
||||
static void services_init(void)
|
||||
{
|
||||
static void services_init(void) {
|
||||
// Initialize EPD Service.
|
||||
memset(&m_epd, 0, sizeof(ble_epd_t));
|
||||
APP_ERROR_CHECK(ble_epd_init(&m_epd));
|
||||
@@ -316,8 +293,7 @@ static void services_init(void)
|
||||
* @details This function will set up all the necessary GAP (Generic Access Profile) parameters of
|
||||
* 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];
|
||||
ble_gap_addr_t addr;
|
||||
ble_gap_conn_params_t gap_conn_params;
|
||||
@@ -330,14 +306,11 @@ static void gap_params_init(void)
|
||||
APP_ERROR_CHECK(sd_ble_gap_address_get(&addr));
|
||||
#endif
|
||||
|
||||
NRF_LOG_INFO("Bluetooth MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
addr.addr[5], addr.addr[4], addr.addr[3],
|
||||
NRF_LOG_INFO("Bluetooth MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n", addr.addr[5], addr.addr[4], addr.addr[3],
|
||||
addr.addr[2], 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,
|
||||
(const uint8_t *)device_name,
|
||||
strlen(device_name)));
|
||||
APP_ERROR_CHECK(sd_ble_gap_device_name_set(&sec_mode, (const uint8_t*)device_name, strlen(device_name)));
|
||||
|
||||
memset(&gap_conn_params, 0, sizeof(gap_conn_params));
|
||||
|
||||
@@ -360,29 +333,21 @@ static void gap_params_init(void)
|
||||
*
|
||||
* @param[in] p_evt Event received from the Connection Parameters Module.
|
||||
*/
|
||||
static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
|
||||
{
|
||||
if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
|
||||
{
|
||||
static void on_conn_params_evt(ble_conn_params_evt_t* p_evt) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling errors from the Connection Parameters module.
|
||||
*
|
||||
* @param[in] nrf_error Error code containing information about what went wrong.
|
||||
*/
|
||||
static void conn_params_error_handler(uint32_t nrf_error)
|
||||
{
|
||||
APP_ERROR_HANDLER(nrf_error);
|
||||
}
|
||||
|
||||
static void conn_params_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); }
|
||||
|
||||
/**@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;
|
||||
|
||||
memset(&cp_init, 0, sizeof(cp_init));
|
||||
@@ -399,9 +364,7 @@ static void conn_params_init(void)
|
||||
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");
|
||||
#if defined(S112)
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling advertising events.
|
||||
*
|
||||
* @details This function will be called for advertising events which are passed to the application.
|
||||
*
|
||||
* @param[in] ble_adv_evt Advertising event.
|
||||
*/
|
||||
static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
|
||||
{
|
||||
switch (ble_adv_evt)
|
||||
{
|
||||
static void on_adv_evt(ble_adv_evt_t ble_adv_evt) {
|
||||
switch (ble_adv_evt) {
|
||||
case BLE_ADV_EVT_FAST:
|
||||
break;
|
||||
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.
|
||||
*/
|
||||
static void on_ble_evt(ble_evt_t * p_ble_evt)
|
||||
{
|
||||
switch (p_ble_evt->header.evt_id)
|
||||
{
|
||||
static void on_ble_evt(ble_evt_t* p_ble_evt) {
|
||||
switch (p_ble_evt->header.evt_id) {
|
||||
case BLE_GAP_EVT_CONNECTED:
|
||||
NRF_LOG_INFO("CONNECTED\n");
|
||||
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
|
||||
break;
|
||||
#if defined(S112)
|
||||
case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
|
||||
{
|
||||
case BLE_GAP_EVT_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,
|
||||
.tx_phys = BLE_GAP_PHY_AUTO,
|
||||
};
|
||||
@@ -496,7 +452,8 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
|
||||
|
||||
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
|
||||
// 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;
|
||||
|
||||
case BLE_GATTS_EVT_SYS_ATTR_MISSING:
|
||||
@@ -506,14 +463,14 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
|
||||
|
||||
case BLE_GATTC_EVT_TIMEOUT:
|
||||
// Disconnect on GATT Client timeout event.
|
||||
APP_ERROR_CHECK(sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
|
||||
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
|
||||
APP_ERROR_CHECK(
|
||||
sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
|
||||
break;
|
||||
|
||||
case BLE_GATTS_EVT_TIMEOUT:
|
||||
// Disconnect on GATT Server timeout event.
|
||||
APP_ERROR_CHECK(sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
|
||||
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
|
||||
APP_ERROR_CHECK(
|
||||
sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -522,15 +479,13 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(S112)
|
||||
/**@brief Function for handling BLE events.
|
||||
*
|
||||
* @param[in] p_ble_evt Bluetooth stack event.
|
||||
* @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);
|
||||
|
||||
on_ble_evt((ble_evt_t*)p_ble_evt);
|
||||
@@ -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.
|
||||
*/
|
||||
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_epd_on_ble_evt(&m_epd, 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);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for dispatching a system event to interested modules.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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
|
||||
// dispatched to the Flash Data Storage (FDS) module.
|
||||
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.
|
||||
*/
|
||||
static void ble_stack_init(void)
|
||||
{
|
||||
static void ble_stack_init(void) {
|
||||
#if defined(S112)
|
||||
APP_ERROR_CHECK(nrf_sdh_enable_request());
|
||||
|
||||
@@ -601,9 +552,8 @@ static void ble_stack_init(void)
|
||||
SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);
|
||||
|
||||
ble_enable_params_t ble_enable_params;
|
||||
APP_ERROR_CHECK(softdevice_enable_get_default_config(CENTRAL_LINK_COUNT,
|
||||
PERIPHERAL_LINK_COUNT,
|
||||
&ble_enable_params));
|
||||
APP_ERROR_CHECK(
|
||||
softdevice_enable_get_default_config(CENTRAL_LINK_COUNT, PERIPHERAL_LINK_COUNT, &ble_enable_params));
|
||||
ble_enable_params.common_enable_params.vs_uuid_count = 2;
|
||||
|
||||
// Check the ram settings against the used number of links
|
||||
@@ -622,29 +572,23 @@ static void ble_stack_init(void)
|
||||
|
||||
#if defined(S112)
|
||||
/**@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)
|
||||
{
|
||||
if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
|
||||
{
|
||||
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)) {
|
||||
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_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x",
|
||||
p_gatt->att_mtu_desired_central,
|
||||
NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x", p_gatt->att_mtu_desired_central,
|
||||
p_gatt->att_mtu_desired_periph);
|
||||
}
|
||||
|
||||
|
||||
/**@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_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE));
|
||||
}
|
||||
#else
|
||||
// Set BW Config to HIGH.
|
||||
static void ble_options_set(void)
|
||||
{
|
||||
static void ble_options_set(void) {
|
||||
ble_opt_t ble_opt;
|
||||
|
||||
memset(&ble_opt, 0, sizeof(ble_opt));
|
||||
@@ -659,8 +603,7 @@ static void ble_options_set(void)
|
||||
|
||||
/**@brief Function for initializing the Advertising functionality.
|
||||
*/
|
||||
static void advertising_init(void)
|
||||
{
|
||||
static void advertising_init(void) {
|
||||
#if defined(S112)
|
||||
ble_advertising_init_t init;
|
||||
|
||||
@@ -707,8 +650,7 @@ static void advertising_init(void)
|
||||
|
||||
/**@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));
|
||||
#if defined(S112)
|
||||
NRF_LOG_DEFAULT_BACKENDS_INIT();
|
||||
@@ -717,8 +659,7 @@ static void log_init(void)
|
||||
|
||||
/**@brief Function for initializing power management.
|
||||
*/
|
||||
static void power_management_init(void)
|
||||
{
|
||||
static void power_management_init(void) {
|
||||
#if defined(S112)
|
||||
APP_ERROR_CHECK(nrf_pwr_mgmt_init());
|
||||
#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.
|
||||
*/
|
||||
static void idle_state_handle(void)
|
||||
{
|
||||
static void idle_state_handle(void) {
|
||||
app_feed_wdt();
|
||||
|
||||
if (NRF_LOG_PROCESS() == false)
|
||||
nrf_pwr_mgmt_run();
|
||||
if (NRF_LOG_PROCESS() == false) nrf_pwr_mgmt_run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief WDT events handler.
|
||||
*/
|
||||
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 occurs
|
||||
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
|
||||
// occurs
|
||||
NRF_LOG_ERROR("WDT Rest!\r\n");
|
||||
NRF_LOG_FINAL_FLUSH();
|
||||
}
|
||||
|
||||
/**@brief Function for application main entry.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
int main(void) {
|
||||
log_init();
|
||||
|
||||
// Save reset reason.
|
||||
@@ -798,8 +736,7 @@ int main(void)
|
||||
ble_epd_on_timer(&m_epd, m_timestamp, true);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (;;) {
|
||||
app_sched_execute();
|
||||
idle_state_handle();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user