AVR Z-LINKŪ


tat.c

Go to the documentation of this file.
00001 /* This file has been prepared for Doxygen automatic documentation generation.*/
00048 /*============================ INCLDUE =======================================*/
00049 #include <stdint.h>
00050 #include <stdbool.h>
00051 
00052 #include "at86rf230_registermap.h"
00053 
00054 #include "compiler.h"
00055 #include "tat.h"
00056 #include "hal.h"
00057 /*============================ MACROS ========================================*/
00058 #define TAT_CCA_DONE_MASK     ( 1 << 7 ) 
00059 #define TAT_CCA_IDLE_MASK     ( 1 << 6 ) 
00060 
00061 #define TAT_START_CCA ( 1 ) 
00062 
00063 #define TAT_TRANSMISSION_SUCCESS  ( 0 )
00064 #define TAT_BUSY_CHANNEL          ( 3 )
00065 #define TAT_MIN_IEEE_FRAME_LENGTH ( 5 )
00066 /*============================ TYPEDEFS ======================================*/
00067 
00075 typedef enum{
00076 
00077     TIME_P_ON_TO_TRX_OFF             = 510, 
00078     TIME_SLEEP_TO_TRX_OFF            = 880, 
00079     TIME_RESET                       = 6,   
00080     TIME_ED_MEASUREMENT              = 140, 
00081     TIME_CCA                         = 140, 
00082     TIME_PLL_LOCK                    = 150, 
00083     TIME_FTN_TUNING                  = 25,  
00084     TIME_NOCLK_TO_WAKE               = 6,   
00085     TIME_CMD_FORCE_TRX_OFF           = 1,    
00086     TIME_TRX_OFF_TO_PLL_ACTIVE       = 180, 
00087     TIME_STATE_TRANSITION_PLL_ACTIVE = 1, 
00088 }tat_trx_timing_t;
00089 /*============================ VARIABLES =====================================*/
00090 /*============================ PROTOTYPES ====================================*/
00091 static bool is_sleeping( void );
00092 
00110 tat_status_t tat_init( void ){
00111     
00112     tat_status_t init_status = TAT_SUCCESS;
00113         
00114     //Initialize Hardware Abstraction Layer.
00115     hal_init( );
00116     sei( ); //Enable global interrupts.
00117     
00118     tat_reset_trx( ); //Do HW reset of radio transeiver.
00119     
00120     //Force transition to TRX_OFF.
00121     hal_subregister_write( SR_TRX_CMD, CMD_FORCE_TRX_OFF );
00122     delay_us( TIME_P_ON_TO_TRX_OFF ); //Wait for the transition to be complete.
00123     
00124     if (tat_get_trx_state( ) != TRX_OFF) {
00125         init_status = TAT_TIMED_OUT;    
00126     } else {
00127     
00128         //Read Version Number
00129         uint8_t version_number = hal_register_read( RG_VERSION_NUM );
00130         
00131         if ((version_number != RF230_REVA ) && (version_number != RF230_REVB)) {
00132             init_status = TAT_UNSUPPORTED_DEVICE;
00133         } else {
00134         
00135             if (hal_register_read( RG_MAN_ID_0 ) != SUPPORTED_MANUFACTURER_ID) {
00136                 init_status = TAT_UNSUPPORTED_DEVICE;
00137             } else {
00138                 hal_register_write( RG_IRQ_MASK, RF230_SUPPORTED_INTERRUPT_MASK );
00139                 hal_subregister_write( SR_CLKM_CTRL, CLKM_DISABLED );
00140             } // end: if (hal_register_read( RG_MAN_ID_0 ) != ...
00141         } // end: if ((version_number != RF230_REVA ) ...
00142     } // end: if (tat_get_trx_state( ) ...
00143     
00144     return init_status;
00145 }
00146 
00153 uint8_t tat_get_operating_channel( void ){
00154     return hal_subregister_read( SR_CHANNEL );
00155 }
00156 
00169 tat_status_t tat_set_operating_channel( uint8_t channel ){
00170     
00171     /*Do function parameter and state check.*/
00172     if ((channel < RF230_MIN_CHANNEL) || (channel > RF230_MAX_CHANNEL)) {
00173         return TAT_INVALID_ARGUMENT;
00174     }
00175     
00176     if (is_sleeping( ) == true) { return TAT_WRONG_STATE; }
00177     
00178     if (tat_get_operating_channel( ) == channel) { return TAT_SUCCESS; }
00179     
00180     /*Set new operating channel.*/        
00181     hal_subregister_write( SR_CHANNEL, channel );
00182                 
00183     //Read current state and wait for the PLL_LOCK interrupt if the
00184     //radio transceiver is in either RX_ON or PLL_ON.
00185     uint8_t trx_state = tat_get_trx_state( );
00186                 
00187     if ((trx_state == RX_ON) || (trx_state == PLL_ON)) {
00188         delay_us( TIME_PLL_LOCK );
00189     }
00190     
00191     tat_status_t channel_set_status = TAT_TIMED_OUT;
00192     
00193     //Check that the channel was set properly.
00194     if (tat_get_operating_channel( ) == channel) {
00195         channel_set_status = TAT_SUCCESS;
00196     }
00197     
00198     return channel_set_status;
00199 }
00200 
00208 uint8_t tat_get_tx_power_level( void ){
00209     return hal_subregister_read( SR_TX_PWR );
00210 }
00211 
00224 tat_status_t tat_set_tx_power_level( uint8_t power_level ){
00225         
00226     /*Check function parameter and state.*/
00227     if (power_level > TX_PWR_17_2DBM) { return TAT_INVALID_ARGUMENT; }
00228     
00229     if (is_sleeping( ) == true) { return TAT_WRONG_STATE; }
00230     
00231     /*Set new power level*/
00232     hal_subregister_write( SR_TX_PWR, power_level );
00233         
00234     return TAT_SUCCESS;
00235 }
00236 
00249 tat_status_t tat_do_ed_scan( uint8_t *ed_level ){
00250 
00251     uint8_t current_state = tat_get_trx_state( );
00252     
00253     /*Check state. Only possible to do ed measurement from RX_ON or BUSY_RX.*/
00254     if ((current_state != RX_ON ) && (current_state != BUSY_RX)) {
00255         return TAT_WRONG_STATE;
00256     }
00257     
00258     /*Do ED measurement.*/    
00259     //Initiate the measurement by writing to the PHY_ED_LEVEL register.
00260     hal_register_write( RG_PHY_ED_LEVEL, 0 );
00261     delay_us( TIME_ED_MEASUREMENT ); //Wait 128 us + 12 us computation time.
00262     *ed_level = hal_register_read( RG_PHY_ED_LEVEL ); //Write ED level to pointer.
00263 
00264     return TAT_SUCCESS;
00265 }
00266 
00273 uint8_t tat_get_cca_mode( void ){           
00274     return hal_subregister_read( SR_CCA_MODE );
00275 }
00276 
00283 uint8_t tat_get_ed_threshold( void ){
00284     return hal_subregister_read( SR_CCA_ED_THRES );
00285 }
00286 
00304 tat_status_t tat_set_cca_mode( uint8_t mode, uint8_t ed_threshold ){
00305     
00306     /*Check function parameters and state.*/
00307     if ((mode != CCA_ED) && (mode != CCA_CARRIER_SENSE) && 
00308         (mode != CCA_CARRIER_SENSE_WITH_ED)) {
00309         return TAT_INVALID_ARGUMENT;
00310     } 
00311        
00312     //Ensure that the ED threshold is within bounds.
00313     if (ed_threshold > RF230_MAX_ED_THRESHOLD) { return TAT_INVALID_ARGUMENT; } 
00314             
00315     //Ensure that the radio transceiver is not sleeping.
00316     if (is_sleeping( ) == true) { return TAT_WRONG_STATE; } 
00317                 
00318     /*Change cca mode and ed threshold.*/
00319     hal_subregister_write( SR_CCA_MODE, mode );
00320     hal_subregister_write( SR_CCA_ED_THRES, ed_threshold );
00321         
00322     return TAT_SUCCESS;
00323 }
00324 
00336 tat_status_t tat_do_cca( void ){
00337 
00338     /*Check state. CCA measurement only possible form PLL_ON state.*/
00339     if (tat_get_trx_state( ) != PLL_ON) { return TAT_WRONG_STATE; }
00340     
00341     /*Ensure that it is possible to enter RX_ON*/
00342     if (tat_set_trx_state( RX_ON ) != TAT_SUCCESS) { return TAT_TIMED_OUT; }
00343             
00344     //The CCA is initiated by writing 1 to the CCA_REQUEST subregister.
00345     hal_subregister_write( SR_CCA_REQUEST, TAT_START_CCA );
00346             
00347     //The CCA is measured over 128 us + 12 us computation time.
00348     delay_us( TIME_CCA );
00349     
00350     uint8_t status = hal_register_read( RG_TRX_STATUS ); //Read cca status.
00351     tat_status_t cca_status = TAT_CCA_BUSY; //Return variable.
00352     
00353     //Check if the algorithm finished -> CCA_DONE == 1.
00354     if ((status & TAT_CCA_DONE_MASK) != TAT_CCA_DONE_MASK) {
00355         cca_status = TAT_TIMED_OUT;
00356     } else {
00357                 
00358         //CCA done, but check if the channel is busy or not.
00359         if ((status & TAT_CCA_IDLE_MASK) != TAT_CCA_IDLE_MASK) {
00360             cca_status = TAT_CCA_BUSY;
00361         } else {
00362             cca_status = TAT_CCA_IDLE;
00363         } // end: if ((status & TAT_CCA_IDLE_MASK) ...
00364     } // end: if ((status & TAT_CCA_DONE_MASK) ...
00365     
00366     return cca_status;
00367 }
00368 
00380 tat_status_t tat_get_rssi_value( uint8_t *rssi ){
00381     
00382     uint8_t current_state = tat_get_trx_state( );
00383     tat_status_t retval = TAT_WRONG_STATE;
00384     
00385     /*The RSSI measurement should only be done in RX_ON or BUSY_RX.*/
00386     if ((current_state == RX_ON) || (current_state == BUSY_RX)) {
00387         
00388         *rssi = hal_subregister_read( SR_RSSI );
00389         retval = TAT_SUCCESS;
00390     }
00391     
00392     return retval;
00393 }
00394 
00405 uint8_t tat_batmon_get_voltage_threshold( void ){
00406     return hal_subregister_read( SR_BATMON_VTH );
00407 }
00408 
00419 uint8_t tat_batmon_get_voltage_range( void ){
00420     return hal_subregister_read( SR_BATMON_HR );
00421 }
00422 
00434 tat_status_t tat_batmon_configure( bool range, uint8_t voltage_threshold ){
00435      
00436     /*Check function parameters and state.*/
00437     if (voltage_threshold > BATTERY_MONITOR_HIGHEST_VOLTAGE) {
00438         return TAT_INVALID_ARGUMENT;
00439     }   
00440     
00441     if (is_sleeping( ) == true) { return TAT_WRONG_STATE; }
00442     
00443     /*Write new voltage range and voltage level.*/
00444     if (range == true) {
00445         hal_subregister_write( SR_BATMON_HR, BATTERY_MONITOR_HIGH_VOLTAGE );
00446     } else {
00447         hal_subregister_write( SR_BATMON_HR, BATTERY_MONITOR_LOW_VOLTAGE );
00448     } // end: if (range == true) ...
00449     
00450     hal_subregister_write( SR_BATMON_VTH, voltage_threshold );
00451        
00452     return TAT_SUCCESS;
00453 }
00454 
00465 tat_status_t tat_batmon_get_status( void ){
00466     
00467     tat_status_t batmon_status = TAT_BAT_LOW;
00468     
00469     if (hal_subregister_read( SR_BATMON_OK ) != 
00470         BATTERY_MONITOR_VOLTAGE_UNDER_THRESHOLD) {
00471         batmon_status = TAT_BAT_OK;
00472     }
00473     
00474     return batmon_status;
00475 }
00476 
00488 uint8_t tat_get_clock_speed( void ){
00489     return hal_subregister_read( SR_CLKM_CTRL );
00490 }
00491 
00513 tat_status_t tat_set_clock_speed( bool direct, uint8_t clock_speed ){
00514     
00515     /*Check function parameter and current clock speed.*/
00516     if (clock_speed > CLKM_16MHZ) { return TAT_INVALID_ARGUMENT; }
00517         
00518     if (tat_get_clock_speed( ) == clock_speed) { return TAT_SUCCESS; }
00519     
00520     /*Select to change the CLKM frequency directly or after returning from SLEEP.*/
00521     if (direct == false) {
00522         hal_subregister_write( SR_CLKM_SHA_SEL, 1 );
00523     } else {
00524         hal_subregister_write( SR_CLKM_SHA_SEL, 0 );
00525     } // end: if (direct == false) ...
00526             
00527     hal_subregister_write( SR_CLKM_CTRL, clock_speed );
00528                 
00529     return TAT_SUCCESS;
00530 }
00531 
00541 tat_status_t tat_calibrate_filter( void ){
00542     
00543     /*Check current state. Only possible to do filter calibration from TRX_OFF or PLL_ON.*/
00544     uint8_t trx_state = tat_get_trx_state( );
00545     
00546     if ((trx_state != TRX_OFF ) && (trx_state != PLL_ON)) { return TAT_WRONG_STATE; }
00547         
00548     //Start the tuning algorithm by writing one to the FTN_START subregister.
00549     hal_subregister_write( SR_FTN_START, 1 );   
00550     delay_us( TIME_FTN_TUNING ); //Wait for the calibration to finish.
00551     
00552     tat_status_t filter_calibration_status = TAT_TIMED_OUT;    
00553     
00554     //Verify the calibration result.
00555     if (hal_subregister_read( SR_FTN_START ) == FTN_CALIBRATION_DONE) {
00556         filter_calibration_status = TAT_SUCCESS;
00557     }
00558     
00559     return filter_calibration_status;
00560 }
00561 
00570 tat_status_t tat_calibrate_pll( void ){
00571     
00572     /*Check current state. Only possible to calibrate PLL from PLL_ON state*/
00573     if (tat_get_trx_state( ) != PLL_ON) { return TAT_WRONG_STATE; }
00574     
00575     //Initiate the DCU and CF calibration loops.
00576     hal_subregister_write( SR_PLL_DCU_START, 1 );
00577     hal_subregister_write( SR_PLL_CF_START, 1 );
00578         
00579     //Wait maximum 150 us for the PLL to lock.
00580     hal_clear_pll_lock_flag( );
00581     delay_us( TIME_PLL_LOCK );
00582     
00583     tat_status_t pll_calibration_status = TAT_TIMED_OUT;
00584     
00585     if (hal_get_pll_lock_flag( ) > 0) {
00586     
00587         if (hal_subregister_read( SR_PLL_DCU_START ) == PLL_DCU_CALIBRATION_DONE) {
00588         
00589             if (hal_subregister_read( SR_PLL_CF_START ) == PLL_CF_CALIBRATION_DONE) {
00590                 pll_calibration_status = TAT_SUCCESS;    
00591             } // end: if (hal_subregister_read( SR_PLL_CF_START ) ...
00592         } // end: if (hal_subregister_read( SR_PLL_DCU_START ) ...
00593     } // end: if ((hal_get_pll_lock_flag( ) ...
00594     
00595     return pll_calibration_status;
00596 }
00597 
00642 uint8_t tat_get_trx_state( void ){
00643     return hal_subregister_read( SR_TRX_STATUS );
00644 }
00645 
00654 static bool is_sleeping( void ){
00655     
00656     bool sleeping = false;
00657     
00658     //The radio transceiver will be at SLEEP or one of the *_NOCLK states only if
00659     //the SLP_TR pin is high.
00660     if (hal_get_slptr( ) != 0) {
00661         sleeping = true;
00662     }
00663     
00664     return sleeping;
00665 }
00666 
00687 tat_status_t tat_set_trx_state( uint8_t new_state ){
00688     
00689     /*Check function paramter and current state of the radio transceiver.*/
00690     if (!((new_state == TRX_OFF ) || (new_state == RX_ON) || (new_state == PLL_ON) || 
00691         (new_state == RX_AACK_ON ) || (new_state == TX_ARET_ON ))) { 
00692             
00693         return TAT_INVALID_ARGUMENT; 
00694     }
00695     
00696     if (is_sleeping( ) == true) { return TAT_WRONG_STATE; }
00697     
00698     uint8_t original_state = tat_get_trx_state( );
00699     
00700     if ((original_state == BUSY_RX ) || (original_state == BUSY_TX) || 
00701         (original_state == BUSY_RX_AACK) || (original_state == BUSY_TX_ARET)) { 
00702         return TAT_BUSY_STATE;
00703     }
00704     
00705     if (new_state == original_state) { return TAT_SUCCESS; }
00706                         
00707     //At this point it is clear that the requested new_state is:
00708     //TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON or TX_ARET_ON.
00709                 
00710     //The radio transceiver can be in one of the following states:
00711     //TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON, TX_ARET_ON.
00712     if( new_state == TRX_OFF ){
00713         tat_reset_state_machine( ); //Go to TRX_OFF from any state.
00714     } else {
00715         
00716         //It is not allowed to go from RX_AACK_ON or TX_AACK_ON and directly to
00717         //TX_AACK_ON or RX_AACK_ON respectively. Need to go via RX_ON or PLL_ON.
00718         if ((new_state == TX_ARET_ON) && (original_state == RX_AACK_ON)) {
00719             
00720             //First do intermediate state transition to PLL_ON, then to TX_ARET_ON.
00721             //The final state transition to TX_ARET_ON is handled after the if-else if.
00722             hal_subregister_write( SR_TRX_CMD, PLL_ON );
00723             delay_us( TIME_STATE_TRANSITION_PLL_ACTIVE );
00724         } else if ((new_state == RX_AACK_ON) && (original_state == TX_ARET_ON)) {
00725             
00726             //First do intermediate state transition to RX_ON, then to RX_AACK_ON.
00727             //The final state transition to RX_AACK_ON is handled after the if-else if.
00728             hal_subregister_write( SR_TRX_CMD, RX_ON );
00729             delay_us( TIME_STATE_TRANSITION_PLL_ACTIVE );
00730         }
00731             
00732         //Any other state transition can be done directly.    
00733         hal_subregister_write( SR_TRX_CMD, new_state );
00734         
00735         //When the PLL is active most states can be reached in 1us. However, from
00736         //TRX_OFF the PLL needs time to activate.
00737         if (original_state == TRX_OFF) {
00738             delay_us( TIME_TRX_OFF_TO_PLL_ACTIVE );
00739         } else {
00740             delay_us( TIME_STATE_TRANSITION_PLL_ACTIVE );
00741         } // end: if (original_state == TRX_OFF) ...
00742     } // end: if( new_state == TRX_OFF ) ...
00743         
00744     /*Verify state transition.*/
00745     tat_status_t set_state_status = TAT_TIMED_OUT;
00746     
00747     if( tat_get_trx_state( ) == new_state ){ set_state_status = TAT_SUCCESS; }
00748     
00749     return set_state_status;
00750 }
00751 
00759 tat_status_t tat_enter_sleep_mode( void ){
00760     
00761     if (is_sleeping( ) == true) { return TAT_SUCCESS; }
00762 
00763     tat_reset_state_machine( ); //Force the device into TRX_OFF.
00764     
00765     tat_status_t enter_sleep_status = TAT_TIMED_OUT;
00766     
00767     if (tat_get_trx_state( ) == TRX_OFF) {
00768             
00769         //Enter Sleep.
00770         hal_set_slptr_high( );    
00771         enter_sleep_status = TAT_SUCCESS;
00772     }
00773     
00774     return enter_sleep_status;  
00775 }
00776 
00785 tat_status_t tat_leave_sleep_mode( void ){
00786     
00787     //Check if the radio transceiver is actually sleeping.
00788     if (is_sleeping( ) == false) { return TAT_SUCCESS; }
00789     
00790     hal_set_slptr_low( );
00791     delay_us( TIME_SLEEP_TO_TRX_OFF );
00792     
00793     tat_status_t leave_sleep_status = TAT_TIMED_OUT;
00794     
00795     //Ensure that the radio transceiver is in the TRX_OFF state.
00796     if (tat_get_trx_state( ) == TRX_OFF) {
00797         leave_sleep_status = TAT_SUCCESS;
00798     }
00799     
00800     return leave_sleep_status;
00801 }
00802 
00808 void tat_reset_state_machine( void ){
00809     
00810     hal_set_slptr_low( );
00811     delay_us( TIME_NOCLK_TO_WAKE );
00812     hal_subregister_write( SR_TRX_CMD, CMD_FORCE_TRX_OFF );
00813     delay_us( TIME_CMD_FORCE_TRX_OFF );
00814 }
00815 
00821 void tat_reset_trx( void ){
00822 
00823     hal_set_rst_low( );
00824     hal_set_slptr_low( );
00825     delay_us( TIME_RESET );    
00826     hal_set_rst_high( );
00827 }
00828 
00839 void tat_use_auto_tx_crc( bool auto_crc_on ){
00840     
00841     if (auto_crc_on == true) {
00842         hal_subregister_write( SR_TX_AUTO_CRC_ON, 1 );
00843     } else {
00844         hal_subregister_write( SR_TX_AUTO_CRC_ON, 0 );
00845     } // end: if (auto_crc_on == true) ...
00846 }
00847 
00863 tat_status_t tat_send_data( uint8_t *data, uint8_t data_length ){
00864     
00865     /*Check function parameters and current state.*/
00866     if (data_length > RF230_MAX_TX_FRAME_LENGTH) { return TAT_INVALID_ARGUMENT; }
00867     
00868     if ((tat_get_trx_state( ) != PLL_ON)) { return TAT_WRONG_STATE; }
00869       
00870     /*Do frame transmission.*/
00871     //Toggle the SLP_TR pin to initiate the frame transmission.
00872     hal_set_slptr_high( );
00873     hal_set_slptr_low( );
00874             
00875     hal_frame_write( data, data_length ); //Then write data to the frame buffer.
00876            
00877     return TAT_SUCCESS; 
00878 }
00879 
00886 uint16_t tat_get_pan_id( void ){
00887     
00888     //This union is used for the data convertion purposes.
00889     union{
00890         
00891         uint16_t u16;
00892         uint8_t u8[ 2 ];
00893     }pan_id;
00894     
00895     pan_id.u8[ 0 ] = hal_register_read( RG_PAN_ID_1 );
00896     pan_id.u8[ 1 ] = hal_register_read( RG_PAN_ID_0 );
00897     
00898     return pan_id.u16;
00899 }
00900 
00907 void tat_set_pan_id( uint16_t new_pan_id ){
00908     
00909     //This union is used for the data convertion purposes.
00910     union{
00911         
00912         uint16_t u16;
00913         uint8_t u8[ 2 ];
00914     }pan_id;
00915     
00916     pan_id.u16 = new_pan_id;
00917     
00918     hal_register_write( RG_PAN_ID_1, pan_id.u8[ 0 ] );
00919     hal_register_write( RG_PAN_ID_0, pan_id.u8[ 1 ] );
00920 }
00921 
00929 uint16_t tat_get_short_address( void ){
00930 
00931    //This union is used for the data convertion purposes.
00932    union{
00933         
00934         uint16_t u16;
00935         uint8_t u8[ 2 ];
00936     }short_address;
00937     
00938     short_address.u8[ 0 ] = hal_register_read( RG_SHORT_ADDR_1 );
00939     short_address.u8[ 1 ] = hal_register_read( RG_SHORT_ADDR_0 );
00940     
00941     return short_address.u16;
00942 }
00943 
00950 void tat_set_short_address( uint16_t new_short_address ){
00951     
00952     //This union is used for the data convertion purposes.
00953     union{
00954         
00955         uint16_t u16;
00956         uint8_t u8[ 2 ];
00957     }short_address;
00958     
00959     short_address.u16 = new_short_address;
00960     
00961     hal_register_write( RG_SHORT_ADDR_1, short_address.u8[ 0 ] );
00962     hal_register_write( RG_SHORT_ADDR_0, short_address.u8[ 1 ] );
00963 }
00964 
00972 uint64_t tat_get_extended_address( void ){
00973     
00974     //This union is used for the data convertion purposes.
00975     union{
00976         
00977         uint64_t u64;
00978         uint8_t u8[ 8 ];
00979     }extended_address;
00980     
00981     extended_address.u8[ 0 ] = hal_register_read( RG_IEEE_ADDR_7 );
00982     extended_address.u8[ 1 ] = hal_register_read( RG_IEEE_ADDR_6 );
00983     extended_address.u8[ 2 ] = hal_register_read( RG_IEEE_ADDR_5 );
00984     extended_address.u8[ 3 ] = hal_register_read( RG_IEEE_ADDR_4 );
00985     extended_address.u8[ 4 ] = hal_register_read( RG_IEEE_ADDR_3 );
00986     extended_address.u8[ 5 ] = hal_register_read( RG_IEEE_ADDR_2 );
00987     extended_address.u8[ 6 ] = hal_register_read( RG_IEEE_ADDR_1 );
00988     extended_address.u8[ 7 ] = hal_register_read( RG_IEEE_ADDR_0 );
00989     
00990     return extended_address.u64;
00991 }
00992 
01000 void tat_set_extended_address( uint64_t new_extended_address ){
01001     
01002     //This union is used for the data convertion purposes.
01003     union{
01004         
01005         uint64_t u64;
01006         uint8_t u8[ 8 ];
01007     }extended_address;
01008     
01009     extended_address.u64 = new_extended_address;
01010     
01011     hal_register_write( RG_IEEE_ADDR_7, extended_address.u8[ 0 ] );
01012     hal_register_write( RG_IEEE_ADDR_6, extended_address.u8[ 1 ] );
01013     hal_register_write( RG_IEEE_ADDR_5, extended_address.u8[ 2 ] );
01014     hal_register_write( RG_IEEE_ADDR_4, extended_address.u8[ 3 ] );
01015     hal_register_write( RG_IEEE_ADDR_3, extended_address.u8[ 4 ] );
01016     hal_register_write( RG_IEEE_ADDR_2, extended_address.u8[ 5 ] );
01017     hal_register_write( RG_IEEE_ADDR_1, extended_address.u8[ 6 ] );
01018     hal_register_write( RG_IEEE_ADDR_0, extended_address.u8[ 7 ] );
01019 }
01020 
01042 tat_status_t tat_configure_csma( uint8_t seed0, uint8_t be_csma_seed1 ){
01043     
01044     /*Check state.*/
01045     if (is_sleeping( ) == true) { return TAT_WRONG_STATE; }
01046     
01047     /*Extract parameters, and configure the CSMA-CA algorithm.*/
01048     uint8_t back_off_exponent = ( be_csma_seed1 & 0xC0 ) >> 6;
01049     uint8_t csma_retries      = ( be_csma_seed1 & 0x38 ) >> 3;
01050     uint8_t seed1             = ( be_csma_seed1 & 0x07 );
01051             
01052     hal_subregister_write( SR_MAX_FRAME_RETRIES, 0 ); //AT86RF230 rev A errata.
01053     hal_subregister_write( SR_MAX_CSMA_RETRIES, csma_retries );
01054     hal_subregister_write( SR_MIN_BE, back_off_exponent );
01055     hal_subregister_write( SR_CSMA_SEED_0, seed0 );
01056     hal_subregister_write( SR_CSMA_SEED_1, seed1 );
01057             
01058     return TAT_SUCCESS;
01059 }
01060 
01081 tat_status_t tat_send_data_with_retry( uint8_t frame_length, uint8_t *frame, 
01082                                        uint8_t retries ){ 
01083     
01084     tat_status_t task_status = TAT_CHANNEL_ACCESS_FAILURE;          
01085     
01086     /*Do sanity check on function parameters and current state.*/
01087     if ((frame_length > RF230_MAX_TX_FRAME_LENGTH) || 
01088         (frame_length < TAT_MIN_IEEE_FRAME_LENGTH)) { 
01089         return TAT_INVALID_ARGUMENT; 
01090     }
01091     
01092     if (tat_get_trx_state( ) != TX_ARET_ON) { return TAT_WRONG_STATE; }
01093     
01094     hal_clear_trx_end_flag( );
01095     
01096     /*Do initial frame transmission.*/
01097     hal_set_slptr_high( );
01098     hal_set_slptr_low( );
01099     hal_frame_write( frame, frame_length ); //Then write data to the frame buffer.
01100     
01101     bool retry = false; // Variable used to control the retry loop.
01102     
01103     /*Do retry if requested.*/
01104     do{
01105         
01106         //Wait for TRX_END interrupt.
01107         while (hal_get_trx_end_flag( ) == 0) {;}
01108         
01109         //Check status.
01110         uint8_t transaction_status = hal_subregister_read( SR_TRAC_STATUS );
01111         
01112         //Check for failure.
01113         if ((transaction_status != TAT_TRANSMISSION_SUCCESS)) {
01114             
01115             if (transaction_status == TAT_BUSY_CHANNEL) {
01116                 task_status = TAT_CHANNEL_ACCESS_FAILURE;
01117             } else {
01118                 task_status = TAT_NO_ACK;
01119             }
01120             
01121             if ((retries--) > 0) {
01122                 
01123                 retry = true;
01124                 
01125                 //Wait for the TRX to go back to TX_ARET_ON.
01126                 while (tat_get_trx_state() != TX_ARET_ON) {;}
01127             
01128                 hal_clear_trx_end_flag( );
01129                 hal_set_slptr_high( );
01130                 hal_set_slptr_low( );
01131             } else {
01132                 retry = false;
01133             }
01134         } else{
01135             
01136             task_status = TAT_SUCCESS;
01137             retry = false;            
01138         } // end: if ((transaction_status != TAT_TRANSMISSION_SUCCESS)) ...
01139     } while (retry == true);
01140     
01141     return task_status;                                       
01142 }
01143 /*EOF*/
@DOC_TITLE@
Generated on Wed Jul 11 18:16:31 2007 for AVR2001 AT86RF230 Software Programmer's Manual by doxygen 1.4.7