2019-11-17 19:47:04 +00:00
|
|
|
#include <FreeRTOS.h>
|
|
|
|
#include <task.h>
|
|
|
|
#include <libraries/bsp/bsp.h>
|
|
|
|
#include <legacy/nrf_drv_clock.h>
|
|
|
|
#include <libraries/timer/app_timer.h>
|
|
|
|
#include <libraries/gpiote/app_gpiote.h>
|
2019-12-05 20:19:47 +00:00
|
|
|
#include <DisplayApp/DisplayApp.h>
|
2019-12-21 16:58:00 +00:00
|
|
|
#include <softdevice/common/nrf_sdh.h>
|
|
|
|
#include <softdevice/common/nrf_sdh_freertos.h>
|
2019-12-26 17:33:40 +00:00
|
|
|
#include <hal/nrf_rtc.h>
|
|
|
|
#include <timers.h>
|
2019-12-27 14:11:21 +00:00
|
|
|
#include <libraries/log/nrf_log.h>
|
2019-12-28 13:34:50 +00:00
|
|
|
#include <ble/ble_services/ble_cts_c/ble_cts_c.h>
|
|
|
|
#include <Components/DateTime/DateTimeController.h>
|
2019-12-23 18:57:45 +00:00
|
|
|
#include "BLE/BleManager.h"
|
2019-12-27 15:05:35 +00:00
|
|
|
#include "Components/Battery/BatteryController.h"
|
2019-12-27 16:05:49 +00:00
|
|
|
#include "Components/Ble/BleController.h"
|
2019-11-17 19:47:04 +00:00
|
|
|
|
|
|
|
#if NRF_LOG_ENABLED
|
|
|
|
#include "Logging/NrfLogger.h"
|
|
|
|
Pinetime::Logging::NrfLogger logger;
|
|
|
|
#else
|
|
|
|
#include "Logging/DummyLogger.h"
|
|
|
|
Pinetime::Logging::DummyLogger logger;
|
|
|
|
#endif
|
|
|
|
|
2019-12-27 15:05:35 +00:00
|
|
|
std::unique_ptr<Pinetime::Applications::DisplayApp> displayApp;
|
2019-11-17 19:47:04 +00:00
|
|
|
TaskHandle_t systemThread;
|
2019-12-26 17:33:40 +00:00
|
|
|
bool isSleeping = false;
|
|
|
|
TimerHandle_t debounceTimer;
|
2019-12-27 15:05:35 +00:00
|
|
|
Pinetime::Controllers::Battery batteryController;
|
2019-12-27 16:05:49 +00:00
|
|
|
Pinetime::Controllers::Ble bleController;
|
2019-12-28 13:34:50 +00:00
|
|
|
Pinetime::Controllers::DateTime dateTimeController;
|
2019-11-17 19:47:04 +00:00
|
|
|
|
2020-01-03 15:32:31 +00:00
|
|
|
|
2020-01-12 15:39:03 +00:00
|
|
|
void ble_manager_set_ble_connection_callback(void (*connection)());
|
|
|
|
void ble_manager_set_ble_disconnection_callback(void (*disconnection)());
|
2020-01-03 15:32:31 +00:00
|
|
|
static constexpr uint8_t pinButton = 13;
|
|
|
|
static constexpr uint8_t pinTouchIrq = 28;
|
2020-01-18 12:56:25 +00:00
|
|
|
QueueHandle_t systemTaksMsgQueue;
|
|
|
|
enum class SystemTaskMessages {GoToSleep, GoToRunning};
|
|
|
|
void SystemTask_PushMessage(SystemTaskMessages message);
|
2020-01-03 15:32:31 +00:00
|
|
|
|
2019-12-26 17:33:40 +00:00
|
|
|
void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
|
2020-01-03 15:32:31 +00:00
|
|
|
if(pin == pinTouchIrq) {
|
|
|
|
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::TouchEvent);
|
|
|
|
if(!isSleeping) return;
|
|
|
|
}
|
|
|
|
|
2019-12-26 17:33:40 +00:00
|
|
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
|
|
|
xTimerStartFromISR(debounceTimer, &xHigherPriorityTaskWoken);
|
2020-01-09 21:00:54 +00:00
|
|
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
2019-12-26 17:33:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DebounceTimerCallback(TimerHandle_t xTimer) {
|
|
|
|
xTimerStop(xTimer, 0);
|
|
|
|
if(isSleeping) {
|
2020-01-18 12:56:25 +00:00
|
|
|
SystemTask_PushMessage(SystemTaskMessages::GoToRunning);
|
2019-12-27 15:05:35 +00:00
|
|
|
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToRunning);
|
2019-12-26 17:33:40 +00:00
|
|
|
isSleeping = false;
|
2019-12-27 15:05:35 +00:00
|
|
|
batteryController.Update();
|
2019-12-28 13:34:50 +00:00
|
|
|
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBatteryLevel);
|
2019-12-26 17:33:40 +00:00
|
|
|
}
|
|
|
|
else {
|
2020-01-18 12:56:25 +00:00
|
|
|
SystemTask_PushMessage(SystemTaskMessages::GoToSleep);
|
2019-12-27 15:05:35 +00:00
|
|
|
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep);
|
2019-12-26 17:33:40 +00:00
|
|
|
isSleeping = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-18 12:56:25 +00:00
|
|
|
void SystemTask_PushMessage(SystemTaskMessages message) {
|
|
|
|
BaseType_t xHigherPriorityTaskWoken;
|
|
|
|
xHigherPriorityTaskWoken = pdFALSE;
|
|
|
|
xQueueSendFromISR(systemTaksMsgQueue, &message, &xHigherPriorityTaskWoken);
|
|
|
|
if (xHigherPriorityTaskWoken) {
|
|
|
|
/* Actual macro used here is port specific. */
|
|
|
|
// TODO : should I do something here?
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO The whole SystemTask should go in its own class
|
2019-11-17 19:47:04 +00:00
|
|
|
void SystemTask(void *) {
|
|
|
|
APP_GPIOTE_INIT(2);
|
2019-12-21 16:58:00 +00:00
|
|
|
bool erase_bonds=false;
|
2019-12-23 18:57:45 +00:00
|
|
|
nrf_sdh_freertos_init(ble_manager_start_advertising, &erase_bonds);
|
2019-12-27 15:05:35 +00:00
|
|
|
displayApp->Start();
|
|
|
|
|
|
|
|
batteryController.Init();
|
|
|
|
batteryController.Update();
|
2019-12-28 13:34:50 +00:00
|
|
|
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBatteryLevel);
|
2019-11-17 19:47:04 +00:00
|
|
|
|
2019-12-26 17:33:40 +00:00
|
|
|
debounceTimer = xTimerCreate ("debounceTimer", 200, pdFALSE, (void *) 0, DebounceTimerCallback);
|
|
|
|
|
2020-01-03 15:32:31 +00:00
|
|
|
nrf_gpio_cfg_sense_input(pinButton, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pulldown, (nrf_gpio_pin_sense_t)GPIO_PIN_CNF_SENSE_High);
|
2019-12-26 17:33:40 +00:00
|
|
|
nrf_gpio_cfg_output(15);
|
|
|
|
nrf_gpio_pin_set(15);
|
|
|
|
|
|
|
|
nrfx_gpiote_in_config_t pinConfig;
|
|
|
|
pinConfig.skip_gpio_setup = true;
|
|
|
|
pinConfig.hi_accuracy = false;
|
|
|
|
pinConfig.is_watcher = false;
|
|
|
|
pinConfig.sense = (nrf_gpiote_polarity_t)NRF_GPIOTE_POLARITY_HITOLO;
|
|
|
|
pinConfig.pull = (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pulldown;
|
|
|
|
|
2020-01-03 15:32:31 +00:00
|
|
|
nrfx_gpiote_in_init(pinButton, &pinConfig, nrfx_gpiote_evt_handler);
|
|
|
|
|
|
|
|
nrf_gpio_cfg_sense_input(pinTouchIrq, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup, (nrf_gpio_pin_sense_t)GPIO_PIN_CNF_SENSE_Low);
|
|
|
|
|
|
|
|
pinConfig.skip_gpio_setup = true;
|
|
|
|
pinConfig.hi_accuracy = false;
|
|
|
|
pinConfig.is_watcher = false;
|
|
|
|
pinConfig.sense = (nrf_gpiote_polarity_t)NRF_GPIOTE_POLARITY_HITOLO;
|
|
|
|
pinConfig.pull = (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup;
|
|
|
|
|
|
|
|
nrfx_gpiote_in_init(pinTouchIrq, &pinConfig, nrfx_gpiote_evt_handler);
|
2020-01-18 12:56:25 +00:00
|
|
|
|
|
|
|
systemTaksMsgQueue = xQueueCreate(10, 1);
|
|
|
|
bool systemTaskSleeping = false;
|
|
|
|
|
|
|
|
while(true) {
|
|
|
|
uint8_t msg;
|
|
|
|
|
|
|
|
if (xQueueReceive(systemTaksMsgQueue, &msg, systemTaskSleeping?3600000 : 1000)) {
|
|
|
|
SystemTaskMessages message = static_cast<SystemTaskMessages >(msg);
|
|
|
|
switch(message) {
|
|
|
|
case SystemTaskMessages::GoToRunning: systemTaskSleeping = false; break;
|
|
|
|
case SystemTaskMessages::GoToSleep: systemTaskSleeping = true; break;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG);
|
|
|
|
dateTimeController.UpdateTime(systick_counter);
|
|
|
|
}
|
2019-11-17 19:47:04 +00:00
|
|
|
}
|
|
|
|
|
2020-01-12 15:39:03 +00:00
|
|
|
void OnBleConnection() {
|
2019-12-27 16:05:49 +00:00
|
|
|
bleController.Connect();
|
2019-12-28 13:34:50 +00:00
|
|
|
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBleConnection);
|
2020-01-12 15:39:03 +00:00
|
|
|
}
|
2019-12-28 13:34:50 +00:00
|
|
|
|
2020-01-12 15:39:03 +00:00
|
|
|
void OnBleDisconnection() {
|
|
|
|
bleController.Disconnect();
|
|
|
|
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBleConnection);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OnNewTime(current_time_char_t* currentTime) {
|
2019-12-28 13:34:50 +00:00
|
|
|
auto dayOfWeek = currentTime->exact_time_256.day_date_time.day_of_week;
|
|
|
|
auto year = currentTime->exact_time_256.day_date_time.date_time.year;
|
|
|
|
auto month = currentTime->exact_time_256.day_date_time.date_time.month;
|
|
|
|
auto day = currentTime->exact_time_256.day_date_time.date_time.day;
|
|
|
|
auto hour = currentTime->exact_time_256.day_date_time.date_time.hours;
|
|
|
|
auto minute = currentTime->exact_time_256.day_date_time.date_time.minutes;
|
|
|
|
auto second = currentTime->exact_time_256.day_date_time.date_time.seconds;
|
2020-01-18 12:56:25 +00:00
|
|
|
|
|
|
|
dateTimeController.SetTime(year, month, day,
|
|
|
|
dayOfWeek, hour, minute, second, nrf_rtc_counter_get(portNRF_RTC_REG));
|
2019-12-21 16:58:00 +00:00
|
|
|
}
|
|
|
|
|
2019-11-17 19:47:04 +00:00
|
|
|
int main(void) {
|
2019-12-28 13:34:50 +00:00
|
|
|
displayApp.reset(new Pinetime::Applications::DisplayApp(batteryController, bleController, dateTimeController));
|
2019-11-17 19:47:04 +00:00
|
|
|
logger.Init();
|
|
|
|
nrf_drv_clock_init();
|
|
|
|
|
|
|
|
if (pdPASS != xTaskCreate(SystemTask, "MAIN", 256, nullptr, 0, &systemThread))
|
|
|
|
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
|
|
|
|
|
2019-12-23 18:57:45 +00:00
|
|
|
ble_manager_init();
|
2020-01-12 15:39:03 +00:00
|
|
|
ble_manager_set_new_time_callback(OnNewTime);
|
|
|
|
ble_manager_set_ble_connection_callback(OnBleConnection);
|
|
|
|
ble_manager_set_ble_disconnection_callback(OnBleDisconnection);
|
2019-12-21 16:58:00 +00:00
|
|
|
|
2019-11-17 19:47:04 +00:00
|
|
|
vTaskStartScheduler();
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
APP_ERROR_HANDLER(NRF_ERROR_FORBIDDEN);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-01-12 15:39:03 +00:00
|
|
|
|