1 | Hier nur die wichtigsten code-teile
|
2 |
|
3 |
|
4 | /**************************************************
|
5 | Function: SwitchToRxMode();
|
6 | Description:
|
7 | switch to Rx mode
|
8 | mode 0 = RX, mode 1 = Tx
|
9 | **************************************************/
|
10 | void SwitchRxTxMode(uint8_t mode)
|
11 | {
|
12 | uint8_t status;
|
13 |
|
14 | status = SPI_send_get(FLUSH_RX, TX_ptr, RX_ptr,0);
|
15 | status = SPI_send_get(FLUSH_TX, TX_ptr, RX_ptr,0);
|
16 | status |= STATUS_RX_DR | STATUS_TX_DS | STATUS_MAX_RT; // clear RX_DR or TX_DS or MAX_RT interrupt flag
|
17 | SPI_send_get(WRITE_REG|STATUS, &status, RX_ptr,1); // update status reg
|
18 | RFM70_disable;
|
19 | if (mode) status = MASK_RX_DR | EN_CRC | CRCO | PWR_UP; // Tx config register
|
20 | else status = MASK_TX_DS | MASK_MAX_TR | EN_CRC | CRCO | PWR_UP | PRIM_RX; // Rx config register
|
21 | SPI_send_get(WRITE_REG|CONFIG, &status, RX_ptr,1);
|
22 | RFM70_enable;
|
23 | }
|
24 | /**************************************************
|
25 | Function: Clear_IRQ();
|
26 | clear all interrupts
|
27 | **************************************************/
|
28 | void Clear_IRQ()
|
29 | {
|
30 | uint8_t status;
|
31 |
|
32 | status = SPI_send_get(NOP_NOP, TX_ptr, RX_ptr,0);
|
33 | status |= STATUS_RX_DR | STATUS_TX_DS | STATUS_MAX_RT; // clear RX_DR or TX_DS or MAX_RT interrupt flag
|
34 | SPI_send_get(WRITE_REG|STATUS, &status, RX_ptr,1); // update status reg
|
35 | }
|
36 |
|
37 |
|
38 |
|
39 | main
|
40 |
|
41 |
|
42 | #include <avr/io.h>
|
43 | #include <stdint.h>
|
44 | #include <stdio.h>
|
45 | #include <string.h>
|
46 |
|
47 | #define F_CPU 16000000UL
|
48 |
|
49 | #define LEDPORT PORTF
|
50 | #define LED_READY_bm 16 // Port F Pin 4
|
51 | #define LED_1_bm 32 // Port F Pin 5
|
52 | #define LED_2_bm 64 // Port F Pin 6
|
53 | #define LED_3_bm 128 // Port F Pin 7
|
54 |
|
55 |
|
56 | #define SWITCHPORT PORTF
|
57 | #define SWITCH_REC_bm 2 // Port F Pin 1
|
58 | #define SWITCHMASK 2 // Port F Pin 1
|
59 |
|
60 | #define TIMEOUT 0xFF00 // for UART (TCC1) = ca 4 s
|
61 |
|
62 | #define device_no 1 // Device 1: sender, 2: receiver
|
63 |
|
64 |
|
65 | char string1[200];
|
66 |
|
67 | uint8_t *TX_ptr;
|
68 | uint8_t *RX_ptr;
|
69 |
|
70 |
|
71 |
|
72 |
|
73 | #include <util/delay.h>
|
74 | #include <avr/usart_driver.h>
|
75 | #include "C:\Programme\AVR Programme\subroutines\Matlab_communication.c"
|
76 | // #include "C:\Programme\AVR Programme\subroutines\spi_driver.h"
|
77 | // #include "C:\Programme\AVR Programme\subroutines\spi_driver.c"
|
78 | #include "C:\Programme\AVR Programme\RFM70\RFM70_kb.h"
|
79 | // #include "C:\Programme\AVR Programme\RFM70\RFM70_init_KB.c"
|
80 | /* RFM70 init routine
|
81 | K. Boetzel 2013
|
82 | ATXMEGA128
|
83 | */
|
84 |
|
85 |
|
86 |
|
87 | // SPI
|
88 |
|
89 | #define SlaveDeselect_RFM70 PORTC.OUTSET = PIN4_bm // Port C Pin 4
|
90 | #define SlaveSelect_RFM70 PORTC.OUTCLR = PIN4_bm; _delay_us(2)
|
91 | #define RFM70_enable PORTC.OUTSET = PIN3_bm // chip enable (CE)
|
92 | #define RFM70_disable PORTC.OUTCLR = PIN3_bm
|
93 | #define RFM70_IRQ PORTC.IN & PIN2_bm // Interrupt
|
94 |
|
95 | // in main program:
|
96 | // PORTC.DIRSET = PIN3_bm | PIN4_bm | PIN5_bm | PIN7_bm; // CE, SS, Mosi und CLK as output
|
97 | // PORTC.PIN4CTRL = PORT_OPC_WIREDANDPULL_gc;
|
98 |
|
99 |
|
100 |
|
101 | //Bank1 register initialization values
|
102 | uint8_t Bank1_Reg_val[]=
|
103 | {
|
104 | 0x40, 0x4B, 0x01, 0xE2, //0xE2014B40 Address 0
|
105 | 0xC0, 0x4B, 0x00, 0x00, //0x00004BC0 Address 1
|
106 | 0xD0, 0xFC, 0x8C, 0x02, //0x028CFCD0 Address 2
|
107 | 0x99, 0x00, 0x39, 0x41, //0x41390099 Address 3
|
108 | 0xF9, 0x9E, 0x86, 0x0B, //0x0B869ED9 Address 4 D9 oder F9? oder 09 ??// von 0xD99E860Bauf 0x099E860B)
|
109 | 0x24, 0x06, 0x7F, 0xA6, //0xA67F0624 Address 5
|
110 | 0x00, 0x12, 0x73, 0x00, //0x00127300 Address C
|
111 | 0x36, 0xB4, 0x80, 0x00 //0x36B48000 Address D
|
112 | };
|
113 |
|
114 | //Bank1 register numbers
|
115 | uint8_t Bank1_Reg_no[8]={0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0C, 0x0D};
|
116 |
|
117 | //Bank1 register 14 initialization values
|
118 | uint8_t Bank1_Reg14[]={0x41, 0x20, 0x08, 0x04, 0x81, 0x20, 0xCF, 0xF7, 0xFE, 0xFF, 0xFF};
|
119 |
|
120 | uint8_t channel = 0x17;
|
121 |
|
122 | //Bank0 register initialization values
|
123 | uint8_t Bank0_Reg[]={
|
124 | 0, 0x0F, //reflect all interrupts,Enable CRC,2byte,POWER UP,PRX
|
125 | 1, 0x01, //Enable auto acknowledgement data pipe 0
|
126 | 2, 0x01, //Enable RX Addresses pipe 0
|
127 | 3, 0x03, //RX/TX address field width 5byte
|
128 | 4, 0xF0, //auto retransmission dalay (4000us),auto retransmission of !!!
|
129 | 5, 0x17, //23 channel
|
130 | 6, 0x37, //air data rate-1M,out power 5dbm,setup LNA gain
|
131 | 17,0x01, //Number of bytes in RX payload in data pipe0(1 byte)
|
132 | 18,0x00 //Number of bytes in RX payload in data pipe1(not used)
|
133 | // 29,0x07} // //Enable EN_DPL, EN_ACK_PAY, EN_DYN_ACK erst Activate + 0x73 (Register 29 freischalten)
|
134 | };
|
135 |
|
136 |
|
137 | // setup for different devices
|
138 | // device 1: (sender)
|
139 |
|
140 | uint8_t RX0_Address[]={0x01,0x01,0x01,0x01,0x01}; // Receive address data pipe 0; LSByte to MSByte; same as TX_ADDR
|
141 | /* TX_Address[]={0x01,0x01,0x01,0x01,0x01};
|
142 |
|
143 |
|
144 | device 2: (receiver)
|
145 | // can send data to all (but at the same time !!)
|
146 | uint8_t RX0_Address[]={0x01,0x01,0x01,0x01,0x01}; // Receive address data pipe 0; LSByte to MSByte; same as TX_ADDR
|
147 | TX_Address[]={0x02,0x01,0x01,0x01,0x01};
|
148 |
|
149 | */
|
150 |
|
151 |
|
152 |
|
153 |
|
154 | /*
|
155 |
|
156 | */
|
157 |
|
158 |
|
159 |
|
160 | /* ############################################################################
|
161 | Routine for reading and receiving several bytes from specified register
|
162 | cmd = command | register or command only
|
163 | *send_byte = data to send; nbytes = no of data bytes
|
164 | returns status byte
|
165 | ############################################################################
|
166 | */
|
167 |
|
168 | uint8_t SPI_send_get(uint8_t cmd, uint8_t *send_byte, uint8_t *get_byte, uint8_t nbytes)
|
169 |
|
170 | {
|
171 | uint8_t n, status;
|
172 |
|
173 | SlaveSelect_RFM70;
|
174 | SPIC.DATA = cmd;
|
175 | while(!(SPIC_STATUS & SPI_IF_bm));
|
176 | status = SPIC.DATA;
|
177 |
|
178 | for(n=0; n<nbytes; n++) {
|
179 | SPIC.DATA = *send_byte++;
|
180 | while(!(SPIC_STATUS & SPI_IF_bm));
|
181 | *get_byte++ = SPIC.DATA;
|
182 | }
|
183 | SlaveDeselect_RFM70;
|
184 | return(status);
|
185 | }
|
186 |
|
187 |
|
188 | /**************************************************
|
189 | Function: SwitchToRxMode();
|
190 | Description:
|
191 | switch to Rx mode
|
192 | mode 0 = RX, mode 1 = Tx
|
193 | **************************************************/
|
194 | void SwitchRxTxMode(uint8_t mode)
|
195 | {
|
196 | uint8_t status;
|
197 |
|
198 | status = SPI_send_get(FLUSH_RX, TX_ptr, RX_ptr,0);
|
199 | status = SPI_send_get(FLUSH_TX, TX_ptr, RX_ptr,0);
|
200 | status |= STATUS_RX_DR | STATUS_TX_DS | STATUS_MAX_RT; // clear RX_DR or TX_DS or MAX_RT interrupt flag
|
201 | SPI_send_get(WRITE_REG|STATUS, &status, RX_ptr,1); // update status reg
|
202 | RFM70_disable;
|
203 | if (mode) status = MASK_RX_DR | MASK_MAX_TR | EN_CRC | CRCO | PWR_UP; // Tx config register
|
204 | else status = MASK_TX_DS | MASK_MAX_TR | EN_CRC | CRCO | PWR_UP | PRIM_RX; // Rx config register
|
205 | SPI_send_get(WRITE_REG|CONFIG, &status, RX_ptr,1);
|
206 | RFM70_enable;
|
207 | }
|
208 | /**************************************************
|
209 | Function: Clear_IRQ();
|
210 | **************************************************/
|
211 | void Clear_IRQ()
|
212 | {
|
213 | uint8_t status;
|
214 |
|
215 | status = SPI_send_get(NOP_NOP, TX_ptr, RX_ptr,0);
|
216 | status |= STATUS_RX_DR | STATUS_TX_DS | STATUS_MAX_RT; // clear RX_DR or TX_DS or MAX_RT interrupt flag
|
217 | SPI_send_get(WRITE_REG|STATUS, &status, RX_ptr,1); // update status reg
|
218 | }
|
219 | /**************************************************
|
220 | Function: Switch_Bank();
|
221 | **************************************************/
|
222 | void Switch_Bank(uint8_t bank) //1:Bank1 0:Bank0
|
223 | {
|
224 | uint8_t status;
|
225 |
|
226 | status = SPI_send_get(NOP_NOP, TX_ptr, RX_ptr,0);
|
227 | status &= 0x80; // bit 7 = 0, bank 0
|
228 |
|
229 | if ((status && !bank) || (!status && bank)) {
|
230 | TX_ptr[0] = 0x53;
|
231 | SPI_send_get(ACTIVATE_CMD, TX_ptr, RX_ptr,1);
|
232 | }
|
233 | }
|
234 |
|
235 | /**************************************************
|
236 | Function: RFM70_Initialize();
|
237 |
|
238 | Description:
|
239 | register initialization
|
240 | **************************************************/
|
241 | void RFM70_Initialize()
|
242 | {
|
243 | uint8_t i, val;
|
244 |
|
245 | _delay_ms(100); //delay more than 50ms.
|
246 |
|
247 | //******************** Write Bank0 registers ******************
|
248 | Switch_Bank(0);
|
249 |
|
250 | for(i=0; i<10; i++) SPI_send_get(WRITE_REG|Bank0_Reg[i*2], &Bank0_Reg[i*2+1], RX_ptr,1);
|
251 |
|
252 | StrMat("\n Bank 0 ok");
|
253 |
|
254 |
|
255 | SPI_send_get(WRITE_REG|10, RX0_Address, RX_ptr,5); // RX0_Address
|
256 | // SPI_send_get(WRITE_REG|11, RX1_Address, RX_ptr,5); // RX1_Address (not necessary when only pipe 0 is active)
|
257 | if (device_no == 2) RX0_Address[0] = 0x02; // TX-Address for device 2 is not used, but should not be same as dev 1
|
258 | SPI_send_get(WRITE_REG|16, RX0_Address, RX_ptr,5); // TX_Address = RX0_Adress (same as RX0 in sender to receive ACK, not necessary in receiver)
|
259 |
|
260 | StrMat("\n Address ok");
|
261 |
|
262 | //******************** Write Bank1 registers ******************
|
263 | Switch_Bank(1);
|
264 | for(i=0; i<9; i++) SPI_send_get(WRITE_REG|Bank1_Reg_no[i], &Bank1_Reg_val[i*4], RX_ptr, 4);
|
265 | SPI_send_get(WRITE_REG|14, Bank1_Reg14, RX_ptr, 11);
|
266 | _delay_ms(50);
|
267 | StrMat("\n Bank 1");
|
268 | //******************** Write Bank0 registers ******************
|
269 | Switch_Bank(0);
|
270 | SPI_send_get(READ_REG | 29, TX_ptr, RX_ptr,1); // Reg 29: if = 0, chip not activated
|
271 | if (!RX_ptr[0]) {
|
272 | TX_ptr[0] = 0x73;
|
273 | SPI_send_get(ACTIVATE_CMD, TX_ptr, RX_ptr,1);
|
274 | }
|
275 | val = 0x07;
|
276 | SPI_send_get(WRITE_REG|29, &val, RX_ptr,1); // Write Reg 29 (only possible after activated)
|
277 | StrMat("\n Reg 29");
|
278 | }
|
279 |
|
280 |
|
281 |
|
282 |
|
283 | int main(void)
|
284 | {
|
285 |
|
286 |
|
287 | ...
|
288 |
|
289 |
|
290 | RFM70_Initialize();
|
291 | LEDPORT.OUTSET = LED_READY_bm; // ready !
|
292 |
|
293 | switch (device_no) {
|
294 | case 1: // ****** send data ******
|
295 | to = 20; // timeout for reception of interupt in TX-mode (in ms, change value here)
|
296 | to = F_CPU / 1024 / 1000 * to; // timeout in clock tics of TCC1 (DIV 1024)
|
297 | sprintf(string1,"\n Timeout in tics : %d",to);
|
298 | StrMat(string1);
|
299 | SwitchRxTxMode(1); // TX-mode
|
300 | RFM70_enable;
|
301 | _delay_ms(100);
|
302 |
|
303 |
|
304 | while(1){
|
305 | for (n=0; n<8; n++) {
|
306 | TCC1.CNT = 0;
|
307 | SPI_send_get(READ_REG | FIFO_STATUS, tx_data, rx_data,1); // read FIFO status
|
308 | if (rx_data[0] & FIFO_STATUS_TX_FULL) SPI_send_get(FLUSH_TX, TX_ptr, RX_ptr,0);
|
309 | SPI_send_get(WR_TX_PLOAD, &n, rx_data,1); // send 1 byte (number 0:7)
|
310 | sprintf(string1,"\n Data paket no %d sent by SPI; Timer : %d",n, TCC1.CNT);
|
311 | StrMat(string1);
|
312 |
|
313 | while (RFM70_IRQ && TCC1.CNT < to); // while interrupt pin is high ...
|
314 | status = SPI_send_get(NOP_NOP, TX_ptr, RX_ptr,0);
|
315 | if (!(status & STATUS_TX_DS)){ // maximum no of retry is reached
|
316 | sprintf(string1,"\n Timeout 1. Timer : %d; Status : %d",TCC1.CNT, status);
|
317 | StrMat(string1);
|
318 | SPI_send_get(REUSE_TX_PL, TX_ptr, RX_ptr,0); // send data over and over again ..
|
319 | while (RFM70_IRQ && TCC1.CNT < (to * 2));
|
320 | status = SPI_send_get(NOP_NOP, TX_ptr, RX_ptr,0);
|
321 | if (!(status & STATUS_TX_DS)) {
|
322 | sprintf(string1,"\n Timeout 2. Timer : %d; Status : %d",TCC1.CNT, status);
|
323 | StrMat(string1);
|
324 | SPI_send_get(FLUSH_TX, TX_ptr, RX_ptr,0); // stop REUSE_TX_PL
|
325 | }
|
326 | }
|
327 | Clear_IRQ();
|
328 | while (TCC1.CNT < 8000) ; // delay 500 ms
|
329 | }
|
330 | }
|
331 | break;
|
332 |
|
333 | case 2: // ****** receive data ******
|
334 | SwitchRxTxMode(0); // RX-mode
|
335 | RFM70_enable;
|
336 | _delay_ms(100);
|
337 | while(1){
|
338 | while (RFM70_IRQ); // while interrupt pin is high ...
|
339 | SPI_send_get(RD_RX_PLOAD, tx_data, rx_data,1);
|
340 | n = LEDPORT.OUT & 0x1F; // clear bit 5-7
|
341 | LEDPORT.OUT = n | (rx_data[0] << 5); // display data on pin 5-7 (LED)
|
342 | Clear_IRQ();
|
343 | }
|
344 | }
|
345 | }
|