Remote Access Control


comms.c File Reference


Detailed Description

Source file for communications public and support functions.

This file contains the function implementation for the communications control functions. Refer to the comms.h file for more details.

Author:
Atmel Corporation: http://www.atmel.com
Support email: avr@atmel.com
Name
Revision
1686
Date
2007-04-30 12:01:30 +0200 (ma, 30 apr 2007)

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


Function Documentation

void continueTransmission ( const byte buffer,
byte  byteCount 
)

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 }

void startTransmission ( const byte buffer,
byte  byteCount 
)

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 }


Variable Documentation

const byte __flash manchesterNibble[16] [static]

Lookup table for converting 4 bits to Manchester encoding.

Definition at line 161 of file comms.c.

byte manchesterPartThree [static]

Part three of Manchester encoded byte.

Definition at line 158 of file comms.c.

byte manchesterPartTwo [static]

Part two of Manchester encoded byte.

Definition at line 156 of file comms.c.

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().

@DOC_TITLE@
Generated on Fri Aug 8 11:03:23 2008 for AVR411 Secure Rolling Code Algorithm (Transmitter) by doxygen 1.4.7