📄 rxworwithack.c
字号:
/*******************************************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** This file contains all functions related to the receiving (WOR) unit *
* *** + + *** *
* *** + *
* *** + + *** *
* *** +++ *** RxWorWithAck.c *
* *** *** *
* ************ *
* ********** *
* *
*******************************************************************************************************
* Compiler: Keil C51 V7.50 *
* Target platform: Chipcon CCxxx0 (Silabs F320) *
* Author: ESY *
*******************************************************************************************************
* Revision history: See end of file *
*******************************************************************************************************/
#include <Chipcon\srf04\regssrf04.h>
#include <Chipcon\srf04\halsrf04.h>
#include <Chipcon\srf04\ebsrf04.h>
#include <WorWithAck.h>
//-------------------------------------------------------------------------------------------------------
// Defines
#define RX_BYTES 0x7F
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// Global Variables
// Variables to control the incoming packets and outgoing ACKs
UINT32 xdata packetsReceived = 0;
UINT8 xdata sendAck = FALSE;
// Byte/char arrays for LCD presentation of data
BYTE xdata asciiJoystickPosition[] = "Joystick: ";
BYTE xdata asciiPackets[] = "Pkts rcvd: ";
UINT8 xdata updateLcd = FALSE;
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// Function declarations
void initReceiver();
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// void runReceiver(void)
//
// DESCRIPTION:
// This function is used to put the radio in SLEEP mode using WOR. If the MCU detects that a packet
// is received, this function will send an ACK and then update the LCD display in accordance with
// the packet data received.
//-------------------------------------------------------------------------------------------------------
void runReceiver(void) {
UINT8 i;
// Initialize receiver
initReceiver();
SET_YLED(LED_ON); // Turn on yellow LED to indicate unit is running
// Put the radio to SLEEP by starting Wake-on-Radio.
halSpiStrobe(CCxxx0_SWORRST); // Resets the real time clock
halSpiStrobe(CCxxx0_SWOR); // Starts Wake-on-Radio
// The MCU could here enter some power-down state to reduce power consumption while waiting for a
// WOR interrupt from the CCxx00 radio (this is not implemented here in this example
// - instead there is a while loop updating the LCD).
// Loops forever updating LCD with the received data. Button S1 for abortion.
while(!ebButtonPushed()) {
if (updateLcd) { // This flag is set in EXTERNAL1_ISR if the LCD needs to be updated
updateLcd = FALSE;
intToAscii(packetsReceived);
// Copying chars for better LCD presentation
for (i = 0; asciiString[i] >= '0' && asciiString[i] <= '9'; i++)
asciiPackets[11 + i] = asciiString[i];
asciiPackets[11 + i] = NULL;
ebLcdUpdate(asciiPackets, asciiJoystickPosition);
}
}
//Button S1 has been pressed for abortion
INT_ENABLE(INUM_EXTERNAL1, INT_OFF); // Disable external1 interrupts
SET_YLED(LED_OFF); // Turn off yellow LED to indicate unit has stopped.
}// runReceiver
//-------------------------------------------------------------------------------------------------------
// void initReceiver(void)
//
// DESCRIPTION:
// This function is configuring some specific radio register settings and initiating
// interrupt for the receiver/WOR unit.
//-------------------------------------------------------------------------------------------------------
void initReceiver(void) {
// Configuring all the WOR related settings
// Enable automatic initial calibration of RCosc.
// Set T_event1 ~ 345 us, enough for XOSC stabilize before starting calibration.
// Enable RC oscillator before starting with WOR (or else it will not wake up).
halSpiWriteReg(CCxxx0_WORCTRL, 0x38); // Not using AUTO_SYNC function.
// Set Event0 timeout = 300 ms (RX polling interval)
// WOR_RES = 0
// T_event0 = 750 / f_xosc * EVENT0 * 2^(5*WOR_RES) = 300 ms // Assuming f_xosc = 26 MHz
// => EVENT0 = 10400 = 0x28A0
halSpiWriteReg(CCxxx0_WOREVT1, 0x28); // High byte Event0 timeout
halSpiWriteReg(CCxxx0_WOREVT0, 0xA0); // Low byte Event0 timeout.
// Setting Rx_timeout < 0.5 %.
// => MCSM2.RX_TIME = 101b
// => Rx_timeout = EVENT0 * 0.1127 = 10400 * 0.1127 = 1.172 ms, i.e. 0.391% RX duty cycle
halSpiWriteReg(CCxxx0_MCSM2, 0x05);
// Enable automatic FS calibration when going from IDLE to RX/TX/FSTXON (starting at EVENT1)
halSpiWriteReg(CCxxx0_MCSM0, 0x18);
// RXOFF_MODE=01b (RX->FSTXON: 9.6 us), TXOFF_MODE=00b (TX->IDLE, no FS calib: 0.1 us).
halSpiWriteReg(CCxxx0_MCSM1, 0x04);
// Enable external interrupt when packet is received
// IOCFG2 register = 0x06 => GDO2 pin is asserted when sync word detected/sent, de-asserted at
// end of packet.
// MCU is interrupted by radio on low edge of GDO2, i.e. whenever a packet is received.
ENABLE_GLOBAL_INT(INT_OFF);
SETUP_GDO2_INT(EDGE, LOW); // Enable external interrupt on low edge
INT_SETFLAG(INUM_EXTERNAL1, INT_CLR); // Clear the interrupt flag
ENABLE_GLOBAL_INT(INT_ON);
}// initReceiver
//-------------------------------------------------------------------------------------------------------
// void EXTERNAL1_ISR(void)
//
// DESCRIPTION:
// This interrupt service routine occurs whenever the radio detects a packet using Wake-on-Radio
//-------------------------------------------------------------------------------------------------------
void EXTERNAL1_ISR(void) interrupt INUM_EXTERNAL1 {
UINT8 packetLength;
// The contents of TX FIFO and RX FIFO are cleared when entering SLEEP state (WOR),
// so the RX FIFO does only contain the new packet.
// The CRC_AUTOFLUSH function is enabled: automatically flushing the RX FIFO if received packet
// contains CRC error
// Fixed packet length enabled (1 byte): packets longer than 1 byte is automatically filtered out
// Disable new interrupts
INT_ENABLE(INUM_EXTERNAL1, INT_OFF);
// Radio should now be in FSTXON state (RXOFF_MODE).
// Check if we got any packets in the RX FIFO
// This status register is safe to read since it will not be updated after
// the packet has been received (See the CC1100 or 2500 Errata Note)
packetLength = halSpiReadStatus(CCxxx0_RXBYTES) & RX_BYTES;
if (packetLength != 0) { // Packet received ok.. Must reply with ACK.
// Read out packet (should only be one byte with joystickposition)
rxBuffer[0] = halSpiReadReg(CCxxx0_RXFIFO);
// Write ACK byte into TX FIFO and send ACK as quickly as possible
// ACK byte is the received byte inverted
halSpiWriteReg(CCxxx0_TXFIFO, (rxBuffer[0]^0xFF));
halSpiStrobe(CCxxx0_STX);
while (!GDO2_PIN);
while (GDO2_PIN); // Wait for GDO2 to be de-asserted => end of transmitted packet
// Put radio back to sleep/WOR (must be in IDLE when this is done)
halSpiStrobe(CCxxx0_SWOR);
// Parsing received data byte into correct char for proper LCD presentation
joystickPosition = rxBuffer[0];
switch(joystickPosition) {
default: // Other received byte values are parsed as 'C' for ease
case JOYSTICK_CENTER:
asciiJoystickPosition[10] = 'C';
break;
case JOYSTICK_LEFT:
asciiJoystickPosition[10] = 'L';
break;
case JOYSTICK_RIGHT:
asciiJoystickPosition[10] = 'R';
break;
case JOYSTICK_UP:
asciiJoystickPosition[10] = 'U';
break;
case JOYSTICK_DOWN:
asciiJoystickPosition[10] = 'D';
break;
case JOYSTICK_PUSHED:
asciiJoystickPosition[10] = 'P';
break;
}
packetsReceived++;
updateLcd = TRUE;
P_LED1 = ~P_LED1; // Toggle green LED for packet received.
P_LED4 = ~P_LED4; // Toggle blue LED for ACK sent.
} else { // No packet received. No need for ACK.
// Go back to sleep/WOR (have to go via IDLE, i.e.: FSTXON -> IDLE -> SLEEP)
halSpiStrobe(CCxxx0_SIDLE);
halSpiStrobe(CCxxx0_SWOR);
P_LED2 = ~P_LED2; // Toggle red LED for error.
}
INT_SETFLAG(INUM_EXTERNAL1, INT_CLR); // Clear interrupt flag
INT_ENABLE(INUM_EXTERNAL1, INT_ON); // Re-enable new interrupts
// The MCU could now enter some power-down state to reduce power consumption while waiting
// for the next WOR interrupt from the CC2500 radio (this is not implemented here).
}// EXTERNAL1_ISR
/******************************************************************************************************
* Revision history: *
*
* $Log: RxWorWithAck.c,v $
* Revision 1.2 2006/04/25 15:03:34 a0190596
* tEVENT1 changed from 1.38 ms to 345 us.
* Comments added
*
* Revision 1.1 2005/10/06 12:13:31 sna
* Initial version in CVS.
*
*
*
******************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -