Microcontroller Wireless Solutions


pal_irq.c
Go to the documentation of this file.
00001 
00015 /*
00016  * Copyright (c) 2009, Atmel Corporation All rights reserved.
00017  *
00018  * Licensed under Atmel's Limited License Agreement --> EULA.txt
00019  */
00020 
00021 /* === Includes ============================================================ */
00022 
00023 #include <stdint.h>
00024 #include "pal.h"
00025 
00026 #if (PAL_TYPE == ATMEGA128RFA1)
00027 
00028 /* === Types =============================================================== */
00029 
00030 
00031 /* === Externals =========================================================== */
00032 
00033 #ifdef WATCHDOG_TIMER
00034 #include "pal_timer.h"
00035 extern volatile bool timer_trigger;
00036 extern timer_info_t timer_array[TOTAL_NUMBER_OF_TIMERS];
00037 extern uint8_t running_timers;
00038 #endif
00039 
00040 /* === Globals ============================================================= */
00041 
00042 /*
00043  * Function pointers to store the callback function of
00044  * the transceiver interrupt
00045  */
00047 static irq_handler_t irq_hdl_trx_tx_end;
00049 static irq_handler_t irq_hdl_trx_rx_end;
00051 static irq_handler_t irq_hdl_trx_cca_ed;
00052 
00053 #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) || (defined DOXYGEN)
00054 
00055 static irq_handler_t irq_hdl_trx_tstamp;
00056 #endif
00057 
00058 #if (defined ENABLE_ALL_TRX_IRQS) || (defined DOXYGEN)
00059 
00060 static irq_handler_t irq_hdl_trx_awake;
00062 static irq_handler_t irq_hdl_trx_ami;
00064 static irq_handler_t irq_hdl_trx_batmon;
00066 static irq_handler_t irq_hdl_trx_pll_lock;
00068 static irq_handler_t irq_hdl_trx_pll_unlock;
00070 static irq_handler_t irq_hdl_trx_aes_ready;
00071 #endif  /* ENABLE_ALL_TRX_IRQS */
00072 
00073 /* === Prototypes ========================================================== */
00074 
00075 
00076 /* === Implementation ====================================================== */
00077 
00086 void pal_trx_irq_init_tx_end(FUNC_PTR trx_irq_cb)
00087 {
00088     irq_hdl_trx_tx_end = (irq_handler_t)trx_irq_cb;
00089 }
00090 
00091 
00100 void pal_trx_irq_init_rx_end(FUNC_PTR trx_irq_cb)
00101 {
00102     irq_hdl_trx_rx_end = (irq_handler_t)trx_irq_cb;
00103 }
00104 
00105 
00114 void pal_trx_irq_init_cca_ed(FUNC_PTR trx_irq_cb)
00115 {
00116     irq_hdl_trx_cca_ed = (irq_handler_t)trx_irq_cb;
00117 }
00118 
00119 
00120 #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) || (defined DOXYGEN)
00121 
00130 void pal_trx_irq_init_tstamp(FUNC_PTR trx_irq_cb)
00131 {
00132     irq_hdl_trx_tstamp = (irq_handler_t)trx_irq_cb;
00133 }
00134 #endif  /* #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) || (defined DOXYGEN) */
00135 
00136 
00137 #if defined(ENABLE_ALL_TRX_IRQS) || defined(DOXYGEN)
00138 
00146 void pal_trx_irq_init_awake(FUNC_PTR trx_irq_cb)
00147 {
00148     irq_hdl_trx_awake = (irq_handler_t)trx_irq_cb;
00149 }
00150 
00151 
00160 void pal_trx_irq_init_ami(FUNC_PTR trx_irq_cb)
00161 {
00162     irq_hdl_trx_ami = (irq_handler_t)trx_irq_cb;
00163 }
00164 
00165 
00174 void pal_trx_irq_init_batmon(FUNC_PTR trx_irq_cb)
00175 {
00176     irq_hdl_trx_batmon = (irq_handler_t)trx_irq_cb;
00177 }
00178 
00179 
00188 void pal_trx_irq_init_pll_lock(FUNC_PTR trx_irq_cb)
00189 {
00190     irq_hdl_trx_pll_lock = (irq_handler_t)trx_irq_cb;
00191 }
00192 
00193 
00202 void pal_trx_irq_init_pll_unlock(FUNC_PTR trx_irq_cb)
00203 {
00204     irq_hdl_trx_pll_unlock = (irq_handler_t)trx_irq_cb;
00205 }
00206 
00207 
00216 void pal_trx_irq_init_aes_ready(FUNC_PTR trx_irq_cb)
00217 {
00218     irq_hdl_trx_aes_ready = (irq_handler_t)trx_irq_cb;
00219 }
00220 #endif  /* ENABLE_ALL_TRX_IRQS */
00221 
00222 
00226 ISR(TRX24_TX_END_vect)
00227 {
00228     irq_hdl_trx_tx_end();
00229 }
00230 
00234 ISR(TRX24_RX_END_vect)
00235 {
00236     irq_hdl_trx_rx_end();
00237 }
00238 
00242 ISR(TRX24_CCA_ED_DONE_vect)
00243 {
00244     irq_hdl_trx_cca_ed();
00245 }
00246 
00250 ISR(TRX24_AWAKE_vect)
00251 {
00252 #ifdef ENABLE_ALL_TRX_IRQS
00253     irq_hdl_trx_awake();
00254 #endif
00255 }
00256 
00263 ISR(TRX24_RX_START_vect)
00264 {
00265 #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP)
00266     irq_hdl_trx_tstamp();
00267 #endif  /* #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */
00268 }
00269 
00273 ISR(TRX24_PLL_LOCK_vect)
00274 {
00275 #ifdef ENABLE_ALL_TRX_IRQS
00276     irq_hdl_trx_pll_lock();
00277 #endif  /*  ENABLE_ALL_TRX_IRQS*/
00278 }
00279 
00283 ISR(TRX24_PLL_UNLOCK_vect)
00284 {
00285 #ifdef ENABLE_ALL_TRX_IRQS
00286     irq_hdl_trx_pll_unlock();
00287 #endif  /*  ENABLE_ALL_TRX_IRQS*/
00288 }
00289 
00293 ISR(TRX24_XAH_AMI_vect)
00294 {
00295 #ifdef ENABLE_ALL_TRX_IRQS
00296     irq_hdl_trx_ami();
00297 #endif  /*  ENABLE_ALL_TRX_IRQS*/
00298 }
00299 
00303 ISR(BAT_LOW_vect)
00304 {
00305 #ifdef ENABLE_ALL_TRX_IRQS
00306     irq_hdl_trx_batmon();
00307 #endif  /*  ENABLE_ALL_TRX_IRQS*/
00308 }
00309 
00313 ISR(AES_READY_vect)
00314 {
00315 #ifdef ENABLE_ALL_TRX_IRQS
00316     irq_hdl_trx_aes_ready();
00317 #endif  /*  ENABLE_ALL_TRX_IRQS*/
00318 }
00319 
00320 
00321 #if defined(WATCHDOG_TIMER) || defined(DOXYGEN)
00322 
00325 ISR(WDT_vect)
00326 {
00327     /* Disable Watchdog Interrupt Mode */
00328     WDTCSR &= ~(1 << WDIE);
00329 
00330 #ifdef NO_32KHZ_CRYSTAL
00331     /* Wakeup the trx to enable clock source for symbol counter. */
00332     PAL_SLP_TR_LOW();
00333 
00334     /* Adjust system time */
00335     uint32_t cnt_val = SC_READ32(SCCNT) & MASK_LOW28;
00336     cnt_val += WDT_WAKEUP_INTERVAL_US / PAL_US_PER_SYMBOLS;
00337     cnt_val &= MASK_LOW28;
00338     SC_WRITE32(SCCNT, cnt_val);
00339 
00340     /* Check for any pending timer event. */
00341     uint32_t now;
00342     pal_get_current_time(&now);
00343 
00344     /* Check for any pending timer event */
00345     if (running_timers > 0)
00346     {
00347         for (uint8_t i = 0; i < TOTAL_NUMBER_OF_TIMERS; i++)
00348         {
00349             if (timer_array[i].timer_cb != NULL)
00350             {
00351                 if (now >= timer_array[i].abs_exp_timer)
00352                 {
00353                     /* Trigger timer event handling */
00354                     timer_trigger = true;
00355                     break;
00356                 }
00357             }
00358         }
00359     }
00360 
00361     /* Wait until 16MHz oscillator is ready. */
00362     while (pal_trx_bit_read(SR_TRX_STATUS) != TRX_OFF)
00363     {
00364         /* wait */
00365         /* Reduce CPU clock speed (1 MHz) to consume less power during wait period. */
00366         clock_prescale_set(clock_div_8);
00367     }
00368     /* Restore to 16MHz CPU clock speed. */
00369 #if (F_CPU == 16000000)
00370     clock_prescale_set(0x0F);
00371 #endif
00372 #if (F_CPU == 8000000)
00373     clock_prescale_set(clock_div_1);
00374 #endif
00375 #if (F_CPU == 4000000)
00376     clock_prescale_set(clock_div_2);
00377 #endif
00378 
00379     /* Toggle AS2 to trigger internal 32kHz crystal oscillator output. */
00380     ASSR = _BV(AS2);
00381     ASSR &= ~_BV(AS2);
00382 #endif
00383 }
00384 #endif
00385 
00386 
00387 #endif /* (PAL_TYPE == ATMEGA128RFA1) */
00388 
00389 /* EOF */