Commit e83b60a8 authored by Sandeep Mistry's avatar Sandeep Mistry

Use RTC1 for mills, micros, and delay (instead of SysTick)

parent a4c68659
......@@ -16,7 +16,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "nrf.h"
#include "nrf_rtc.h"
#include "delay.h"
#include "Arduino.h"
......@@ -25,42 +25,20 @@
extern "C" {
#endif
/** Tick Counter united by ms */
static volatile uint32_t _ulTickCount=0 ;
static volatile uint32_t overflows = 0;
uint32_t millis( void )
{
// todo: ensure no interrupts
return _ulTickCount ;
uint64_t ticks = (uint64_t)(overflows << (uint64_t)32) | (uint64_t)nrf_rtc_counter_get(NRF_RTC1);
return (ticks * 1000) / RTC_INPUT_FREQ;
}
// Interrupt-compatible version of micros
// Theory: repeatedly take readings of SysTick counter, millis counter and SysTick interrupt pending flag.
// When it appears that millis counter and pending is stable and SysTick hasn't rolled over, use these
// values to calculate micros. If there is a pending SysTick, add one to the millis counter in the calculation.
uint32_t micros( void )
{
uint32_t ticks, ticks2;
uint32_t pend, pend2;
uint32_t count, count2;
ticks2 = SysTick->VAL;
pend2 = !!(SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) ;
count2 = _ulTickCount ;
uint64_t ticks = (uint64_t)(overflows << (uint64_t)32) | (uint64_t)nrf_rtc_counter_get(NRF_RTC1);
do
{
ticks=ticks2;
pend=pend2;
count=count2;
ticks2 = SysTick->VAL;
pend2 = !!(SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) ;
count2 = _ulTickCount ;
} while ((pend != pend2) || (count != count2) || (ticks < ticks2));
return ((count+pend) * 1000) + (((SysTick->LOAD - ticks)*(1048576/(VARIANT_MCK/1000000)))>>20) ;
// this is an optimization to turn a runtime division into two compile-time divisions and
// a runtime multiplication and shift, saving a few cycles
return (ticks * 1000000) / RTC_INPUT_FREQ;
}
void delay( uint32_t ms )
......@@ -70,18 +48,19 @@ void delay( uint32_t ms )
return ;
}
uint32_t start = _ulTickCount ;
uint32_t start = millis() ;
do
{
yield() ;
} while ( _ulTickCount - start < ms ) ;
} while ( millis() - start < ms ) ;
}
void SysTick_Handler(void)
void RTC1_IRQHandler(void)
{
// Increment tick count each ms
_ulTickCount++;
nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_EVENT_OVERFLOW);
overflows = (overflows + 1) & 0xff;
}
#ifdef __cplusplus
......
......@@ -29,7 +29,9 @@
#include <stddef.h>
#include <stdbool.h>
#include "nrf.h"
#ifndef ARDUINO
#include "nrf_assert.h"
#endif
/**
* @brief Macro for getting the number of compare channels available
......@@ -268,7 +270,9 @@ __STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type * p_rtc)
__STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_rtc, uint32_t val)
{
#ifndef ARDUINO
ASSERT(val <= (RTC_PRESCALER_PRESCALER_Msk >> RTC_PRESCALER_PRESCALER_Pos));
#endif
p_rtc->PRESCALER = val;
}
__STATIC_INLINE uint32_t rtc_prescaler_get(NRF_RTC_Type * p_rtc)
......
......@@ -16,7 +16,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "nrf.h"
#include "nrf_clock.h"
#include "nrf_rtc.h"
#include "Arduino.h"
......@@ -24,22 +25,19 @@
extern "C" {
#endif
/*
* Arduino Zero board initialization
*
* Good to know:
* - At reset, ResetHandler did the system clock configuration. Core is running at 48MHz.
* - Watchdog is disabled by default, unless someone plays with NVM User page
* - During reset, all PORT lines are configured as inputs with input buffers, output buffers and pull disabled.
*/
void init( void )
{
// Set Systick to 1ms interval, common to all Cortex-M variants
if ( SysTick_Config( SystemCoreClock / 1000 ) )
{
// Capture error
while ( 1 ) ;
}
NVIC_SetPriority(RTC1_IRQn, 15);
NVIC_ClearPendingIRQ(RTC1_IRQn);
NVIC_EnableIRQ(RTC1_IRQn);
nrf_clock_lf_src_set(CLOCK_LFCLKSRC_SRC_RC);
nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART);
nrf_rtc_prescaler_set(NRF_RTC1, 0);
nrf_rtc_event_enable(NRF_RTC1, NRF_RTC_EVENT_OVERFLOW);
nrf_rtc_int_enable(NRF_RTC1, NRF_RTC_EVENT_OVERFLOW);
nrf_rtc_task_trigger(NRF_RTC1, NRF_RTC_TASK_START);
}
#ifdef __cplusplus
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment