📄 fhp.c
字号:
/*****************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** *
* *** + CHIPCON CC1010 *
* *** + + *** FREQUENCY JUMPING PROTOCOL *
* *** +++ *** *
* *** *** *
* *********** *
* ********* *
* *
*****************************************************************************
* This file contains the implementations of all the functions from the *
* Frequency Hopping Protocol library, which is found in Cul.h, as well as *
* some internal utility functions. *
*****************************************************************************
* Author: OGR *
*****************************************************************************
* Revision history: *
* *
* $Log: Fhp.c,v $
* Revision 1.1 2003/07/29 11:24:48 tos
* Initial version in CVS.
*
*
* *
****************************************************************************/
#include <chipcon/hal.h>
#include <chipcon/cul.h>
#include <chipcon/cc1010eb.h>
#include <stdlib.h>
#define TRBIT 128
#define ACKBYTE 0x3B
#define PREAMBLE_BYTE_COUNT 5
#define GO_OFFLINE (FHPstatus==IDLE && FHPmode!=ACTIVE)
#define BEACON (systemID^0x80)
xdata bool isMaster = TRUE;
xdata byte FHPmode = OFF;
xdata byte FHPstatus = IDLE;
xdata byte systemID = 0x4C;
xdata byte ownID = 1;
extern xdata byte maxPacketLength;
xdata byte messageLength = 0;
xdata byte xdata* sendPacket;
xdata byte sendLength;
xdata byte sendDest;
xdata byte ctrl[2];
xdata byte requester = 0;
xdata byte errors = 99;
xdata byte lastKnownPosition = 0;
data void (*receivingFunction) () = NULL;
data void (*callback) () = NULL;
data void (*synchFailed) () = NULL;
//----------------------------------------------------------------------------
// void showLED(...)
//
// Description:
// Internal function only to be used by the FHP itself.
// Displays the four least significant bits of the argument
// on the LEDs on the evaluation board.
// Used for debugging purposes.
//
// Arguments:
// byte a
// The value to be displayed on the LEDs.
//
// Return value:
// void
//----------------------------------------------------------------------------
void showLED(byte a) {
BLED = !(a&0x01);
GLED = !(a&0x02);
YLED = !(a&0x04);
RLED = !(a&0x08);
} // end showLED
//----------------------------------------------------------------------------
// void fhpSendPacket()
//
// Description:
// Internal function only to be used by the FHP itself.
// Transmits a packet, possibly receives acknowledgement
// and calls the callback function if successfull.
//
// Arguments:
// None.
//
// Return value:
// void
//----------------------------------------------------------------------------
void fhpSendPacket() {
bool success = TRUE;
halRFSendPacket(PREAMBLE_BYTE_COUNT, &sendPacket[0], sendLength);
if (fhpSettings.useAck && (sendDest!=0 || !isMaster)) {
changeFreq(RF_RX, 0);
halWait(1,fhpSettings.clkFreq);
if (!(halRFReceivePacket(fhpSettings.listenTime, &ctrl[0], 2, 0, fhpSettings.clkFreq)==2 && ctrl[0]==systemID && ctrl[1]==ACKBYTE)) {
success = FALSE;
}
}
if (success) {
FHPstatus = IDLE;
if (callback != NULL)
callback();
}
} // end fhpSendPacket
//----------------------------------------------------------------------------
// void fhpReceivePacket(...)
//
// Description:
// Internal function only to be used by the FHP itself.
// Receives a packet and possibly sends an acknowledgement.
// The receivingFunction is called if successfull.
//
// Arguments:
// bool sendAck
// Specifies whether or not to send an acknowledgement.
//
// Return value:
// void
//----------------------------------------------------------------------------
void fhpReceivePacket(bool sendAck) {
messageLength = halRFReceivePacket(fhpSettings.listenTime, message, maxPacketLength, 0, fhpSettings.clkFreq);
if (messageLength > 0) {
if (fhpSettings.useAck && sendAck) {
changeFreq(RF_TX, 0);
ctrl[0] = systemID;
ctrl[1] = ACKBYTE;
halWait(1,fhpSettings.clkFreq);
halRFSendPacket(PREAMBLE_BYTE_COUNT, &ctrl[0], 2);
}
if (receivingFunction!=NULL)
receivingFunction();
}
} // end fhpReceivePacket
//----------------------------------------------------------------------------
// void setupTimer2(word period)
//
// Description:
// Internal function only to be used by the FHP itself.
// Sets up timer 2 as an interrupt timer and enables it.
//
// Arguments:
// word period
// The value to be loaded into the timer whenever it overflows.
//
// Return value:
// void
//----------------------------------------------------------------------------
void setupTimer2(word period) {
EXIF&=~0x80; // Clear interrupt flag
ET2=1; // Enable timer interrupt
EA=1; // Enable global interrupt
T2PRE=(byte)(period>>8);
T2=(byte)period;
TCON2=(TCON2&~0x0C);
INT_PRIORITY(INUM_TIMER2, INT_HIGH);
TIMER2_RUN(FALSE);
} // end setupTimer2
//----------------------------------------------------------------------------
// void initializeFHP(...)
//
// Description:
// Used to initialize the FHP protocol as either a master or a slave.
// Frequencies are calibrated and timers are set up.
//
// Arguments:
// bool master
// TRUE if master, FALSE if slave
//
// Return value:
// void
//----------------------------------------------------------------------------
void initializeFHP(bool master) {
isMaster = master;
if (fhpSettings.useLEDs) showLED(15);
initializeFrequencies();
if (fhpSettings.useLEDs) showLED(0);
if (master) {
setupTimer2((word)(((ulong)fhpSettings.period*fhpSettings.clkFreq+127)/255));
} else {
setModulus(fhpSettings.period*(ulong)1000*numberOfFrequencies);
setupTimer2((word)((((ulong)(fhpSettings.period-fhpSettings.overhead))*fhpSettings.clkFreq+127)/255)); //-5*fhpSettings.listenTime
}
} // end initializeFHP
//----------------------------------------------------------------------------
// void setReceivingFunction(...)
//
// Description:
// Used to specify which function should be called when
// a packet arrives. The function may simply set a flag to
// indicate the arrival, or it may process the packet itself.
// The packet is available in the buffer message until a new
// packet arrives.
// An argument of NULL specifies that no function will be called.
// This is the default behaviour on start-up.
//
// Arguments:
// void (*pF) ()
// A pointer to the function that will be notified of new packets.
//
// Return value:
// void
//----------------------------------------------------------------------------
void setReceivingFunction( void (*pF) () ) {
receivingFunction = pF;
} // end setReceivingFunction
//----------------------------------------------------------------------------
// void setCallbackFunction(...)
//
// Description:
// Used to specify which function should be called when
// a packet is successfully sent.
// An argument of NULL specifies that no function will be called.
// This is the default behaviour on start-up.
//
// Arguments:
// void (*pF) ()
// A pointer to the function that will be notified
// of successful transmissions.
//
// Return value:
// void
//----------------------------------------------------------------------------
void setCallbackFunction( void (*pF) () ) {
callback = pF;
} // end setCallbackFunction
//----------------------------------------------------------------------------
// void setSynchronizationFailedFunction(...)
//
// Description:
// Used to specify which function should be called when
// an acquisition attempt is unsuccessful.
// The user application must then initiate a new attempt.
// This could be done in a number of ways:
// - calling the synchronize function
// - calling setMode(ACTIVE)
// - sending a new packet if in the PASSIVE mode
// (any previous packet must be canceled)
// An argument of NULL specifies that the FHP should go on trying
// to synchronize until it is successful instead of calling a
// user function. This is the default behaviour on start-up.
//
// Arguments:
// void (*pF) ()
// A pointer to the function that will be notified failed acquisitions.
//
// Return value:
// void
//----------------------------------------------------------------------------
void setSynchronizationFailedFunction( void (*pF) () ) {
synchFailed = pF;
} // end setSynchronizationFailedFunction
//----------------------------------------------------------------------------
// void resetTimers()
//
// Description:
// Internal function only to be used by the FHP itself.
// Resets timer 2 and the real time clock.
// To be called when contact is established with the master.
//
// Arguments:
// None.
//
// Return value:
// void
//----------------------------------------------------------------------------
void resetTimers() {
TIMER2_RUN(FALSE);
TIMER2_RUN(TRUE);
setTime(1000*(ulong)(fhpSettings.overhead+fhpSettings.period/2));
lastKnownPosition = getFrequencyPosition();
errors = 0;
} // end resetTimers
//----------------------------------------------------------------------------
// bool listenForBeacon(...)
//
// Description:
// Internal function only to be used by the FHP itself.
// Receives the beacon transmitted by the master and possibly
// receives a packet, transmits a packet or transmits a signal
// to indicate that the slave wants to transmit a packet.
//
// Arguments:
// byte timeout
// The time in tenths of milliseconds that it will listen for beacon.
// Return value:
// bool
// Indicates whether or not a beacon was received.
//----------------------------------------------------------------------------
bool listenForBeacon(byte timeout) {
byte length, control;
if (fhpSettings.useLEDs) RLED = GLED = LED_OFF;
length = halRFReceivePacket(timeout, &ctrl[0], 2, 0, fhpSettings.clkFreq);
if (fhpSettings.useLEDs) YLED = LED_OFF;
if (length==2 && ctrl[0]==BEACON) {
resetTimers();
if (FHPstatus == NOLINK)
FHPstatus = WAITING;
if (fhpSettings.useLEDs) {
GLED = LED_ON;
RLED = LED_OFF;
}
control = ctrl[1];
// Respond
if (control&TRBIT) {
// Master is going to send
if ( (control==(BROADCASTID|TRBIT)) || (control==(ownID|TRBIT)) ) {
// The packet will be for me
fhpReceivePacket(control==(ownID|TRBIT));
}
} else if ( FHPstatus != IDLE ) {
// A packet is ready
if (control == BROADCASTID) {
// nobody will send
changeFreq(RF_TX, 0);
ctrl[0] = systemID;
ctrl[1] = ownID;
halWait((rand()%fhpSettings.timeslots)*fhpSettings.slotSize,fhpSettings.clkFreq);
halRFSendPacket(PREAMBLE_BYTE_COUNT, &ctrl[0], 2);
} else if (control == ownID) {
changeFreq(RF_TX, 0);
fhpSendPacket();
if (GO_OFFLINE)
TIMER2_RUN(FALSE);
} // else someone else will send
}
return TRUE;
} else {
++errors;
if (fhpSettings.useLEDs) RLED = LED_ON;
return FALSE;
}
} // end listenForBeacon
//----------------------------------------------------------------------------
// bool newSending(...)
//
// Description:
// Initiates a new transmission.
// The previous transmission must either have been successfully completed
// or canceled.
// The function returns immediately, and the packet must not be altered
// before the packet has been sent or canceled.
//
// Arguments:
// byte xdata* packet
// A pointer to the packet, which must reside in external memory.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -