Hardware Design: SIE
Sign in or create your account | Project List | Help
Hardware Design: SIE Git Source Tree
Root/
| 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 | |
| 37 | void 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 | |
| 44 | unsigned char receive1byteUSART0(void) |
| 45 | { |
| 46 | loop_until_bit_is_set(UCSR0A, RXC0); |
| 47 | return UDR0; |
| 48 | } |
| 49 | |
| 50 | void transmit1byteUSART0(unsigned char data) |
| 51 | { |
| 52 | loop_until_bit_is_set(UCSR0A, UDRE0); |
| 53 | UDR0 = data; |
| 54 | } |
| 55 | |
| 56 | void transmitStrUSART0(char *str) |
| 57 | { |
| 58 | while (*str != 0) { |
| 59 | transmit1byteUSART0(*str); |
| 60 | *str++; |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | void 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 | |
| 81 | unsigned 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 | |
| 94 | void 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 | |
| 105 | unsigned 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 | |
| 119 | unsigned 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 | |
| 143 | void 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 | |
| 247 | void 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 | |
| 267 | void 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 | |
| 289 | void 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 |
| 340 | void 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 | |
| 364 | void 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 |
| 383 | void 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 |
| 398 | int 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 |
Branches:
master
