Remote Access Control


radio.c File Reference


Detailed Description

Source file for the RF receiver support functions.

This file contains the function implementation for the RF receiver support functions. Refer to the radio.h file for more details.

Author:
Atmel Corporation: http://www.atmel.com
Support email: avr@atmel.com
Name
Revision
1193
Date
2006-10-31 14:21:08 +0100 (ti, 31 okt 2006)

Copyright (c) 2006, Atmel Corporation All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. The name of ATMEL may not be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file radio.c.

#include "radio.h"
#include "common.h"
#include "config.h"
#include <stddef.h>

Include dependency graph for radio.c:

Go to the source code of this file.

Defines

#define DELAY_US(delay)   __delay_cycles( (delay) * (CPU_F / 1000000) )
#define DRIVE_RX_DATA()   RX_DATA_DDR_REG |= (1<<RX_DATA_BIT_POS);
#define PROG_BIT_DELAY()   DELAY_US( RX_BASIC_CLK_US * PROG_BIT_PULSE_CYCLES )
#define PROG_BIT_PULSE_CYCLES   70
#define PROG_RESET_MARKER_HALF_PERIOD_DELAY()   DELAY_US( RX_BASIC_CLK_US * (PROG_RESET_MARKER_PERIOD_CYCLES / 2) )
#define PROG_RESET_MARKER_PERIOD_CYCLES   4096
#define PROG_RESET_MARKER_QUARTER_PERIOD_DELAY()   DELAY_US( RX_BASIC_CLK_US * (PROG_RESET_MARKER_PERIOD_CYCLES / 4) )
#define PROG_START_DELAY()   DELAY_US( RX_BASIC_CLK_US * PROG_START_PULSE_CYCLES )
#define PROG_START_PULSE_CYCLES   5000
#define PROG_START_RESET_DELAY()   DELAY_US( RX_BASIC_CLK_US * PROG_START_RESET_PULSE_CYCLES )
#define PROG_START_RESET_PULSE_CYCLES   8700
#define PROG_WINDOW_DELAY()   DELAY_US( RX_BASIC_CLK_US * PROG_WINDOW_DELAY_CYCLES )
#define PROG_WINDOW_DELAY_CYCLES   76
#define RELEASE_RX_DATA()   RX_DATA_DDR_REG &= ~(1<<RX_DATA_BIT_POS);
#define RX_BASIC_CLK_US   ( RX_PRESCALE / (RX_XTAL_HZ / 1000000) )
#define RX_TIMEOUT_VALUE   (RX_BASIC_CLK_US * PROG_RESET_MARKER_PERIOD_CYCLES)
#define WAIT_RX_DATA_EDGE(timeoutCountdownVar)
#define WAIT_RX_DATA_FALLING(timeoutCountdownVar)
#define WAIT_RX_DATA_RISING(timeoutCountdownVar)

Typedefs

typedef unsigned int rx_timeout_t

Functions

bool rx_CheckResetMarker (unsigned char checkCycles)
bool rx_WriteLIMIT (const rx_LIMIT_t *settings, bool longStartPulse, bool *equivalenceValue)
bool rx_WriteOFF (bool longStartPulse)
bool rx_WriteOPMODE (const rx_OPMODE_t *settings, bool longStartPulse, bool *equivalenceValue)
bool rx_WriteRegister (unsigned int value, bool longStartPulse, bool *equivalenceValue)
bool rx_WriteVerifySleep (const rx_OPMODE_t *opmode, const rx_LIMIT_t *limit)


Define Documentation

#define DELAY_US ( delay   )     __delay_cycles( (delay) * (CPU_F / 1000000) )

Macro to delay given number of microseconds based on AVR CPU speed.

Definition at line 76 of file radio.c.

 
#define DRIVE_RX_DATA (  )     RX_DATA_DDR_REG |= (1<<RX_DATA_BIT_POS);

Drive the RF receiver data line low from the AVR side.

Definition at line 106 of file radio.c.

Referenced by rx_WriteOFF(), and rx_WriteRegister().

 
#define PROG_BIT_DELAY (  )     DELAY_US( RX_BASIC_CLK_US * PROG_BIT_PULSE_CYCLES )

Delay for the length of one programming bit pulse.

Definition at line 89 of file radio.c.

Referenced by rx_WriteOFF(), and rx_WriteRegister().

#define PROG_BIT_PULSE_CYCLES   70

Length of programming bit pulse in 'basic clock cycles'.

Definition at line 67 of file radio.c.

 
#define PROG_RESET_MARKER_HALF_PERIOD_DELAY (  )     DELAY_US( RX_BASIC_CLK_US * (PROG_RESET_MARKER_PERIOD_CYCLES / 2) )

Delay for one half of a reset marker period.

Definition at line 95 of file radio.c.

Referenced by rx_CheckResetMarker().

#define PROG_RESET_MARKER_PERIOD_CYCLES   4096

Length of whole reset marker period in 'basic clock cycles'.

Definition at line 69 of file radio.c.

 
#define PROG_RESET_MARKER_QUARTER_PERIOD_DELAY (  )     DELAY_US( RX_BASIC_CLK_US * (PROG_RESET_MARKER_PERIOD_CYCLES / 4) )

Delay for one quarter of a reset marker period.

Definition at line 92 of file radio.c.

Referenced by rx_CheckResetMarker().

 
#define PROG_START_DELAY (  )     DELAY_US( RX_BASIC_CLK_US * PROG_START_PULSE_CYCLES )

Delay for the length of one programming start pulse.

Definition at line 80 of file radio.c.

Referenced by rx_WriteOFF(), and rx_WriteRegister().

#define PROG_START_PULSE_CYCLES   5000

Length of programming start pulse in 'basic clock cycles'.

Definition at line 61 of file radio.c.

 
#define PROG_START_RESET_DELAY (  )     DELAY_US( RX_BASIC_CLK_US * PROG_START_RESET_PULSE_CYCLES )

Delay for the length of one long start pulse.

Definition at line 83 of file radio.c.

Referenced by rx_WriteOFF(), and rx_WriteRegister().

#define PROG_START_RESET_PULSE_CYCLES   8700

Length of long start pulse in 'basic clock cycles'.

Definition at line 63 of file radio.c.

 
#define PROG_WINDOW_DELAY (  )     DELAY_US( RX_BASIC_CLK_US * PROG_WINDOW_DELAY_CYCLES )

Delay for the length of one programming window delay.

Definition at line 86 of file radio.c.

Referenced by rx_WriteOFF(), and rx_WriteRegister().

#define PROG_WINDOW_DELAY_CYCLES   76

Length of programming window delay in 'basic clock cycles'.

Definition at line 65 of file radio.c.

 
#define RELEASE_RX_DATA (  )     RX_DATA_DDR_REG &= ~(1<<RX_DATA_BIT_POS);

Release the RF receiver data line from the AVR side.

Definition at line 103 of file radio.c.

Referenced by rx_WriteOFF(), and rx_WriteRegister().

#define RX_BASIC_CLK_US   ( RX_PRESCALE / (RX_XTAL_HZ / 1000000) )

Internal RF basic clock cycle period in microseconds (equals RF freq. / 14).

Definition at line 58 of file radio.c.

#define RX_TIMEOUT_VALUE   (RX_BASIC_CLK_US * PROG_RESET_MARKER_PERIOD_CYCLES)

Timeout value guaranteed to a least exceed a valid reset marker period.

Definition at line 134 of file radio.c.

Referenced by rx_CheckResetMarker(), rx_WriteOFF(), and rx_WriteRegister().

#define WAIT_RX_DATA_EDGE ( timeoutCountdownVar   ) 

Value:

{ \
                unsigned char tempValue = GET_RX_DATA(); \
                do {} while( (GET_RX_DATA() == tempValue) && (--timeoutCountdownVar > 0) ); \
        }
Wait for any edge on the RF receiver data line while decrementing the timeout value.

Definition at line 121 of file radio.c.

Referenced by rx_CheckResetMarker().

#define WAIT_RX_DATA_FALLING ( timeoutCountdownVar   ) 

Value:

do {} while( (GET_RX_DATA() == 0) && (--timeoutCountdownVar > 0) ); \
        if( timeoutCountdownVar > 0 ) { \
                do {} while( (GET_RX_DATA() != 0) && (--timeoutCountdownVar > 0) ); \
        }
Wait for falling edge on the RF receiver data line while decrementing the timeout value.

Definition at line 109 of file radio.c.

Referenced by rx_WriteOFF(), and rx_WriteRegister().

#define WAIT_RX_DATA_RISING ( timeoutCountdownVar   ) 

Value:

do {} while( (GET_RX_DATA() != 0) && (--timeoutCountdownVar > 0) ); \
        if( timeoutCountdownVar > 0 ) { \
                do {} while( (GET_RX_DATA() == 0) && (--timeoutCountdownVar > 0) ); \
        }
Wait for rising edge on the RF receiver data line while decrementing the timeout value.

Definition at line 115 of file radio.c.

Referenced by rx_WriteOFF(), and rx_WriteRegister().


Typedef Documentation

typedef unsigned int rx_timeout_t

Data type to use for the timeout countdown value while waiting for edges on the data line.

Definition at line 132 of file radio.c.


Function Documentation

bool rx_CheckResetMarker ( unsigned char  checkCycles  ) 

Check if the reset marker (square wave) is present for 'checkCycles' cycles in the data line.

Definition at line 208 of file radio.c.

References GET_RX_DATA, PROG_RESET_MARKER_HALF_PERIOD_DELAY, PROG_RESET_MARKER_QUARTER_PERIOD_DELAY, RX_TIMEOUT_VALUE, and WAIT_RX_DATA_EDGE.

00209 {
00210         rx_timeout_t timeoutCountdown;
00211 
00212         timeoutCountdown = RX_TIMEOUT_VALUE;
00213         WAIT_RX_DATA_EDGE( timeoutCountdown ); // Wait for first edge.
00214         if( timeoutCountdown == 0 ) return false; // Timed out => no reset marker.
00215         PROG_RESET_MARKER_QUARTER_PERIOD_DELAY(); // Wait until the middle of the half-period.
00216 
00217         unsigned char tempValue = GET_RX_DATA();
00218         do {
00219                 PROG_RESET_MARKER_HALF_PERIOD_DELAY(); // Wait until next half of period.
00220 
00221                 if( GET_RX_DATA() == tempValue ) {
00222                         // No change on data line => no reset marker.
00223                         return false;
00224                 } else {
00225                         // Change => Store value and check next half-period.
00226                         tempValue = GET_RX_DATA();
00227                 }
00228         } while( --checkCycles );
00229 
00230         return true; // Yes, we found the reset marker.
00231 }

bool rx_WriteLIMIT ( const rx_LIMIT_t settings,
bool  longStartPulse,
bool *  equivalenceValue 
)

Set the RF receiver's LIMIT register.

The contents of the rx_LIMIT_t struct is programmed into the LIMIT register.

If 'longStartPulse' is true, the programming is initiated with a long start pulse cancelling any reset marker and initializing all registers.

If an equivalence bit is returned from the RF recevier, ie. the programmed values were already present in the LIMIT register, the 'bool' pointed to by 'equivalenceValue' is set to true. If not, it is set to false.

If the programming sessions fails or times out, nothing is changed and the function returns false. It return true if everything succeeds, regardless of the equivalence bit returned from the RF receiver.

Definition at line 331 of file radio.c.

References rx_LIMIT_t::limMax, rx_LIMIT_t::limMin, and rx_WriteRegister().

Referenced by rx_WriteVerifySleep().

00332 {
00333         if( settings == NULL ) {
00334                 return false; // Invalid input.
00335         }
00336 
00337         if( settings->limMin >= (1<<6) || settings->limMax >= (1<<6) ) {
00338                 return false; // Invalid input.
00339         }
00340 
00341         unsigned int registerValue = 0x0000; // Blank LIMIT frame.
00342         // Place fields correctly in frame.
00343         // Shift amount = register value bits (16) - position from right - field size in bits.
00344         registerValue |= settings->limMin << (16-2-6);
00345         registerValue |= settings->limMax << (16-8-6);
00346 
00347         return rx_WriteRegister( registerValue, longStartPulse, equivalenceValue );
00348 }

Here is the call graph for this function:

bool rx_WriteOFF ( bool  longStartPulse  ) 

Write an OFF command to the RF recevier.

An OFF command is sent to the RF receiver.

If 'longStartPulse' is true, the programming is initiated with a long start pulse cancelling any reset marker and initializing all registers.

If the programming sessions fails or times out, nothing is changed and the function returns false. It return true if everything succeeds, regardless of the equivalence bit returned from the RF receiver.

Definition at line 245 of file radio.c.

References DRIVE_RX_DATA, PROG_BIT_DELAY, PROG_START_DELAY, PROG_START_RESET_DELAY, PROG_WINDOW_DELAY, RELEASE_RX_DATA, RX_TIMEOUT_VALUE, WAIT_RX_DATA_FALLING, and WAIT_RX_DATA_RISING.

Referenced by main(), receiverTimedOut(), rx_WriteVerifySleep(), and rxClockLineHandler().

00246 {
00247         rx_timeout_t timeoutCountdown;
00248 
00249         DRIVE_RX_DATA(); // Begin 'programming start' pulse.
00250         if( longStartPulse == true ) {
00251                 PROG_START_RESET_DELAY();
00252         } else {
00253                 PROG_START_DELAY();
00254         }
00255         RELEASE_RX_DATA(); // End 'programming start' pulse.
00256 
00257         timeoutCountdown = RX_TIMEOUT_VALUE;
00258         WAIT_RX_DATA_FALLING( timeoutCountdown ); // Wait for synch. pulse begin edge.
00259         if( timeoutCountdown == 0 ) return false; // Timed out!
00260         timeoutCountdown = RX_TIMEOUT_VALUE;
00261         WAIT_RX_DATA_RISING( timeoutCountdown ); // Wait for synch. pulse end edge.
00262         if( timeoutCountdown == 0 ) return false; // Timed out!
00263 
00264         PROG_WINDOW_DELAY(); // Wait for programming window.
00265         PROG_BIT_DELAY(); // Bit pulse duration for logic 1.
00266 
00267         return true; // Success!
00268 }

bool rx_WriteOPMODE ( const rx_OPMODE_t settings,
bool  longStartPulse,
bool *  equivalenceValue 
)

Set the RF recevier's OPMODE register.

The contents of the rx_OPMODE_t struct is programmed into the OPMODE register.

If 'longStartPulse' is true, the programming is initiated with a long start pulse cancelling any reset marker and initializing all registers.

If an equivalence bit is returned from the RF recevier, ie. the programmed values were already present in the OPMODE register, the 'bool' pointed to by 'equivalenceValue' is set to true. If not, it is set to false.

If the programming sessions fails or times out, nothing is changed and the function returns false. It return true if everything succeeds, regardless of the equivalence bit returned from the RF receiver.

Definition at line 286 of file radio.c.

References rx_OPMODE_t::amplitudeModulation, rx_OPMODE_t::baudRateRange, rx_OPMODE_t::bitCheck, rx_OPMODE_t::noiseSuppression, rx_WriteRegister(), rx_OPMODE_t::sleepExtension, and rx_OPMODE_t::sleepValue.

Referenced by rx_WriteVerifySleep().

00287 {
00288         if( settings == NULL ) {
00289                 return false; // Invalid input.
00290         }
00291 
00292         // Check that no fields exceed their bitfield's max value.
00293         if( settings->baudRateRange >= (1<<2) ||
00294                         settings->bitCheck >= (1<<2) ||
00295                         settings->amplitudeModulation >= (1<<1) ||
00296                         settings->sleepValue >= (1<<5) ||
00297                         settings->sleepExtension >= (1<<1) ||
00298                         settings->noiseSuppression >= (1<<1) ) {
00299                 return false; // Invalid input.
00300         }
00301 
00302         unsigned int registerValue = 0x4000; // Blank OPMODE frame.
00303         // Place fields correctly in frame.
00304         // Shift amount = register value bits (16) - position from right - field size in bits.
00305         registerValue |= settings->baudRateRange << (16-2-2);
00306         registerValue |= settings->bitCheck << (16-4-2);
00307         registerValue |= settings->amplitudeModulation << (16-6-1);
00308         registerValue |= settings->sleepValue << (16-7-5);
00309         registerValue |= settings->sleepExtension << (16-12-1);
00310         registerValue |= settings->noiseSuppression << (16-13-1);
00311 
00312         return rx_WriteRegister( registerValue, longStartPulse, equivalenceValue );
00313 }

Here is the call graph for this function:

bool rx_WriteRegister ( unsigned int  value,
bool  longStartPulse,
bool *  equivalenceValue 
)

The upper 15 bits of 'value' is programmed into the RF recevier.

If 'longStartPulse' is true, the programming is initiated with a long start pulse cancelling any reset marker and initializing all registers.

If an equivalence bit is returned from the RF recevier, ie. the programmed values were already present in the register in question, the 'bool' pointed to by 'equivalenceValue' is set to true. If not, it is set to false.

If the programming sessions fails or times out, nothing is changed and the function returns false. It return true if everything succeeds, regardless of the equivalence bit returned from the RF receiver.

Definition at line 152 of file radio.c.

References DRIVE_RX_DATA, PROG_BIT_DELAY, PROG_START_DELAY, PROG_START_RESET_DELAY, PROG_WINDOW_DELAY, RELEASE_RX_DATA, RX_TIMEOUT_VALUE, WAIT_RX_DATA_FALLING, and WAIT_RX_DATA_RISING.

Referenced by rx_WriteLIMIT(), and rx_WriteOPMODE().

00153 {
00154         unsigned char bitCount = 15;
00155         rx_timeout_t timeoutCountdown;
00156 
00157         DRIVE_RX_DATA(); // Begin 'programming start' pulse.
00158         if( longStartPulse == true ) {
00159                 PROG_START_RESET_DELAY();
00160         } else {
00161                 PROG_START_DELAY();
00162         }
00163         RELEASE_RX_DATA(); // End 'programming start' pulse.
00164 
00165         do {
00166                 timeoutCountdown = RX_TIMEOUT_VALUE;
00167                 WAIT_RX_DATA_FALLING( timeoutCountdown ) // Wait for synch. pulse begin edge.
00168                 if( timeoutCountdown == 0 ) return false; // Timed out!
00169                 timeoutCountdown = RX_TIMEOUT_VALUE;
00170                 WAIT_RX_DATA_RISING( timeoutCountdown ) // Wait for synch. pulse end edge.
00171 
00172                 if( timeoutCountdown == 0 ) return false; // Timed out!
00173 
00174                 PROG_WINDOW_DELAY(); // Wait for programming window.
00175                 if( !(value & 0x8000) ) {
00176                         DRIVE_RX_DATA(); // Drive data line low to indicate logic 0.
00177                         PROG_BIT_DELAY(); // Bit pulse duration.
00178                         RELEASE_RX_DATA(); // Release line after bit pulse.
00179                 } else {
00180                         PROG_BIT_DELAY(); // Bit pulse duration for logic 1.
00181                 }
00182 
00183                 value <<= 1; // Move next bit into MSB of word.
00184         } while( --bitCount );
00185 
00186         bool equivalenceBit;
00187         timeoutCountdown = RX_TIMEOUT_VALUE;
00188         WAIT_RX_DATA_FALLING( timeoutCountdown ); // Wait for equivalence pulse begin egde.
00189         if( timeoutCountdown == 0 ) {
00190                 equivalenceBit = false; // Timed out => no pulse.
00191         } else {
00192                 timeoutCountdown = RX_TIMEOUT_VALUE;
00193                 WAIT_RX_DATA_RISING( timeoutCountdown ) // Wait for equivalence pulse end edge.
00194                 if( timeoutCountdown == 0 ) return false; // Timed out!
00195                 equivalenceBit = true; // No timeout => pulse present.
00196         }
00197 
00198         // If pointer is supplied, store equivalence bit.
00199         if( equivalenceValue ) {
00200                 *equivalenceValue = equivalenceBit;
00201         }
00202 
00203         return true; // Success!
00204 }

bool rx_WriteVerifySleep ( const rx_OPMODE_t opmode,
const rx_LIMIT_t limit 
)

Write both registers, verify settings and finish with an OFF command for the RF receiver.

Definition at line 352 of file radio.c.

References rx_WriteLIMIT(), rx_WriteOFF(), and rx_WriteOPMODE().

Referenced by initReceiver().

00353 {
00354         bool success;
00355         bool equivalent;
00356 
00357         success = rx_WriteOPMODE( opmode, true, NULL );
00358         if( !success ) {
00359                 // Try again of no success on first try.
00360                 success = rx_WriteOPMODE( opmode, true, NULL );
00361                 if( !success ) return false;
00362         }
00363         success = rx_WriteOPMODE( opmode, false, &equivalent );
00364         if( !success || !equivalent ) {
00365                 // Try again of no success on first try.
00366                 success = rx_WriteOPMODE( opmode, false, &equivalent );
00367                 if( !success || !equivalent ) return false;
00368         }
00369 
00370         success = rx_WriteLIMIT( limit, false, NULL );
00371         if( !success ) {
00372                 // Try again of no success on first try.
00373                 success = rx_WriteLIMIT( limit, false, NULL );
00374                 if( !success ) return false;
00375         }
00376         success = rx_WriteLIMIT( limit, false, &equivalent );
00377         if( !success || !equivalent ) {
00378                 // Try again of no success on first try.
00379                 success = rx_WriteLIMIT( limit, false, &equivalent );
00380                 if( !success || !equivalent ) return false;
00381         }
00382 
00383         success = rx_WriteOFF( false );
00384         if( !success ) {
00385                 // Try again of no success on first try.
00386                 success = rx_WriteOFF( false );
00387                 if( !success ) return false;
00388         }
00389 
00390         return true;
00391 }

Here is the call graph for this function:

@DOC_TITLE@
Generated on Fri Aug 8 11:04:05 2008 for AVR411 Secure Rolling Code Algorithm (Receiver) by doxygen 1.4.7