cpu/atmega256rfr2: symbol counter based RTT support
This commit is contained in:
parent
f05004b3fd
commit
efa9bb88a2
@ -177,15 +177,33 @@ typedef struct {
|
|||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name RTT configuration
|
* @name RTT configuration
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define RTT_MAX_VALUE (0x00FFFFFF) /* 24-bit timer */
|
#if defined(SCCR0) && !defined(RTT_BACKEND_SC)
|
||||||
|
#define RTT_BACKEND_SC (1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if RTT_BACKEND_SC
|
||||||
|
/* For MCU with MAC symbol counter */
|
||||||
|
#ifndef RTT_MAX_VALUE
|
||||||
|
#define RTT_MAX_VALUE (0xFFFFFFFFUL) /* 32-bit timer */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RTT_FREQUENCY
|
||||||
|
#define RTT_FREQUENCY (62500UL) /* in Hz. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* For MCU without MAC symbol counter */
|
||||||
|
#ifndef RTT_MAX_VALUE
|
||||||
|
#define RTT_MAX_VALUE (0x00FFFFFF) /* 24-bit timer */
|
||||||
|
#endif
|
||||||
/* possible values: 32, 128, 256, 512, 1024, 4096, 32768 */
|
/* possible values: 32, 128, 256, 512, 1024, 4096, 32768 */
|
||||||
#ifndef RTT_FREQUENCY
|
#ifndef RTT_FREQUENCY
|
||||||
#define RTT_FREQUENCY (1024U) /* in Hz. */
|
#define RTT_FREQUENCY (1024U) /* in Hz. */
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@ -18,7 +18,9 @@
|
|||||||
* oscillator.
|
* oscillator.
|
||||||
*
|
*
|
||||||
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
|
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
|
||||||
|
* @author Alexander Chudov <chudov@gmail.com>
|
||||||
*
|
*
|
||||||
|
* For all atmega except rfa1, rfr2
|
||||||
* In order to safely sleep when using the RTT:
|
* In order to safely sleep when using the RTT:
|
||||||
* 1. Disable interrupts
|
* 1. Disable interrupts
|
||||||
* 2. Write to one of the asynch registers (e.g. TCCR2A)
|
* 2. Write to one of the asynch registers (e.g. TCCR2A)
|
||||||
@ -26,11 +28,23 @@
|
|||||||
* 4. Re-enable interrupts
|
* 4. Re-enable interrupts
|
||||||
* 5. Sleep before interrupt re-enable takes effect
|
* 5. Sleep before interrupt re-enable takes effect
|
||||||
*
|
*
|
||||||
|
* For MCUs with a MAC symbol counter (ATmegaXXXRFA1 and ATmegaXXXRFR2):
|
||||||
|
* The MAC symbol counter is a 32 bit counter which can be sourced by a 62.5 kHz
|
||||||
|
* clock, derived from the 16 MHz system clock or from the 32.768 kHz RTC.
|
||||||
|
* When either the CPU or the transceivers is going to sleep,
|
||||||
|
* the MAC symbol counter is sourced by the RTC for both options. In order to
|
||||||
|
* not have to compensate for a changing clock frequency, this RTT
|
||||||
|
* implementation uses the 32.768kHz RTC as source even when both CPU and
|
||||||
|
* transceiver are active. The 32 bit comparator in SCOCR2 is used for alarms.
|
||||||
|
*
|
||||||
|
* SCCR0 is defined if an MCU has MAC symbol counter
|
||||||
|
*
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
#include "byteorder.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include "periph/rtt.h"
|
#include "periph/rtt.h"
|
||||||
@ -39,8 +53,61 @@
|
|||||||
#define ENABLE_DEBUG (0)
|
#define ENABLE_DEBUG (0)
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
#if RTT_BACKEND_SC
|
||||||
|
/*
|
||||||
|
* Read a 32 bit register as described in section 10.3 of the datasheet: A read
|
||||||
|
* of the least significant byte causes the current value to be atomically
|
||||||
|
* captured in a temporary 32 bit registers. The remaining reads will access this
|
||||||
|
* register instead. Only a single 32 bit temporary register is used to provide
|
||||||
|
* means to atomically access them. Thus, interrupts must be disabled during the
|
||||||
|
* read sequence in order to prevent other threads (or ISRs) from updating the
|
||||||
|
* temporary 32 bit register before the reading sequence has completed.
|
||||||
|
*/
|
||||||
|
static inline uint32_t reg32_read(volatile uint8_t *reg_ll)
|
||||||
|
{
|
||||||
|
le_uint32_t reg;
|
||||||
|
unsigned state = irq_disable();
|
||||||
|
reg.u8[0] = reg_ll[0];
|
||||||
|
reg.u8[1] = reg_ll[1];
|
||||||
|
reg.u8[2] = reg_ll[2];
|
||||||
|
reg.u8[3] = reg_ll[3];
|
||||||
|
irq_restore(state);
|
||||||
|
return reg.u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write a 32 bit register done in the same manner as read: A write of the least
|
||||||
|
* significant byte causes the atomic store the 32 bit value in the registers
|
||||||
|
*/
|
||||||
|
static inline void reg32_write(volatile uint8_t *reg_ll, uint32_t _val)
|
||||||
|
{
|
||||||
|
le_uint32_t val = { .u32 = _val };
|
||||||
|
unsigned state = irq_disable();
|
||||||
|
reg_ll[3] = val.u8[3];
|
||||||
|
reg_ll[2] = val.u8[2];
|
||||||
|
reg_ll[1] = val.u8[1];
|
||||||
|
reg_ll[0] = val.u8[0];
|
||||||
|
irq_restore(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To build proper register names */
|
||||||
|
#ifndef CONCAT
|
||||||
|
#define CONCAT(a, b) (a##b)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* To read the whole 32-bit register */
|
||||||
|
#define RG_READ32(reg) (reg32_read(&CONCAT(reg, LL)))
|
||||||
|
|
||||||
|
/* To write the whole 32-bit register */
|
||||||
|
#define RG_WRITE32(reg, val) (reg32_write(&CONCAT(reg, LL), val))
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
#if RTT_BACKEND_SC == 0
|
||||||
uint16_t ext_comp; /* Extend compare to 24-bits */
|
uint16_t ext_comp; /* Extend compare to 24-bits */
|
||||||
|
#endif
|
||||||
rtt_cb_t alarm_cb; /* callback called from RTT alarm */
|
rtt_cb_t alarm_cb; /* callback called from RTT alarm */
|
||||||
void *alarm_arg; /* argument passed to the callback */
|
void *alarm_arg; /* argument passed to the callback */
|
||||||
rtt_cb_t overflow_cb; /* callback called when RTT overflows */
|
rtt_cb_t overflow_cb; /* callback called when RTT overflows */
|
||||||
@ -48,19 +115,29 @@ typedef struct {
|
|||||||
} rtt_state_t;
|
} rtt_state_t;
|
||||||
|
|
||||||
static rtt_state_t rtt_state;
|
static rtt_state_t rtt_state;
|
||||||
|
#if RTT_BACKEND_SC == 0
|
||||||
static uint16_t ext_cnt;
|
static uint16_t ext_cnt;
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline void _asynch_wait(void)
|
static inline void _asynch_wait(void)
|
||||||
{
|
{
|
||||||
|
#if RTT_BACKEND_SC
|
||||||
|
/* Wait until counter update flag clear. */
|
||||||
|
while (SCSR & ((1 << SCBSY) )) {}
|
||||||
|
#else
|
||||||
/* Wait until all busy flags clear. According to the datasheet,
|
/* Wait until all busy flags clear. According to the datasheet,
|
||||||
* this can take up to 2 positive edges of TOSC1 (32kHz). */
|
* this can take up to 2 positive edges of TOSC1 (32kHz). */
|
||||||
while (ASSR & ((1 << TCN2UB) | (1 << OCR2AUB) | (1 << OCR2BUB)
|
while (ASSR & ((1 << TCN2UB) | (1 << OCR2AUB) | (1 << OCR2BUB)
|
||||||
| (1 << TCR2AUB) | (1 << TCR2BUB))) {}
|
| (1 << TCR2AUB) | (1 << TCR2BUB))) {}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* interrupts are disabled here */
|
/* interrupts are disabled here */
|
||||||
static uint32_t _safe_cnt_get(void)
|
static uint32_t _safe_cnt_get(void)
|
||||||
{
|
{
|
||||||
|
#if RTT_BACKEND_SC
|
||||||
|
return RG_READ32(SCCNT);
|
||||||
|
#else
|
||||||
uint8_t cnt = TCNT2;
|
uint8_t cnt = TCNT2;
|
||||||
|
|
||||||
/* If an overflow occurred since we disabled interrupts, manually
|
/* If an overflow occurred since we disabled interrupts, manually
|
||||||
@ -80,8 +157,44 @@ static uint32_t _safe_cnt_get(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (ext_cnt << 8) | cnt;
|
return (ext_cnt << 8) | cnt;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if RTT_BACKEND_SC
|
||||||
|
static inline void _timer_init(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* ATmega256RFR2 symbol counter init sequence:
|
||||||
|
* 1. Disable all related interrupts
|
||||||
|
* 2. Enable 32 kHz oscillator
|
||||||
|
* 3. Enable symbol counter, clock it from TOSC1 only
|
||||||
|
* 4. Reset prescaller, enable rx timestamping, start symbol counter
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Disable all symbol counter interrupts */
|
||||||
|
SCIRQM = 0;
|
||||||
|
|
||||||
|
/* Clear all interrupt flags by writing '1' */
|
||||||
|
SCIRQS = (1 << IRQSBO) | (1 << IRQSOF)
|
||||||
|
| (1 << IRQSCP3) | (1 << IRQSCP2) | (1 << IRQSCP1);
|
||||||
|
|
||||||
|
/* Reset compare values */
|
||||||
|
RG_WRITE32(SCOCR1, 0);
|
||||||
|
RG_WRITE32(SCOCR2, 0);
|
||||||
|
RG_WRITE32(SCOCR3, 0);
|
||||||
|
|
||||||
|
/* Enable 32 kHz oscillator. All T/C2-related settings are overridden */
|
||||||
|
ASSR = (1 << AS2);
|
||||||
|
|
||||||
|
/* Enable symbol counter, clock from TOSC1, timestamping enabled */
|
||||||
|
SCCR0 = (1 << SCRES) | (1 << SCEN) | (1 << SCCKSEL) | (1 << SCTSE);
|
||||||
|
|
||||||
|
/* Reset the symbol counter */
|
||||||
|
RG_WRITE32(SCCNT, 0);
|
||||||
|
/* Wait until not busy anymore */
|
||||||
|
DEBUG("RTT waits until SC not busy\n");
|
||||||
|
}
|
||||||
|
#else
|
||||||
static inline uint8_t _rtt_div(uint16_t freq)
|
static inline uint8_t _rtt_div(uint16_t freq)
|
||||||
{
|
{
|
||||||
switch (freq) {
|
switch (freq) {
|
||||||
@ -96,11 +209,8 @@ static inline uint8_t _rtt_div(uint16_t freq)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtt_init(void)
|
static inline void _timer_init(void)
|
||||||
{
|
{
|
||||||
DEBUG("Initializing RTT\n");
|
|
||||||
|
|
||||||
rtt_poweron();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* From the datasheet section "Asynchronous Operation of Timer/Counter2"
|
* From the datasheet section "Asynchronous Operation of Timer/Counter2"
|
||||||
@ -134,15 +244,26 @@ void rtt_init(void)
|
|||||||
|
|
||||||
/* Wait until not busy anymore */
|
/* Wait until not busy anymore */
|
||||||
DEBUG("RTT waits until ASSR not busy\n");
|
DEBUG("RTT waits until ASSR not busy\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void rtt_init(void)
|
||||||
|
{
|
||||||
|
DEBUG("Initializing RTT\n");
|
||||||
|
|
||||||
|
rtt_poweron();
|
||||||
|
|
||||||
|
_timer_init();
|
||||||
_asynch_wait();
|
_asynch_wait();
|
||||||
|
|
||||||
|
#if RTT_BACKEND_SC == 0
|
||||||
/* Clear interrupt flags */
|
/* Clear interrupt flags */
|
||||||
/* Oddly, this is done by writing ones; see datasheet */
|
/* Oddly, this is done by writing ones; see datasheet */
|
||||||
TIFR2 = (1 << OCF2B) | (1 << OCF2A) | (1 << TOV2);
|
TIFR2 = (1 << OCF2B) | (1 << OCF2A) | (1 << TOV2);
|
||||||
|
|
||||||
/* Enable 8-bit overflow interrupt */
|
/* Enable 8-bit overflow interrupt */
|
||||||
TIMSK2 |= (1 << TOIE2);
|
TIMSK2 |= (1 << TOIE2);
|
||||||
|
#endif
|
||||||
DEBUG("RTT initialized\n");
|
DEBUG("RTT initialized\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,12 +293,12 @@ uint32_t rtt_get_counter(void)
|
|||||||
{
|
{
|
||||||
unsigned state;
|
unsigned state;
|
||||||
uint32_t now;
|
uint32_t now;
|
||||||
|
#if RTT_BACKEND_SC == 0
|
||||||
/* Make sure it is safe to read TCNT2, in case we just woke up */
|
/* Make sure it is safe to read TCNT2, in case we just woke up */
|
||||||
DEBUG("RTT sleeps until safe to read TCNT2\n");
|
DEBUG("RTT sleeps until safe to read TCNT2\n");
|
||||||
TCCR2A = 0;
|
TCCR2A = 0;
|
||||||
_asynch_wait();
|
_asynch_wait();
|
||||||
|
#endif
|
||||||
state = irq_disable();
|
state = irq_disable();
|
||||||
now = _safe_cnt_get();
|
now = _safe_cnt_get();
|
||||||
irq_restore(state);
|
irq_restore(state);
|
||||||
@ -188,12 +309,18 @@ uint32_t rtt_get_counter(void)
|
|||||||
void rtt_set_counter(uint32_t counter)
|
void rtt_set_counter(uint32_t counter)
|
||||||
{
|
{
|
||||||
/* Wait until not busy anymore (should be immediate) */
|
/* Wait until not busy anymore (should be immediate) */
|
||||||
DEBUG("RTT sleeps until safe to write TCNT2\n");
|
DEBUG("RTT sleeps until safe to write\n");
|
||||||
_asynch_wait();
|
_asynch_wait();
|
||||||
|
|
||||||
/* Make non-atomic writes atomic (for concurrent access) */
|
/* Make non-atomic writes atomic (for concurrent access) */
|
||||||
unsigned state = irq_disable();
|
unsigned state = irq_disable();
|
||||||
|
#if RTT_BACKEND_SC
|
||||||
|
/* Clear overflow flag by writing a one; see datasheet */
|
||||||
|
SCIRQS = (1 << IRQSOF);
|
||||||
|
|
||||||
|
RG_WRITE32(SCCNT, counter);
|
||||||
|
_asynch_wait();
|
||||||
|
#else
|
||||||
/* Prevent overflow flag from being set during update */
|
/* Prevent overflow flag from being set during update */
|
||||||
TCNT2 = 0;
|
TCNT2 = 0;
|
||||||
|
|
||||||
@ -203,26 +330,44 @@ void rtt_set_counter(uint32_t counter)
|
|||||||
|
|
||||||
ext_cnt = (uint16_t)(counter >> 8);
|
ext_cnt = (uint16_t)(counter >> 8);
|
||||||
TCNT2 = (uint8_t)counter;
|
TCNT2 = (uint8_t)counter;
|
||||||
|
#endif
|
||||||
irq_restore(state);
|
irq_restore(state);
|
||||||
|
|
||||||
DEBUG("RTT set counter TCNT2: %" PRIu8 ", ext_cnt: %" PRIu16 "\n",
|
|
||||||
TCNT2, ext_cnt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtt_set_alarm(uint32_t alarm, rtt_cb_t cb, void *arg)
|
void rtt_set_alarm(uint32_t alarm, rtt_cb_t cb, void *arg)
|
||||||
{
|
{
|
||||||
/* Disable alarm */
|
/* Disable alarm */
|
||||||
rtt_clear_alarm();
|
rtt_clear_alarm();
|
||||||
|
#if RTT_BACKEND_SC
|
||||||
|
/* Make non-atomic writes atomic */
|
||||||
|
unsigned state = irq_disable();
|
||||||
|
|
||||||
|
/* Set the alarm value to SCOCR2. Atomic for concurrent access */
|
||||||
|
RG_WRITE32(SCOCR2, alarm);
|
||||||
|
|
||||||
|
rtt_state.alarm_cb = cb;
|
||||||
|
rtt_state.alarm_arg = arg;
|
||||||
|
|
||||||
|
irq_restore(state);
|
||||||
|
|
||||||
|
DEBUG("RTT set alarm SCCNT: %" PRIu32 ", SCOCR2: %" PRIu32 "\n",
|
||||||
|
RG_READ32(SCCNT), RG_READ32(SCOCR2));
|
||||||
|
|
||||||
|
/* Enable alarm interrupt */
|
||||||
|
SCIRQS |= (1 << IRQSCP2);
|
||||||
|
SCIRQM |= (1 << IRQMCP2);
|
||||||
|
|
||||||
|
DEBUG("RTT alarm interrupt active\n");
|
||||||
|
|
||||||
|
#else
|
||||||
/* Make sure it is safe to read TCNT2, in case we just woke up, and */
|
/* Make sure it is safe to read TCNT2, in case we just woke up, and */
|
||||||
/* safe to write OCR2B (in case it was busy) */
|
/* safe to write OCR2B (in case it was busy) */
|
||||||
DEBUG("RTT sleeps until safe read TCNT2 and to write OCR2B\n");
|
DEBUG("RTT sleeps until safe read TCNT2 and to write OCR2B\n");
|
||||||
TCCR2A = 0;
|
TCCR2A = 0;
|
||||||
_asynch_wait();
|
_asynch_wait();
|
||||||
|
|
||||||
/* Make non-atomic writes atomic */
|
/* Make non-atomic writes atomic */
|
||||||
unsigned state = irq_disable();
|
unsigned state = irq_disable();
|
||||||
|
|
||||||
uint32_t now = _safe_cnt_get();
|
uint32_t now = _safe_cnt_get();
|
||||||
|
|
||||||
/* Set the alarm value. Atomic for concurrent access */
|
/* Set the alarm value. Atomic for concurrent access */
|
||||||
@ -249,11 +394,17 @@ void rtt_set_alarm(uint32_t alarm, rtt_cb_t cb, void *arg)
|
|||||||
else {
|
else {
|
||||||
DEBUG("RTT alarm interrupt not active\n");
|
DEBUG("RTT alarm interrupt not active\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rtt_get_alarm(void)
|
uint32_t rtt_get_alarm(void)
|
||||||
{
|
{
|
||||||
|
#if RTT_BACKEND_SC
|
||||||
|
return RG_READ32(SCOCR2);
|
||||||
|
#else
|
||||||
return (rtt_state.ext_comp << 8) | OCR2A;
|
return (rtt_state.ext_comp << 8) | OCR2A;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtt_clear_alarm(void)
|
void rtt_clear_alarm(void)
|
||||||
@ -262,8 +413,11 @@ void rtt_clear_alarm(void)
|
|||||||
unsigned state = irq_disable();
|
unsigned state = irq_disable();
|
||||||
|
|
||||||
/* Disable alarm interrupt */
|
/* Disable alarm interrupt */
|
||||||
|
#if RTT_BACKEND_SC
|
||||||
|
SCIRQM &= ~(1 << IRQMCP2);
|
||||||
|
#else
|
||||||
TIMSK2 &= ~(1 << OCIE2A);
|
TIMSK2 &= ~(1 << OCIE2A);
|
||||||
|
#endif
|
||||||
rtt_state.alarm_cb = NULL;
|
rtt_state.alarm_cb = NULL;
|
||||||
rtt_state.alarm_arg = NULL;
|
rtt_state.alarm_arg = NULL;
|
||||||
|
|
||||||
@ -272,14 +426,34 @@ void rtt_clear_alarm(void)
|
|||||||
|
|
||||||
void rtt_poweron(void)
|
void rtt_poweron(void)
|
||||||
{
|
{
|
||||||
|
#if RTT_BACKEND_SC
|
||||||
|
SCCR0 |= (1 << SCEN);
|
||||||
|
#else
|
||||||
power_timer2_enable();
|
power_timer2_enable();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtt_poweroff(void)
|
void rtt_poweroff(void)
|
||||||
{
|
{
|
||||||
|
#if RTT_BACKEND_SC
|
||||||
|
SCCR0 &= ~(1 << SCEN);
|
||||||
|
#else
|
||||||
power_timer2_disable();
|
power_timer2_disable();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if RTT_BACKEND_SC
|
||||||
|
ISR(SCNT_OVFL_vect)
|
||||||
|
{
|
||||||
|
atmega_enter_isr();
|
||||||
|
/* Execute callback */
|
||||||
|
if (rtt_state.overflow_cb != NULL) {
|
||||||
|
rtt_state.overflow_cb(rtt_state.overflow_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
atmega_exit_isr();
|
||||||
|
}
|
||||||
|
#else
|
||||||
ISR(TIMER2_OVF_vect)
|
ISR(TIMER2_OVF_vect)
|
||||||
{
|
{
|
||||||
atmega_enter_isr();
|
atmega_enter_isr();
|
||||||
@ -305,13 +479,21 @@ ISR(TIMER2_OVF_vect)
|
|||||||
|
|
||||||
atmega_exit_isr();
|
atmega_exit_isr();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if RTT_BACKEND_SC
|
||||||
|
ISR(SCNT_CMP2_vect)
|
||||||
|
#else
|
||||||
ISR(TIMER2_COMPA_vect)
|
ISR(TIMER2_COMPA_vect)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
atmega_enter_isr();
|
atmega_enter_isr();
|
||||||
/* Disable alarm interrupt */
|
/* Disable alarm interrupt */
|
||||||
|
#if RTT_BACKEND_SC
|
||||||
|
SCIRQM &= ~(1 << IRQMCP2);
|
||||||
|
#else
|
||||||
TIMSK2 &= ~(1 << OCIE2A);
|
TIMSK2 &= ~(1 << OCIE2A);
|
||||||
|
#endif
|
||||||
if (rtt_state.alarm_cb != NULL) {
|
if (rtt_state.alarm_cb != NULL) {
|
||||||
/* Clear callback */
|
/* Clear callback */
|
||||||
rtt_cb_t cb = rtt_state.alarm_cb;
|
rtt_cb_t cb = rtt_state.alarm_cb;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user