Functions | |
void | mrf24h40_pan_association_requested () |
void | mrf24j40_active_channel_scan () |
void | mrf24j40_associate_to_pan () |
void | mrf24j40_flush_receive_buffer () |
Flush receive buffer of mrf24j40. | |
void | mrf24j40_handle_isr () |
Interrupt service routine for mrf24j40 chip. | |
void | mrf24j40_init () |
Initialises mrf24j40 chip ready for use. | |
void | mrf24j40_init_coordinator () |
uns8 | mrf24j40_long_addr_read (uns16 addr) |
Read data from long address of memory location in mrf24j40. | |
void | mrf24j40_long_addr_write (uns16 addr, uns8 data) |
Write data to long address memory location. | |
void | mrf24j40_orphan_channel_scan () |
void | mrf24j40_realign_pan () |
uns8 | mrf24j40_receive (uns8 *data, uns8 bytes_to_receive) |
Pull received data from buffer. | |
uns8 | mrf24j40_scan_for_lowest_channel_ed () |
Scan all channels for lowest RF energy. | |
void | mrf24j40_set_channel (uns8 channel) |
Change channels. | |
void | mrf24j40_set_extended_address (uns8 *_extended_address) |
Set extended address. | |
void | mrf24j40_set_pan_id (uns16 _pan_id) |
Set PAN id. | |
void | mrf24j40_set_short_address (uns16 _short_address) |
Set short address. | |
void | mrf24j40_setup_io () |
Setup ports/pins as inputs/outputs ready for use. | |
uns8 | mrf24j40_short_addr_read (uns8 addr) |
Read data from short address of memory location in mrf24j40. | |
void | mrf24j40_short_addr_write (uns8 addr, uns8 data) |
Write data to short address memory location. | |
void | mrf24j40_start_pan () |
void | mrf24j40_transmit (uns8 *data, uns8 bytes_to_transmit) |
Transmit raw data. | |
void | mrf24j40_transmit_to_extended_address (uns8 frame_type, uns16 dest_pan_id, uns8 *dest_extended_address, uns8 *data, uns8 data_length, uns8 ack) |
Transmit packet to extended address. | |
void | mrf24j40_transmit_to_short_address (uns8 frame_type, uns16 dest_pan_id, uns16 dest_short_address, uns8 *data, uns8 bytes_to_transmit, uns8 ack) |
Transmit packet to short address. | |
Variables | |
uns8 | current_channel = 0 |
uns8 | data_sequence_number |
uns8 | extended_address [8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} |
uns16 | pan_id = 0xffff |
uns16 | short_address = 0xffff |
void mrf24h40_pan_association_requested | ( | ) |
void mrf24j40_active_channel_scan | ( | ) |
00134 { 00135 00136 uns8 rxflush; 00137 uns16 prev_pan_id; 00138 uns8 channel; 00139 uns8 highest_on_channel; 00140 uns16 scan_count; 00141 uns8 bbreg6; 00142 uns8 rssi; 00143 00144 // receive only beacon frames 00145 00146 rxflush = mrf24j40_short_addr_read(RXFLUSH); 00147 set_bit(rxflush, RXFLUSH_BCNONLY); 00148 mrf24j40_short_addr_write(RXFLUSH, rxflush); 00149 00150 00151 // ignore pending data 00152 00153 00154 // store pan id 00155 prev_pan_id = pan_id; 00156 00157 // set pan id to ffff 00158 mrf24j40_set_pan_id(0xffff); 00159 00160 for (channel = MRF_FIRST_CHANNEL; channel <= MRF_LAST_CHANNEL; channel++) { 00161 serial_print_str("Searching on channel: "); 00162 serial_print_int(channel); 00163 serial_print_nl(); 00164 00165 // switch channel 00166 mrf24j40_set_channel(channel); 00167 00168 // send beacon request 00169 uns8 fc_msb = 0b11001100; // 64 bit dest (10,11) 64 bit src (14,15) 00170 // 0b00000011; 00171 uns8 fc_lsb = 0b00000001; // data, no pan id compression 00172 00173 data_sequence_number++; 00174 uns8 bytes_to_transmit = 5;//?? 00175 uns8 header_length = 3+8+8+2+2; // Just two bytes of frame control + sequence number 00176 uns8 frame_length = header_length + bytes_to_transmit; 00177 00178 // TxBuffer[0] = 0x03; // fc lsb 00179 // TxBuffer[1] = 0x08; // fc msb 00180 // TxBuffer[2] = IEEESeqNum++; //sequence number 00181 // TxBuffer[3] = 0xFF; 00182 // TxBuffer[4] = 0xFF; 00183 // TxBuffer[5] = 0xFF; 00184 // TxBuffer[6] = 0xFF; 00185 // TxBuffer[7] = 0x07; 00186 00187 mrf24j40_long_addr_write(0x00, header_length); 00188 mrf24j40_long_addr_write(0x01, frame_length); 00189 mrf24j40_long_addr_write(0x02, fc_lsb); // swapped 00190 mrf24j40_long_addr_write(0x03, fc_msb); 00191 mrf24j40_long_addr_write(0x04, data_sequence_number); 00192 00193 mrf24j40_long_addr_write(0x05, 0x05); // dest pan id LSB 00194 mrf24j40_long_addr_write(0x06, 0x00); // MSB 00195 00196 00197 // wait [aBaseSuperframeDuration * (2^n + 1)] symbols, n=scanduration parameter 00198 // store info on pan in pan description structure 00199 // beacon is unique if pan id and source address haven't been seen before on current channel 00200 00201 highest_on_channel = 0; 00202 for (scan_count = 0; scan_count < 1000; scan_count++) { 00203 mrf24j40_short_addr_write(BBREG6, 1 << BBREG6_RSSIMODE1); 00204 do { 00205 bbreg6 = mrf24j40_short_addr_read(BBREG6); 00206 } while (!test_bit(bbreg6, BBREG6_RSSIRDY)); 00207 rssi = mrf24j40_long_addr_read(RSSI); 00208 if (rssi > highest_on_channel) { 00209 highest_on_channel = rssi; 00210 } 00211 } 00212 serial_print_str("Highest on channel = "); 00213 serial_print_int(highest_on_channel); 00214 serial_print_nl(); 00215 00216 00217 00218 } 00219 // restore pan id 00220 // switch channel 00221 //.. receive all frames 00222 serial_print_str("/-----\n"); 00223 00224 }
void mrf24j40_associate_to_pan | ( | ) |
void mrf24j40_flush_receive_buffer | ( | ) |
No need to call this routine normally, except according to mrf24j40 errata (promiscuous mode)
00052 { 00053 00054 uns8 rxflush; 00055 00056 rxflush = mrf24j40_short_addr_read(RXFLUSH); // Get rxflush 00057 set_bit(rxflush, RXFLUSH_RXFLUSH); // Set flush bit 00058 mrf24j40_short_addr_write(RXFLUSH, rxflush); // Push it back to the mrf 00059 }
void mrf24j40_handle_isr | ( | ) |
Call this routine when the mrf24j40 indicates an interrupt condition, or called regularly.
00287 { 00288 00289 uns8 intstat; 00290 00291 // first we need to get a copy of intstat to find out what happened 00292 intstat = mrf24j40_short_addr_read(INTSTAT); 00293 00294 // mrf24j40 intstat register is cleared on read 00295 if (test_bit(intstat, INTSTAT_RXIF)) { 00296 serial_print_str("R"); 00297 // handle receive 00298 mrf24j40_receive_callback(); 00299 } 00300 if (test_bit(intstat, INTSTAT_TXNIF)) { 00301 serial_print_str("Tx complete txstat=0x"); 00302 uns8 stat = mrf24j40_short_addr_read(TXSTAT); 00303 mrf24j40_transmit_callback(stat & 0b00000001, // success = 0 00304 stat >> 6, // retries 00305 test_bit(stat, TXSTAT_CCAFAIL)); // due to cca failure? 00306 serial_print_int_hex(stat); 00307 serial_print_nl(); 00308 } 00309 00310 }
void mrf24j40_init | ( | ) |
Sets int pin as input and cs pin as output.
00499 { 00500 00501 uns8 check; 00502 00503 // Example steps to initialize the MRF24J40: 00504 00505 // 1. SOFTRST (0x2A) = 0x07 – Perform a software Reset. The bits will be automatically cleared to ‘0’ by hardware. 00506 mrf24j40_short_addr_write(SOFTRST, 0x07); 00507 00508 // Wait for soft reset to complete 00509 00510 do { 00511 check = mrf24j40_short_addr_read(SOFTRST); 00512 } while (check != 0); 00513 00514 #if defined(ENABLE_PA_LNA) && defined(MRF24J40MB) 00515 // Turn on PA/LNA if we have one 00516 mrf24j40_long_addr_write(TESTMODE, 0x0f); 00517 #endif 00518 00519 // 2. PACON2 (0x18) = 0x98 – Initialize FIFOEN = 1 and TXONTS = 0x6. 00520 mrf24j40_short_addr_write(PACON2, 0x98); 00521 // 3. TXSTBL (0x2E) = 0x95 – Initialize RFSTBL = 0x9. 00522 mrf24j40_short_addr_write(TXSTBL, 0x95); 00523 00524 // wait for mrf to be in receive mode 00525 00526 do { 00527 check = mrf24j40_long_addr_read(RFSTATE); 00528 } while (check & 0xa0 != 0xa0); 00529 00530 mrf24j40_long_addr_write(RFCON0, 0x03); // or three? 00531 // mrf24j40_long_addr_write(RFCON1, 0x02); // VCO control mode (1 or 2?) 00532 // miwi stack source is at odds with data sheet here 00533 00534 // 4. RFCON1 (0x201) = 0x01 – Initialize VCOOPT = 0x01. 00535 mrf24j40_long_addr_write(RFCON1, 0x01); 00536 // 5. RFCON2 (0x202) = 0x80 – Enable PLL (PLLEN = 1). 00537 mrf24j40_long_addr_write(RFCON2, 0x80); 00538 // 6. RFCON6 (0x206) = 0x90 – Initialize TXFIL = 1 and 20MRECVR = 1. 00539 mrf24j40_long_addr_write(RFCON6, 0x90); 00540 // 7. RFCON7 (0x207) = 0x80 – Initialize SLPCLKSEL = 0x2 (100 kHz Internal oscillator). 00541 mrf24j40_long_addr_write(RFCON7, 0x08); 00542 // 8. RFCON8 (0x208) = 0x10 – Initialize RFVCO = 1. 00543 mrf24j40_long_addr_write(RFCON8, 0x10); 00544 // 9. SLPCON1 (0x220) = 0x21 – Initialize CLKOUTEN = 1 and SLPCLKDIV = 0x01. 00545 mrf24j40_long_addr_write(SLPCON1, 0x21); 00546 00547 //Configuration for nonbeacon-enabled devices 00548 //(see Section MRF datasheet 3.8 “Beacon-Enabled and Nonbeacon-Enabled Networks”): 00549 //10. BBREG2 (0x3A) = 0x80 – Set CCA mode to ED. 00550 mrf24j40_short_addr_write(BBREG2, 0x80); 00551 // 11. RSSITHCCA (0x3F) = 0x60 – Set CCA ED threshold. 00552 // IH: I think the datasheet is wrong, the mem address is "CCAEDTH", even though 00553 // it's referred to as RSSITHCCA and CCAMODE in the documentation... 00554 00555 mrf24j40_short_addr_write(CCAEDTH, 0x60); 00556 // 12. BBREG6 (0x3E) = 0x40 – Set appended RSSI value to RXFIFO. 00557 mrf24j40_short_addr_write(BBREG6, 1 << BBREG6_RSSIMODE2); 00558 // 13. Enable interrupts – See Section 3.3 “Interrupts”. 00559 mrf24j40_short_addr_write(MRF_INTCON, (1 << MRF_INTCON_RXIE) & (1 << MRF_INTCON_TXNIE)); 00560 // 14. Set channel – See Section 3.4 “Channel Selection”. 00561 mrf24j40_long_addr_write(RFCON0, 11); 00562 00563 #if defined(ENABLE_PA_LNA) && defined(MRF24J40MB) 00564 // There are special MRF24J40 transceiver output power 00565 // setting for Microchip MRF24J40MB module. 00566 // To do: Correct settings for other locations 00567 00568 #if APPLICATION_SITE == EUROPE 00569 // MRF24J40 output power set to be -14.9dB 00570 mrf24j40_long_addr_write(RFCON3, 0x70); 00571 #else 00572 // MRF24J40 output power set to be -1.9dB - Stock setting 00573 // mrf24j40_long_addr_writeRFCON3, 0x18); 00574 00575 // MRF24J40 output power set to be -1.2dB 00576 // mrf24j40_long_addr_write(RFCON3, 0x10); 00577 00578 // MRF24J40 output power set to be -0.5dB 00579 // mrf24j40_long_addr_write(RFCON3, 0x08); 00580 00581 // MRF24J40 output power set to be -0dB -> 22,5 dBm output power 00582 mrf24j40_long_addr_write(RFCON3, 0x00); 00583 #endif 00584 #else 00585 // power level to be 0dBms 00586 mrf24j40_long_addr_write(RFCON3,0x00); 00587 #endif 00588 00589 // 15. RFCTL (0x36) = 0x04 – Reset RF state machine. 00590 mrf24j40_short_addr_write(RFCTL, 0x04); 00591 00592 // 16. RFCTL (0x36) = 0x00. 00593 mrf24j40_short_addr_write(RFCTL, 0x00); 00594 // 17. Delay at least 192 ìs. 00595 delay_us(200); 00596 00597 // RXMCR.PANCOORD = 1 if coordinator, 0 is default (not coordinator) 00598 00599 //mrf24j40_short_addr_write(RXMCR, 0x01); // promiscuous mode, no coord 00600 00601 data_sequence_number = 0; 00602 00603 }
void mrf24j40_init_coordinator | ( | ) |
00606 { 00607 uns8 val; 00608 00609 // Example steps to initialize the MRF24J40: 00610 00611 // 1. SOFTRST (0x2A) = 0x07 – Perform a software Reset. The bits will be automatically cleared to ‘0’ by hardware. 00612 mrf24j40_short_addr_write(SOFTRST, 0x07); 00613 // 2. PACON2 (0x18) = 0x98 – Initialize FIFOEN = 1 and TXONTS = 0x6. 00614 mrf24j40_short_addr_write(PACON2, 0x98); 00615 // 3. TXSTBL (0x2E) = 0x95 – Initialize RFSTBL = 0x9. 00616 mrf24j40_short_addr_write(TXSTBL, 0x95); 00617 // 4. RFCON1 (0x201) = 0x01 – Initialize VCOOPT = 0x01. 00618 mrf24j40_long_addr_write(RFCON1, 0x01); 00619 // 5. RFCON2 (0x202) = 0x80 – Enable PLL (PLLEN = 1). 00620 mrf24j40_long_addr_write(RFCON2, 0x008); 00621 // 6. RFCON6 (0x206) = 0x90 – Initialize TXFIL = 1 and 20MRECVR = 1. 00622 mrf24j40_long_addr_write(RFCON6, 0x90); 00623 // 7. RFCON7 (0x207) = 0x80 – Initialize SLPCLKSEL = 0x2 (100 kHz Internal oscillator). 00624 mrf24j40_long_addr_write(RFCON7, 0x08); 00625 // 8. RFCON8 (0x208) = 0x10 – Initialize RFVCO = 1. 00626 mrf24j40_long_addr_write(RFCON8, 0x10); 00627 // 9. SLPCON1 (0x220) = 0x21 – Initialize CLKOUTEN = 1 and SLPCLKDIV = 0x01. 00628 mrf24j40_long_addr_write(SLPCON1, 0x21); 00629 00630 //Configuration for nonbeacon-enabled devices 00631 //(see Section MRF datasheet 3.8 “Beacon-Enabled and Nonbeacon-Enabled Networks”): 00632 //10. BBREG2 (0x3A) = 0x80 – Set CCA mode to ED. 00633 mrf24j40_short_addr_write(BBREG2, 0x80); 00634 // 11. RSSITHCCA (0x3F) = 0x60 – Set CCA ED threshold. 00635 // IH: I think the datasheet is wrong, the mem address is "CCAEDTH", even though 00636 // it's referred to as RSSITHCCA and CCAMODE in the documentation... 00637 mrf24j40_short_addr_write(CCAEDTH, 0x60); 00638 // 12. BBREG6 (0x3E) = 0x40 – Set appended RSSI value to RXFIFO. 00639 mrf24j40_short_addr_write(BBREG6, 0x40); 00640 // 13. Enable interrupts – See Section 3.3 “Interrupts”. 00641 mrf24j40_short_addr_write(MRF_INTCON, (1 << MRF_INTCON_RXIE) & (1 << MRF_INTCON_TXNIE)); 00642 // 14. Set channel – See Section 3.4 “Channel Selection”. 00643 mrf24j40_long_addr_write(RFCON0, 11); 00644 // 15. RFCTL (0x36) = 0x04 – Reset RF state machine. 00645 mrf24j40_short_addr_write(RFCTL, 0x04); 00646 00647 // 16. RFCTL (0x36) = 0x00. 00648 mrf24j40_short_addr_write(RFCTL, 0x00); 00649 // 17. Delay at least 192 ìs. 00650 delay_us(200); 00651 00652 // RXMCR.PANCOORD = 1 if coordinator, 0 is default (not coordinator) 00653 // TXMCR.SLOTTED = 1 for slotted CSMA-CA mode, 0 is default (unslotted CSMA_CA mode) 00654 00655 //mrf24j40_short_addr_write(RXMCR, 0x01); // promiscuous mode, no coord 00656 00657 //Set the PANCOORD (RXMCR 0x00<3>) bit = 1 to configure as PAN coordinator. 00658 val = mrf24j40_short_addr_read(RXMCR); 00659 set_bit(val, RXMCR_PANCOORD); 00660 mrf24j40_short_addr_write(RXMCR, val); 00661 00662 //2. Set the SLOTTED (TXMCR 0x11<5>) bit = 1 to use Slotted CSMA-CA mode. 00663 // turn on slotted 00664 val = mrf24j40_short_addr_read(TXMCR); 00665 set_bit(val, TXMCR_SLOTTED); 00666 mrf24j40_short_addr_write(TXMCR, val); 00667 00668 // 3. Load the beacon frame into the TXBFIFO (0x080-0x0FF). 00669 uns8 header_length = 2+1+10; 00670 uns8 frame_length = header_length + 6; 00671 uns8 superframe_spec_field_l = 0b10001000; // bo = 8, so = 8 00672 uns8 superframe_spec_field_h = 0b11001000; // AP/PC/R/BLE/final cap slot 00673 00674 mrf24j40_long_addr_write(0x080+0, header_length); 00675 mrf24j40_long_addr_write(0x080+1, frame_length); 00676 mrf24j40_long_addr_write(0x080+2, 0x00); //frame control - beacon 00677 mrf24j40_long_addr_write(0x080+3, 0x80); //addressing mode - source only 00678 mrf24j40_long_addr_write(0x080+4, data_sequence_number++); //seq number 00679 mrf24j40_long_addr_write(0x080+5, 5); //PANID LSB 00680 mrf24j40_long_addr_write(0x080+6, 0); //PANID MSB 00681 mrf24j40_long_addr_write(0x080+7, extended_address[7]); // LSB 00682 mrf24j40_long_addr_write(0x080+8, extended_address[6]); 00683 mrf24j40_long_addr_write(0x080+9, extended_address[5]); 00684 mrf24j40_long_addr_write(0x080+10, extended_address[4]); 00685 mrf24j40_long_addr_write(0x080+11, extended_address[3]); 00686 mrf24j40_long_addr_write(0x080+12, extended_address[2]); 00687 mrf24j40_long_addr_write(0x080+13, extended_address[1]); 00688 mrf24j40_long_addr_write(0x080+14, extended_address[0]); // MSB 00689 00690 mrf24j40_long_addr_write(0x080+15, superframe_spec_field_l); 00691 mrf24j40_long_addr_write(0x080+16, superframe_spec_field_h); 00692 00693 mrf24j40_long_addr_write(0x080+17, 0); // GTS 00694 mrf24j40_long_addr_write(0x080+18, 0); // Pending addresses 00695 mrf24j40_long_addr_write(0x080+19, 0x4d); // Protocol ID 00696 mrf24j40_long_addr_write(0x080+20, 0x10); // version 00697 // no payload 00698 00699 00700 // 4. Set the TXBMSK (TXBCON1 0x25<7>) bit = 1 to mask the beacon interrupt mask. 00701 //val = mrf24j40_short_addr_read(TXBCON1); 00702 //set_bit(val, TXBCON1_TXBMSK); 00703 //mrf24j40_short_addr_write(RXMCR); 00704 00705 //5. Program the CAP end slot (ESLOTG1 0x13<3:0>) value. If the coordinator supports 00706 //Guaranteed Time Slot operation, refer to Section 3.8.1.5 “Configuring Beacon-Enabled 00707 //GTS Settings for PAN Coordinator” below. 00708 00709 //6. Calibrate the Sleep Clock (SLPCLK) frequency. Refer to Section 3.15.1.2 “Sleep Clock Calibration”. 00710 //7. Set WAKECNT (SLPACK 0x35<6:0>) value = 0x5F to set the main oscillator (20 MHz) 00711 //start-up timer value. 00712 //8. Program the Beacon Interval into the Main Counter, 00713 //MAINCNT (0x229<1:0>, 0x228, 0x227, 0x226), 00714 //and Remain Counter, REMCNT (0x225, 0x224), according to BO and SO values. Refer to 00715 //Section 3.15.1.3 “Sleep Mode Counters”. 00716 //9. Configure the BO (ORDER 0x10<7:4>) and SO (ORDER 0x10<3:0>) values. After configuring 00717 //BO and SO, the beacon frame will be sent immediately. 00718 //BO3(1) BO2(1) BO1(1) BO0(1) SO3(1) SO2(1) SO1(1) SO0(1) 00719 //mrf24j40_short_addr_write(ORDER, 0b10001000); 00720 00721 data_sequence_number = 0; 00722 00723 }
uns8 mrf24j40_long_addr_read | ( | uns16 | addr | ) |
Returns the value in the memory location specified.
addr | Long address memory location (see mrf24h40_defines.h) |
00749 { 00750 00751 uns8 result; 00752 00753 clear_pin(mrf24j40_cs_port, mrf24j40_cs_pin); 00754 00755 addr = addr & 0b0000001111111111; // <9:0> bits 00756 addr = addr << 5; 00757 set_bit(addr, 15); // long addresss 00758 spi_hw_transmit(addr >> 8); 00759 spi_hw_transmit(addr & 0x00ff); 00760 result = spi_hw_receive(); 00761 00762 set_pin(mrf24j40_cs_port, mrf24j40_cs_pin); 00763 00764 return result; 00765 }
void mrf24j40_long_addr_write | ( | uns16 | addr, | |
uns8 | data | |||
) |
Sets the memory location to the value specified
addr | Long address memory location (see mrf24h40_defines.h) | |
data | Value that the memory location should be set to |
00767 { 00768 00769 clear_pin(mrf24j40_cs_port, mrf24j40_cs_pin); 00770 00771 addr = addr & 0b0000001111111111; // <9:0> bits 00772 addr = addr << 5; 00773 00774 set_bit(addr, 15); // long addresss 00775 set_bit(addr, 4); // set for write 00776 00777 spi_hw_transmit(addr >> 8 ); 00778 spi_hw_transmit(addr & 0x00ff); 00779 spi_hw_transmit(data); 00780 00781 set_pin(mrf24j40_cs_port, mrf24j40_cs_pin); 00782 }
uns8 mrf24j40_receive | ( | uns8 * | data, | |
uns8 | bytes_to_receive | |||
) |
Once an interrupt has occured and we know it is because a packet has been received, this routine will pull the data from the mrf receive buffer. This needs to be done quickly so that the next packet is not lost.
00312 { 00313 00314 uns8 frame_length; 00315 uns16 frame_pos; 00316 uns8 buffer_count; 00317 /* 00318 1. Receive RXIF interrupt. 00319 2. Disable host microcontroller interrupts. 00320 3. Set RXDECINV = 1; disable receiving packets off air. 00321 4. Read address, 0x300; get RXFIFO frame length value. 00322 5. Read RXFIFO addresses, 0x301 through (0x300 + Frame Length + 2); read packet data plus LQI and RSSI. 00323 6. Clear RXDECINV = 0; enable receiving packets. 00324 7. Enable host microcontroller interrupts. 00325 */ 00326 serial_putc('a'); 00327 // Disable reading packets off air 00328 mrf24j40_short_addr_write(BBREG1, 1 << BBREG1_RXDECINV); 00329 serial_putc('b'); 00330 00331 frame_pos = 0x300; 00332 frame_length = mrf24j40_long_addr_read(frame_pos++); 00333 buffer_count = 0; 00334 serial_putc('c'); 00335 00336 while ((buffer_count <= bytes_to_receive) && (buffer_count <= frame_length + 2)) { 00337 //0x301 through (0x300 + Frame Length + 2 ); read packet data plus LQI and RSSI. 00338 data[buffer_count++] = mrf24j40_long_addr_read(frame_pos++); 00339 } 00340 serial_putc('d'); 00341 00342 // Re-enable reading packets off air 00343 mrf24j40_short_addr_write(BBREG1, 0); 00344 serial_putc('e'); 00345 00346 return buffer_count - 1; 00347 00348 }
uns8 mrf24j40_scan_for_lowest_channel_ed | ( | ) |
Scans through all channels and reports the channel with the lowest Energy Detection level.
00077 { 00078 00079 uns8 rssi; 00080 uns8 channel; 00081 uns16 scan_count; 00082 uns8 highest_on_channel; 00083 uns8 lowest_channel = MRF_LAST_CHANNEL; 00084 uns8 lowest_ed = 0xff; 00085 uns8 bbreg6; 00086 00087 // We should really ignore all packets here (do to) 00088 00089 #if defined(ENABLE_PA_LNA) 00090 mrf24j40_long_addr_write(TESTMODE, 0x08); // Disable automatic switch on PA/LNA 00091 mrf24j40_short_addr_write(TRISGPIO, 0x0F); // Set GPIO direction 00092 mrf24j40_short_addr_write(GPIO, 0x0C); // Enable LNA 00093 #endif 00094 00095 00096 for (channel = MRF_FIRST_CHANNEL; channel <= MRF_LAST_CHANNEL; channel++) { 00097 00098 // switch channel 00099 mrf24j40_set_channel(channel); 00100 00101 highest_on_channel = 0; 00102 for (scan_count = 0; scan_count < 1000; scan_count++) { 00103 mrf24j40_short_addr_write(BBREG6, 1 << BBREG6_RSSIMODE1); 00104 do { 00105 bbreg6 = mrf24j40_short_addr_read(BBREG6); 00106 } while (!test_bit(bbreg6, BBREG6_RSSIRDY)); 00107 rssi = mrf24j40_long_addr_read(RSSI); 00108 if (rssi > highest_on_channel) { 00109 highest_on_channel = rssi; 00110 } 00111 } 00112 00113 if (highest_on_channel < lowest_ed) { 00114 lowest_ed = highest_on_channel; 00115 lowest_channel = channel; 00116 } 00117 } 00118 mrf24j40_short_addr_write(BBREG6, 1 << BBREG6_RSSIMODE2); // Back to mode 2 (rssi in pkt) 00119 00120 // Should stop ignoring all packets now if we started ignoring them earlier 00121 // (to do) 00122 00123 #if defined(ENABLE_PA_LNA) 00124 mrf24j40_short_addr_write(GPIO, 0); 00125 mrf24j40_short_addr_write(TRISGPIO, 0x00); 00126 mrf24j40_long_addr_write(TESTMODE, 0x0F); 00127 #endif 00128 00129 00130 return lowest_channel; 00131 }
void mrf24j40_set_channel | ( | uns8 | channel | ) |
Change to the specified channel, in the range MRF_FIRST_CHANNEL to MRF_LAST_CHANNEL.
channel | Channel to change to. |
00063 { 00064 00065 current_channel = channel; 00066 channel = channel - 11; 00067 channel = 0x02 + 0x10 * channel; 00068 00069 mrf24j40_long_addr_write(RFCON0, channel); // Set channel 00070 mrf24j40_short_addr_write(RFCTL, 0x04); // RFCTL (0x36) = 0x04 – Reset RF state machine. 00071 mrf24j40_short_addr_write(RFCTL, 0x00); // RFCTL (0x36) = 0x00 00072 00073 delay_us(200); // Delay at least 192us 00074 }
void mrf24j40_set_extended_address | ( | uns8 * | _extended_address | ) |
Set IEEE 802.15.4 extended address.
Sets the 64 bit extended address of the module. Pass a pointer to an 8 byte uns8 array containing the address.
00259 { 00260 uns8 count; 00261 uns8 mem_pos = EADR7; 00262 serial_print_str("Setting EA to: "); 00263 for (count = 0; count < 8; count++) { 00264 extended_address[count] = _extended_address[count]; 00265 mrf24j40_short_addr_write(mem_pos--, extended_address[count]); 00266 serial_print_int_hex(extended_address[count]); 00267 serial_putc(' '); 00268 00269 } 00270 serial_print_nl(); 00271 }
void mrf24j40_set_pan_id | ( | uns16 | _pan_id | ) |
Sets the 16 bit PAN id of the module.
00252 { 00253 pan_id = _pan_id; 00254 mrf24j40_short_addr_write(PANIDL, pan_id & 0xff); 00255 mrf24j40_short_addr_write(PANIDH, pan_id >> 8); 00256 00257 }
void mrf24j40_set_short_address | ( | uns16 | _short_address | ) |
Sets the 16 bit short address of the module.
00273 { 00274 00275 // Keep hold of the short address 00276 short_address = _short_address; 00277 00278 // Tell the mrf about it 00279 mrf24j40_short_addr_write(SADRL, short_address & 0xff); 00280 mrf24j40_short_addr_write(SADRH, short_address >> 8); 00281 00282 }
void mrf24j40_setup_io | ( | ) |
Sets int pin as input and cs pin as output.
00785 { 00786 00787 make_input(mrf24j40_int_port, mrf24j40_int_pin); 00788 set_pin(mrf24j40_cs_port, mrf24j40_cs_pin); // keep high 00789 make_output(mrf24j40_cs_port, mrf24j40_cs_pin); 00790 00791 }
uns8 mrf24j40_short_addr_read | ( | uns8 | addr | ) |
Returns the value in the memory location specified.
addr | Short address memory location (see mrf24h40_defines.h) |
00725 { 00726 00727 clear_pin(mrf24j40_cs_port, mrf24j40_cs_pin); 00728 addr = addr & 0b00111111; // <5:0> bits 00729 addr = addr << 1; // LSB = 0, means read 00730 spi_hw_transmit(addr); 00731 uns8 result = spi_hw_receive(); 00732 00733 set_pin(mrf24j40_cs_port, mrf24j40_cs_pin); 00734 return result; 00735 }
void mrf24j40_short_addr_write | ( | uns8 | addr, | |
uns8 | data | |||
) |
Sets the memory location to the value specified
addr | Short address memory location (see mrf24h40_defines.h) | |
data | Value that the memory location should be set to |
00737 { 00738 clear_pin(mrf24j40_cs_port, mrf24j40_cs_pin); 00739 addr = addr & 0b00111111; // <5:0> bits 00740 addr = addr << 1; // LSB = 0, means read 00741 set_bit(addr, 0); // write 00742 00743 spi_hw_transmit(addr); 00744 spi_hw_transmit(data); 00745 00746 set_pin(mrf24j40_cs_port, mrf24j40_cs_pin); 00747 }
void mrf24j40_transmit | ( | uns8 * | data, | |
uns8 | bytes_to_transmit | |||
) |
Transmit a raw packet - this assumes you have already created an 802.15.4 compatible packet. Normally you would use transmit_to_extended_adddress or transmit_to_short_address instead.
00470 { 00471 00472 00473 uns8 fc_lsb = 0b01000001; 00474 uns8 fc_msb = 0b00000000; 00475 00476 00477 data_sequence_number++; 00478 uns8 header_length = 3; // Just two bytes of frame control + sequence number, no addrs 00479 uns8 frame_length = header_length + bytes_to_transmit; 00480 00481 mrf24j40_long_addr_write(0x00, header_length); 00482 mrf24j40_long_addr_write(0x01, frame_length); 00483 mrf24j40_long_addr_write(0x02, fc_lsb); 00484 mrf24j40_long_addr_write(0x03, fc_msb); 00485 mrf24j40_long_addr_write(0x04, data_sequence_number); 00486 00487 for (uns8 count=0; count < bytes_to_transmit; count++) { // check format here 00488 mrf24j40_long_addr_write(count+header_length+2, data[count]); 00489 } 00490 00491 uns8 txncon = mrf24j40_short_addr_read(TXNCON); 00492 set_bit(txncon, TXNCON_TXNTRIG); 00493 mrf24j40_short_addr_write(TXNCON, txncon); 00494 00495 00496 }
void mrf24j40_transmit_to_extended_address | ( | uns8 | frame_type, | |
uns16 | dest_pan_id, | |||
uns8 * | dest_extended_address, | |||
uns8 * | data, | |||
uns8 | data_length, | |||
uns8 | ack | |||
) |
Requests that the mrf24j40 transmit the packet to the specified extended address
frame_type | 802.15.4 frame type | |
dest_pan_id | PAN id of destination | |
dest_extended_address | Pointer to uns8 array indicating extended address of destination | |
data | Pointer to uns8 array of bytes to transmit | |
bytes_to_transmit | ||
ack | Either MRF_ACK or MRF_NO_ACK depending if you want hardware acknowledgement |
00351 { 00352 00353 // See notes below on frame control bytes format: 00354 uns8 fc_msb = 0b11001100; // 64 bit dest (10,11) 64 bit src (14,15) 00355 uns8 fc_lsb = 0b00000000 | frame_type; // pan id compression=0, data 00356 00357 if (ack) { 00358 set_bit(fc_lsb, 5); // ack bit 00359 } 00360 00361 data_sequence_number++; 00362 00363 uns8 header_length = 3+8+8+2+2; 00364 uns8 frame_length = header_length + data_length; 00365 00366 // Write out data to mrf 00367 00368 mrf24j40_long_addr_write(0x00, header_length); 00369 mrf24j40_long_addr_write(0x01, frame_length); 00370 00371 mrf24j40_long_addr_write(0x02, fc_lsb); 00372 mrf24j40_long_addr_write(0x03, fc_msb); 00373 mrf24j40_long_addr_write(0x04, data_sequence_number); 00374 00375 mrf24j40_long_addr_write(0x05, dest_pan_id & 0xff); // dest pan id LSB 00376 mrf24j40_long_addr_write(0x06, dest_pan_id >> 8); // MSB 00377 00378 mrf24j40_long_addr_write(0x07, dest_extended_address[7]); // LSB 00379 mrf24j40_long_addr_write(0x08, dest_extended_address[6]); 00380 mrf24j40_long_addr_write(0x09, dest_extended_address[5]); 00381 mrf24j40_long_addr_write(0x0a, dest_extended_address[4]); 00382 mrf24j40_long_addr_write(0x0b, dest_extended_address[3]); 00383 mrf24j40_long_addr_write(0x0c, dest_extended_address[2]); 00384 mrf24j40_long_addr_write(0x0d, dest_extended_address[1]); 00385 mrf24j40_long_addr_write(0x0e, dest_extended_address[0]); // MSB 00386 00387 mrf24j40_long_addr_write(0x0f, pan_id & 0xff); // src pan id LSB 00388 mrf24j40_long_addr_write(0x10, pan_id >> 8); // MSB 00389 00390 00391 mrf24j40_long_addr_write(0x11, extended_address[7]); // LSB 00392 mrf24j40_long_addr_write(0x12, extended_address[6]); 00393 mrf24j40_long_addr_write(0x13, extended_address[5]); 00394 mrf24j40_long_addr_write(0x14, extended_address[4]); 00395 mrf24j40_long_addr_write(0x15, extended_address[3]); 00396 mrf24j40_long_addr_write(0x16, extended_address[2]); 00397 mrf24j40_long_addr_write(0x17, extended_address[1]); 00398 mrf24j40_long_addr_write(0x18, extended_address[0]); // MSB 00399 00400 for (uns8 count=0; count < data_length; count++) { 00401 mrf24j40_long_addr_write(count+header_length+2, data[count]); 00402 } 00403 00404 uns8 txncon = mrf24j40_short_addr_read(TXNCON); 00405 00406 set_bit(txncon, TXNCON_TXNTRIG); 00407 if (ack) { 00408 set_bit(txncon, TXNCON_TXNACKREQ); 00409 } 00410 mrf24j40_short_addr_write(TXNCON, txncon); 00411 00412 00413 }
void mrf24j40_transmit_to_short_address | ( | uns8 | frame_type, | |
uns16 | dest_pan_id, | |||
uns16 | dest_short_address, | |||
uns8 * | data, | |||
uns8 | bytes_to_transmit, | |||
uns8 | ack | |||
) |
Requests that the mrf24j40 transmit the packet to the specified short address
frame_type | 802.15.4 frame type | |
dest_pan_id | PAN id of destination | |
dest_short_address | 16 bit short address of destination | |
data | Pointer to uns8 array of bytes to transmit | |
bytes_to_transmit | ||
ack | Either MRF_ACK or MRF_NO_ACK depending if you want hardware acknowledgement |
00416 { 00417 00418 uns8 fc_msb = 0b10001000; // short dest (10,11) short src (14,15) 00419 uns8 fc_lsb = 0b00000000 | frame_type; // data, pan id compression (only have dest pan id) 00420 // To do: 00421 // Not smart enough for this yet: 00422 //if (dest_pan_id == pan_id) { 00423 // set_bit(fc_lsb, 6); // pan compression 00424 //} 00425 if (ack) { 00426 set_bit(fc_lsb, 5); // ack bit 00427 } 00428 00429 data_sequence_number++; 00430 00431 uns8 header_length = 3+2+2+2+2; 00432 uns8 frame_length = header_length + bytes_to_transmit; 00433 00434 mrf24j40_long_addr_write(0x00, header_length); 00435 mrf24j40_long_addr_write(0x01, frame_length); 00436 00437 mrf24j40_long_addr_write(0x02, fc_lsb); 00438 mrf24j40_long_addr_write(0x03, fc_msb); 00439 mrf24j40_long_addr_write(0x04, data_sequence_number); 00440 00441 mrf24j40_long_addr_write(0x05, dest_pan_id & 0xff); // dest pan id LSB 00442 mrf24j40_long_addr_write(0x06, dest_pan_id >> 8); // MSB 00443 00444 mrf24j40_long_addr_write(0x07, dest_short_address & 0xff); // LSB 00445 mrf24j40_long_addr_write(0x08, dest_short_address >> 8); // MSB 00446 00447 mrf24j40_long_addr_write(0x09, pan_id & 0xff); // src pan id (=ours) LSB 00448 mrf24j40_long_addr_write(0x0a, pan_id >> 8); // MSB 00449 00450 00451 mrf24j40_long_addr_write(0x0b, short_address & 0xff); // LSB 00452 mrf24j40_long_addr_write(0x0c, short_address >> 8); 00453 00454 for (uns8 count=0; count < bytes_to_transmit; count++) { // check format here 00455 mrf24j40_long_addr_write(count+header_length+2, data[count]); 00456 } 00457 00458 uns8 txncon = mrf24j40_short_addr_read(TXNCON); 00459 set_bit(txncon, TXNCON_TXNTRIG); 00460 if (ack) { 00461 set_bit(txncon, TXNCON_TXNACKREQ); 00462 } 00463 mrf24j40_short_addr_write(TXNCON, txncon); 00464 00465 00466 }
uns8 current_channel = 0 |
uns8 data_sequence_number |
uns8 extended_address[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} |
uns16 pan_id = 0xffff |
uns16 short_address = 0xffff |