Exemplo n.º 1
0
uint8_t CC110x::receiveData(uint8_t *buf) {												// read data packet from RX FIFO
	uint8_t rxBytes = readReg(CC1101_RXBYTES, CC1101_STATUS);							// how many bytes are in the buffer
	
	//Serial << rxBytes << F(" ");

	if ((rxBytes & 0x7F) && !(rxBytes & 0x80)) {										// any byte waiting to be read and no overflow?
		buf[0] = readReg(CC1101_RXFIFO, CC1101_CONFIG);									// read data length

		if (buf[0] > CC1101_DATA_LEN)													// if packet is too long
			buf[0] = 0;																	// discard packet
		else {
			readBurst(&buf[1], CC1101_RXFIFO, buf[0]);									// read data packet
			readReg(CC1101_RXFIFO, CC1101_CONFIG);										// read RSSI

			uint8_t val = readReg(CC1101_RXFIFO, CC1101_CONFIG);						// read LQI and CRC_OK
			lqi = val & 0x7F;
			crc_ok = bitRead(val, 7);
		}
	} else {
		buf[0] = 0;																		// nothing to do, or overflow
	}

	cmdStrobe(CC1101_SFRX);																// flush Rx FIFO
	cmdStrobe(CC1101_SIDLE);															// enter IDLE state
	cmdStrobe(CC1101_SRX);																// back to RX state
	cmdStrobe(CC1101_SWORRST);															// reset real time clock
//	trx868.rfState = RFSTATE_RX;														// declare to be in Rx state

	#if defined(CC_DBG)																	// debug message, string should be short, otherwise program stops
		if (buf[0] > 0) Serial; pHex(&buf[1], buf[0], SERIAL_DBG_MODE_LEN | SERIAL_DBG_PHEX_MODE_TIME);
	#endif

	return buf[0];																		// return the data buffer
}
Exemplo n.º 2
0
/**
 * setPowerDownState
 * 
 * Put CC1101 into power-down state
 */
void CC1101::setPowerDownState() 
{
  // Comming from RX state, we need to enter the IDLE state first
  cmdStrobe(CC1101_SIDLE);
  // Enter Power-down state
  cmdStrobe(CC1101_SPWD);
}
Exemplo n.º 3
0
uint8_t receiveData(uint8_t *buf) {												// read data packet from RX FIFO
	uint8_t rxBytes = readReg(CC1101_RXBYTES, CC1101_STATUS);					// how many bytes are in the buffer

	if ((rxBytes & 0x7F) && !(rxBytes & 0x80)) {								// any byte waiting to be read and no overflow?
		buf[0] = readReg(CC1101_RXFIFO, CC1101_CONFIG);							// read data length
		
		if (buf[0] > CC1101_DATA_LEN)											// if packet is too long
			buf[0] = 0;															// discard packet
		else {
			readBurst(&buf[1], CC1101_RXFIFO, buf[0]);							// read data packet
			readReg(CC1101_RXFIFO, CC1101_CONFIG);								// read RSSI
			
			uint8_t val   = readReg(CC1101_RXFIFO, CC1101_CONFIG);				// read LQI and CRC_OK
			trx868.lqi    = val & 0x7F;
			trx868.crc_ok = bitRead(val, 7);
		}
	} else buf[0] = 0;															// nothing to do, or overflow

	cmdStrobe(CC1101_SFRX);														// flush Rx FIFO
	cmdStrobe(CC1101_SIDLE);													// enter IDLE state
	cmdStrobe(CC1101_SRX);														// back to RX state
	cmdStrobe(CC1101_SWORRST);													// reset real time clock
	
	return buf[0];																// return the data buffer
}
Exemplo n.º 4
0
void sendData(uint8_t *buf, uint8_t burst) {									// send data packet via RF

	/**
	 * Going from RX to TX does not work if there was a reception less than 0.5
	 * seconds ago. Due to CCA? Using IDLE helps to shorten this period(?)
	 * ccStrobe(CC1100_SIDLE);
	 * uint8_t cnt = 0xff;
	 * while(cnt-- && (ccStrobe( CC1100_STX ) & 0x70) != 2)
	 * my_delay_us(10);
	 */
 	cmdStrobe(CC1101_SIDLE);													// go to idle mode
	cmdStrobe(CC1101_SFRX );													// flush RX buffer
	cmdStrobe(CC1101_SFTX );													// flush TX buffer
	
	_delay_ms(1);																// wait a short time to set TX mode

	writeBurst(CC1101_TXFIFO, buf, buf[0]+1);									// write in TX FIFO

	cmdStrobe(CC1101_SFRX);														// flush the RX buffer
	cmdStrobe(CC1101_STX);														// send a burst

	for(uint8_t i=0; i< 200;++i) {												// after sending out all bytes the chip should go automatically in RX mode
		if( readReg(CC1101_MARCSTATE, CC1101_STATUS) == CC1101_MARCSTATE_RX)
			break;																//now in RX mode, good
		if( readReg(CC1101_MARCSTATE, CC1101_STATUS) != CC1101_MARCSTATE_TX) {
			break;																//neither in RX nor TX, probably some error
		}

		_delay_us(10);
	}
}
Exemplo n.º 5
0
/*
 * initialize CC1101
 */
void cc1101Init(uint8_t mode100k) {
	cli();

	bitSet(DDR_SPI,    PIN_SPI_SS);												// set B2(SS) as Output
	bitSet(DDR_SPI,    PIN_SPI_MOSI);											// set B3(MOSI) as Output
	bitClear(DDR_SPI,  PIN_SPI_MISO);											// set B4(MISO) as Input
	bitSet(DDR_SPI,    PIN_SPI_SCK);											// set B5(SCK) as Output

	bitClear(DDR_GDO0, PIN_GDO0);												// set B2(SS) as Input

	bitSet(PORT_SPI,   PIN_SPI_SS);												// set SS high
	bitSet(PORT_SPI,   PIN_SPI_SCK);											// set SCK high
	bitClear(PORT_SPI, PIN_SPI_MOSI);											// set MOSI high

	SPCR = _BV(SPE) | _BV(MSTR);												// SPI speed = CLK/4

	cc1101_Deselect();															// some deselect and selects to initialize the TRX868modul
	_delay_us(30);

	cc1101_Select();	
	_delay_us(30);

	cc1101_Deselect();
	_delay_us(45);

	cmdStrobe(CC1101_SRES);														// send reset
	_delay_us(100);

	for (uint8_t i=0; i<sizeof(initVal); i += 2) {								// write initialize value to cc1101
		writeReg(pgm_read_byte(&initVal[i]), pgm_read_byte(&initVal[i+1]));	
	}

	if (mode100k) {																// switch to 100k mode
		for (uint8_t i=0; i<sizeof(initValUpdate); i += 2) {					// write initialize value to cc1101
			writeReg(
				pgm_read_byte(&initValUpdate[i]),
				pgm_read_byte(&initValUpdate[i+1])
			);
		}
	}

	cmdStrobe(CC1101_SCAL);														// calibrate frequency synthesizer and turn it off
	_delay_ms(4);

	do {
		cmdStrobe(CC1101_SRX);
	} while (readReg(CC1101_MARCSTATE, CC1101_STATUS) != 0x0D);
	
	writeReg(CC1101_PATABLE, PA_MaxPower);										// configure PATABLE
	cmdStrobe(CC1101_SRX);														// flush the RX buffer
	cmdStrobe(CC1101_SWORRST);													// reset real time clock

	_delay_ms(3);

	sei();
}
Exemplo n.º 6
0
uint8_t CC110x::detectBurst(void) {														// wake up CC1101 from power down state
	// 10 7/10 5 in front of the received string; 33 after received string
	// 10 - 00001010 - sync word found
	// 7  - 00000111 - GDO0 = 1, GDO2 = 1
	// 5  - 00000101 - GDO0 = 1, GDO2 = 1
	// 33 - 00100001 - GDO0 = 1, preamble quality reached
	// 96 - 01100000 - burst sent
	// 48 - 00110000 - in receive mode
	//
	// Status byte table:
	//	0 current GDO0 value
	//	1 reserved
	//	2 GDO2
	//	3 sync word found
	//	4 channel is clear
	//	5 preamble quality reached
	//	6 carrier sense
	//	7 CRC ok
	//
	// possible solution for finding a burst is to check for bit 6, carrier sense

	// set RXTX module in receive mode
	cc1101_Select();																	// select CC1101
	wait_Miso();																		// wait until MISO goes low
	cc1101_Deselect();																	// deselect CC1101
	cmdStrobe(CC1101_SRX);																// set RX mode again
	_delay_ms(3);																		// wait a short time to set RX mode

	// todo: check carrier sense for 5ms to avoid wakeup due to normal transmition
	//Serial << F("rx\n");
//	return bitRead(hm.cc.monitorStatus(),6);											// return the detected signal
	return bitRead(monitorStatus(),6);													// return the detected signal
}
Exemplo n.º 7
0
uint8_t CC110x::sendData(uint8_t *buf, uint8_t burst) {									// send data packet via RF

	// Going from RX to TX does not work if there was a reception less than 0.5
	// sec ago. Due to CCA? Using IDLE helps to shorten this period(?)
	//ccStrobe(CC1100_SIDLE);
	//uint8_t cnt = 0xff;
	//while(cnt-- && (ccStrobe( CC1100_STX ) & 0x70) != 2)
	//my_delay_us(10);
 	cmdStrobe(CC1101_SIDLE);															// go to idle mode
	cmdStrobe(CC1101_SFRX );															// flush RX buffer
	cmdStrobe(CC1101_SFTX );															// flush TX buffer

	//Serial << "tx\r\n";

	if (burst) {																		// BURST-bit set?
		cmdStrobe(CC1101_STX  );														// send a burst
		_delay_ms(360);																	// according to ELV, devices get activated every 300ms, so send burst for 360ms
		//Serial << "send burst\r\n";

	} else {
		_delay_ms(1);																	// wait a short time to set TX mode
	}

	writeBurst(CC1101_TXFIFO, buf, buf[0]+1);											// write in TX FIFO

	cmdStrobe(CC1101_SFRX);																// flush the RX buffer
	cmdStrobe(CC1101_STX);																// send a burst

	for(uint8_t i=0; i< 200;++i) {														// after sending out all bytes the chip should go automatically in RX mode
		if( readReg(CC1101_MARCSTATE, CC1101_STATUS) == MARCSTATE_RX)
			break;																		//now in RX mode, good
		if( readReg(CC1101_MARCSTATE, CC1101_STATUS) != MARCSTATE_TX) {
			break;																		//neither in RX nor TX, probably some error
		}
		_delay_us(10);
	}

	//uint8_t cnt = 0xff;
	//while(cnt-- && (sendSPI(CC1101_SRX) & 0x70) != 1)
	//delayMicroseconds(10);

	#if defined(CC_DBG)																	// some debug message
		Serial << F("<- ") << pHexL(&buf[0], buf[0]+1) << pTime();
	#endif

	//Serial << "rx\r\n";
	return true;
}
Exemplo n.º 8
0
/**
 * sendData
 * 
 * Send data packet via RF
 * 
 * 'packet'	Packet to be transmitted
 *
 *  Return:
 *    True if the transmission succeeds
 *    False otherwise
 */
boolean CC1101::sendData(CCPACKET packet)
{
  // Enter RX state
  setRxState();

  // Check that the RX state has been entered
  while (readStatusReg(CC1101_MARCSTATE) != 0x0D)
    delay(1);
  delayMicroseconds(500);

  // Set data length at the first position of the TX FIFO
  writeReg(CC1101_TXFIFO,  packet.length);
  // Write data into the TX FIFO
  writeBurstReg(CC1101_TXFIFO, packet.data, packet.length);

  // CCA enabled: will enter TX state only if the channel is clear
  cmdStrobe(CC1101_STX);

  // Check that TX state is being entered (state = RXTX_SETTLING)
  if(readStatusReg(CC1101_MARCSTATE) != 0x15)
    return false;

  // Wait for the sync word to be transmitted
  wait_GDO0_high();

  // Wait until the end of the packet transmission
  wait_GDO0_low();

  // Flush TX FIFO. Don't uncomment
  // cmdStrobe(CC1101_SFTX);
  
  // Enter back into RX state
  setRxState();

  // Check that the TX FIFO is empty
  if((readStatusReg(CC1101_TXBYTES) & 0x7F) == 0)
    return true;

  return false;
}
Exemplo n.º 9
0
void    CC110x::setPowerDownState() {													// put CC1101 into power-down state
	cmdStrobe(CC1101_SIDLE);															// coming from RX state, we need to enter the IDLE state first
	cmdStrobe(CC1101_SFRX);
	cmdStrobe(CC1101_SPWD);																// enter power down state
	//Serial << F("pd\n");
}
Exemplo n.º 10
0
void    CC110x::init(void) {													// initialize CC1101
	
	#if defined(CC_DBG)
		Serial << F("CC1101_init: ");
	#endif

	pinMode(csPin, OUTPUT);														// set pins for SPI communication
	pinMode(mosiPin, OUTPUT);
	pinMode(misoPin, INPUT);
	pinMode(sckPin, OUTPUT);
	pinMode(gdo0Pin, INPUT);													// config GDO0 as input

	digitalWrite(csPin, HIGH);													// SPI init
	digitalWrite(sckPin, HIGH);
	digitalWrite(mosiPin, LOW);

	SPCR = _BV(SPE) | _BV(MSTR);												// SPI speed = CLK/4

	cc1101_Deselect();															// some deselect and selects to init the TRX868modul
	_delay_us(5);

	cc1101_Select();
	_delay_us(10);

	cc1101_Deselect();
	_delay_us(41);

	cmdStrobe(CC1101_SRES);														// send reset
	_delay_ms(10);

	#if defined(CC_DBG)
		Serial << F("1");
	#endif

	// define init settings for TRX868
	static const uint8_t initVal[] PROGMEM = {
		CC1101_IOCFG2,     0x2E,												// non inverted GDO2, high impedance tri state
		//CC1101_IOCFG1,    0x2E,	(default)									// low output drive strength, non inverted GD=1, high impedance tri state
		CC1101_IOCFG0,     0x06,	// packet CRC ok							// disable temperature sensor, non inverted GDO0,
		CC1101_FIFOTHR,    0x0D,												// 0 ADC retention, 0 close in RX, TX FIFO = 9 / RX FIFO = 56 byte
		CC1101_SYNC1,      0xE9,
		CC1101_SYNC0,      0xCA,
		CC1101_PKTLEN,     0x3D,												// packet length 61
		CC1101_PKTCTRL1,   0x0C,												// PQT = 0, CRC auto flush = 1, append status = 1, no address check
		CC1101_FSCTRL1,    0x06,

		// 868.299866 MHz
		//CC1101_FREQ2,     0x21,
		//CC1101_FREQ1,     0x65,
		//CC1101_FREQ0,     0x6A,

		// 868.2895508
		CC1101_FREQ2,      0x21,
		CC1101_FREQ1,      0x65,
		CC1101_FREQ0,      0x50,

		CC1101_MDMCFG4,    0xC8,
		CC1101_MDMCFG3,    0x93,
		CC1101_MDMCFG2,    0x03,
		CC1101_DEVIATN,    0x34,												// 19.042969 kHz
		CC1101_MCSM2,      0x01,
		//CC1101_MCSM1,     0x30,	(default)									// always go into IDLE
		CC1101_MCSM0,      0x18,
		CC1101_FOCCFG,     0x16,
		CC1101_AGCCTRL2,   0x43,
		//CC1101_WOREVT1,   0x28,												// tEVENT0 = 50 ms, RX timeout = 390 us
		//7CC1101_WOREVT0,  0xA0,
		//CC1101_WORCTRL,   0xFB,												//EVENT1 = 3, WOR_RES = 0
		CC1101_FREND1,     0x56, //
		CC1101_FSCAL1,     0x00,
		CC1101_FSCAL0,     0x11,
		CC1101_TEST1,      0x35,
		CC1101_PATABLE,    0xC3,
	};

	for (uint8_t i=0; i<sizeof(initVal); i+=2) {								// write init value to TRX868
		writeReg(pgm_read_byte(&initVal[i]), pgm_read_byte(&initVal[i+1]));
	}

	#if defined(CC_DBG)
		Serial << F("2");
	#endif

	cmdStrobe(CC1101_SCAL);																// calibrate frequency synthesizer and turn it off
	while (readReg(CC1101_MARCSTATE, CC1101_STATUS) != 1) {								// waits until module gets ready
		_delay_us(1);

		#if defined(CC_DBG)
			Serial << F(".");
		#endif
	}

	#if defined(CC_DBG)
		Serial << F("3");
	#endif

	writeReg(CC1101_PATABLE, PA_MaxPower);												// configure PATABLE
	cmdStrobe(CC1101_SRX);																// flush the RX buffer
	cmdStrobe(CC1101_SWORRST);															// reset real time clock

	#if defined(CC_DBG)
	Serial << F(" - ready\n");
	#endif
}
Exemplo n.º 11
0
void    CC110x::init(void) {															// initialize CC1101
	
	#if defined(CC_DBG)
	Serial << F("CC1101_init: ");
	#endif

	pinMode(csPin, OUTPUT);																// set pins for SPI communication
	pinMode(mosiPin, OUTPUT);
	pinMode(misoPin, INPUT);
	pinMode(sckPin, OUTPUT);
	pinMode(gdo0Pin, INPUT);															// config GDO0 as input

	digitalWrite(csPin, HIGH);															// SPI init
	digitalWrite(sckPin, HIGH);
	digitalWrite(mosiPin, LOW);

	SPCR = _BV(SPE) | _BV(MSTR);														// SPI speed = CLK/4

	cc1101_Deselect();																	// some deselect and selects to init the TRX868modul
	_delay_us(5);

	cc1101_Select();
	_delay_us(10);

	cc1101_Deselect();
	_delay_us(41);

	cmdStrobe(CC1101_SRES);																// send reset
	_delay_ms(10);

	#if defined(CC_DBG)
		Serial << '1';
	#endif

	static prog_uint8_t initVal[] PROGMEM = {											// define init settings for TRX868
		0x00, 0x2E,			// IOCFG2: tristate											// non inverted GDO2, high impedance tri state
		0x01, 0x2E,			// IOCFG1: tristate											// low output drive strength, non inverted GD=1, high impedance tri state
		0x02, 0x06,			// IOCFG0: packet CRC ok									// disable temperature sensor, non inverted GDO0, asserts when a sync word has been sent/received, and de-asserts at the end of the packet. in RX, the pin will also de-assert when a package is discarded due to address or maximum length filtering
		0x03, 0x0D,			// FIFOTHR: TX:9 / RX:56									// 0 ADC retention, 0 close in RX, TX FIFO = 9 / RX FIFO = 56 byte
		0x04, 0xE9,			// SYNC1													// Sync word
		0x05, 0xCA,			// SYNC0
		0x06, 0x3D,			// PKTLEN(x): 61											// packet length 61
		0x07, 0x0C,			// PKTCTRL1:												// PQT = 0, CRC auto flush = 1, append status = 1, no address check
		0x0B, 0x06,			// FSCTRL1:													// frequency synthesizer control
		0x0D, 0x21,			// FREQ2
		0x0E, 0x65,			// FREQ1
		0x0F, 0x6A,			// FREQ0
		0x10, 0xC8,			// MDMCFG4
		0x11, 0x93,			// MDMCFG3
		0x12, 0x03,			// MDMCFG2
		0x15, 0x34,			// DEVIATN
		0x16, 0x01,         // MCSM2
		0x17, 0x30,			// MCSM1: always go into IDLE
		0x18, 0x18,			// MCSM0
		0x19, 0x16,			// FOCCFG
		0x1B, 0x43,			// AGCTRL2
		//0x1E, 0x28,       // ..WOREVT1: tEVENT0 = 50 ms, RX timeout = 390 us
		//0x1F, 0xA0,		// ..WOREVT0:
		//0x20, 0xFB,		// ..WORCTRL: EVENT1 = 3, WOR_RES = 0
		0x21, 0x56,			// FREND1
		0x25, 0x00,
		0x26, 0x11,			// FSCAL0
		0x2D, 0x35,			// TEST1
		0x3E, 0xC3,			// ?
	};

	for (uint8_t i=0; i<sizeof(initVal); i++) {											// write init value to TRX868
		writeReg(pgm_read_byte(&initVal[i++]), pgm_read_byte(&initVal[i]));
	}

	#if defined(CC_DBG)
		Serial << '2';
	#endif

	cmdStrobe(CC1101_SCAL);																// calibrate frequency synthesizer and turn it off
	while (readReg(CC1101_MARCSTATE, CC1101_STATUS) != 1) {								// waits until module gets ready
		_delay_us(1);

		#if defined(CC_DBG)
			Serial << '.';
		#endif
	}

	#if defined(CC_DBG)
		Serial << '3';
	#endif

	writeReg(CC1101_PATABLE, PA_MaxPower);												// configure PATABLE
	cmdStrobe(CC1101_SRX);																// flush the RX buffer
	cmdStrobe(CC1101_SWORRST);															// reset real time clock

	#if defined(CC_DBG)
	Serial << F(" - ready\r\n");
	#endif
}