/******************************************************************************* FILE NAME: rfmodem.c Copyright 1999-2000 SAGE Telecommunications Pty Ltd All rights Reserved The information contained herein is confidential property of the company. The use, copying, transfer or disclosure of such information is prohibited except by express written agreement with the Company. Permission is hereby granted to use this software for non-commercial purposes. AUTHOR: Rod Egan from SAGE Telecommunications Pty Ltd http://www.sages.com.au DESCRIPTION: RF modem packet rx/tx routines REVISION HISTORY: 0.0 11-Dec-99 initial source 0.1 12-May-00 released for private use *******************************************************************************/ #include "picreg.h" #fuses HS,NOPROTECT,WDT #zero_ram #use delay(clock=4000000, RESTART_WDT ) #define BUF_SIZE 32 // 5mSec of chars at 2400 ( 10 bits per char ~= 4.2mSec per char #define PREAMBLE_LEN 4 #define PREAMBLE 0xaa // rx uart sync delay in mSec ( 2 char times ) #define SYNC_DELAY 9 #define HDR1 0x55 #define HDR2 0xaa // postamble in mSec #define POSTAMBLE 1 // rx delay loops are ~12uSec // wait for 1st char 100mSec #define PREAMBLE_DLY 8500 // delay between chars after preamble ~1.5 char times 6mSec #define INTERCHAR_DLY 500 enum OPM { MS_MODE, PKT_MODE, STATS_MODE, LAST_MODE }op_mode; /* global variable storage */ byte buffer[ BUF_SIZE ]; byte buf_len; byte cksm; byte rx_len; /* global prototypes declaration */ /* local prototypes declaration */ byte get_packet( void ); void send_packet( void ); /****************************************************************************/ /* modem receive packet routine */ /* Receive encapsulated packet */ /* entry: na */ /* exit: True is packet rx'd ok with data in buffer */ /* else */ /* False if timeout or error */ /****************************************************************************/ byte get_packet( void ) { short status = FALSE; short got_hdr1 = FALSE; short got_hdr2 = FALSE; byte *ptr; byte c; long timeout; timeout = PREAMBLE_DLY; // wait for 1st header char do { if( kbhit() ) { if( getc() == HDR1 ) { got_hdr1 = TRUE; timeout = PREAMBLE_DLY; break; } } }while( --timeout ); // if we have 1st char then wait for 2nd header char if( got_hdr1 ) { do { if( kbhit() ) { c = getc(); if( c == HDR2 ) { // got 2nd header so flag and exit got_hdr2 = TRUE; timeout = INTERCHAR_DLY; break; } else if( c == HDR1 ) { // another chance at rx'ing 1st header timeout = PREAMBLE_DLY; } } }while( --timeout ); } // if rx'd 2nd header then get len byte if( got_hdr2 ) { do { if( kbhit() ) { cksm = buf_len = rx_len = getc(); // got len byte, abort if absurd value if( buf_len <= sizeof( buffer ) ) { // got len and it's ok now get data ptr = buffer; timeout = INTERCHAR_DLY; do { if( kbhit() ) { c = getc(); *ptr++ = c; cksm ^= c; timeout = INTERCHAR_DLY; if( !(--rx_len ) ) break; } }while( --timeout ); // if got all rx data then check CRC if( !rx_len ) { do { if( kbhit() ) { if( cksm == getc() ) { // crc ok, so flag and exit status = TRUE; } // break anyway even if bad CRC break; } }while( --timeout ); } } break; } }while( --timeout ); } return( status ); } /****************************************************************************/ /* modem send packet routine */ /* Encapsulate packet buffer and send to RF modem */ /* entry: na */ /* exit: na */ /****************************************************************************/ void send_packet( void ) { byte i, c; byte *ptr; // send preamble to help sync rx module data slicer i = PREAMBLE_LEN; do { putc( PREAMBLE ); }while( --i ); restart_wdt(); // send a continual 'high' for ~2 char periods to allow RX uart to sync io_portb.tx_m = TRUE; delay_ms( SYNC_DELAY ); restart_wdt(); // send data packet header, lenght byte then data putc( HDR1 ); putc( HDR2 ); putc( buf_len ); // seed checksum with data length cksm = i = buf_len; ptr = buffer; do { c = *ptr++; putc( c ); cksm ^= c; }while( --i ); // send checksum putc( cksm ); // make sure Tx is turned off io_portb.tx_m = FALSE; sent_count++; } /* end of file rfmodem.c */