Root/Examples/UNFURO/RF/main.c

1//UNAL 2010
2//RFM22B Demo example by juan64bits, based on HOPE RF examples for PIC
3//and datasheet. http://www.hoperf.com/rf_fsk/rfm22b.htm
4//FIXME:
5// *¿?
6//TODO:
7// *In order to avoid using while() loops is necessary to
8// implement ISR (interrupt service routine) for RF_IRQ pin
9// *
10
11#include <avr/io.h>
12#include <util/delay.h>
13
14#define DEBUG 0 // Debug mode.
15#define DEMO_RX 0 // Rx demo mode.
16#define DEMO_TX 1 // Tx demo mode.
17
18#define F_CPU 1000000UL // 1 MHz
19#define SPI_PORT PORTB // SPI PORT
20#define SPI_DDR DDRB // PORT REGISTER
21#define SPI_CS PB0 // RF_nSEL
22
23#define RF_PORT PORTD // RF PORT
24#define RF_DDR DDRD // RF DDRD
25#define RF_PIN PIND // RF PIN
26#define RF_RXEN PD4 // Rx enable
27#define RF_TXEN PD3 // Tx enable
28#define RF_IRQ PD7 // IRQ
29
30#define RF22B_PWRSTATE_POWERDOWN 0x00
31#define RF22B_PWRSTATE_READY 0x01
32#define RF22B_Rx_packet_received_interrupt 0x02
33#define RF22B_PACKET_SENT_INTERRUPT 0x04
34#define RF22B_PWRSTATE_RX 0x05
35#define RF22B_PWRSTATE_TX 0x09
36
37void initUSART0(unsigned long baud)
38{
39    UBRR0 = F_CPU/16/baud-1; // Set Baudrate
40    UCSR0C = (3<<UCSZ00); // Character Size 8 bit
41    UCSR0B |= _BV(RXEN0) | _BV(TXEN0); // Receiver and Transmitter Enable
42}
43
44unsigned char receive1byteUSART0(void)
45{
46    loop_until_bit_is_set(UCSR0A, RXC0);
47    return UDR0;
48}
49
50void transmit1byteUSART0(unsigned char data)
51{
52    loop_until_bit_is_set(UCSR0A, UDRE0);
53    UDR0 = data;
54}
55
56void transmitStrUSART0(char *str)
57{
58    while (*str != 0) {
59        transmit1byteUSART0(*str);
60        *str++;
61    }
62}
63
64void sendByteToHexUart(unsigned char value)
65{
66    transmit1byteUSART0('0');
67    transmit1byteUSART0('x');
68    if((value>>4)<10)
69        transmit1byteUSART0('0'+(value>>4));
70    else
71        transmit1byteUSART0('A'+(value>>4)-10);
72    if((value&0x0F)<10)
73        transmit1byteUSART0('0'+(value&0x0F));
74    else
75        transmit1byteUSART0('A'+(value&0x0F)-10);
76    transmit1byteUSART0(' ');
77    transmit1byteUSART0(0);
78
79}
80
81unsigned char spiWriteRead(unsigned char dataout)
82{
83  unsigned char datain;
84  // Start transmission (MOSI)
85  SPDR = dataout;
86  // Wait for transmission complete
87  while(!(SPSR & (1<<SPIF))){}
88  // Get return Value;
89  datain = SPDR;
90  // Return Serial In Value (MISO)
91  return datain;
92}
93
94void initSPI(void)
95{
96    // Set MOSI and SCK as output, others as input
97    SPI_DDR = 0xFF;
98    SPI_DDR &= ~(1<<PB4);
99    // Enable SPI, Master, set clock rate fck/2 (maximum)
100    SPCR = (1<<SPE)|(0<<DORD)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0);
101
102    SPI_PORT |= (1<<SPI_CS); // SPI SS set to high
103}
104
105unsigned char spiRead(unsigned char address)
106{
107    // nSEL= L
108    SPI_PORT &= ~(1<<SPI_CS);
109    //_delay_us(10); // Setup time : min 20 ns
110    unsigned char result;
111    spiWriteRead(address&0x7f); // D7 = 0 for read
112    result = spiWriteRead(0x00); // SDI don't care
113    // nSEL= H
114    //_delay_us(10); // High period min: 80ns
115    SPI_PORT |= (1<<SPI_CS);
116    return(result);
117}
118
119unsigned char spiWrite(unsigned char address,unsigned char data)
120{
121    // nSEL= L
122    SPI_PORT &= ~(1<<SPI_CS);
123    //_delay_us(10); // Setup time : min 20 ns
124    unsigned char result;
125    spiWriteRead(address|0x80); // Send address, D7 = 1 for write
126    result = spiWriteRead(data); // Send register value
127    // nSEL= H
128    //_delay_us(10); // High period min: 80ns
129    SPI_PORT |= (1<<SPI_CS);
130#if DEBUG==1
131    transmitStrUSART0("Setting REG[ ");
132    sendByteToHexUart(address);
133    transmitStrUSART0("]= ");
134    sendByteToHexUart(data);
135    transmitStrUSART0(" ( ");
136    sendByteToHexUart(spiRead(address));
137    transmitStrUSART0(")");
138    transmitStrUSART0("\r\n");
139#endif
140    return(result);
141}
142
143void rfm22bInit(void)
144{
145    RF_PORT |= (1<<RF_IRQ); // IRQ PULLUP
146
147    RF_DDR &= ~(1<<RF_IRQ); // Input
148    RF_DDR |= (1<<RF_TXEN); // Output
149    RF_DDR |= (1<<RF_RXEN); // Output
150    
151    RF_PORT &= ~(1<<RF_RXEN); // RXEN Low
152    RF_PORT &= ~(1<<RF_TXEN); // TXEN Low
153
154    _delay_ms(100);
155
156#if DEMO_TX==1
157    transmitStrUSART0("RFM22B Initialize Process (TX DEMO)\r\n");
158#elif DEMO_RX==1
159    transmitStrUSART0("RFM22B Initialize Process (RX DEMO)\r\n");
160#endif
161
162#if DEBUG==1
163    transmitStrUSART0(" Register 0x03:");
164    sendByteToHexUart(spiRead(0x03));
165
166    transmitStrUSART0(" Register 0x04:");
167    sendByteToHexUart(spiRead(0x04));
168    
169    transmitStrUSART0("\r\n");
170#else
171    spiRead(0x03);
172    spiRead(0x04);
173#endif
174
175        
176    spiWrite(0x06, 0x00); // no wakeup up, lbd,
177    // disable lbd, wakeup timer, use internal 32768,xton = 1; in ready mode
178    spiWrite(0x07, RF22B_PWRSTATE_READY);
179    spiWrite(0x09, 0x7f); // c = 12.5p
180    spiWrite(0x0a, 0x05);
181    spiWrite(0x0b, 0xf4); // gpio0 for received data output
182    spiWrite(0x0c, 0xef); // gpio 1 for clk output
183    spiWrite(0x0d, 0xfd); // gpio 2 micro-controller clk output
184    spiWrite(0x0e, 0x00); // gpio 0, 1,2 NO OTHER FUNCTION.
185    spiWrite(0x70, 0x20); // disable manchest
186    
187    spiWrite(0x1d, 0x00); // enable afc
188    spiWrite(0x1c, 0x1d); // RATE_24K: // 2.4k
189    //0x20 calculate from the datasheet
190    //= 500*(1+2*down3_bypass)/(2^ndec*RB*(1+enmanch))
191    spiWrite(0x20,0x41);
192    // 0x21 , rxosr[10--8] = 0; stalltr = (default), ccoff[19:16] = 0;
193    spiWrite(0x21, 0x60);
194    spiWrite(0x22, 0x27); // 0x22 ncoff =5033 = 0x13a9
195    spiWrite(0x23, 0x52); // 0x23
196    spiWrite(0x24, 0x00); // 0x24
197    spiWrite(0x25, 0x06); // 0x25
198    spiWrite(0x2a, 0x1e);
199    
200    //case RATE_24K: // 2.4k
201    spiWrite(0x6e, 0x13);
202    spiWrite(0x6f, 0xa9);
203    //PH+FIFO
204    spiWrite(0x30, 0x8c); // enable packet handler, msb first, enable crc,
205                           // 0x31 only readable
206    // 0x32address enable for headere byte 0, 1,2,3, receive
207    // header check for byte 0, 1,2,3
208    spiWrite(0x32, 0xff);
209    // header 3, 2, 1,0 used for head length, fixed packet length,
210    // synchronize word length 3, 2,
211    spiWrite(0x34, 64);
212    spiWrite(0x33, 0x42);
213    // 64 nibble = 32byte preamble
214    spiWrite(0x36, 0x2d); // synchronize word
215    spiWrite(0x37, 0xd4);
216    spiWrite(0x38, 0x00);
217    spiWrite(0x39, 0x00);
218    spiWrite(0x3a, 's'); // tx header
219    spiWrite(0x3b, 'o');
220    spiWrite(0x3c, 'n');
221    spiWrite(0x3d, 'g');
222    spiWrite(0x3e, 1); // total tx 1 byte 0x52, 53, 54, 55 H set to default;
223    // check hearder
224    spiWrite(0x3f, 's');
225    spiWrite(0x40, 'o');
226    spiWrite(0x41, 'n');
227    spiWrite(0x42, 'g');
228    spiWrite(0x43, 0xff); // all the bit to be checked
229    spiWrite(0x44, 0xff); // all the bit to be checked
230    spiWrite(0x45, 0xff); // all the bit to be checked
231    spiWrite(0x46, 0xff); // all the bit to be checked
232    // 0x56 ---------0x6c
233    spiWrite(0x6d, 0x0f); // set power max power
234    spiWrite(0x79, 0x0); // no hopping
235    spiWrite(0x7a, 0x0); // no hopping
236    // Gfsk, fd[8] =0, no invert for Tx/Rx data, fifo mode, txclk -->gpio
237    spiWrite(0x71, 0x22);
238    spiWrite(0x72, 0x38); // frequency deviation setting to 45k = 72*625
239    spiWrite(0x73, 0x0);
240    spiWrite(0x74, 0x0); // no offset
241    //band 434
242    spiWrite(0x75, 0x53); // hbsel = 0, sbsel =1 ???, fb = 19
243    spiWrite(0x76, 0x64); // 25600= 0x6400 for 434Mhz
244    spiWrite(0x77, 0x00);
245}
246
247void rfm22bSetReady(void)
248{
249#if DEBUG==1
250    transmitStrUSART0("RFM22B Setting Ready Mode\r\n");
251
252    transmitStrUSART0(" Register 0x03:");
253    sendByteToHexUart(spiRead(0x03));
254
255    transmitStrUSART0(" Register 0x04:");
256    sendByteToHexUart(spiRead(0x04));
257    
258    transmitStrUSART0("\r\n");
259#else
260    spiRead(0x03);
261    spiRead(0x04);
262#endif
263             
264    spiWrite(0x07, RF22B_PWRSTATE_READY);
265}
266
267void rfm22bSetSleep(void)
268{
269    spiWrite(0x07, RF22B_PWRSTATE_READY);
270
271#if DEBUG==1
272    transmitStrUSART0("RFM22B Setting Sleep Mode\r\n");
273
274    transmitStrUSART0(" Register 0x03:");
275    sendByteToHexUart(spiRead(0x03));
276
277    transmitStrUSART0(" Register 0x04:");
278    sendByteToHexUart(spiRead(0x04));
279    
280    transmitStrUSART0("\r\n");
281#else
282    spiRead(0x03);
283    spiRead(0x04);
284#endif
285
286    spiWrite(0x07, RF22B_PWRSTATE_POWERDOWN);
287}
288
289void rfm22bSendByte(unsigned char value)
290{
291   
292    transmitStrUSART0("RFM22B Sending Data:");
293    sendByteToHexUart(value);
294    transmitStrUSART0("\r\n");
295    
296    rfm22bSetReady();
297    
298    RF_PORT &= ~(1<<RF_RXEN); // RXEN low
299    RF_PORT |= (1<<RF_TXEN); // TXEN High
300
301    // disABLE AUTO TX MODE, enable multi packet clear fifo
302    spiWrite(0x08, 0x03);
303    // disABLE AUTO TX MODE, enable multi packet, clear fifo
304    spiWrite(0x08, 0x00);
305
306    // ph +fifo mode
307    spiWrite(0x34, 64); // 64 nibble = 32byte preamble
308    spiWrite(0x3e, 1); // total tx 1 byte
309    spiWrite(0x7f, value); // Insert to FIFO
310    spiWrite(0x05, RF22B_PACKET_SENT_INTERRUPT);
311    
312#if DEBUG==1
313    transmitStrUSART0("RFM22B Clearing IRQ\r\n");
314
315    transmitStrUSART0(" Register 0x03:");
316    sendByteToHexUart(spiRead(0x03));
317
318    transmitStrUSART0(" Register 0x04:");
319    sendByteToHexUart(spiRead(0x04));
320    
321    transmitStrUSART0("\r\n");
322#else
323    spiRead(0x03);
324    spiRead(0x04);
325#endif
326    
327    spiWrite(0x07, RF22B_PWRSTATE_TX); // to tx mode
328
329    while(RF_PIN & (1<<RF_IRQ)); // wait for interruption
330    
331    rfm22bSetReady();
332    
333    RF_PORT &= ~(1<<RF_RXEN); // RXEN low
334    RF_PORT &= ~(1<<RF_TXEN); // TXEN low
335    
336    _delay_ms(50);
337}
338
339#if DEMO_RX==1
340void rfm22bRxReset(void)
341{
342    spiWrite(0x07, RF22B_PWRSTATE_READY);
343    // threshold for rx almost full, interrupt when 1 byte received
344    spiWrite(0x7e, 1);
345    spiWrite(0x08, 0x03); //clear fifo disable multi packet
346    spiWrite(0x08, 0x00); // clear fifo, disable multi packet
347    spiWrite(0x07, RF22B_PWRSTATE_RX ); // to rx mode
348    spiWrite(0x05, RF22B_Rx_packet_received_interrupt);
349    
350#if DEBUG==1
351    transmitStrUSART0(" Register 0x03:");
352    sendByteToHexUart(spiRead(0x03));
353
354    transmitStrUSART0(" Register 0x04:");
355    sendByteToHexUart(spiRead(0x04));
356    
357    transmitStrUSART0("\r\n");
358#else
359    spiRead(0x03);
360    spiRead(0x04);
361#endif
362}
363 
364void rfm22bSetRxMode(void)
365{
366    RF_PORT &= ~(1<<RF_RXEN); // RXEN low
367    RF_PORT &= ~(1<<RF_TXEN); // TXEN low
368    
369 #if DEBUG==1
370    transmitStrUSART0("RFM22B Setting Rx Mode\r\n");
371 #endif
372  
373    rfm22bSetReady();
374     _delay_ms(50);
375     
376    RF_PORT |= (1<<RF_RXEN); // RXEN High
377    RF_PORT &= ~(1<<RF_TXEN); // TXEN low
378    
379    rfm22bRxReset();
380}
381#endif
382#if DEBUG==1
383void rfm22bReadAllRegisters(void)
384{
385    //*** TEST: Read all registers ***//
386    unsigned char i;
387    transmitStrUSART0("Reading all registers:");
388    for(i=0; i<0x80; i++)
389    {
390        transmitStrUSART0("REG[ ");
391        sendByteToHexUart(i);
392        transmitStrUSART0("]= ");
393        sendByteToHexUart(spiRead(i));
394        transmitStrUSART0("\r\n");
395    }
396}
397#endif
398int main(void)
399{
400    initSPI(); // initialize SPI
401    initUSART0(4800); // initialize USART0
402
403    //POWER ON DELAY for RFM22B
404    _delay_ms(1000);
405          
406#if DEBUG==1
407    rfm22bReadAllRegisters();
408#endif
409 
410#if DEMO_TX==1
411    rfm22bInit();
412    //*** TRANSMIT ***//
413    unsigned char count=0;
414    while(1)
415    {
416        rfm22bSendByte(count++);
417        _delay_ms(1000);
418    }
419#elif DEMO_RX==1
420    rfm22bInit();
421    //*** RECEIVE ***//
422    rfm22bSetRxMode();
423    
424    while(1)
425    {
426        while(RF_PIN & (1<<RF_IRQ)); // wait for interruption
427        
428#if DEBUG==1
429        transmitStrUSART0("RFM22B Clearing IRQ\r\n");
430
431        transmitStrUSART0(" Register 0x03:");
432        sendByteToHexUart(spiRead(0x03));
433
434        transmitStrUSART0(" Register 0x04:");
435        sendByteToHexUart(spiRead(0x04));
436        
437        transmitStrUSART0("\r\n");
438#else
439        spiRead(0x03);
440        spiRead(0x04);
441#endif
442        
443        transmitStrUSART0("RFM22B Receiving Data: ");
444        sendByteToHexUart(spiRead(0x7f));
445        
446        transmitStrUSART0("\r\n");
447        
448        _delay_ms(1000);
449        rfm22bSetRxMode(); // rx reset
450    }
451#endif
452    return 0;
453}
454

Archive Download this file

Branches:
master



interactive