using new IEEE 802.15.4 defs in mrf_tx function
[mrf-link.git] / fw / mrf / mrf_impl.h
blob71e2dc1cca96cd90871584dcd1f276dbf74d4617
1 /*
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/>.
20 #ifndef __MRF_IMPL__
21 #define __MRF_IMPL__
23 #include <mrf/mrf.h>
25 #include <util/delay.h>
26 #include <avr/spi.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)
36 uint8_t sreg = SREG;
37 cli();
38 spi_select();
39 spi_shift_byte(0x1 | (addr << 1));
40 spi_shift_byte(val);
41 spi_deselect();
42 SREG = sreg;
45 // get and return value of given short register via spi
46 uint8_t mrf_read_short_addr(uint8_t addr)
48 uint8_t sreg = SREG;
49 cli();
50 spi_select();
51 spi_shift_byte(addr << 1);
52 uint8_t res = spi_shift_byte(0x00);
53 spi_deselect();
54 SREG = sreg;
55 return res;
58 // set given long register to given value via spi
59 void mrf_write_long_addr(uint16_t addr, uint8_t val)
61 uint8_t sreg = SREG;
62 cli();
63 spi_select();
64 spi_shift_byte(0x80 | (addr >> 3));
65 spi_shift_byte(0x10 | (addr << 5));
66 spi_shift_byte(val);
67 spi_deselect();
68 SREG = sreg;
71 // get and return value of given long register via spi
72 uint8_t mrf_read_long_addr(uint16_t addr)
74 uint8_t sreg = SREG;
75 cli();
76 spi_select();
77 spi_shift_byte(0x80 | (addr >> 3));
78 spi_shift_byte(addr << 5);
79 uint8_t res = spi_shift_byte(0x00);
80 spi_deselect();
81 SREG = sreg;
82 return res;
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);
90 // reset rf module
91 mrf_set_reg(MRF_R_RFCTL, _BV(MRF_B_RFRST));
92 mrf_set_reg(MRF_R_RFCTL, 0);
93 _delay_us(192);
96 // reset and initialize radio
97 void mrf_init()
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);
124 mrf_set_channel(0);
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);
137 // frame control
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);
141 // sequence number
142 mrf_write_long_addr(addr++, mrf_seq_num++);
144 // dest pan id
145 mrf_write_long_addr(addr++, pan_id);
146 mrf_write_long_addr(addr++, pan_id>>8);
148 // dest short addr
149 mrf_write_long_addr(addr++, short_addr);
150 mrf_write_long_addr(addr++, short_addr>>8);
152 // source pan id
153 mrf_write_long_addr(addr++, mrf_pan_id);
154 mrf_write_long_addr(addr++, mrf_pan_id>>8);
156 // source short addr
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__