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

- File: comms.c
- Compiler: IAR EWAVR 4.11B
- Supported devices: ATtiny45/85
- AppNote: AVR411 - Secure Rolling Code Algorithm for Wireless Link

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@