// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "pit.hpp" #include #include #include #include #include struct PIT_t { uint32_t usec = 1000000; xQueueHandle qhandle = nullptr; std::function irq_cb; }; static PIT_t LPIT; static void pit_init(xQueueHandle qhandle); static void pit_start(uint32_t usec, std::function cb); static void pit_stop(); namespace bsp { namespace pit { void init(xQueueHandle qhandle) { pit_init(qhandle); } void start(uint32_t usec, std::function cb) { pit_start(usec, cb); } void stop() { pit_stop(); } }; // namespace pit }; // namespace bsp /// bsp static void pit_init(xQueueHandle qhandle) { LPIT.qhandle = qhandle; pit_config_t pitConfig; PIT_GetDefaultConfig(&pitConfig); PIT_Init(PIT, &pitConfig); } static void pit_start(uint32_t usec, std::function cb) { LPIT.usec = usec; DisableIRQ(PIT_IRQn); PIT_DisableInterrupts(PIT, kPIT_Chnl_0, kPIT_TimerInterruptEnable); PIT_SetTimerPeriod(PIT, kPIT_Chnl_0, USEC_TO_COUNT(usec, CLOCK_GetFreq(kCLOCK_OscClk))); LPIT.irq_cb = cb; PIT_EnableInterrupts(PIT, kPIT_Chnl_0, kPIT_TimerInterruptEnable); EnableIRQ(PIT_IRQn); PIT_StartTimer(PIT, kPIT_Chnl_0); } static void pit_stop() { PIT_StopTimer(PIT, kPIT_Chnl_0); } extern "C" { void PIT_IRQHandler(void) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; if (LPIT.qhandle) { auto val = bsp::pit::Event::Overflow; xQueueSendFromISR(LPIT.qhandle, &val, &xHigherPriorityTaskWoken); } PIT_ClearStatusFlags(PIT, kPIT_Chnl_0, kPIT_TimerFlag); __DSB(); /// stop timer - we are interested in one time run pit_stop(); if (LPIT.irq_cb) LPIT.irq_cb(); portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } };