add calendar support

This commit is contained in:
Shuanglei Tao
2025-02-09 18:26:43 +08:00
parent 147181e2f8
commit 9d6cbff256
26 changed files with 3351 additions and 1706 deletions

176
main.c
View File

@@ -24,7 +24,9 @@
#include "fstorage.h"
#include "app_error.h"
#include "app_timer.h"
#include "nrf_drv_gpiote.h"
#include "EPD_ble.h"
#include "Calendar.h"
#define NRF_LOG_MODULE_NAME "main"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
@@ -33,8 +35,8 @@
#define PERIPHERAL_LINK_COUNT 1 /**< Number of peripheral links used by the application. When changing this number remember to adjust the RAM settings*/
#define DEVICE_NAME "NRF_EPD" /**< Name of device. Will be included in the advertising data. */
#define APP_ADV_INTERVAL 300 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
#define APP_ADV_TIMEOUT_IN_SECONDS 180 /**< The advertising timeout (in units of seconds). */
#define APP_ADV_INTERVAL 320 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
#define APP_ADV_TIMEOUT_IN_SECONDS 120 /**< The advertising timeout (in units of seconds). */
#define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */
#define APP_TIMER_OP_QUEUE_SIZE 4 /**< Size of timer operation queues. */
@@ -47,11 +49,37 @@
#define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(30000, APP_TIMER_PRESCALER) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */
#define CLOCK_TIMER_INTERVAL APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER) /**< Clock timer interval (ticks). */
#define DEAD_BEEF 0xDEADBEEF /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
static uint16_t m_driver_refs = 0;
static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
static ble_uuid_t m_adv_uuids[] = {{BLE_UUID_EPD_SERVICE, EPD_SERVICE_UUID_TYPE}}; /**< Universally unique service identifier. */
static ble_epd_t m_epd; /**< Structure to identify the EPD Service. */
static uint32_t m_timestamp = 1735689600; /**< Current timestamp. */
static bool m_update_calendar = false; /**< Update calendar if true */
static bool m_calendar_mode = false; /**< Whether we are in calendar mode */
APP_TIMER_DEF(m_clock_timer_id); /**< Clock timer. */
static void epd_driver_init()
{
if (m_driver_refs == 0) {
NRF_LOG_DEBUG("[EPD]: driver init\n");
DEV_Module_Init();
}
m_driver_refs++;
}
static void epd_driver_exit()
{
m_driver_refs--;
if (m_driver_refs == 0) {
NRF_LOG_DEBUG("[EPD]: driver exit\n");
DEV_Module_Exit();
}
}
/**@brief Callback function for asserts in the SoftDevice.
*
@@ -69,6 +97,19 @@ void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
app_error_handler(DEAD_BEEF, line_num, p_file_name);
}
static void clock_timer_timeout_handler(void * p_context)
{
UNUSED_PARAMETER(p_context);
m_timestamp++;
// Update calendar on 00:00:00
if (m_calendar_mode && m_timestamp % 86400 == 0)
{
m_update_calendar = true;
}
}
/**@brief Function for the Timer initialization.
*
* @details Initializes the timer module. This creates and starts application timers.
@@ -77,6 +118,54 @@ static void timers_init(void)
{
// Initialize timer module.
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
// Create timers.
uint32_t err_code = app_timer_create(&m_clock_timer_id,
APP_TIMER_MODE_REPEATED,
clock_timer_timeout_handler);
APP_ERROR_CHECK(err_code);
}
/**@brief Function for starting application timers.
*/
static void application_timers_start(void)
{
// Start application timers.
uint32_t err_code = app_timer_start(m_clock_timer_id, CLOCK_TIMER_INTERVAL, NULL);
APP_ERROR_CHECK(err_code);
}
bool epd_cmd_callback(uint8_t cmd, uint8_t *data, uint16_t len)
{
switch (cmd)
{
case EPD_CMD_SET_TIME:
if (len < 4) {
NRF_LOG_DEBUG("invalid time data!\n");
return false;
}
NRF_LOG_DEBUG("time: %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3]);
if (len > 4) {
NRF_LOG_DEBUG("timezone: %d\n", (int8_t)data[4]);
}
app_timer_stop(m_clock_timer_id);
m_timestamp = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
m_timestamp += (len > 4 ? (int8_t)data[4] : 8) * 60 * 60; // timezone
app_timer_start(m_clock_timer_id, CLOCK_TIMER_INTERVAL, NULL);
m_calendar_mode = true;
m_update_calendar = true;
return true;
case EPD_CMD_CLEAR:
case EPD_CMD_DISPLAY:
m_calendar_mode = false;
break;
default:
break;
}
return false;
}
/**@brief Function for initializing services that will be used by the application.
@@ -89,7 +178,7 @@ static void services_init(void)
APP_ERROR_CHECK(err_code);
memset(&m_epd, 0, sizeof(ble_epd_t));
err_code = ble_epd_init(&m_epd);
err_code = ble_epd_init(&m_epd, epd_cmd_callback);
APP_ERROR_CHECK(err_code);
}
@@ -188,12 +277,21 @@ static void conn_params_init(void)
}
static void advertising_start(void)
{
NRF_LOG_INFO("advertising start\n");
uint32_t err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
APP_ERROR_CHECK(err_code);
}
/**@brief Function for putting the chip into sleep mode.
*
* @note This function will not return.
*/
static void sleep_mode_enter(void)
{
NRF_LOG_DEBUG("Entering deep sleep mode\n");
// Prepare wakeup pin
ble_epd_sleep_prepare(&m_epd);
@@ -202,6 +300,30 @@ static void sleep_mode_enter(void)
APP_ERROR_CHECK(err_code);
}
void gpiote_evt_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
NRF_LOG_DEBUG("pin: %d, event: %d\n", pin, action);
nrf_drv_gpiote_in_event_disable(pin);
nrf_drv_gpiote_in_uninit(pin);
nrf_drv_gpiote_uninit();
advertising_start();
}
static void setup_wakeup_pin(nrf_drv_gpiote_pin_t pin) {
NRF_LOG_DEBUG("Setting up wakeup pin\n");
ret_code_t err_code = nrf_drv_gpiote_init();
APP_ERROR_CHECK(err_code);
nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);
err_code = nrf_drv_gpiote_in_init(pin, &config, gpiote_evt_handler);
APP_ERROR_CHECK(err_code);
nrf_drv_gpiote_in_event_enable(pin, true);
}
/**@brief Function for handling advertising events.
*
@@ -216,7 +338,12 @@ static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
case BLE_ADV_EVT_FAST:
break;
case BLE_ADV_EVT_IDLE:
sleep_mode_enter();
NRF_LOG_INFO("advertising timeout\n");
if (m_calendar_mode) {
setup_wakeup_pin(m_epd.config.wakeup_pin);
} else {
sleep_mode_enter();
}
break;
default:
break;
@@ -236,13 +363,14 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
case BLE_GAP_EVT_CONNECTED:
NRF_LOG_INFO("CONNECTED\n");
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
epd_driver_init();
break;
case BLE_GAP_EVT_DISCONNECTED:
NRF_LOG_INFO("DISCONNECTED\n");
m_conn_handle = BLE_CONN_HANDLE_INVALID;
err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
APP_ERROR_CHECK(err_code);
epd_driver_exit();
advertising_start();
break;
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
@@ -404,13 +532,31 @@ static void power_manage(void)
APP_ERROR_CHECK(err_code);
}
static void calendar_update(void)
{
if (!m_update_calendar) return;
m_update_calendar = false;
epd_driver_init();
m_epd.driver->init();
DrawCalendar(m_timestamp);
epd_driver_exit();
}
#if NRF_MODULE_ENABLED(NRF_LOG)
static uint32_t timestamp_func(void)
{
return m_timestamp;
}
#endif
/**@brief Function for application main entry.
*/
int main(void)
{
uint32_t err_code;
err_code = NRF_LOG_INIT(NULL);
err_code = NRF_LOG_INIT(timestamp_func);
APP_ERROR_CHECK(err_code);
NRF_LOG_DEBUG("init..\n");
@@ -424,16 +570,20 @@ int main(void)
conn_params_init();
NRF_LOG_DEBUG("start..\n");
err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
APP_ERROR_CHECK(err_code);
// Start execution.
application_timers_start();
advertising_start();
NRF_LOG_DEBUG("done.\n");
for (;;)
{
if (NRF_LOG_PROCESS() == false)
{
power_manage();
}
while(NRF_LOG_PROCESS());
calendar_update();
power_manage();
}
}