| Remote Access Control | |||||
This file contains the function implementation for the communications control functions. Refer to the comms.h file for more details.
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 comms.c.
#include "comms.h"
#include "common.h"
#include "config.h"
Include dependency graph for comms.c:

Go to the source code of this file.
Functions | |
| void | continueTransmission (const byte *buffer, byte byteCount) |
| void | startTransmission (const byte *buffer, byte byteCount) |
| void | stopTransmission () |
| __interrupt void | USIOverflowHandler (void) |
| void | waitForTransmission () |
Variables | |
| static const byte __flash | manchesterNibble [16] |
| static byte | manchesterPartThree |
| static byte | manchesterPartTwo |
| static const byte *volatile | nextUSIByte |
| static volatile byte | USIBytesLeft |
Add 'byteCount' bytes from 'buffer' in SRAM to an already running transmission.
Definition at line 338 of file comms.c.
References nextUSIByte, and USIBytesLeft.
Referenced by transmitCommandMessage(), and transmitTeachMessage().
00339 { 00340 // Prepare control variables. 00341 byte currentByte = *buffer++; 00342 nextUSIByte = buffer; 00343 USIBytesLeft = byteCount; 00344 00345 // Prepare Manchester pattern. 00346 byte manchesterByte1 = manchesterNibble[ currentByte >> 4 ]; 00347 byte manchesterByte2 = manchesterNibble[ currentByte & 0x0f ]; 00348 00349 // Put bit 0-6 of pattern at the end of USI data register. 00350 USIDR = USIDR & 0x80 | (manchesterByte1 >> 1); 00351 00352 // Prepare part two of pattern, ie. bits 6-13. 00353 manchesterPartTwo = (manchesterByte1 << 6) | (manchesterByte2 >> 2); 00354 00355 // Prepare part three of pattern, ie. bits 13-15 and 5 dummy zero bits. 00356 manchesterPartThree = (manchesterByte2 << 5); 00357 00358 // Enable USI interrupts again. 00359 USICR |= (1<<USIOIE); 00360 }
Start transmitting 'byteCount' bytes from 'buffer' in SRAM using Manchester encoding.
Definition at line 266 of file comms.c.
References nextUSIByte, and USIBytesLeft.
Referenced by transmitCommandMessage(), and transmitTeachMessage().
00267 { 00268 // Prepare control variables. 00269 byte currentByte = *buffer++; 00270 nextUSIByte = buffer; 00271 USIBytesLeft = byteCount; 00272 00273 // Prepare Manchester pattern. 00274 byte manchesterByte1 = manchesterNibble[ currentByte >> 4 ]; 00275 byte manchesterByte2 = manchesterNibble[ currentByte & 0x0f ]; 00276 00277 // Put idle bit value and bit 0-6 of pattern in USI data register. 00278 // This is the first part of the pattern. The output pin changes immediately. 00279 USIDR = 0x80 | (manchesterByte1 >> 1); 00280 00281 // Prepare part two of pattern, ie. bits 6-13. 00282 manchesterPartTwo = (manchesterByte1 << 6) | (manchesterByte2 >> 2); 00283 00284 // Prepare part three of pattern, ie. bits 13-15 and 5 dummy zero bits. 00285 manchesterPartThree = (manchesterByte2 << 5); 00286 00287 // Clear overflow flag and seed USI timer 00288 // to overflow in 7 bit shifts, so that last bit of first part of pattern is left. 00289 USISR = (1<<USIOIF) | (16-7); 00290 00291 // Start USI in Three-wire mode clocked by 00292 // Timer/Counter0 Compare Match A. Overflow interrupt enabled. 00293 #ifdef ASK 00294 USICR = (1<<USIOIE) | 00295 (0<<USIWM1) | (1<<USIWM0) | // Three-wire mode, data output on PB1. 00296 (0<<USICS1) | (1<<USICS0); 00297 #endif 00298 #ifdef FSK 00299 USICR = (1<<USIOIE) | 00300 (1<<USIWM1) | (0<<USIWM0) | // Two-wire mode, data output on PB0 (open collector). 00301 (0<<USICS1) | (1<<USICS0); 00302 DDRB |= (1<<PB0); // Enable data line output open collector driver. 00303 PORTB |= ((1<<PB1) | (1<<PB0)); // Turn on carrier wave and give data line to USI module. 00304 #endif 00305 00306 #ifdef BPS_19200 00307 // Set data rate to 19200 bps (ie. 9600 bps with Manchester). 00308 TCNT0 = 0x00; 00309 OCR0A = 51; // approx. (8MHz/8/19200bps)-1, ref. CTC Mode in datasheet. 00310 TCCR0A = (1<<WGM01); // Clear on Compare Match. 00311 TCCR0B = (0<<CS02) | (1<<CS01) | (0<<CS00); // Prescaler factor 8. 00312 #endif 00313 #ifdef BPS_9600 00314 // Set data rate to 9600 bps (ie. 4800 bps with Manchester). 00315 TCNT0 = 0x00; 00316 OCR0A = 103; // approx. (8MHz/8/9600bps)-1, ref. CTC Mode in datasheet. 00317 TCCR0A = (1<<WGM01); // Clear on Compare Match. 00318 TCCR0B = (0<<CS02) | (1<<CS01) | (0<<CS00); // Prescaler factor 8. 00319 #endif 00320 #ifdef BPS_4800 00321 // Set data rate to 4800 bps (ie. 2400 bps with Manchester). 00322 TCNT0 = 0x00; 00323 OCR0A = 25; // approx. (8MHz/64/2400bps)-1, ref. CTC Mode in datasheet. 00324 TCCR0A = (1<<WGM01); // Clear on Compare Match. 00325 TCCR0B = (0<<CS02) | (1<<CS01) | (1<<CS00); // Prescaler factor 64. 00326 #endif 00327 #ifdef BPS_2400 00328 // Set data rate to 2400 bps (ie. 1200 bps with Manchester). 00329 TCNT0 = 0x00; 00330 OCR0A = 51; // approx. (8MHz/64/2400bps)-1, ref. CTC Mode in datasheet. 00331 TCCR0A = (1<<WGM01); // Clear on Compare Match. 00332 TCCR0B = (0<<CS02) | (1<<CS01) | (1<<CS00); // Prescaler factor 64. 00333 #endif 00334 }
| void stopTransmission | ( | ) |
Stop transmission module and restore previous port states.
Definition at line 368 of file comms.c.
Referenced by transmitCommandMessage(), and transmitTeachMessage().
00369 { 00370 USICR = 0x00; 00371 #ifdef FSK 00372 PORTB &= ~((1<<PB1) | (1<<PB0)); // Turn off carrier wave and release data line. 00373 DDRB &= ~(1<<PB0); // Disable data line output open collector driver. 00374 #endif 00375 }
| __interrupt void USIOverflowHandler | ( | void | ) |
Put next byte into USI Data Register or stop transmitting.
Definition at line 209 of file comms.c.
References nextUSIByte, and USIBytesLeft.
00210 { 00211 // 'manchesterPartTwo' is non-zero if part two has not been sent. 00212 if( manchesterPartTwo != 0x00 ) { 00213 USISR = (1<<USIOIF) | (16-7); 00214 USIDR = manchesterPartTwo; 00215 manchesterPartTwo = 0x00; 00216 00217 // 'manchesterPartThree' is non-zero if part three has not been sent. 00218 } else if( manchesterPartThree != 0x00 ) { 00219 USISR = (1<<USIOIF) | (16-2); 00220 USIDR = manchesterPartThree; 00221 manchesterPartThree = 0x00; 00222 00223 // If part two and three are zero, it's time to prepare next byte. 00224 } else { 00225 // Clear overflow flag and seed USI counter. 00226 // to overflow in 7 bit shifts. It is important to 00227 // seed the timer this early, so that the computations 00228 // below does not affect the transmission timing. 00229 USISR = (1<<USIOIF) | (16-7); 00230 00231 --USIBytesLeft; // One less byte left to transmit. 00232 00233 // If bytes left, prepare for sending the next. 00234 if( USIBytesLeft > 0 ) { 00235 byte currentByte = *nextUSIByte++; 00236 byte manchesterByte1; 00237 byte manchesterByte2; 00238 00239 // Prepare Manchester pattern. 00240 manchesterByte1 = manchesterNibble[ currentByte >> 4 ]; 00241 manchesterByte2 = manchesterNibble[ currentByte & 0x0f ]; 00242 00243 // Put bit 0-6 of pattern at the end of USI data register. 00244 USIDR = USIDR & 0x80 | (manchesterByte1 >> 1); 00245 00246 // Prepare part two of pattern, ie. bits 6-13. 00247 manchesterPartTwo = (manchesterByte1 << 6) | (manchesterByte2 >> 2); 00248 00249 // Prepare part three of pattern, ie. bits 13-15 and 5 dummy zero bits. 00250 manchesterPartThree = (manchesterByte2 << 5); 00251 } else { 00252 // No bytes left => turn off further interrupts, in case 00253 // the call to stopTransmission is delayed. 00254 // The USI module will continue transmittion zeros. 00255 // We cannot stop the whole USI module, since the user 00256 // might want to continue transmitting. In that case, the 00257 // user must call continueTransmission as soon as possible 00258 // after returning from waitForTransmission. 00259 USICR &= ~(1<<USIOIE); // Disable interrupts. 00260 } 00261 } 00262 }
| void waitForTransmission | ( | ) |
Sleep and wait for a running transmission to finish.
Definition at line 379 of file comms.c.
References USIBytesLeft.
Referenced by transmitCommandMessage(), and transmitTeachMessage().
00380 { 00381 // Enter Idle sleep mode while waiting for transmission to finish. 00382 MCUCR = (1<<SE) | (0<<SM1) | (0<<SM0); 00383 while( USIBytesLeft ) { __sleep(); } 00384 }
const byte __flash manchesterNibble[16] [static] |
byte manchesterPartThree [static] |
byte manchesterPartTwo [static] |
const byte* volatile nextUSIByte [static] |
Pointer to next byte to be transmitted.
Definition at line 55 of file comms.c.
Referenced by continueTransmission(), startTransmission(), and USIOverflowHandler().
volatile byte USIBytesLeft [static] |
Number of bytes left to transmit.
Definition at line 57 of file comms.c.
Referenced by continueTransmission(), startTransmission(), USIOverflowHandler(), and waitForTransmission().
Generated on Fri Aug 8 11:03:23 2008 for AVR411 Secure Rolling Code Algorithm (Transmitter) by 1.4.7
|