Microchip mrf24j40 IEEE 802.15.4 module routines. More...
Go to the source code of this file.
Defines | |
#define | LOC_CANADA 0x02 |
#define | LOC_EUROPE 0x03 |
#define | LOC_UNDEFINED 0x00 |
#define | LOC_UNITED_STATES 0x01 |
#define | MRF_ACK 1 |
#define | MRF_FIRST_CHANNEL 11 |
#define | MRF_LAST_CHANNEL 26 |
#define | MRF_NO_ACK 0 |
Functions | |
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. | |
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. | |
uns8 | mrf24j40_receive (uns8 *data, uns8 bytes_to_receive) |
Pull received data from buffer. | |
void | mrf24j40_receive_callback () |
Callback is actioned when mrf24j40 has a packet received off air. | |
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 IEEE 802.15.4 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_transmit (uns8 *data, uns8 bytes_to_transmit) |
Transmit raw data. | |
void | mrf24j40_transmit_callback (uns8 status, uns8 retries, uns8 channel_busy) |
Callback is actioned when mrf24j40 has finished transmitting a packet, or failed to do so. | |
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. |
#define LOC_CANADA 0x02 |
Module located in Canada (?? power)
#define LOC_EUROPE 0x03 |
Module located in Europe (-14.9dB power)
#define LOC_UNDEFINED 0x00 |
Module located in undefined location (full power)
#define LOC_UNITED_STATES 0x01 |
Module located in United States (?? power)
#define MRF_ACK 1 |
Send mrf packet and request acknowledgement
#define MRF_FIRST_CHANNEL 11 |
First available mrf channel
#define MRF_LAST_CHANNEL 26 |
Last availablre mrf channel
#define MRF_NO_ACK 0 |
Send mrf packet without acknowledgement
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 }
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 }
void mrf24j40_receive_callback | ( | ) |
Callback indicating the mrf24j40 has a packet ready.
00056 { 00057 serial_putc('r'); 00058 if (pkt_received) { 00059 receive_lost++; 00060 debug_str("<Lost receive>"); 00061 mrf24j40_flush_receive_buffer(); 00062 } else { 00063 pkt_received++; 00064 wpan_rx_count = mrf24j40_receive(&wpan_rx_buffer, sizeof(wpan_rx_buffer)); 00065 00066 debug_str("Rx: "); 00067 debug_int(wpan_rx_count); 00068 debug_str(" bytes "); 00069 } 00070 00071 // this will get picked up in wpan_process 00072 00073 }
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 extended address.
Pass a pointer to an 8 byte uns8 array with the address embedded as MSB leftmost byte and LSB rightmost byte, eg
uns8 EA_3[8] = { 0, 0, 0, 0, 0, 0, 0, 3 };
Set extended address to 0x0000000000000003 (64 bit address) mrf24j40_set_extended_address(&EA_3);
Sets the 64 bit extended address of the module. Pass a pointer to an 8 byte uns8 array containing the 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_callback | ( | uns8 | status, | |
uns8 | retries, | |||
uns8 | channel_busy | |||
) |
Callback indicating the mrf24j40 has finished the transmission sequence.
status | Set to 0 for success or 1 for failure | |
retries | Set to the number of retries | |
channel_busy | Set to 1 if failure was due to the channel being busy. |
00077 { // 1 if fail due to channel busy 00078 debug_str(" <Tx: "); 00079 if (!status) { 00080 debug_str(" Good"); 00081 } else { 00082 debug_str(" Fail"); 00083 if (channel_busy) { 00084 debug_str(" (channel busy)"); 00085 } 00086 } 00087 debug_str(" Retries: "); 00088 debug_int(retries); 00089 debug_str(">\n"); 00090 00091 wpan_data_transmitted_callback(status, retries, channel_busy); 00092 00093 }
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 }