65 #define PRINTF(...) printf(__VA_ARGS__)
71 PROCESS(mrf24j40_process,
"MRF24J40 driver");
74 static volatile uint8_t mrf24j40_last_lqi;
75 static volatile uint8_t mrf24j40_last_rssi;
76 static volatile uint8_t status_tx;
77 static volatile uint8_t pending;
78 static volatile uint8_t receive_on;
82 set_short_add_mem(uint8_t addr, uint8_t val)
84 const uint8_t tmp = MRF24J40_INTERRUPT_ENABLE_STAT();
87 msg[0] = (addr << 1) | 0x01;
91 MRF24J40_INTERRUPT_ENABLE_CLR();
95 MRF24J40_SPI_PORT_WRITE(msg, 2);
99 MRF24J40_INTERRUPT_ENABLE_SET();
104 set_long_add_mem(uint16_t addr, uint8_t val)
106 const uint8_t tmp = MRF24J40_INTERRUPT_ENABLE_STAT();
109 msg[0] = (((uint8_t)(addr >> 3)) & 0x7F) | 0x80;
110 msg[1] = (((uint8_t)(addr << 5)) & 0xE0) | 0x10;
114 MRF24J40_INTERRUPT_ENABLE_CLR();
118 MRF24J40_SPI_PORT_WRITE(msg, 3);
122 MRF24J40_INTERRUPT_ENABLE_SET();
127 get_short_add_mem(uint8_t addr)
129 const uint8_t tmp = MRF24J40_INTERRUPT_ENABLE_STAT();
135 MRF24J40_INTERRUPT_ENABLE_CLR();
139 MRF24J40_SPI_PORT_WRITE(&addr, 1);
140 MRF24J40_SPI_PORT_READ(&ret_val, 1);
144 MRF24J40_INTERRUPT_ENABLE_SET();
151 get_long_add_mem(uint16_t addr)
153 const uint8_t tmp = MRF24J40_INTERRUPT_ENABLE_STAT();
157 msg[0] = (((uint8_t)(addr >> 3)) & 0x7F) | 0x80;
158 msg[1] = ((uint8_t)(addr << 5)) & 0xE0;
161 MRF24J40_INTERRUPT_ENABLE_CLR();
165 MRF24J40_SPI_PORT_WRITE(msg, 2);
166 MRF24J40_SPI_PORT_READ(&ret_val, 1);
170 MRF24J40_INTERRUPT_ENABLE_SET();
177 reset_rf_state_machine(
void)
183 const uint8_t rfctl = get_short_add_mem(MRF24J40_RFCTL);
185 set_short_add_mem(MRF24J40_RFCTL, rfctl | 0b00000100);
186 set_short_add_mem(MRF24J40_RFCTL, rfctl & 0b11111011);
194 set_short_add_mem(MRF24J40_RXFLUSH, get_short_add_mem(MRF24J40_RXFLUSH) | 0b00000001);
205 set_long_add_mem(MRF24J40_RFCON0, ((ch - 11) << 4) | 0b00000011);
207 reset_rf_state_machine();
218 set_short_add_mem(MRF24J40_PANIDL, (uint8_t)
id);
219 set_short_add_mem(MRF24J40_PANIDH, (uint8_t)(
id >> 8));
230 set_short_add_mem(MRF24J40_SADRL, (uint8_t)addr);
231 set_short_add_mem(MRF24J40_SADRH, (uint8_t)(addr >> 8));
242 set_short_add_mem(MRF24J40_EADR7, (uint8_t)addr);
243 set_short_add_mem(MRF24J40_EADR6, (uint8_t)(addr >> 8));
244 set_short_add_mem(MRF24J40_EADR5, (uint8_t)(addr >> 16));
245 set_short_add_mem(MRF24J40_EADR4, (uint8_t)(addr >> 24));
246 set_short_add_mem(MRF24J40_EADR3, (uint8_t)(addr >> 32));
247 set_short_add_mem(MRF24J40_EADR2, (uint8_t)(addr >> 40));
248 set_short_add_mem(MRF24J40_EADR1, (uint8_t)(addr >> 48));
249 set_short_add_mem(MRF24J40_EADR0, (uint8_t)(addr >> 56));
260 *(((uint8_t *)& addr)) = get_short_add_mem(MRF24J40_SADRH);
261 *(((uint8_t *)& addr) + 1) = get_short_add_mem(MRF24J40_SADRL);
272 *(((uint8_t *)& addr)) = get_short_add_mem(MRF24J40_EADR7);
273 *(((uint8_t *)& addr) + 1) = get_short_add_mem(MRF24J40_EADR6);
274 *(((uint8_t *)& addr) + 2) = get_short_add_mem(MRF24J40_EADR5);
275 *(((uint8_t *)& addr) + 3) = get_short_add_mem(MRF24J40_EADR4);
276 *(((uint8_t *)& addr) + 4) = get_short_add_mem(MRF24J40_EADR3);
277 *(((uint8_t *)& addr) + 5) = get_short_add_mem(MRF24J40_EADR2);
278 *(((uint8_t *)& addr) + 6) = get_short_add_mem(MRF24J40_EADR1);
279 *(((uint8_t *)& addr) + 7) = get_short_add_mem(MRF24J40_EADR0);
290 set_long_add_mem(MRF24J40_RFCON3, pwr);
301 return get_long_add_mem(MRF24J40_RFSTATE);
336 set_short_add_mem(MRF24J40_BBREG6, get_short_add_mem(MRF24J40_BBREG6) | 0b10000000);
339 while(!(get_short_add_mem(MRF24J40_BBREG6) & 0b00000001)) {
343 mrf24j40_last_rssi = get_long_add_mem(MRF24J40_RSSI);
345 return mrf24j40_last_rssi;
358 return mrf24j40_last_rssi;
369 return mrf24j40_last_lqi;
383 if((buf_len == 0) || (buf_len > 128)) {
387 set_long_add_mem(MRF24J40_NORMAL_TX_FIFO, 0);
389 set_long_add_mem(MRF24J40_NORMAL_TX_FIFO + 1, buf_len);
391 for(i = 0; i < buf_len; ++i) {
392 set_long_add_mem(MRF24J40_NORMAL_TX_FIFO + 2 + i, buf[i]);
408 MRF24J40_INTERRUPT_ENABLE_CLR();
411 set_short_add_mem(MRF24J40_BBREG1, 0b00000100);
414 len = get_long_add_mem(MRF24J40_RX_FIFO) - 2;
418 for(i = 0; i < len; ++i) {
419 buf[i] = get_long_add_mem(MRF24J40_RX_FIFO + i + 1);
425 #ifdef ADD_RSSI_AND_LQI_TO_PACKET
426 mrf24j40_last_lqi = get_long_add_mem(MRF24J40_RX_FIFO + len + 3);
427 mrf24j40_last_rssi = get_long_add_mem(MRF24J40_RX_FIFO + len + 4);
434 set_short_add_mem(MRF24J40_BBREG1, 0b00000000);
438 #ifdef MRF24J40_PROMISCUOUS_MODE
446 MRF24J40_INTERRUPT_ENABLE_SET();
448 return len == 0 ? -1 : len;
463 set_short_add_mem(MRF24J40_WAKECON, 0b10000000);
465 set_short_add_mem(MRF24J40_SOFTRST, 0b00000100);
467 set_short_add_mem(MRF24J40_RXFLUSH, 0b01100000);
470 set_short_add_mem(MRF24J40_SLPACK, 0b10000000);
486 set_short_add_mem(MRF24J40_RFCTL, 0b00000100);
487 set_short_add_mem(MRF24J40_RFCTL, 0b00000000);
498 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
509 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
529 MRF24J40_PINDIRECTION_INIT();
532 MRF24J40_INTERRUPT_INIT(6, 3);
534 if(MRF24J40_SPI_PORT_INIT(10000000, SPI_DEFAULT) < 0)
537 PRINTF(
"MRF24J40 Initialization started\n");
539 MRF24J40_HARDRESET_LOW();
543 MRF24J40_HARDRESET_HIGH();
556 set_short_add_mem(MRF24J40_SOFTRST, 0b00000111);
562 i = get_short_add_mem(MRF24J40_SOFTRST);
563 }
while((i & 0b0000111) != 0);
578 set_short_add_mem(MRF24J40_PACON2, 0b10011000);
582 set_long_add_mem(MRF24J40_RFCON1, 0b00000010);
585 set_long_add_mem(MRF24J40_RFCON2, 0b10000000);
598 set_long_add_mem(MRF24J40_RFCON6, 0b10010000);
600 set_long_add_mem(MRF24J40_RFCON7, 0b10000000);
601 set_long_add_mem(MRF24J40_RFCON8, 0b00000010);
603 set_long_add_mem(MRF24J40_SLPCON1, 0b00100001);
606 set_short_add_mem(MRF24J40_BBREG2, 0b01111000);
607 set_short_add_mem(MRF24J40_CCAEDTH, 0b01100000);
611 set_long_add_mem(MRF24J40_TESTMODE, 0b0001111);
612 PRINTF(
"MRF24J40 Init Amplifier activated \n");
615 #ifdef ADD_RSSI_AND_LQI_TO_PACKET
617 set_short_add_mem(MRF24J40_BBREG6, 0b01000000);
618 PRINTF(
"MRF24J40 Init append RSSI and LQI to packet\n");
625 i = get_long_add_mem(MRF24J40_RFSTATE);
626 }
while((i & 0xA0) != 0xA0);
630 #ifdef MRF24J40_DISABLE_AUTOMATIC_ACK
632 PRINTF(
"MRF24J40 Init NO_AUTO_ACK\n");
635 #ifdef MRF24J40_PAN_COORDINATOR
637 PRINTF(
"MRF24J40 Init PAN COORD\n");
638 set_short_add_mem(MRF24J40_ORDER, 0b11111111);
641 #ifdef MRF24J40_COORDINATOR
643 PRINTF(
"MRF24J40 Init COORD\n");
646 #ifdef MRF24J40_ACCEPT_WRONG_CRC_PKT
648 PRINTF(
"MRF24J40 Init Accept Wrong CRC\n");
651 #ifdef MRF24J40_PROMISCUOUS_MODE
653 PRINTF(
"MRF24J40 Init PROMISCUOUS MODE\n");
666 set_short_add_mem(MRF24J40_RXMCR, i);
667 PRINTF(
"RXMCR 0x%X\n", i);
677 set_short_add_mem(MRF24J40_TXMCR, 0b00011100);
679 i = get_short_add_mem(MRF24J40_TXMCR);
680 PRINTF(
"TXMCR 0x%X\n", i);
685 set_short_add_mem(MRF24J40_TXSTBL, 0b10010101);
686 set_short_add_mem(MRF24J40_TXTIME, 0b00110000);
688 #ifdef INT_POLARITY_HIGH
690 set_long_add_mem(MRF24J40_SLPCON0, 0b00000011);
691 PRINTF(
"MRF24J40 Init INT Polarity High\n");
693 set_long_add_mem(MRF24J40_SLPCON0, 0b00000001);
694 PRINTF(
"MRF24J40 Init INT Polarity Low\n");
697 PRINTF(
"MRF24J40 Inititialization completed\n");
699 mrf24j40_last_lqi = 0;
700 mrf24j40_last_rssi = 0;
701 status_tx = MRF24J40_TX_ERR_NONE;
705 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
707 reset_rf_state_machine();
728 set_short_add_mem(MRF24J40_INTCON, 0b11110110);
734 mrf24j40_prepare(
const void *data,
unsigned short len)
736 PRINTF(
"PREPARE %u bytes\n", len);
738 uint8_t receive_was_on = receive_on;
742 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
744 ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
748 ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
750 if(!receive_was_on) {
753 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
760 mrf24j40_transmit(
unsigned short len)
762 PRINTF(
"TRANSMIT %u bytes\n", len);
764 uint8_t receive_was_on = receive_on;
768 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
770 ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
772 status_tx = MRF24J40_TX_WAIT;
774 set_short_add_mem(MRF24J40_TXNCON, 0b00000001);
777 while(status_tx == MRF24J40_TX_WAIT) {
781 ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
783 if(!receive_was_on) {
786 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
790 case MRF24J40_TX_ERR_NONE:
792 case MRF24J40_TX_ERR_COLLISION:
793 return RADIO_TX_COLLISION;
794 case MRF24J40_TX_ERR_MAXRETRY:
795 return RADIO_TX_NOACK;
802 mrf24j40_write(
const void *data, uint16_t len)
806 PRINTF(
"PREPARE & TRANSMIT %u bytes\n", len);
808 if(mrf24j40_prepare(data, len))
811 ret = mrf24j40_transmit(len);
818 mrf24j40_read(
void *data, uint16_t len)
828 uint8_t receive_was_on = receive_on;
832 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
834 ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
838 if(!receive_was_on) {
841 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
848 mrf24j40_receiving_packet(
void)
854 mrf24j40_pending_packet(
void)
861 INT_status int_status;
864 ENERGEST_ON(ENERGEST_TYPE_IRQ);
866 int_status.val = get_short_add_mem(MRF24J40_INTSTAT);
868 if(!int_status.val) {
872 if(int_status.bits.RXIF) {
880 if(int_status.bits.TXNIF) {
882 tx_status.val = get_short_add_mem(MRF24J40_TXSTAT);
884 if(tx_status.bits.TXNSTAT) {
885 if(tx_status.bits.CCAFAIL) {
886 status_tx = MRF24J40_TX_ERR_COLLISION;
888 status_tx = MRF24J40_TX_ERR_MAXRETRY;
891 status_tx = MRF24J40_TX_ERR_NONE;
895 MRF24J40_INTERRUPT_FLAG_CLR();
897 ENERGEST_OFF(ENERGEST_TYPE_IRQ);
919 #ifdef ADD_RSSI_AND_LQI_TO_PACKET
920 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, mrf24j40_last_rssi);
921 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, mrf24j40_last_lqi);
924 NETSTACK_RDC.input();
931 static radio_result_t
934 return RADIO_RESULT_NOT_SUPPORTED;
937 static radio_result_t
940 return RADIO_RESULT_NOT_SUPPORTED;
943 static radio_result_t
944 get_object(radio_param_t param,
void *dest,
size_t size)
946 return RADIO_RESULT_NOT_SUPPORTED;
949 static radio_result_t
950 set_object(radio_param_t param,
const void *src,
size_t size)
952 return RADIO_RESULT_NOT_SUPPORTED;
963 mrf24j40_receiving_packet,
964 mrf24j40_pending_packet,
void mrf24j40_set_short_mac_addr(uint16_t addr)
Store short MAC address.
void process_poll(struct process *p)
Request a process to be polled.
uint8_t mrf24j40_get_rssi(void)
Get the RSSI.
SPI interface for PIC32MX (pic32mx795f512l)
#define PROCESS_BEGIN()
Define the beginning of a process.
void clock_delay_usec(uint16_t dt)
Delay a given number of microseconds.
void mrf24j40_set_tx_power(uint8_t pwr)
Set TX power.
INTERRUPT interface for PIC32MX (pic32mx795f512l)
Header file for the Rime buffer (packetbuf) management
void mrf24j40_set_channel(uint16_t ch)
Set the channel.
#define NULL
The null pointer.
The structure of a device driver for a radio in Contiki.
int mrf24j40_init(void)
Init transceiver.
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio...
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
uint8_t mrf24j40_get_last_rssi(void)
Get the last read RSSI.
uint8_t mrf24j40_get_last_lqi(void)
Get the last read LQI.
void mrf24j40_set_panid(uint16_t id)
Store MAC PAN ID.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
#define PROCESS_END()
Define the end of a process.
void mrf24j40_get_extended_mac_addr(uint64_t *addr)
Gets extended MAC address.
void mrf24j40_set_extended_mac_addr(uint64_t addr)
Store extended MAC address.
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
#define PROCESS(name, strname)
Declare a process.
void mrf24j40_get_short_mac_addr(uint16_t *addr)
Get short MAC address.
void packetbuf_clear(void)
Clear and reset the packetbuf.
void process_start(struct process *p, process_data_t data)
Start a process.
int32_t mrf24j40_get_rxfifo(uint8_t *buf, uint8_t buf_len)
Get message.
int32_t mrf24j40_set_txfifo(const uint8_t *buf, uint8_t buf_len)
Store message.
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
radio_result_t(* set_object)(radio_param_t param, const void *src, size_t size)
Set a radio parameter object.
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
MRF24J40 Specific Arch Conf.
uint8_t mrf24j40_get_status(void)
Get radio status.
Include file for the Contiki low-layer network stack (NETSTACK)