InfiniTime/src/main.cpp

344 lines
11 KiB
C++
Raw Normal View History

2020-11-15 09:05:51 -05:00
// nrf
#include <hal/nrf_rtc.h>
#include <hal/nrf_wdt.h>
2020-11-15 09:05:51 -05:00
#include <legacy/nrf_drv_clock.h>
2019-11-17 14:47:04 -05:00
#include <libraries/gpiote/app_gpiote.h>
2020-11-15 09:05:51 -05:00
#include <libraries/timer/app_timer.h>
#include <softdevice/common/nrf_sdh.h>
2021-08-09 14:49:35 -04:00
#include <nrf_delay.h>
2020-11-15 09:05:51 -05:00
// nimble
#define min // workaround: nimble's min/max macros conflict with libstdc++
#define max
#include <controller/ble_ll.h>
2020-11-15 09:05:51 -05:00
#include <host/ble_hs.h>
#include <host/util/util.h>
2020-11-15 09:05:51 -05:00
#include <nimble/nimble_port.h>
#include <nimble/nimble_port_freertos.h>
#include <nimble/npl_freertos.h>
#include <os/os_cputime.h>
#include <services/gap/ble_svc_gap.h>
2020-11-15 09:05:51 -05:00
#include <transport/ram/ble_hci_ram.h>
#undef max
#undef min
// FreeRTOS
#include <FreeRTOS.h>
#include <task.h>
#include <timers.h>
#include <drivers/Hrs3300.h>
#include <drivers/Bma421.h>
#include "BootloaderVersion.h"
2020-11-15 09:05:51 -05:00
#include "components/battery/BatteryController.h"
#include "components/ble/BleController.h"
#include "components/ble/NotificationManager.h"
#include "components/motor/MotorController.h"
2020-11-15 09:05:51 -05:00
#include "components/datetime/DateTimeController.h"
#include "components/heartrate/HeartRateController.h"
#include "components/fs/FS.h"
2020-11-15 09:05:51 -05:00
#include "drivers/Spi.h"
#include "drivers/SpiMaster.h"
#include "drivers/SpiNorFlash.h"
#include "drivers/St7789.h"
#include "drivers/TwiMaster.h"
#include "drivers/Cst816s.h"
#include "systemtask/SystemTask.h"
2019-11-17 14:47:04 -05:00
#if NRF_LOG_ENABLED
#include "logging/NrfLogger.h"
2019-11-17 14:47:04 -05:00
Pinetime::Logging::NrfLogger logger;
#else
#include "logging/DummyLogger.h"
2019-11-17 14:47:04 -05:00
Pinetime::Logging::DummyLogger logger;
#endif
static constexpr uint8_t pinSpiSck = 2;
static constexpr uint8_t pinSpiMosi = 3;
static constexpr uint8_t pinSpiMiso = 4;
2020-05-07 13:53:51 -04:00
static constexpr uint8_t pinSpiFlashCsn = 5;
static constexpr uint8_t pinLcdCsn = 25;
static constexpr uint8_t pinLcdDataCommand = 18;
static constexpr uint8_t pinTwiScl = 7;
static constexpr uint8_t pinTwiSda = 6;
static constexpr uint8_t touchPanelTwiAddress = 0x15;
static constexpr uint8_t motionSensorTwiAddress = 0x18;
static constexpr uint8_t heartRateSensorTwiAddress = 0x44;
Pinetime::Drivers::SpiMaster spi {Pinetime::Drivers::SpiMaster::SpiModule::SPI0,
{Pinetime::Drivers::SpiMaster::BitOrder::Msb_Lsb,
Pinetime::Drivers::SpiMaster::Modes::Mode3,
Pinetime::Drivers::SpiMaster::Frequencies::Freq8Mhz,
pinSpiSck,
pinSpiMosi,
pinSpiMiso}};
2020-05-07 13:53:51 -04:00
Pinetime::Drivers::Spi lcdSpi {spi, pinLcdCsn};
Pinetime::Drivers::St7789 lcd {lcdSpi, pinLcdDataCommand};
Pinetime::Drivers::Spi flashSpi {spi, pinSpiFlashCsn};
Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi};
// The TWI device should work @ up to 400Khz but there is a HW bug which prevent it from
// respecting correct timings. According to erratas heet, this magic value makes it run
// at ~390Khz with correct timings.
static constexpr uint32_t MaxTwiFrequencyWithoutHardwareBug {0x06200000};
Pinetime::Drivers::TwiMaster twiMaster {Pinetime::Drivers::TwiMaster::Modules::TWIM1,
Pinetime::Drivers::TwiMaster::Parameters {MaxTwiFrequencyWithoutHardwareBug, pinTwiSda, pinTwiScl}};
Pinetime::Drivers::Cst816S touchPanel {twiMaster, touchPanelTwiAddress};
#ifdef PINETIME_IS_RECOVERY
static constexpr bool isFactory = true;
#include "displayapp/DummyLittleVgl.h"
#include "displayapp/DisplayAppRecovery.h"
Pinetime::Components::LittleVgl lvgl {lcd, touchPanel};
#else
static constexpr bool isFactory = false;
#include "displayapp/LittleVgl.h"
#include "displayapp/DisplayApp.h"
Pinetime::Components::LittleVgl lvgl {lcd, touchPanel};
#endif
Pinetime::Drivers::Bma421 motionSensor {twiMaster, motionSensorTwiAddress};
Pinetime::Drivers::Hrs3300 heartRateSensor {twiMaster, heartRateSensorTwiAddress};
TimerHandle_t debounceTimer;
TimerHandle_t debounceChargeTimer;
Pinetime::Controllers::Battery batteryController;
Pinetime::Controllers::Ble bleController;
void ble_manager_set_ble_connection_callback(void (*connection)());
void ble_manager_set_ble_disconnection_callback(void (*disconnection)());
static constexpr uint8_t pinTouchIrq = 28;
static constexpr uint8_t pinPowerPresentIrq = 19;
Pinetime::Controllers::HeartRateController heartRateController;
Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController);
Pinetime::Controllers::DateTime dateTimeController;
Pinetime::Drivers::Watchdog watchdog;
Pinetime::Drivers::WatchdogView watchdogView(watchdog);
Pinetime::Controllers::NotificationManager notificationManager;
Pinetime::Controllers::MotionController motionController;
Pinetime::Controllers::TimerController timerController;
Pinetime::Controllers::FS fs {spiNorFlash};
Pinetime::Controllers::Settings settingsController {fs};
Pinetime::Controllers::MotorController motorController {settingsController};
Pinetime::Applications::DisplayApp displayApp(lcd,
lvgl,
touchPanel,
batteryController,
bleController,
dateTimeController,
watchdogView,
notificationManager,
heartRateController,
settingsController,
motorController,
motionController,
timerController);
Pinetime::System::SystemTask systemTask(spi,
lcd,
spiNorFlash,
twiMaster,
touchPanel,
lvgl,
batteryController,
bleController,
dateTimeController,
timerController,
watchdog,
notificationManager,
motorController,
heartRateSensor,
motionController,
motionSensor,
settingsController,
heartRateController,
displayApp,
heartRateApp,
fs);
2021-08-17 19:53:57 -04:00
uint32_t MAGIC_RAM __attribute__((section(".noinit")));
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> BackUpTime __attribute__((section(".noinit")));
void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
if (pin == pinTouchIrq) {
systemTask.OnTouchEvent();
return;
}
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if (pin == pinPowerPresentIrq and action == NRF_GPIOTE_POLARITY_TOGGLE) {
xTimerStartFromISR(debounceChargeTimer, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
return;
}
xTimerStartFromISR(debounceTimer, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void DebounceTimerChargeCallback(TimerHandle_t xTimer) {
xTimerStop(xTimer, 0);
systemTask.PushMessage(Pinetime::System::Messages::OnChargingEvent);
}
void DebounceTimerCallback(TimerHandle_t xTimer) {
xTimerStop(xTimer, 0);
systemTask.OnButtonPushed();
2019-11-17 14:47:04 -05:00
}
void SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler(void) {
if (((NRF_SPIM0->INTENSET & (1 << 6)) != 0) && NRF_SPIM0->EVENTS_END == 1) {
NRF_SPIM0->EVENTS_END = 0;
spi.OnEndEvent();
}
if (((NRF_SPIM0->INTENSET & (1 << 19)) != 0) && NRF_SPIM0->EVENTS_STARTED == 1) {
NRF_SPIM0->EVENTS_STARTED = 0;
spi.OnStartedEvent();
}
if (((NRF_SPIM0->INTENSET & (1 << 1)) != 0) && NRF_SPIM0->EVENTS_STOPPED == 1) {
NRF_SPIM0->EVENTS_STOPPED = 0;
}
}
static void (*radio_isr_addr)(void);
static void (*rng_isr_addr)(void);
static void (*rtc0_isr_addr)(void);
/* Some interrupt handlers required for NimBLE radio driver */
extern "C" {
void RADIO_IRQHandler(void) {
((void (*)(void)) radio_isr_addr)();
}
void RNG_IRQHandler(void) {
((void (*)(void)) rng_isr_addr)();
}
void RTC0_IRQHandler(void) {
((void (*)(void)) rtc0_isr_addr)();
}
void WDT_IRQHandler(void) {
nrf_wdt_event_clear(NRF_WDT_EVENT_TIMEOUT);
}
void npl_freertos_hw_set_isr(int irqn, void (*addr)(void)) {
switch (irqn) {
case RADIO_IRQn:
radio_isr_addr = addr;
break;
case RNG_IRQn:
rng_isr_addr = addr;
break;
case RTC0_IRQn:
rtc0_isr_addr = addr;
break;
}
}
uint32_t npl_freertos_hw_enter_critical(void) {
uint32_t ctx = __get_PRIMASK();
__disable_irq();
return (ctx & 0x01);
}
void npl_freertos_hw_exit_critical(uint32_t ctx) {
if (!ctx) {
__enable_irq();
}
}
static struct ble_npl_eventq g_eventq_dflt;
struct ble_npl_eventq* nimble_port_get_dflt_eventq(void) {
return &g_eventq_dflt;
}
void nimble_port_run(void) {
struct ble_npl_event* ev;
while (1) {
ev = ble_npl_eventq_get(&g_eventq_dflt, BLE_NPL_TIME_FOREVER);
ble_npl_event_run(ev);
}
}
void BleHost(void*) {
nimble_port_run();
}
void nimble_port_init(void) {
void os_msys_init(void);
void ble_store_ram_init(void);
ble_npl_eventq_init(&g_eventq_dflt);
os_msys_init();
ble_hs_init();
ble_store_ram_init();
2020-05-02 11:42:26 -04:00
int res;
res = hal_timer_init(5, NULL);
ASSERT(res == 0);
res = os_cputime_init(32768);
ASSERT(res == 0);
ble_ll_init();
ble_hci_ram_init();
nimble_port_freertos_init(BleHost);
}
void nimble_port_ll_task_func(void* args) {
extern void ble_ll_task(void*);
ble_ll_task(args);
}
}
2019-11-17 14:47:04 -05:00
int main(void) {
logger.Init();
2019-11-17 14:47:04 -05:00
nrf_drv_clock_init();
2021-08-09 14:49:35 -04:00
// Unblock i2c?
2021-08-09 15:07:06 -04:00
nrf_gpio_cfg(pinTwiScl,
NRF_GPIO_PIN_DIR_OUTPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_NOPULL,
NRF_GPIO_PIN_S0D1,
NRF_GPIO_PIN_NOSENSE);
2021-08-09 15:11:35 -04:00
nrf_gpio_pin_set(pinTwiScl);
2021-08-09 14:49:35 -04:00
for (uint8_t i = 0; i < 16; i++) {
nrf_gpio_pin_toggle(pinTwiScl);
nrf_delay_us(5);
}
nrf_gpio_cfg_default(pinTwiScl);
debounceTimer = xTimerCreate("debounceTimer", 200, pdFALSE, (void*) 0, DebounceTimerCallback);
debounceChargeTimer = xTimerCreate("debounceTimerCharge", 200, pdFALSE, (void*) 0, DebounceTimerChargeCallback);
// retrieve version stored by bootloader
Pinetime::BootloaderVersion::SetVersion(NRF_TIMER2->CC[0]);
2021-08-17 19:53:57 -04:00
// Check Magic Ram and reset lost variables
if (MAGIC_RAM == 0xDEADBEEF) {
dateTimeController.SetCurrentTime(BackUpTime);
} else {
MAGIC_RAM = 0xDEADBEEF;
}
lvgl.Init();
systemTask.Start();
nimble_port_init();
2019-11-17 14:47:04 -05:00
vTaskStartScheduler();
for (;;) {
APP_ERROR_HANDLER(NRF_ERROR_FORBIDDEN);
}
}