(For the working code scroll all the way to the bottom!)
I free-formed a simple RFM12B atmega168 temperature sensor circuit using a 3.7 lithium ion battery I would one day like to solar recharge. Behold!:
Notes: DO for Data Out and DI for Data In, from the perspective of the RFM12B. I’m using a 7cm long antenna because these modules are 868MHz (you can tell the frequency based on the existence or not of a certain capacitor).
The MISO line is dead, the RFM12B is not responding to anything I’m sending it…
The RFM works with 16 bit data and I am currently trying to squeeze two 8 bit data transmissions, this is why I think things are not currently working. This project might be the limit of where it is easy to make one’s own code and when one must rely on code produced by the manufacturer of the chip in question.
An additional problem with the particilar project is the poor documentation by the manufacturer of the RFM12B module. Even the numbering of the registers is not consistent and there are errors in example code.
Here is the (not yet working) TX side code:
// *
// * Atmega168 RFM12B TX
// *
// * Created:
// * Author : FablabDigiscope
// */
#define F_CPU 8000000
#include <avr/io.h>
#include <util/delay.h>
#define NIRQ PB0 // input for nIRQ which goes low after a transmit is received?
void SPI_Init();
void SPI_Transmit(char dataout);
void SPI_Stop();
void rfInit();
int main(void)
{
SPI_Init();
SPDR = (0x00); // byte to send
SPDR = (0x00); // byte to send
rfInit();
DDRD = 0b10000000; //LED for RX/TX rec/sent
while (1)
{
char dataout = 0b10011001; // 0x99 //
SPI_Transmit(0xB8); //this must precede data, it is the transmit register write command.
SPI_Transmit(0xAA); // PREAMBLE
SPI_Transmit(0xB8); //this must precede data, it is the transmit register write command.
SPI_Transmit(0xAA);
SPI_Transmit(0xB8); //this must precede data, it is the transmit register write command.
SPI_Transmit(0xAA);
SPI_Transmit(0xB8); //this must precede data, it is the transmit register write command.
SPI_Transmit(0x2D); // SYNC
SPI_Transmit(0xB8); //this must precede data, it is the transmit register write command.
SPI_Transmit(0xD4); // Network ID
SPI_Transmit(0xB8); //this must precede data, it is the transmit register write command.
SPI_Transmit(dataout);
SPI_Transmit(0x00); //
SPI_Transmit(0xAA); // DUMMY BYTES, optional?
SPI_Transmit(0x00); //
SPI_Transmit(0xAA);
SPI_Transmit(0x00); //
SPI_Transmit(0xAA);
SPI_Stop();
_delay_ms(1);
PORTD = 0b10000000; // turn on LED
}
}
void SPI_Init()
{
DDRB = ((1<<DDB2)|(1<<DDB5)|(1<<DDB3)); //SPI pins on port B: SS, SCK, MOSI outputs
//set MISO as input
PORTB |= (1<<DDB2); //start with SS high (slave not selected). DO THIS BEFORE BEGINING ISP
PORTB |= (1<<DDB4); //MISO pull-up activated
SPCR = ((1<<SPE)|(1<<MSTR)|(1<<SPR1)); // SPI enable, Master enable, f/64. DO THIS AFTER DDR!
}
void SPI_Transmit(char dataout)
{
//SPI_Transmit
PORTB &= ~(1<<DDB2); // pull slave select low
while(PINB & (1<<NIRQ)); // wait until ready signal (low)
SPDR = (dataout); // byte to send
while(!(SPSR & (1<<SPIF))); // wait for SPIF transmit flag to be set. After this, SPDR will contain the received byte!
}
void SPI_Stop()
{
PORTB |= (1<<DDB2); //slave select high
}
void rfInit()
{
SPI_Transmit(0x80);
SPI_Transmit(0xE7); //EL (turn on internal data reg.),EF (FIFO rx mode enabled, data and dclk used for data and data clock output),868band,12.0pF
SPI_Transmit(0x82);
SPI_Transmit(0x39); //er (for rec. mode),!ebb,ET(for rec. mode),ES,EX,!eb,!ew,DC for receiver mode//
SPI_Transmit(0xA6);
SPI_Transmit(0x40); //frequency select
SPI_Transmit(0xC6);
SPI_Transmit(0x47); //4.8kbps
SPI_Transmit(0x94);
SPI_Transmit(0xA0); //VDI,FAST,134kHz,0dBm,-103dBm
SPI_Transmit(0xC2);
SPI_Transmit(0xAC); //AL,!ml,DIG,DQD4
SPI_Transmit(0xCA);
SPI_Transmit(0x81); //FIFO8,SYNC,!ff,DR ***** (this must be set to 0xCA83 to rx)
SPI_Transmit(0xCE);
SPI_Transmit(0xD4); //SYNC=2DD4 ,AG
SPI_Transmit(0xC4);
SPI_Transmit(0x83); //@PWR,NO RSTRIC,!st,!fi,OE,EN
SPI_Transmit(0x98);
SPI_Transmit(0x50); //!mp,90kHz,MAX OUT
SPI_Transmit(0xCC);
SPI_Transmit(0x17); //OB1 , ACOB0, LPX,Iddy,CDDIT,CBW0
SPI_Transmit(0xE0);
SPI_Transmit(0x00); //NOT USED
SPI_Transmit(0xC8);
SPI_Transmit(0x00); //NOT USED
SPI_Transmit(0xC0);
SPI_Transmit(0x40); //1.66MHz,2.2V
}
Here is the (not yet working) RX side of the code:
// *
// * Atmega168 RFM12B RX
// *
// * Created:
// * Author : FablabDigiscope
// */
#define F_CPU 8000000
#include <avr/io.h>
#include <util/delay.h>
#define NIRQ PB0 // input for nIRQ which goes low after a transmit is received?
void FIFO_Reset();
void SPI_Transmit(char dataout);
void SPI_Init();
void rfInit();
void SPI_Stop();
char SPI_Receive();
int main(void)
{
DDRD = 0b10000000; //LED for RX/TX rec/sent
SPI_Init();
rfInit();
while (1)
{
char storage;
SPI_Transmit(0x00);
SPI_Transmit(0x00);
FIFO_Reset();
storage = SPI_Receive(); //should get only last byte of message?
if(storage == 0b10011001) // 0x99
{
PORTD = 0b10000000; //turn on LED
FIFO_Reset();
}
SPI_Stop();
_delay_us(1);
}
}
void SPI_Init()
{
DDRB = ((1<<DDB2)|(1<<DDB5)|(1<<DDB3)); //SPI pins on port B: SS, SCK, MOSI outputs
//set MISO as input
PORTB |= (1<<DDB2); //start with SS high (slave not selected). DO THIS BEFORE BEGINING ISP
PORTB |= (1<<DDB4); //MISO pull-up activated
SPCR = ((1<<SPE)|(1<<MSTR)|(1<<SPR1)); // SPI enable, Master enable, f/64. DO THIS AFTER DDR!
}
char SPI_Receive() //must be in receive mode for this to work//
{
char received;
//SPI_Receive
PORTB &= ~(1<<DDB2); // pull slave select low
while(PINB & (1<<NIRQ)); // wait until ready signal (low)
SPDR = (0xB0); // byte to send
while(!(SPSR & (1<<SPIF))); // wait for SPIF transmit flag to be set. After this, SPDR will contain the received byte!
while(PINB & (1<<NIRQ)); // wait until ready signal (low)
SPDR = (0x00); // byte to send
while(!(SPSR & (1<<SPIF))); // wait for SPIF transmit flag to be set. After this, SPDR will contain the received byte!
received = SPDR;
return received;
}
void SPI_Transmit(char dataout)
{
//SPI_Transmit
PORTB &= ~(1<<DDB2); // pull slave select low
while(PINB & (1<<NIRQ)); // wait until ready signal (low)
SPDR = (dataout); // byte to send
while(!(SPSR & (1<<SPIF))); // wait for SPIF transmit flag to be set. After this, SPDR will contain the received byte!
}
void FIFO_Reset()
{
SPI_Transmit(0xCA);
SPI_Transmit(0x81);
SPI_Transmit(0xCA);
SPI_Transmit(0x83);
}
void rfInit()
{
SPI_Transmit(0x80);
SPI_Transmit(0xE7); //EL (turn on internal data reg.),EF (FIFO rx mode enabled, data and dclk used for data and data clock output),868band,12.0pF
SPI_Transmit(0x82);
SPI_Transmit(0x99); //er (for rec. mode),!ebb,ET(for rec. mode),ES,EX,!eb,!ew,DC for receiver mode//
SPI_Transmit(0xA6);
SPI_Transmit(0x40); //frequency select
SPI_Transmit(0xC6);
SPI_Transmit(0x47); //4.8kbps
SPI_Transmit(0x94);
SPI_Transmit(0xA0); //VDI,FAST,134kHz,0dBm,-103dBm
SPI_Transmit(0xC2);
SPI_Transmit(0xAC); //AL,!ml,DIG,DQD4
SPI_Transmit(0xCA);
SPI_Transmit(0x81); //FIFO8,SYNC,!ff,DR ***** (this must be set to 0xCA83 to rx)
SPI_Transmit(0xCE);
SPI_Transmit(0xD4); //SYNC=2DD4 ,AG
SPI_Transmit(0xC4);
SPI_Transmit(0x83); //@PWR,NO RSTRIC,!st,!fi,OE,EN
SPI_Transmit(0x98);
SPI_Transmit(0x50); //!mp,90kHz,MAX OUT
SPI_Transmit(0xCC);
SPI_Transmit(0x17); //OB1 , ACOB0, LPX,Iddy,CDDIT,CBW0
SPI_Transmit(0xE0);
SPI_Transmit(0x00); //NOT USED
SPI_Transmit(0xC8);
SPI_Transmit(0x00); //NOT USED
SPI_Transmit(0xC0);
SPI_Transmit(0x40); //1.66MHz,2.2V
}
void SPI_Stop()
{
PORTB |= (1<<DDB2); //slave select high
}
This code works (most of the time!), it’s from http://dlehard.narod.ru/quick_start.pdf, dlehard did a wonderful job making this clear and legible, thank you for your work!
I think the main reason it is working is the fact that it does not rely on the AVR USI but has its own custom 16 bit Write(Cmd) function. This function is straight forward, it takes a 16 bit input and bit bangs the SDO (Microchip input from RFM12B output) one bit at a time while also reading the SDI (Microchip output to RFM12B input) and writing it to the recv variable. It manually does the basic SPI stuff, pulling Chip Select (CS) low and pulling the clock low before putting SDI in the appropriate state and ticking the clock up. The part I had difficulty understanding was the ANDing with 0x8000, now I understand this is a bitmask which looks only at the highest bit in the 16 bit value (0x8000 = 0b1000000000000000) while the loop bitshifts the Cmd to the left each time, ANDing the next bit with 1. ANDing produces a 1 only if A and B are both 1 and otherwise produces a 0, this is why it is useful as a bitmask.
I don’t know how the timing of this SPI setup is controlled but I guess it’s not critical.
The TX side turns on an LED everytime it transmits, the RX side turns on an LED if it receives the byte 0x30.
I was too lazy to get the USART to work with the Atmega168 (I have a previous post on getting it going with an Attiny2313) so that part of the code is commented out.
Here is the RX side:
/*
* Atmega168 RFM12B rev.2 RX.c
*
* Created: 4/30/2019 2:56:31 PM
* Author : FablabDigiscope
*/
#include <avr/io.h>
/* RFM12B INTERFACE */
#define SCK 5 // SPI clock
#define SDO 4 // SPI Data output (RFM12B side)
#define SDI 3 // SPI Data input (RFM12B side)
#define CS 2 // SPI SS (chip select)
#define NIRQ 2 // (PORTD)
/* IO CONTROL */
#define HI(x) PORTB |= (1<<(x))
#define LO(x) PORTB &= ~(1<<(x))
/* LED */
#define LED 6
#define LED_OFF() PORTD &= ~(1<<LED)
#define LED_ON() PORTD |= (1<<LED)
/* USART */
//#define BAUDRATE 25 // 19200 at 8MHz
void portInit() {
HI(CS);
HI(SDI);
LO(SCK);
DDRB = (1<<CS) | (1<<SDI) | (1<<SCK);
DDRD = (1<<LED);
}
unsigned int writeCmd(unsigned int cmd) {
unsigned char i;
unsigned int recv;
recv = 0;
LO(SCK);
LO(CS);
for(i=0; i<16; i++) {
if(cmd&0x8000) HI(SDI); else LO(SDI);
HI(SCK);
recv<<=1;
if( PINB&(1<<SDO) ) {
recv|=0x0001;
}
LO(SCK);
cmd<<=1;
}
HI(CS);
return recv;
}
/*
void rsInit(unsigned char baud) {
UBRRL = baud;
UCSRC = (1<<UCSZ0) | (1<<UCSZ1); // 8N1
UCSRB = (1<<RXEN) | (1<<TXEN); // enable tx and rx
}
void rsSend(unsigned char data) {
while( !(UCSRA & (1<<UDRE)));
UDR = data;
}
unsigned char rsRecv() {
while( !(UCSRA & (1<<RXC)));
return UDR;
}
*/
void rfInit() {
writeCmd(0x80E7); //EL,EF,868band,12.0pF
writeCmd(0x8299); //er,!ebb,ET,ES,EX,!eb,!ew,DC (bug was here)
writeCmd(0xA640); //freq select
writeCmd(0xC647); //4.8kbps
writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR (FIFO level = 8)
writeCmd(0xCED4); //SYNC=2DD4;
writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
writeCmd(0x9850); //!mp,90kHz,MAX OUT
writeCmd(0xCC17); //!OB1,!OB0, LPX,!ddy,DDIT,BW0
writeCmd(0xE000); //NOT USE
writeCmd(0xC800); //NOT USE
writeCmd(0xC040); //1.66MHz,2.2V
}
/*
void rfSend(unsigned char data){
while(PIND&(1<<NIRQ));
writeCmd(0xB800 + data);
}
*/
unsigned char rfRecv() {
unsigned int data;
while(1) {
data = writeCmd(0x0000);
if ( (data&0x8000) ) {
data = writeCmd(0xB000);
return (data&0x00FF);
}
}
}
void FIFOReset() {
writeCmd(0xCA81);
writeCmd(0xCA83);
}
int main(void) {
unsigned char data, i;
LED_OFF();
portInit();
rfInit();
// rsInit(BAUDRATE);
FIFOReset();
while(1) {
//waitForData();
for (i=0; i<16; i++) {
data = rfRecv();
if (data == 0x30){
LED_ON(); //delete this
}
}
FIFOReset();
LED_OFF();
}
return 0;
}
Here is the TX side:
/*
* Atmega168 RFM12B rev.2.c
*
* Created: 4/25/2019 5:27:15 PM
* Author : FablabDigiscope
*/
#include <avr/io.h>
/* RFM12B INTERFACE */
#define SCK 5 // SPI clock
#define SDO 4 // SPI Data output (RFM12B side)
#define SDI 3 // SPI Data input (RFM12B side)
#define CS 2 // SPI SS (chip select)
#define NIRQ 2 // (PORTD)
/* IO CONTROL */
#define HI(x) PORTB |= (1<<(x))
#define LO(x) PORTB &= ~(1<<(x))
/* LED */
#define LED 6
#define LED_OFF() PORTD &= ~(1<<LED)
#define LED_ON() PORTD |= (1<<LED)
void portInit() {
HI(CS);
HI(SDI);
LO(SCK);
DDRB = (1<<CS) | (1<<SDI) | (1<<SCK);
DDRD = (1<<LED);
}
unsigned int writeCmd(unsigned int cmd) {
unsigned char i;
unsigned int recv;
recv = 0;
LO(SCK);
LO(CS);
for(i=0; i<16; i++) {
if(cmd&0x8000) HI(SDI); else LO(SDI);
HI(SCK);
recv<<=1;
if( PINB&(1<<SDO) ) {
recv|=0x0001;
}
LO(SCK);
cmd<<=1;
}
HI(CS);
return recv;
}
void rfInit() {
writeCmd(0x80E7); //EL,EF,868band,12.0pF
writeCmd(0x8239); //!er,!ebb,ET,ES,EX,!eb,!ew,DC
writeCmd(0xA640); //frequency select
writeCmd(0xC647); //4.8kbps
writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR
writeCmd(0xCED4); //SYNC=2DD4,AG
writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
writeCmd(0x9850); //!mp,90kHz,MAX OUT
writeCmd(0xCC17); //OB1,ACOB0, LPX,Iddy,CDDIT,CBW0
writeCmd(0xE000); //NOT USED
writeCmd(0xC800); //NOT USED
writeCmd(0xC040); //1.66MHz,2.2V
}
void rfSend(unsigned char data){
while(PIND&(1<<NIRQ));
writeCmd(0xB800 + data);
}
int main() {
volatile unsigned int i,j;
asm("cli");
for(i=0;i<1000;i++)for(j=0;j<123;j++);
portInit();
rfInit();
while(1){
LED_ON();
writeCmd(0x0000);
rfSend(0xAA); // PREAMBLE
rfSend(0xAA);
rfSend(0xAA);
rfSend(0x2D); // SYNC
rfSend(0xD4);
for(i=0; i<16; i++) {
rfSend(0x30+i);
}
rfSend(0xAA); // DUMMY BYTES
rfSend(0xAA);
rfSend(0xAA);
LED_OFF();
for(i=0; i<10000; i++) // some not very
for(j=0; j<123; j++); // sophisticated delay
}
}
And here’s a photo of the two modules communicating when each is battery powered from two 1.5 watch battery cells. They continue to be able to communicate after a shortish but not insignificant walk to the coffee machine (50 meters or so).
Here is the code for one RFM12B taking an analog measurement and sending it to the other which is printing the result via USART to a serial port.
TX side:
/*
* Atmega168 RFM12B TX rev.2.c
*
* Created: 4/25/2019 5:27:15 PM
* Author : FablabDigiscope
*/
#include <avr/io.h>
/* RFM12B INTERFACE */
#define SCK 5 // SPI clock
#define SDO 4 // SPI Data output (RFM12B side)
#define SDI 3 // SPI Data input (RFM12B side)
#define CS 2 // SPI SS (chip select)
#define NIRQ 2 // (PORTD)
/* IO CONTROL */
#define HI(x) PORTB |= (1<<(x))
#define LO(x) PORTB &= ~(1<<(x))
/* LED */
#define LED 6
#define LED_OFF() PORTD &= ~(1<<LED)
#define LED_ON() PORTD |= (1<<LED)
void analogInit() {
ADMUX |= (1 << REFS0); // AREF ref voltage connected to power
// PC0 input select
ADCSRA |= (1 << ADPS2) | (1 << ADPS0); // set clock to 32 divisions for 8MHz
ADCSRA |= (1 << ADEN); /* enable ADC */
}
unsigned int analogRead() {
uint16_t adcValue; //16 bit variable because the ADC on the Attiny84 is 10 bits.
ADCSRA |= (1 << ADSC); /* start conversion */
adcValue = ADC; /* store high byte into adcValue */
return adcValue;
}
void portInit() {
HI(CS);
HI(SDI);
LO(SCK);
DDRB = (1<<CS) | (1<<SDI) | (1<<SCK);
DDRD = (1<<LED);
}
unsigned int writeCmd(unsigned int cmd) {
unsigned char i;
unsigned int recv;
recv = 0;
LO(SCK);
LO(CS);
for(i=0; i<16; i++) {
if(cmd&0x8000) HI(SDI); else LO(SDI);
HI(SCK);
recv<<=1;
if( PINB&(1<<SDO) ) {
recv|=0x0001;
}
LO(SCK);
cmd<<=1;
}
HI(CS);
return recv;
}
void rfInit() {
writeCmd(0x80E7); //EL,EF,868band,12.0pF
writeCmd(0x8239); //!er,!ebb,ET,ES,EX,!eb,!ew,DC
writeCmd(0xA640); //frequency select
writeCmd(0xC647); //4.8kbps
writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR
writeCmd(0xCED4); //SYNC=2DD4,AG
writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
writeCmd(0x9850); //!mp,90kHz,MAX OUT
writeCmd(0xCC17); //OB1,ACOB0, LPX,Iddy,CDDIT,CBW0
writeCmd(0xE000); //NOT USED
writeCmd(0xC800); //NOT USED
writeCmd(0xC040); //1.66MHz,2.2V
}
void rfSend(unsigned char data){
while(PIND&(1<<NIRQ));
writeCmd(0xB800 + data);
}
int main() {
volatile unsigned int i,j;
asm("cli");
for(i=0;i<1000;i++)for(j=0;j<123;j++);
portInit();
analogInit();
rfInit();
while(1){
LED_ON();
writeCmd(0x0000);
rfSend(0xAA); // PREAMBLE
rfSend(0xAA);
rfSend(0xAA);
rfSend(0x2D); // SYNC
rfSend(0xD4);
for(i=0; i<16; i++) {
rfSend(analogRead());
}
rfSend(0xAA); // DUMMY BYTES
rfSend(0xAA);
rfSend(0xAA);
LED_OFF();
for(i=0; i<10000; i++) // some not very
for(j=0; j<123; j++); // sophisticated delay
}
}
RX side:
/*
* Atmega168 RFM12B rev.2 RX.c
*
* Created: 4/30/2019 2:56:31 PM
* Author : FablabDigiscope
*/
#include <avr/io.h>
/* RFM12B INTERFACE */
#define SCK 5 // SPI clock
#define SDO 4 // SPI Data output (RFM12B side)
#define SDI 3 // SPI Data input (RFM12B side)
#define CS 2 // SPI SS (chip select)
#define NIRQ 2 // (PORTD)
/* IO CONTROL */
#define HI(x) PORTB |= (1<<(x))
#define LO(x) PORTB &= ~(1<<(x))
/* LED */
#define LED 6
#define LED_OFF() PORTD &= ~(1<<LED)
#define LED_ON() PORTD |= (1<<LED)
/* USART */
#define BAUDRATE 25 // 19200 at 8MHz
void portInit() {
HI(CS);
HI(SDI);
LO(SCK);
DDRB = (1<<CS) | (1<<SDI) | (1<<SCK);
DDRD = (1<<LED);
}
unsigned int writeCmd(unsigned int cmd) {
unsigned char i;
unsigned int recv;
recv = 0;
LO(SCK);
LO(CS);
for(i=0; i<16; i++) {
if(cmd&0x8000) HI(SDI); else LO(SDI);
HI(SCK);
recv<<=1;
if( PINB&(1<<SDO) ) {
recv|=0x0001;
}
LO(SCK);
cmd<<=1;
}
HI(CS);
return recv;
}
void rsInit(unsigned char baud) {
UBRR0L = baud;
UCSR0C = (1<<UCSZ00) | (1<<UCSZ01); // 8N1
UCSR0B = (1<<RXEN0) | (1<<TXEN0); // enable tx and rx
}
void rsSend(unsigned char data) {
while( !(UCSR0A & (1<<UDRE0)));
UDR0 = data;
}
unsigned char rsRecv() {
while( !(UCSR0A & (1<<RXC0)));
return UDR0;
}
/* FOR ATTINY 2313
void rsInit(unsigned char baud) {
UBRRL = baud;
UCSRC = (1<<UCSZ0) | (1<<UCSZ1); // 8N1
UCSRB = (1<<RXEN) | (1<<TXEN); // enable tx and rx
}
void rsSend(unsigned char data) {
while( !(UCSRA & (1<<UDRE)));
UDR = data;
}
unsigned char rsRecv() {
while( !(UCSRA & (1<<RXC)));
return UDR;
}
*/
void rfInit() {
writeCmd(0x80E7); //EL,EF,868band,12.0pF
writeCmd(0x8299); //er,!ebb,ET,ES,EX,!eb (low batt detector disabled),!ew,DC (bug was here)
writeCmd(0xA640); //freq select
writeCmd(0xC647); //4.8kbps
writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR (FIFO level = 8)
writeCmd(0xCED4); //SYNC=2DD4;
writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
writeCmd(0x9850); //!mp,90kHz,MAX OUT
writeCmd(0xCC17); //!OB1,!OB0, LPX,!ddy,DDIT,BW0
writeCmd(0xE000); //NOT USE
writeCmd(0xC800); //NOT USE
writeCmd(0xC040); //1.66MHz,2.2V
}
void rfSend(unsigned char data){
while(PIND&(1<<NIRQ));
writeCmd(0xB800 + data);
}
unsigned char rfRecv() {
unsigned int data;
while(1) {
data = writeCmd(0x0000); // I think I would add here responses to Status
if ( (data&0x8000) ) {
data = writeCmd(0xB000);
return (data&0x00FF);
}
}
}
void FIFOReset() {
writeCmd(0xCA81);
writeCmd(0xCA83);
}
int main(void) {
unsigned char data, i;
LED_OFF();
portInit();
rfInit();
rsInit(BAUDRATE);
//analogInit();
FIFOReset();
while(1) {
//waitForData();
for (i=0; i<16; i++) {
data = rfRecv();
rsSend(data);
}
FIFOReset();
LED_OFF();
}
return 0;
}