RFM70_HH.c


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
}