📄 worwithack.c
字号:
/*******************************************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** This example shows how to use the Wake-on-Radio function of the CCxx00 *
* *** + in a simple "packet burst with ACK" protocol. *
* *** + + *** *
* *** +++ *** WorWithAck.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>
//-------------------------------------------------------------------------------------------------------
// DESCRIPTION:
// This example is an improved implementation of the simple WOR example described in App. Note 38.
// A transmitter sending packets with control commands to a receiver. WOR is used to reduce power
// consumption at the receiver side.
// The transmitter starts bursting identical packets until it gets an ACK back from receiver.
// This means that there, in contrast to the simple WOR example, is no fixed number of packets
// in a burst. One evaluation board (EB) is set up as transmitter, and the other as a receiver
// (RX/WOR unit). If the joystick position is changed on the transmitter board, data containing
// info about the new position are transmitted to the receiver and the joystick position is
// displayed on the LCD of this EB. Please see App. Note 38 for more details.
//
// RX UNIT:
// * Move joystick right to choose RX
// * Push the S1 button to confirm your choice.
// After the unit has been configured, the yellow LED will be on.
//
// GLED: Toggles when a packet has been received successfully.
// RLED: Toggles when an invalid packet has been received.
// BLED: Toggles when an ACK is sent.
//
// TX UNIT:
// * Move joystick left to choose TX
// * Push the S1 button to confirm your choice.
// After the unit has been configured, the yellow LED will turn on.
//
// BLED: Toggles when a packet has been sent.
// GLED: Toggles every time a valid packet (ACK) has been received.
// RLED: Toggles every time an invalid packet has been received.
//
// On the transmitter, you are now able to push the joystick button or move it up,
// down, left or right. This will start the packet burst and the number of packets sent in the
// burst will be displayed on the LCD. The number of packets in a burst is variable, depending on
// when an ACK is received. Normally, less than 305 packets need to be sent.One should not move
// the joystick to a new position before the previous burst transmission has completed.
//
//
// The receiver will automatically enter the WOR mode, waiting for packets.
//
// The LCD will continuously display how many valid packets have been received together with
// the position of the joystick on the transmitter.
//
// The program can be terminated by pressing the S1 button after the setup has been done.
// This will turn off the yellow LED.
//
// Current config specs
//
// Common Settings:
// Packet format = 4B preamble + 4B sync word + 1B payload + 2B CRC = 11 Bytes
//
// TX Unit Settings:
// Packet interval: 1.0 ms
// Packet send time: ~ 11 B * 8 bit/B / 250 kbps = 352 us
// Tx duty cycle: ~ 352 us / 1.0 ms = 35.2 %
// RX timeout (get ACK): 325 us (word sync search timeout)
// RX duty cycle: 325 us / 1000 us = 32.5 %
//
// RX/WOR Unit Settings:
// Event0 timeout: 300 ms (radio RX polling period)
// Event1 timeout: ~ 345 us (f_xosc = 26 MHz) start RX)
// Rx timeout: ~ 1.172 ms
// Rx duty cycle: ~ 1.172 ms / 300 ms = 0.391 %
// ACK send time: ~ 11B * 8 bit/B / 250 kbps = 352 us
// TX duty cycle (max): 352 us / 300 ms = 0.117 %
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// Global Variables
UINT8 xdata mode = MODE_NOT_SET; // Variable used to hold the mode for the setup menu
// Defining some external variables
UINT8 xdata joystickPosition = JOYSTICK_CENTER;
UINT8 xdata prevJoystickPosition = JOYSTICK_CENTER;
BYTE xdata rxBuffer[1]; // Max received packet length = 1B
BYTE xdata asciiString[11]; // Byte array used by the intToAscii(UINT32 value) function
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// void main(void)
//
// DESCRIPTION:
// This function takes care of all the MCU initialization and radio configuration.
//-------------------------------------------------------------------------------------------------------
void main (void) {
#ifdef STAND_ALONE
// Select the Internal Oscillator as Multiplier input source and disable the watchdog timer
// SYSCLK = 4X Clock Multiplier / 2
CLOCK_INIT();
#endif
// Set up the crossbar and I/O ports to communicate with the SmartRF04EB peripherals
IO_PORT_INIT();
// Initialize the LCD display. The SMBus uses timer 0 to generate SCL
ebLcdInit();
// Initialize the ADC converter
ebAdcInit(ADC_JOY);
SPI_INIT(SCLK_6_MHZ);
POWER_UP_RESET_CCxxx0();
halRfWriteRfSettings(&rfSettings);
halSpiWriteReg(CCxxx0_PATABLE, paTable);
// Write custom sync word (avoiding default sync word)
halSpiWriteReg(CCxxx0_SYNC1, 0x9B);
halSpiWriteReg(CCxxx0_SYNC0, 0xAD);
// Starts menu for setting up EB unit to either "TX" or "RX/WOR" unit.
showMenu();
// Remote control
if (mode == TX) {
ebLcdUpdate("Tx unit...", "(Move joystick)");
runTransmitter();
// Remote-controlled object
} else {
ebLcdUpdate("Rx/WOR unit...", NULL);
runReceiver();
}
}
//-------------------------------------------------------------------------------------------------------
// void showMenu(void)
//
// DESCRIPTION:
// Function to show menu. Select mode by moving joystick left/right.
// Press S1 button to confirm the choice.
//-------------------------------------------------------------------------------------------------------
void showMenu(void) {
mode = MODE_NOT_SET;
ebLcdUpdate("WorWithAck.c", "<- Set Mode ->");
// Select Tx or Rx mode by moving the joystick left or right
do {
halWait(250);
// Get current position of joystick
joystickPosition = ebGetJoystickPosition();
if (prevJoystickPosition != joystickPosition) {
prevJoystickPosition = joystickPosition;
parseMenu(joystickPosition);
}
} while (!ebButtonPushed() || (mode == MODE_NOT_SET));
}// showMenu
//-------------------------------------------------------------------------------------------------------
// void parseMenu(UINT8 joystickPosition)
//
// DESCRIPTION:
// This function selects mode and updates the LCD display based on the joystick position
//
// ARGUMENTS:
// UINT8 joystickPosition
// The position of the joystick
//-------------------------------------------------------------------------------------------------------
void parseMenu(UINT8 joystickPosition) {
switch (joystickPosition) {
case JOYSTICK_LEFT:
if (mode == RX || mode == MODE_NOT_SET) {
mode = MODE_TX;
ebLcdUpdate("Mode:", "Tx/Burst");
}
break;
case JOYSTICK_RIGHT:
if (mode == TX || mode == MODE_NOT_SET) {
mode = MODE_RX;
ebLcdUpdate("Mode:", "Rx/Wake-on-Radio");
}
break;
default: // Other joystick movements: do nothing
break;
}
}// parseMenu
//-------------------------------------------------------------------------------------------------------
// void intToAscii(UINT32 value)
//
// DESCRIPTION:
// Takes a 32 bits integer as input and converts it to ascii. Puts the result in the global
// variable asciiString[]
//
// ARGUMENTS:
// UINT32 value
// The value to be converted
//-------------------------------------------------------------------------------------------------------
void intToAscii(UINT32 value) {
UINT8 i = 10;
UINT8 j = 0;
UINT8 digit_start = 0;
UINT16 digit = 0;
UINT32 denom = 1000000000;
if (value == 0) {
asciiString[0] = '0';
asciiString[1] = NULL;
} else {
for(i = 10; i > 0; i--) {
digit = value / denom;
if((digit_start == 1) || (digit != 0)) {
digit_start = 1;
value %= denom;
asciiString[j++] = (digit + '0');
}
denom /= 10;
}
asciiString[j++] = NULL;
}
}// intToAscii
/******************************************************************************************************
* Revision history: *
*
* $Log: WorWithAck.c,v $
* Revision 1.5 2006/04/25 15:06:58 a0190596
* added POWER_UP_RESET_CCxxx0()
* tEVENT1 changed from 1.38 ms to 345 us.
* removed manual calibration at start-up
* Comments added
*
* Revision 1.4 2006/03/31 13:30:07 a0190596
* POWER_UP_RESET_CCxxx0() removed
*
* Revision 1.3 2006/03/17 10:37:38 a0190596
* New file structure might have caused variables, defines, and functions to move.
* Comments are added.
*
* Revision 1.2 2005/10/25 12:23:40 sna
* Register settings moved to separate *.h file
*
* Revision 1.1 2005/10/06 12:14:27 sna
* Initial version in CVS.
*
*
*
******************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -