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 @@ ...@@ -16,7 +16,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "nrf.h" #include "nrf_rtc.h"
#include "delay.h" #include "delay.h"
#include "Arduino.h" #include "Arduino.h"
...@@ -25,42 +25,20 @@ ...@@ -25,42 +25,20 @@
extern "C" { extern "C" {
#endif #endif
/** Tick Counter united by ms */ static volatile uint32_t overflows = 0;
static volatile uint32_t _ulTickCount=0 ;
uint32_t millis( void ) uint32_t millis( void )
{ {
// todo: ensure no interrupts uint64_t ticks = (uint64_t)(overflows << (uint64_t)32) | (uint64_t)nrf_rtc_counter_get(NRF_RTC1);
return _ulTickCount ;
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 micros( void )
{ {
uint32_t ticks, ticks2; uint64_t ticks = (uint64_t)(overflows << (uint64_t)32) | (uint64_t)nrf_rtc_counter_get(NRF_RTC1);
uint32_t pend, pend2;
uint32_t count, count2;
ticks2 = SysTick->VAL;
pend2 = !!(SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) ;
count2 = _ulTickCount ;
do return (ticks * 1000000) / RTC_INPUT_FREQ;
{
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
} }
void delay( uint32_t ms ) void delay( uint32_t ms )
...@@ -70,18 +48,19 @@ void delay( uint32_t ms ) ...@@ -70,18 +48,19 @@ void delay( uint32_t ms )
return ; return ;
} }
uint32_t start = _ulTickCount ; uint32_t start = millis() ;
do do
{ {
yield() ; yield() ;
} while ( _ulTickCount - start < ms ) ; } while ( millis() - start < ms ) ;
} }
void SysTick_Handler(void) void RTC1_IRQHandler(void)
{ {
// Increment tick count each ms nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_EVENT_OVERFLOW);
_ulTickCount++;
overflows = (overflows + 1) & 0xff;
} }
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -29,7 +29,9 @@ ...@@ -29,7 +29,9 @@
#include <stddef.h> #include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include "nrf.h" #include "nrf.h"
#ifndef ARDUINO
#include "nrf_assert.h" #include "nrf_assert.h"
#endif
/** /**
* @brief Macro for getting the number of compare channels available * @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) ...@@ -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) __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)); ASSERT(val <= (RTC_PRESCALER_PRESCALER_Msk >> RTC_PRESCALER_PRESCALER_Pos));
#endif
p_rtc->PRESCALER = val; p_rtc->PRESCALER = val;
} }
__STATIC_INLINE uint32_t rtc_prescaler_get(NRF_RTC_Type * p_rtc) __STATIC_INLINE uint32_t rtc_prescaler_get(NRF_RTC_Type * p_rtc)
......
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 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" #include "Arduino.h"
...@@ -24,22 +25,19 @@ ...@@ -24,22 +25,19 @@
extern "C" { extern "C" {
#endif #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 ) void init( void )
{ {
// Set Systick to 1ms interval, common to all Cortex-M variants NVIC_SetPriority(RTC1_IRQn, 15);
if ( SysTick_Config( SystemCoreClock / 1000 ) ) NVIC_ClearPendingIRQ(RTC1_IRQn);
{ NVIC_EnableIRQ(RTC1_IRQn);
// Capture error
while ( 1 ) ; 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 #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