| Microcontroller Wireless Solutions | |||||
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 */