793 lines
23 KiB
C
793 lines
23 KiB
C
/*================================================================================================
|
|
SiWiCom.c
|
|
|
|
SiWiCom - Simple Wireless Communication
|
|
copyright 2006 v1.0 (2006-06-22)
|
|
|
|
Name: Joakim Nilsson E-mail: mail@jopin.se
|
|
Name: Christoffer Martinsson E-mail: cm@cmtec.se
|
|
|
|
================================================================================================*/
|
|
|
|
#include "hardware.h"
|
|
|
|
#include <util/delay.h>
|
|
#include <inttypes.h>
|
|
#include <avr/io.h>
|
|
#include <avr/interrupt.h>
|
|
#include <avr/sleep.h>
|
|
#include <stdlib.h>
|
|
#include <avr/eeprom.h>
|
|
|
|
#include "spi.h"
|
|
#include "cc1100.h"
|
|
#include "rfProtocol.h"
|
|
#include "pcProtocol.h"
|
|
#include "usart.h"
|
|
|
|
#define ERR_COUNTER_THR 10
|
|
|
|
// Counter related declarations
|
|
static uint8_t errCounter = 0;
|
|
static uint16_t timeOutCounter = 0;
|
|
static uint8_t wakeUpCounter = 0; // Wakeup counter
|
|
static uint8_t wakeUpValue = 0; // Time to "fully" wakeup (sec)
|
|
static uint8_t wakeUpValueSleep = 5;
|
|
|
|
// Data related declarations
|
|
static uint8_t inputBuffer[6]; // Buffer for incoming data
|
|
static uint8_t outputBuffer[3] = {0,0,0}; // Buffer for outgoing data
|
|
static uint8_t updateBuffer[16][3];
|
|
|
|
// Program state related declarations
|
|
enum {IDLE, MASTER, SLAVE, NOICEMAKER};
|
|
|
|
static uint8_t programMode;
|
|
static uint8_t remoteMode;
|
|
static uint8_t programModeTemp;
|
|
|
|
// RF related declarations
|
|
/* Chipcon */
|
|
/* Product = CC1100 */
|
|
/* Crystal accuracy = 25 ppm */
|
|
/* X-tal frequency = 26 MHz */
|
|
/* RF output power = 0 dBm */
|
|
/* RX filterbandwidth = 101.562500 kHz */
|
|
/* Deviation = 19 kHz */
|
|
/* Datarate = 9.992599 kbps */
|
|
/* Modulation = (1) 2-GFSK */
|
|
/* Manchester enable = (1) Manchester enabled */
|
|
/* RF Frequency = 868.299866 MHz */
|
|
/* Channel spacing = 199.951172 kHz */
|
|
/* Channel number = 0 */
|
|
/* Optimization = - */
|
|
/* Sync mode = (3) 30/32 sync word bits detected */
|
|
/* Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX */
|
|
/* CRC operation = (1) CRC calculation in TX and CRC check in RX enabled */
|
|
/* Forward Error Correction = (0) FEC disabled */
|
|
/* Packetlength = 6 */
|
|
/* Preamble count = (2) 4 bytes */
|
|
/* Append status = 1 */
|
|
/* Address check = (0) No address check */
|
|
uint8_t rfSetupData[] = {
|
|
|
|
0x0A, // IOCFG2
|
|
0x2E, // IOCFG1
|
|
0x80, // IOCFG0D
|
|
0x07, // FIFOTHR
|
|
0xD3, // SYNC1
|
|
0x91, // SYNC0
|
|
0x06, // PKTLEN
|
|
0x04, // PKTCTRL1
|
|
0x44, // PKTCTRL0
|
|
0x00, // ADDR
|
|
0x00, // CHANNR
|
|
0x06, // FSCTRL1
|
|
0x00, // FSCTRL0
|
|
0x21, // FREQ2
|
|
0x65, // FREQ1
|
|
0x6A, // FREQ0
|
|
0xC8, // MDMCFG4
|
|
0x93, // MDMCFG3
|
|
0x1B, // MDMCFG2
|
|
0x22, // MDMCFG1
|
|
0xF8, // MDMCFG0
|
|
0x34, // DEVIATN
|
|
0x07, // MCSM2
|
|
0x30, // MCSM1
|
|
0x18, // MCSM0
|
|
0x16, // FOCCFG
|
|
0x6C, // BSCFG
|
|
0x43, // AGCCTRL2
|
|
0x40, // AGCCTRL1
|
|
0x91, // AGCCTRL0
|
|
0x87, // WOREVT1
|
|
0x6B, // WOREVT0
|
|
0xF8, // WORCTRL
|
|
0x56, // FREND1
|
|
0x10, // FREND0
|
|
0xE9, // FSCAL3
|
|
0x2A, // FSCAL2
|
|
0x00, // FSCAL1
|
|
0x1F, // FSCAL0
|
|
0x41, // RCCTRL1
|
|
0x00, // RCCTRL0
|
|
0x59, // FSTEST
|
|
0x7F, // PTEST
|
|
0x3F, // AGCTST
|
|
0x81, // TEST2
|
|
0x35, // TEST1
|
|
0x09 // TEST0
|
|
};
|
|
|
|
int main (void);
|
|
/*================================================================================================
|
|
Functions
|
|
================================================================================================*/
|
|
/*================================================================================================
|
|
flashLed
|
|
|
|
Description: Flash LED.
|
|
Input: led (LED2, LED3, LED4, LED5)
|
|
Output: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void flashLed(uint8_t led)
|
|
{
|
|
if(LED_PORT & (1<<led))
|
|
{
|
|
LED_PORT &= ~(1<<led);
|
|
_delay_ms(10);
|
|
LED_PORT |= (1<<led);
|
|
}
|
|
else
|
|
{
|
|
LED_PORT |= (1<<led);
|
|
_delay_ms(10);
|
|
LED_PORT &= ~(1<<led);
|
|
}
|
|
}
|
|
/*================================================================================================
|
|
enterSleepMode
|
|
|
|
Description: Enter sleep mode for ATmega48
|
|
(Only start timer2 if USB is active, and not enter SLEEP mode)
|
|
|
|
Input: newWakeUpValue (time to next wakeup from SLEEP mode)
|
|
newCompareValue (compare value for timer2. 0 or 255 = 8sec trigg, 32 = 1sec trigg)
|
|
|
|
Output: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void enterSleepMode(uint8_t newWakeUpValue, uint8_t newCompareValue)
|
|
{
|
|
wakeUpValue = newWakeUpValue; // set wakeUpValue to 5sec //1 minute
|
|
wakeUpCounter = 0; // Clear wakeUpCounter
|
|
|
|
cli();
|
|
|
|
TCCR2B |=(1<<CS20)|(1<<CS21)|(1<<CS22); // Enable timer2 (Prescaler = 1024)
|
|
|
|
if(USB_ACTIVE_PIN & (1<<USB_ACTIVE))
|
|
{
|
|
OCR2A = newCompareValue; // Timer2 compare value (32 -> 1sec)
|
|
TCNT2 = 0; // Reset Timer2 counter register
|
|
while(ASSR &((1<<OCR2AUB)|(1<<TCN2UB))); // Wait until safe to sleep. s155
|
|
|
|
while((wakeUpCounter < wakeUpValue) && (remoteMode == SLAVE))
|
|
{
|
|
if(TIFR2 & (1<<OCF2A))
|
|
{
|
|
wakeUpCounter++;
|
|
TIFR2 |= (1<<OCF2A);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while(wakeUpCounter++ < wakeUpValue)
|
|
{
|
|
OCR2A = newCompareValue; // Timer2 compare value (32 -> 1sec)
|
|
TCNT2 = 0; // Reset Timer2 counter register
|
|
while(ASSR &((1<<OCR2AUB)|(1<<TCN2UB))); // Wait until safe to sleep. s155
|
|
|
|
SMCR |= (1<<SE); // Sleep mode enable
|
|
SMCR |= (1<<SM1)|(1<<SM0); // Sleep mode = power save
|
|
|
|
sei(); // Enable global interrupt
|
|
sleep_cpu(); // Enter sleep mode
|
|
}
|
|
}
|
|
|
|
TCCR2B &= ~((1<<CS20)|(1<<CS21)|(1<<CS22)); // Disable timer2
|
|
sei();
|
|
cc1100WriteCommand(SIDLE); // cc1100 = IDLE
|
|
|
|
}
|
|
/*================================================================================================
|
|
loadSettingsFromEEPROM
|
|
|
|
Description: Load settings from EEPROM
|
|
Input: -
|
|
Output: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void loadSettingsFromEEPROM(void)
|
|
{
|
|
uint8_t *n = 0;
|
|
|
|
eeprom_busy_wait();
|
|
rfProtocolSetMasterAddr(eeprom_read_byte(n++)); // Default target MASTER address
|
|
eeprom_busy_wait();
|
|
rfProtocolSetDeviceAddr(eeprom_read_byte(n++)); // Device address for this module
|
|
|
|
}
|
|
/*================================================================================================
|
|
saveSettingsToEEPROM
|
|
|
|
Description: Save settings to EEPROM
|
|
Input: -
|
|
Output: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void saveSettingsToEEPROM(void)
|
|
{
|
|
uint8_t *n = 0;
|
|
|
|
eeprom_busy_wait();
|
|
eeprom_write_byte(n++,rfProtocolGetMasterAddr());
|
|
eeprom_busy_wait();
|
|
eeprom_write_byte(n++,rfProtocolGetDeviceAddr());
|
|
|
|
}
|
|
/*================================================================================================
|
|
activateRxMode
|
|
|
|
Description: Activate cc1100 RX mode. This will flush cc1100 RXFIFO and then set cc1100 in
|
|
RX mode
|
|
Input: -
|
|
Output: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void activateRxMode(void)
|
|
{
|
|
cc1100WriteCommand(SFRX); // Flush cc1100 RXFIFO
|
|
cc1100WriteCommand(SRX); // cc1100 = RX and clear CRC_OK flag
|
|
|
|
// wait for cc1100 to settle from calibration and enter RX mode
|
|
while(!(cc1100ReadStatusReg(MARCSTATE) == 0x0D));
|
|
}
|
|
/*================================================================================================
|
|
getPowerFromDipSW
|
|
|
|
Description: Get power settings from Dip-switch
|
|
Input: -
|
|
Output: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
uint8_t getPowerFromDipSW(void)
|
|
{
|
|
SW_DDR &= ~((1<<SW1)|(1<<SW2)|(1<<SW3)|(1<<SW4)); // Set pins as input
|
|
SW_PORT |= (1<<SW1)|(1<<SW2)|(1<<SW3)|(1<<SW4); // Enable pullup on dipSW
|
|
|
|
_delay_us(2);
|
|
|
|
uint8_t tmpSW = 0;
|
|
|
|
// DipSwitch power settings
|
|
if((SW_PIN & ((1<<SW3)|(1<<SW4))) == ((1<<SW3)|(1<<SW4)))
|
|
{
|
|
tmpSW = 0x60;
|
|
}
|
|
else if((SW_PIN & ((1<<SW3)|(1<<SW4))) == (1<<SW3))
|
|
{
|
|
tmpSW = 0x85;
|
|
}
|
|
else if((SW_PIN & ((1<<SW3)|(1<<SW4))) == (1<<SW4))
|
|
{
|
|
tmpSW = 0xCC;
|
|
}
|
|
else
|
|
{
|
|
tmpSW = 0xC3;
|
|
}
|
|
|
|
SW_PORT &= ~((1<<SW1)|(1<<SW2)|(1<<SW3)|(1<<SW4)); // Disable pullup on dipSW
|
|
SW_DDR |= (1<<SW1)|(1<<SW2)|(1<<SW3)|(1<<SW4); // Set pins as output
|
|
|
|
return tmpSW;
|
|
}
|
|
/*================================================================================================
|
|
getProgramModeFromDipSW
|
|
|
|
Description: Get power settings from Dip-switch
|
|
Input: -
|
|
Output: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
uint8_t getProgramModeFromDipSW(void)
|
|
{
|
|
SW_DDR &= ~((1<<SW1)|(1<<SW2)|(1<<SW3)|(1<<SW4)); // Set pins as input
|
|
SW_PORT |= (1<<SW1)|(1<<SW2)|(1<<SW3)|(1<<SW4); // Enable pullup on dipSW
|
|
|
|
_delay_us(2);
|
|
|
|
uint8_t tmpSW = 0;
|
|
|
|
// DipSwitch program settings
|
|
if((SW_PIN & ((1<<SW1)|(1<<SW2))) == ((1<<SW1)|(1<<SW2)))
|
|
{
|
|
tmpSW = IDLE;
|
|
}
|
|
else if((SW_PIN & ((1<<SW1)|(1<<SW2))) == (1<<SW1))
|
|
{
|
|
tmpSW = MASTER;
|
|
}
|
|
else if((SW_PIN & ((1<<SW1)|(1<<SW2))) == (1<<SW2))
|
|
{
|
|
tmpSW = SLAVE;
|
|
}
|
|
else
|
|
{
|
|
tmpSW = NOICEMAKER;
|
|
}
|
|
|
|
SW_PORT &= ~((1<<SW1)|(1<<SW2)|(1<<SW3)|(1<<SW4)); // Disable pullup on dipSW
|
|
SW_DDR |= (1<<SW1)|(1<<SW2)|(1<<SW3)|(1<<SW4); // Set pins as output
|
|
|
|
return tmpSW;
|
|
}
|
|
/*================================================================================================
|
|
resetCC1100
|
|
|
|
Description: Reset cc11100 and init all register in cc1100
|
|
Input: -
|
|
Output: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void resetCC1100(void)
|
|
{
|
|
spiChipSelect(CS_CC1100);
|
|
_delay_ms(1);
|
|
spiChipDeSelect();
|
|
_delay_ms(40);
|
|
spiChipSelect(CS_CC1100);
|
|
|
|
cc1100WriteCommand(SRES); // cc1100 = RESET
|
|
|
|
cc1100WriteBurstReg(0x00, rfSetupData, sizeof(rfSetupData)); // Set all config register
|
|
cc1100WriteReg(PATABLE, getPowerFromDipSW()); // Set PATABLE from dipSwitch
|
|
|
|
cc1100WriteCommand(SPWD); // cc1100 = SLEEP
|
|
}
|
|
/*================================================================================================
|
|
initIO
|
|
|
|
Description: Initialise I/O
|
|
Input: -
|
|
Output: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void initIO (void)
|
|
{
|
|
// Init timer2
|
|
ASSR |= (1<<AS2); // Run Timer2 in asyncron mode
|
|
TIMSK2 |=(1<<OCIE2A); // Timer 2 Compare interrupt to OCR2A enable
|
|
|
|
// Init leds and switches
|
|
LED_DDR |=(1<<LED2)|(1<<LED3)|(1<<LED4)|(1<<LED5); // Output (direction for LED_DDR)
|
|
SW_PORT |=(1<<SW1)|(1<<SW2)|(1<<SW3)|(1<<SW4); // Pull-up on switch input
|
|
DDRB |= (1<<PB0); // Pin for measure battery level
|
|
|
|
// Init ADC
|
|
ADMUX |=(1<<ADLAR); // Left adjust the result to make an 8bit
|
|
ADMUX |=(1<<REFS0)|(1<<REFS1); // Internal 1,1V voltage ref for AD
|
|
// sample value.(instead of 10)
|
|
// Init external interrupt
|
|
EICRA |= (1<<ISC01); // Interrupt0 on falling edge
|
|
EIMSK |= (1<<INT0); // Enable external interrupt0
|
|
|
|
// Init Usart
|
|
usartSetBaud(12); // Set usartbaudrate. 12 = baudrate 9600
|
|
}
|
|
/*================================================================================================
|
|
readSensorValue
|
|
|
|
Description: Store an 8bit sample-value of temp and battery level.
|
|
|
|
Input: *storeSensor1 (addres to store sensorvalue 1 - Temperature sensor)
|
|
*storeSensor2 (addres to store sensorvalue 2 - Battery sensor)
|
|
*storeSensor3 (addres to store sensorvalue 3 - Aux sensor)
|
|
|
|
Output: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void readSensorValue(uint8_t *storeSensor1, uint8_t *storeSensor2, uint8_t *storeSensor3)
|
|
{
|
|
PRR &=~ (1<<PRADC); // Power reduction for ADC disabled
|
|
ADCSRA |= (1<<ADEN); // AD-converter enable
|
|
|
|
ADMUX &= ~((1<<MUX3)|(1<<MUX2)|(1<<MUX1)|(1<<MUX0));// ADC0 input pin.
|
|
PORTB |= (1<<PB0); // PB0=1 for batt. measurement;
|
|
|
|
ADCSRA |= (1<<ADSC); // Start conversion
|
|
while(ADCSRA&(1<<ADSC)); // ADSC will go low when conversion is done
|
|
PORTB &=~(1<<PB0); // PB0=0;
|
|
*storeSensor1 = ADCH;
|
|
|
|
ADMUX |= (1<<MUX0); // ADC1 input pin.
|
|
ADCSRA |= (1<<ADSC); // Start conversion
|
|
while(ADCSRA&(1<<ADSC)); // ADSC will go low when conversion is done
|
|
*storeSensor2 = ADCH;
|
|
|
|
ADCSRA &= ~(1<<ADEN); // AD-converter disable
|
|
PRR |= (1<<PRADC); // Power reduction for ADC enable
|
|
|
|
*storeSensor3 = 0x55;
|
|
}
|
|
/*================================================================================================
|
|
delay
|
|
|
|
Description: 500ms delay
|
|
Input: -
|
|
Output: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void delay(void)
|
|
{
|
|
_delay_ms(200);
|
|
_delay_ms(200);
|
|
_delay_ms(100);
|
|
}
|
|
/*================================================================================================
|
|
showDeviceSettings
|
|
|
|
Description: Show device setting on indication leds.
|
|
Input: -
|
|
Output: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void showDeviceSettings(void)
|
|
{
|
|
LED_PORT &= ~((1<<LED2)|(1<<LED3)|(1<<LED4)|(1<<LED5));
|
|
|
|
delay();
|
|
|
|
// Show deviceAddr
|
|
uint8_t i;
|
|
for(i = 0; i < rfProtocolGetDeviceAddr(); i++)
|
|
{
|
|
flashLed(LED2);
|
|
delay();
|
|
}
|
|
|
|
if(programMode == SLAVE)
|
|
{
|
|
// Show masterAddr
|
|
for(i = 0; i < rfProtocolGetMasterAddr(); i++)
|
|
{
|
|
flashLed(LED3);
|
|
delay();
|
|
}
|
|
}
|
|
|
|
delay();
|
|
LED_PORT |= (1<<LED2)|(1<<LED3)|(1<<LED4)|(1<<LED5);
|
|
delay();
|
|
LED_PORT &= ~((1<<LED2)|(1<<LED3)|(1<<LED4)|(1<<LED5));
|
|
delay();
|
|
|
|
if(programMode == MASTER)
|
|
{
|
|
LED_PORT |= (1<<LED2)|(1<<LED3)|(1<<LED4)|(1<<LED5);
|
|
delay();
|
|
LED_PORT &= ~((1<<LED2)|(1<<LED3)|(1<<LED4)|(1<<LED5));
|
|
delay();
|
|
}
|
|
}
|
|
/*================================================================================================
|
|
Interrupt Service Routines
|
|
================================================================================================*/
|
|
/*================================================================================================
|
|
USART_RXC
|
|
|
|
Description: Interrup routine for USART receive
|
|
------------------------------------------------------------------------------------------------*/
|
|
ISR(USART_RX_vect)
|
|
{
|
|
if(pcProtocolAddByteToBuffer(usartReceive()))
|
|
{
|
|
flashLed(LED5);
|
|
uint8_t inputPCBuffer[9];
|
|
pcProtocolGetData(inputPCBuffer);
|
|
|
|
if(inputPCBuffer[1] == PC_COMMAND_GET_LOCAL_DATA)
|
|
{
|
|
// Measure temperature and battery level
|
|
readSensorValue(&outputBuffer[0], &outputBuffer[1], &outputBuffer[2]);
|
|
|
|
// Relay data to PC
|
|
pcProtocolSendData(PC_COMMAND_LOCAL_DATA, rfProtocolGetDeviceAddr(), outputBuffer[0],
|
|
outputBuffer[1], outputBuffer[2], 0x00);
|
|
}
|
|
else if(inputPCBuffer[1] == PC_COMMAND_REMOTE_UPDATE)
|
|
{
|
|
pcProtocolSendACK();
|
|
|
|
updateBuffer[inputPCBuffer[2]][0] = inputPCBuffer[3];
|
|
updateBuffer[inputPCBuffer[2]][1] = inputPCBuffer[4];
|
|
updateBuffer[inputPCBuffer[2]][2] = inputPCBuffer[5];
|
|
}
|
|
else if(inputPCBuffer[1] == PC_COMMAND_LOCAL_UPDATE)
|
|
{
|
|
pcProtocolSendACK();
|
|
|
|
if(inputPCBuffer[2])
|
|
{
|
|
rfProtocolSetMasterAddr(inputPCBuffer[2]);
|
|
}
|
|
|
|
if(inputPCBuffer[3])
|
|
{
|
|
rfProtocolSetDeviceAddr(inputPCBuffer[3]);
|
|
}
|
|
|
|
if(inputPCBuffer[4])
|
|
{
|
|
wakeUpValueSleep = inputPCBuffer[4];
|
|
}
|
|
|
|
if(inputPCBuffer[5])
|
|
{
|
|
remoteMode = inputPCBuffer[5]-1;
|
|
}
|
|
|
|
saveSettingsToEEPROM();
|
|
}
|
|
}
|
|
}
|
|
/*================================================================================================
|
|
INT0
|
|
|
|
Description: Interrup routine for external interrupt 0 (connected to USB active pin).
|
|
Disables usart when USB is disconnected.
|
|
------------------------------------------------------------------------------------------------*/
|
|
ISR(INT0_vect)
|
|
{
|
|
usartDisable();
|
|
LED_PORT &= ~(1<<LED5); // Turn off LED indicating USB present
|
|
main(); // Reset
|
|
}
|
|
/*================================================================================================
|
|
TIMER2_COMPA_vect
|
|
|
|
Description: Interrupt routine for Timer2. Used as wakeup timer.
|
|
------------------------------------------------------------------------------------------------*/
|
|
ISR(TIMER2_COMPA_vect)
|
|
{
|
|
|
|
}
|
|
/*================================================================================================
|
|
Main
|
|
================================================================================================*/
|
|
int main (void){
|
|
|
|
cli(); // Disable global interrupt
|
|
|
|
initIO();
|
|
spiInit();
|
|
|
|
resetCC1100();
|
|
loadSettingsFromEEPROM(); // Set device and master address from EEPROM
|
|
|
|
programMode = getProgramModeFromDipSW(); // Set programMode from DipSwitch
|
|
remoteMode = MASTER; // Default programMode when USB is active
|
|
|
|
programModeTemp = 0xFF; // Used for trigg change of programMode
|
|
|
|
activateRxMode();
|
|
|
|
sei();
|
|
while(1)
|
|
{
|
|
// Check USB connection
|
|
if(USB_ACTIVE_PIN &(1<<USB_ACTIVE))
|
|
{
|
|
usartEnable(); // Enable USART
|
|
LED_PORT |= (1<<LED5); // Turn on LED indicating USB present
|
|
programMode = remoteMode;
|
|
}
|
|
|
|
if(programMode == IDLE)
|
|
{
|
|
// Init IDLE
|
|
if(programModeTemp != programMode)
|
|
{
|
|
resetCC1100();
|
|
LED_PORT &= ~((1<<LED2)|(1<<LED3)|(1<<LED4)|(1<<LED5));
|
|
}
|
|
}
|
|
else if(programMode == MASTER)
|
|
{
|
|
// Init MASTER
|
|
if(programModeTemp != programMode)
|
|
{
|
|
resetCC1100();
|
|
showDeviceSettings();
|
|
}
|
|
|
|
// Check CRC_OK flag (packet received)
|
|
if(cc1100ReadStatusReg(PKTSTATUS) & (1<<7))
|
|
{
|
|
// Check if packet is a DATA-packet
|
|
if(rfProtocolReadPacket(inputBuffer) == RF_COMMAND_DATA)
|
|
{
|
|
_delay_ms(10);
|
|
flashLed(LED2); // Correct data received - GREEN flash (makes a 10ms delay)
|
|
|
|
// Send ACK and update data to slave
|
|
rfProtocolSendACKAndUpdate(inputBuffer[0], updateBuffer[inputBuffer[0]]);
|
|
|
|
if(cc1100ReadStatusReg(MARCSTATE) == 0x01)
|
|
{
|
|
flashLed(LED3); // ACK sent - YELLOW_2 flash (makes a 10ms delay)
|
|
|
|
if(USB_ACTIVE_PIN &(1<<USB_ACTIVE))
|
|
{
|
|
// Relay data to PC
|
|
pcProtocolSendData(PC_COMMAND_REMOTE_DATA, inputBuffer[0],
|
|
inputBuffer[2], inputBuffer[3], inputBuffer[4],
|
|
inputBuffer[5]);
|
|
|
|
flashLed(LED5); // Data sent to PC - YELLOW_1 flash (makes a 10ms delay)
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cc1100WriteCommand(SFTX); // Flush cc1100 TXFIFO
|
|
flashLed(LED4); // Channel busy - RED flash (makes a 10ms delay)
|
|
}
|
|
}
|
|
|
|
timeOutCounter = 0;
|
|
activateRxMode();
|
|
}
|
|
// Restart RX mode if error packet is received (RX overflow)
|
|
else if((!(cc1100ReadStatusReg(MARCSTATE) == 0x0D)) && (++timeOutCounter > 100))
|
|
{
|
|
timeOutCounter = 0;
|
|
activateRxMode();
|
|
}
|
|
}
|
|
else if(programMode == SLAVE)
|
|
{
|
|
// Init SLAVE
|
|
if(programModeTemp != programMode)
|
|
{
|
|
resetCC1100();
|
|
showDeviceSettings();
|
|
}
|
|
|
|
activateRxMode();
|
|
|
|
// Measure temperature and battery level
|
|
readSensorValue(&outputBuffer[0], &outputBuffer[1], &outputBuffer[2]);
|
|
|
|
rfProtocolSendData(outputBuffer); // Send data to master
|
|
|
|
if(cc1100ReadStatusReg(MARCSTATE) == 0x01)
|
|
{
|
|
flashLed(LED3);
|
|
|
|
activateRxMode();
|
|
|
|
timeOutCounter = 0;
|
|
|
|
while((!(cc1100ReadStatusReg(MARCSTATE) == 0x01)) && (++timeOutCounter < 500));
|
|
|
|
// Check CRC_OK flag (packet received)
|
|
if(cc1100ReadStatusReg(PKTSTATUS) & (1<<7))
|
|
{
|
|
// Check if packet is a ACK-packet
|
|
if(rfProtocolReadPacket(inputBuffer) == RF_COMMAND_ACK_AND_UPDATE)
|
|
{
|
|
flashLed(LED2);
|
|
cc1100WriteCommand(SIDLE); // cc1100 = IDLE
|
|
cc1100WriteCommand(SPWD); // cc1100 = SLEEP
|
|
|
|
uint8_t storeNewSettings = 0;
|
|
|
|
if((inputBuffer[2]) && (inputBuffer[2] != rfProtocolGetMasterAddr()))
|
|
{
|
|
rfProtocolSetMasterAddr(inputBuffer[2]);
|
|
storeNewSettings = 1;
|
|
}
|
|
|
|
if((inputBuffer[3]) && (inputBuffer[3] != rfProtocolGetDeviceAddr()))
|
|
{
|
|
rfProtocolSetDeviceAddr(inputBuffer[3]);
|
|
storeNewSettings = 1;
|
|
}
|
|
|
|
if((inputBuffer[4]) && (inputBuffer[4] != wakeUpValueSleep))
|
|
{
|
|
wakeUpValueSleep = inputBuffer[4];
|
|
}
|
|
|
|
if(storeNewSettings)
|
|
{
|
|
saveSettingsToEEPROM();
|
|
}
|
|
|
|
errCounter = 0;
|
|
enterSleepMode(wakeUpValueSleep, 32); // Enter sleep mode for 8sec
|
|
}
|
|
else
|
|
{
|
|
flashLed(LED4);
|
|
cc1100WriteCommand(SIDLE); // cc1100 = IDLE
|
|
cc1100WriteCommand(SPWD); // cc1100 = SLEEP
|
|
|
|
if(++errCounter < ERR_COUNTER_THR)
|
|
{
|
|
enterSleepMode(1, ((rand() % 31)+1)); // Enter sleep mode (random 0-1sec)
|
|
}
|
|
else
|
|
{
|
|
errCounter = 0;
|
|
enterSleepMode(wakeUpValueSleep, 32); // Enter sleep mode for 8sec
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//if(cc1100ReadStatusReg(MARCSTATE) == 0x01)
|
|
//{
|
|
// activateRxMode();
|
|
//}
|
|
flashLed(LED4);
|
|
cc1100WriteCommand(SIDLE); // cc1100 = IDLE
|
|
cc1100WriteCommand(SPWD); // cc1100 = SLEEP
|
|
|
|
if(++errCounter < ERR_COUNTER_THR)
|
|
{
|
|
enterSleepMode(1, ((rand() % 31)+1)); // Enter sleep mode (random 0-1sec)
|
|
}
|
|
else
|
|
{
|
|
errCounter = 0;
|
|
enterSleepMode(wakeUpValueSleep, 32); // Enter sleep mode for 8sec
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cc1100WriteCommand(SFTX); // Flush cc1100 TXFIFO
|
|
flashLed(LED4);
|
|
cc1100WriteCommand(SIDLE); // cc1100 = IDLE
|
|
cc1100WriteCommand(SPWD); // cc1100 = SLEEP
|
|
|
|
if(++errCounter < ERR_COUNTER_THR)
|
|
{
|
|
enterSleepMode(1, ((rand() % 31)+1)); // Enter sleep mode (random 0-1sec)
|
|
}
|
|
else
|
|
{
|
|
errCounter = 0;
|
|
enterSleepMode(wakeUpValueSleep, 32); // Enter sleep mode for 8sec
|
|
}
|
|
}
|
|
}
|
|
else if(programMode == NOICEMAKER)
|
|
{
|
|
// Init NOICEMAKER
|
|
if(programModeTemp != programMode)
|
|
{
|
|
resetCC1100();
|
|
LED_PORT &= ~((1<<LED2)|(1<<LED3)|(1<<LED4)|(1<<LED5));
|
|
cc1100WriteReg(PKTCTRL0, 0x22);
|
|
cc1100WriteCommand(STX);
|
|
}
|
|
|
|
flashLed(LED2);
|
|
flashLed(LED3);
|
|
flashLed(LED5);
|
|
flashLed(LED4);
|
|
|
|
_delay_ms(200);
|
|
}
|
|
programModeTemp = programMode;
|
|
}
|
|
}
|
|
/*================================================================================================
|
|
End
|
|
================================================================================================*/
|