2 * Copyright 2010 Grygoriy Fuchedzhy <grygoriy.fuchedzhy@gmail.com>
4 * This file is part of mrf-link.
6 * mrf-link is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * mrf-link is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with mrf-link. If not, see <http://www.gnu.org/licenses/>.
25 #include <util/delay.h>
27 #include <avr/interrupt.h>
29 uint16_t mrf_short_addr
= MRF_SHORT_ADDR
;
30 uint16_t mrf_pan_id
= MRF_PAN_ID
;
31 uint8_t mrf_seq_num
= 0;
33 // set given short register to given value via spi
34 void mrf_write_short_addr(uint8_t addr
, uint8_t val
)
39 spi_shift_byte(0x1 | (addr
<< 1));
45 // get and return value of given short register via spi
46 uint8_t mrf_read_short_addr(uint8_t addr
)
51 spi_shift_byte(addr
<< 1);
52 uint8_t res
= spi_shift_byte(0x00);
58 // set given long register to given value via spi
59 void mrf_write_long_addr(uint16_t addr
, uint8_t val
)
64 spi_shift_byte(0x80 | (addr
>> 3));
65 spi_shift_byte(0x10 | (addr
<< 5));
71 // get and return value of given long register via spi
72 uint8_t mrf_read_long_addr(uint16_t addr
)
77 spi_shift_byte(0x80 | (addr
>> 3));
78 spi_shift_byte(addr
<< 5);
79 uint8_t res
= spi_shift_byte(0x00);
85 // set channel, ch must be: 0x0 - 0xF
86 void mrf_set_channel(uint8_t ch
)
88 // 0x2 - recommended value
89 mrf_set_reg(MRF_R_RFCON0
, (ch
<<4) | 0x2);
91 mrf_set_reg(MRF_R_RFCTL
, _BV(MRF_B_RFRST
));
92 mrf_set_reg(MRF_R_RFCTL
, 0);
96 // reset and initialize radio
99 // software reset, the bits will be automatically cleared by hardware.
100 mrf_set_reg(MRF_R_SOFTRST
, _BV(MRF_B_RSTPWR
) | _BV(MRF_B_RSTBB
) | _BV(MRF_B_RSTMAC
));
102 // register initialization
103 mrf_set_reg(MRF_R_PACON2
, _BV(MRF_B_FIFOEN
) | MRF_RV_TXONTS
);
104 mrf_set_reg(MRF_R_TXSTBL
, MRF_RV_RFSTBL
| MRF_RV_MSIFS
);
105 mrf_set_reg(MRF_R_RFCON1
, MRF_RV_VCOOPT
);
106 mrf_set_reg(MRF_R_RFCON2
, _BV(MRF_B_PLLEN
));
107 mrf_set_reg(MRF_R_RFCON6
, _BV(MRF_B_TXFIL
) | _BV(MRF_B_20MRECVR
));
108 mrf_set_reg(MRF_R_RFCON7
, MRF_V_SLPCLKSEL_100kHz
);
109 mrf_set_reg(MRF_R_RFCON8
, _BV(MRF_B_RFVCO
));
110 mrf_set_reg(MRF_R_SLPCON1
, _BV(MRF_B_CLKOUTEN
) | 0x1);
111 mrf_set_reg(MRF_R_BBREG2
, MRF_V_CCAMODE_ENERGY_ABOVE_THRESHOLD
);
112 mrf_set_reg(MRF_R_CCAEDTH
, MRF_RV_CCAEDTH
);
113 mrf_set_reg(MRF_R_BBREG6
, _BV(MRF_B_RSSIMODE2
));
115 // enable interrupts, (inverted values for this register)
116 mrf_set_reg(MRF_R_INTCON
, ~(_BV(MRF_B_TXN
) | _BV(MRF_B_RX
)));
118 // read and set address
119 mrf_set_reg(MRF_R_PANIDL
, mrf_pan_id
);
120 mrf_set_reg(MRF_R_PANIDH
, mrf_pan_id
>>8);
121 mrf_set_reg(MRF_R_SADRL
, mrf_short_addr
);
122 mrf_set_reg(MRF_R_SADRH
, mrf_short_addr
>>8);
127 void mrf_tx(uint16_t pan_id
, uint16_t short_addr
, const uint8_t* data
, uint8_t data_length
)
129 uint16_t addr
= MRF_BUF_TX_NORMAL
;
131 // frame control + seq.num. + addressing fields
132 const uint8_t hdr_length
= 2 + 1 + 2*(IEEE802_15_4_SHORT_ADDR_LENGTH
+ IEEE802_15_4_PAN_ID_LENGTH
);
134 mrf_write_long_addr(addr
++, hdr_length
);
135 mrf_write_long_addr(addr
++, hdr_length
+ data_length
);
138 mrf_write_long_addr(addr
++, IEEE802_15_4_DATA
| IEEE802_15_4_ACK_REQ
);
139 mrf_write_long_addr(addr
++, IEEE802_15_4_SHORT_DESTADDR
| IEEE802_15_4_SHORT_SRCADDR
| IEEE802_15_4_2003_VERSION
);
142 mrf_write_long_addr(addr
++, mrf_seq_num
++);
145 mrf_write_long_addr(addr
++, pan_id
);
146 mrf_write_long_addr(addr
++, pan_id
>>8);
149 mrf_write_long_addr(addr
++, short_addr
);
150 mrf_write_long_addr(addr
++, short_addr
>>8);
153 mrf_write_long_addr(addr
++, mrf_pan_id
);
154 mrf_write_long_addr(addr
++, mrf_pan_id
>>8);
157 mrf_write_long_addr(addr
++, mrf_short_addr
);
158 mrf_write_long_addr(addr
++, mrf_short_addr
>>8);
160 for(uint8_t i
= 0; i
< data_length
; ++i
)
161 mrf_write_long_addr(addr
++, data
[i
]);
163 // transmit frame, request acknowledgement
164 mrf_set_reg(MRF_R_TXNCON
, _BV(MRF_B_ACKREQ
) | _BV(MRF_B_TRIG
));
167 #endif // __MRF_IMPL__