/*================================================================================================
 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
================================================================================================*/
