00001
00048 #include "radio.h"
00049 #include "common.h"
00050 #include "config.h"
00051 #include <stddef.h>
00052
00053
00054
00055
00056
00058 #define RX_BASIC_CLK_US ( RX_PRESCALE / (RX_XTAL_HZ / 1000000) )
00059
00061 #define PROG_START_PULSE_CYCLES 5000 // Approx. 10% less than max. (t1 in datasheet).
00063 #define PROG_START_RESET_PULSE_CYCLES 8700 // Approx. 10% more than min. (t1 in datasheet).
00065 #define PROG_WINDOW_DELAY_CYCLES 76 // Approx. 20% more than min. (t4 in datasheet).
00067 #define PROG_BIT_PULSE_CYCLES 70 // Approx. 10% more than min. (t7 in datasheet).
00069 #define PROG_RESET_MARKER_PERIOD_CYCLES 4096 // Exact value (f_RM in datasheet).
00070
00071
00072
00073
00074
00076 #define DELAY_US( delay ) \
00077 __delay_cycles( (delay) * (CPU_F / 1000000) )
00078
00080 #define PROG_START_DELAY() \
00081 DELAY_US( RX_BASIC_CLK_US * PROG_START_PULSE_CYCLES )
00083 #define PROG_START_RESET_DELAY() \
00084 DELAY_US( RX_BASIC_CLK_US * PROG_START_RESET_PULSE_CYCLES )
00086 #define PROG_WINDOW_DELAY() \
00087 DELAY_US( RX_BASIC_CLK_US * PROG_WINDOW_DELAY_CYCLES )
00089 #define PROG_BIT_DELAY() \
00090 DELAY_US( RX_BASIC_CLK_US * PROG_BIT_PULSE_CYCLES )
00092 #define PROG_RESET_MARKER_QUARTER_PERIOD_DELAY() \
00093 DELAY_US( RX_BASIC_CLK_US * (PROG_RESET_MARKER_PERIOD_CYCLES / 4) )
00095 #define PROG_RESET_MARKER_HALF_PERIOD_DELAY() \
00096 DELAY_US( RX_BASIC_CLK_US * (PROG_RESET_MARKER_PERIOD_CYCLES / 2) )
00097
00098
00099
00100
00101
00103 #define RELEASE_RX_DATA() \
00104 RX_DATA_DDR_REG &= ~(1<<RX_DATA_BIT_POS);
00106 #define DRIVE_RX_DATA() \
00107 RX_DATA_DDR_REG |= (1<<RX_DATA_BIT_POS);
00109 #define WAIT_RX_DATA_FALLING( timeoutCountdownVar ) \
00110 do {} while( (GET_RX_DATA() == 0) && (--timeoutCountdownVar > 0) ); \
00111 if( timeoutCountdownVar > 0 ) { \
00112 do {} while( (GET_RX_DATA() != 0) && (--timeoutCountdownVar > 0) ); \
00113 }
00115 #define WAIT_RX_DATA_RISING( timeoutCountdownVar ) \
00116 do {} while( (GET_RX_DATA() != 0) && (--timeoutCountdownVar > 0) ); \
00117 if( timeoutCountdownVar > 0 ) { \
00118 do {} while( (GET_RX_DATA() == 0) && (--timeoutCountdownVar > 0) ); \
00119 }
00121 #define WAIT_RX_DATA_EDGE( timeoutCountdownVar ) \
00122 { \
00123 unsigned char tempValue = GET_RX_DATA(); \
00124 do {} while( (GET_RX_DATA() == tempValue) && (--timeoutCountdownVar > 0) ); \
00125 }
00126
00127
00128
00129
00130
00132 typedef unsigned int rx_timeout_t;
00134 #define RX_TIMEOUT_VALUE (RX_BASIC_CLK_US * PROG_RESET_MARKER_PERIOD_CYCLES)
00135
00136
00137
00152 bool rx_WriteRegister( unsigned int value, bool longStartPulse, bool * equivalenceValue )
00153 {
00154 unsigned char bitCount = 15;
00155 rx_timeout_t timeoutCountdown;
00156
00157 DRIVE_RX_DATA();
00158 if( longStartPulse == true ) {
00159 PROG_START_RESET_DELAY();
00160 } else {
00161 PROG_START_DELAY();
00162 }
00163 RELEASE_RX_DATA();
00164
00165 do {
00166 timeoutCountdown = RX_TIMEOUT_VALUE;
00167 WAIT_RX_DATA_FALLING( timeoutCountdown )
00168 if( timeoutCountdown == 0 ) return false;
00169 timeoutCountdown = RX_TIMEOUT_VALUE;
00170 WAIT_RX_DATA_RISING( timeoutCountdown )
00171
00172 if( timeoutCountdown == 0 ) return false;
00173
00174 PROG_WINDOW_DELAY();
00175 if( !(value & 0x8000) ) {
00176 DRIVE_RX_DATA();
00177 PROG_BIT_DELAY();
00178 RELEASE_RX_DATA();
00179 } else {
00180 PROG_BIT_DELAY();
00181 }
00182
00183 value <<= 1;
00184 } while( --bitCount );
00185
00186 bool equivalenceBit;
00187 timeoutCountdown = RX_TIMEOUT_VALUE;
00188 WAIT_RX_DATA_FALLING( timeoutCountdown );
00189 if( timeoutCountdown == 0 ) {
00190 equivalenceBit = false;
00191 } else {
00192 timeoutCountdown = RX_TIMEOUT_VALUE;
00193 WAIT_RX_DATA_RISING( timeoutCountdown )
00194 if( timeoutCountdown == 0 ) return false;
00195 equivalenceBit = true;
00196 }
00197
00198
00199 if( equivalenceValue ) {
00200 *equivalenceValue = equivalenceBit;
00201 }
00202
00203 return true;
00204 }
00205
00206
00207
00208 bool rx_CheckResetMarker( unsigned char checkCycles )
00209 {
00210 rx_timeout_t timeoutCountdown;
00211
00212 timeoutCountdown = RX_TIMEOUT_VALUE;
00213 WAIT_RX_DATA_EDGE( timeoutCountdown );
00214 if( timeoutCountdown == 0 ) return false;
00215 PROG_RESET_MARKER_QUARTER_PERIOD_DELAY();
00216
00217 unsigned char tempValue = GET_RX_DATA();
00218 do {
00219 PROG_RESET_MARKER_HALF_PERIOD_DELAY();
00220
00221 if( GET_RX_DATA() == tempValue ) {
00222
00223 return false;
00224 } else {
00225
00226 tempValue = GET_RX_DATA();
00227 }
00228 } while( --checkCycles );
00229
00230 return true;
00231 }
00232
00233
00234
00245 bool rx_WriteOFF( bool longStartPulse )
00246 {
00247 rx_timeout_t timeoutCountdown;
00248
00249 DRIVE_RX_DATA();
00250 if( longStartPulse == true ) {
00251 PROG_START_RESET_DELAY();
00252 } else {
00253 PROG_START_DELAY();
00254 }
00255 RELEASE_RX_DATA();
00256
00257 timeoutCountdown = RX_TIMEOUT_VALUE;
00258 WAIT_RX_DATA_FALLING( timeoutCountdown );
00259 if( timeoutCountdown == 0 ) return false;
00260 timeoutCountdown = RX_TIMEOUT_VALUE;
00261 WAIT_RX_DATA_RISING( timeoutCountdown );
00262 if( timeoutCountdown == 0 ) return false;
00263
00264 PROG_WINDOW_DELAY();
00265 PROG_BIT_DELAY();
00266
00267 return true;
00268 }
00269
00270
00271
00286 bool rx_WriteOPMODE( const rx_OPMODE_t * settings, bool longStartPulse, bool * equivalenceValue )
00287 {
00288 if( settings == NULL ) {
00289 return false;
00290 }
00291
00292
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;
00300 }
00301
00302 unsigned int registerValue = 0x4000;
00303
00304
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 }
00314
00315
00316
00331 bool rx_WriteLIMIT( const rx_LIMIT_t * settings, bool longStartPulse, bool * equivalenceValue )
00332 {
00333 if( settings == NULL ) {
00334 return false;
00335 }
00336
00337 if( settings->limMin >= (1<<6) || settings->limMax >= (1<<6) ) {
00338 return false;
00339 }
00340
00341 unsigned int registerValue = 0x0000;
00342
00343
00344 registerValue |= settings->limMin << (16-2-6);
00345 registerValue |= settings->limMax << (16-8-6);
00346
00347 return rx_WriteRegister( registerValue, longStartPulse, equivalenceValue );
00348 }
00349
00350
00351
00352 bool rx_WriteVerifySleep( const rx_OPMODE_t * opmode, const rx_LIMIT_t * limit )
00353 {
00354 bool success;
00355 bool equivalent;
00356
00357 success = rx_WriteOPMODE( opmode, true, NULL );
00358 if( !success ) {
00359
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
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
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
00379 success = rx_WriteLIMIT( limit, false, &equivalent );
00380 if( !success || !equivalent ) return false;
00381 }
00382
00383 success = rx_WriteOFF( false );
00384 if( !success ) {
00385
00386 success = rx_WriteOFF( false );
00387 if( !success ) return false;
00388 }
00389
00390 return true;
00391 }
00392