mrf24j40.c File Reference

Include dependency graph for mrf24j40.c:

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

Function Documentation

void mrf24h40_pan_association_requested (  ) 

00242                                           {
00243     // allocate 16bit short address
00244         // fffe stuff in 7.5.3.1
00245     // generate association response command (see 7.3.2)
00246     // send it indirect, using 7.5.6.3 method
00247     //  add to pending transactions
00248 }

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 }

Here is the call graph for this function:

void mrf24j40_associate_to_pan (  ) 

00236                                  {
00237     // send associate to pan command
00238     // wait macResponseWaitTime
00239     
00240 }

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }   

Here is the call graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

uns8 mrf24j40_long_addr_read ( uns16  addr  ) 

Returns the value in the memory location specified.

Parameters:
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 }   

Here is the call graph for this function:

Here is the caller graph for this function:

void mrf24j40_long_addr_write ( uns16  addr,
uns8  data 
)

Sets the memory location to the value specified

Parameters:
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 }

Here is the call graph for this function:

Here is the caller graph for this function:

void mrf24j40_orphan_channel_scan (  ) 

00226                                     {
00227 }           

void mrf24j40_realign_pan (  ) 

00233                             {
00234 }

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

void mrf24j40_set_channel ( uns8  channel  ) 

Change to the specified channel, in the range MRF_FIRST_CHANNEL to MRF_LAST_CHANNEL.

Parameters:
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 }   

Here is the call graph for this function:

Here is the caller graph for this function:

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 }   

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

uns8 mrf24j40_short_addr_read ( uns8  addr  ) 

Returns the value in the memory location specified.

Parameters:
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 }   

Here is the call graph for this function:

Here is the caller graph for this function:

void mrf24j40_short_addr_write ( uns8  addr,
uns8  data 
)

Sets the memory location to the value specified

Parameters:
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 }   

Here is the call graph for this function:

Here is the caller graph for this function:

void mrf24j40_start_pan (  ) 

00229                           {
00230     
00231 }

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 }

Here is the call graph for this function:

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

Parameters:
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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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

Parameters:
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 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

uns8 current_channel = 0
uns8 extended_address[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
uns16 pan_id = 0xffff
uns16 short_address = 0xffff

Generated on Fri Aug 19 09:07:22 2011 for Pic Pack Library by  doxygen 1.6.1