RFM12 an XMEGA

Gast #2447514
Lesenswert?

Hallo,

wie der Titel schon sagt versuche ich ein RFM12 an einem XMEGA zu 
betreiben. Hierzu hab ich die OpenMCP Bibliothek angepasst.

Zudem hab ich zwei Funkboards von Pollin, welche sich mit dem 
Beispielprogramm prächtig unterhalten.

Jetzt mächte ich quasi das gesendete mithören.

An einem XPLAIN Board hab ich das RFM12 Board angeschlossen. Den SPI Bus 
au Port D, Den Interruptpin ebenfalls und die Versorgung über die 3,3V.

Mit dem Oszilloskop hab ich überprüft, ob der SPI treiber funktioniert. 
Die Daten werden gesendet.

Ab und zu hab ich auch mal einen Interrupt, jedoch ohne empfang von 
Daten.
Vielleicht hab ich irgendetwas nicht verstanden aber eigentloich müsste 
ich doch zumindest datenmüll empfangen.

Des weiteren sehe ich keine Möglichkeit den Status abzufragen. Der 
springt dermaßen, das man da keine Schlüsse draus ziehen kann. Absolut 
unbrauchbar.

Kennt ihr einen Treiber für RFM12 und XMEGA denn man leicht anpassen 
kann?

Oder habt ihr ne idee wie man das debuggen kann? ich bin langsam am 
Ende.

Gruß

Sönke

PS: Hier der Code
1
/***************************************************************************
2
 *  rfm12.c
3
 *
4
 *  Sun Apr 17 17:41:35 2011
5
 *  Based on Firmware version 2.0.1 by Jürgen Eckert
6
 *  -> http://www.mikrocontroller.net/articles/AVR_RFM12
7
 *  Ported to OpenMcp by Jan Wissel 
8
 *  OpenMcp, by  Dirk Broßwick
9
 *  <sharandac@snafu.de>
10
 *  for documentation see:
11
 *  http://www.mikrocontroller.net/articles/RFM12 
12
 ****************************************************************************/
13

14
/*
15
 * This program is free software; you can redistribute it and/or modify
16
 * it under the terms of the GNU General Public License as published by
17
 * the Free Software Foundation; either version 2 of the License, or
18
 * (at your option) any later version.
19
 * 
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU Library General Public License for more details.
24
 * 
25
 * You should have received a copy of the GNU General Public License
26
 * along with this program; if not, write to the Free Software
27
 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
28
 */
29

30
#include <stdio.h>
31
#include <stdlib.h>
32
#include <string.h>
33
#include <avr/io.h>
34
#include <avr/interrupt.h>
35
#include <util/delay.h>
36
#include "hardware/spi/spi_core.h"
37
#include "hardware/ext_int/ext_int.h"
38
#include "hardware/led/led_core.h"
39
#include "system/clock/clock.h"
40
#include "config.h"
41
#include "system/thread/thread.h"
42

43
#if defined( RFM12 )
44

45
#include "rfm12.h"
46

47
//used by interrupt routine
48
struct RFM12_stati RFM12_status;
49
volatile unsigned char RFM12_Index = 0;
50
unsigned char RFM12_Data[RFM12_DataLength+10];  // +10 == paket overhead
51

52
#define RFM_PACKET_SIZE 8
53

54

55
void rftransmit(void)
56
{  
57
    unsigned char RFMdata=0;
58
    unsigned char RFMpacket[RFM_PACKET_SIZE];
59
    unsigned char i;   
60

61
  for(i=0;i<RFM_PACKET_SIZE;i++){
62
        RFMpacket[i]=RFMdata;
63
        RFMdata++;
64
    }
65
 
66
    if ( RFM12_txstart(RFMpacket, RFM_PACKET_SIZE) != 0 )
67
    LED_toggle(2);
68
}
69

70
void rfrecieve(void)
71
{
72
    unsigned char RFMpacket[RFM_PACKET_SIZE], temp;
73
  int i;
74
  
75
  temp = RFM12_rxfinish( RFMpacket );
76
  if ( temp != 255 && temp != 254 )
77
  {
78
    printf_P( PSTR("RFM12 %d Bytes recieve."), temp );
79
    for ( i = 0 ; i < RFM_PACKET_SIZE ; i++)
80
      printf_P( PSTR("%02x ") , RFMpacket[ i ] );
81
    if ( RFM12_rxstart() != 0 )
82
      printf_P( PSTR("RFM12 error"));
83
    printf_P( PSTR("\r\n"));
84
  }
85
}
86

87

88
//interrupt service routine
89
void RFM12_isr( void )
90
{
91
  LED_off(7);
92
  
93
  if(RFM12_status.Rx)
94
  {
95
    if(RFM12_Index < RFM12_DataLength)
96
    {
97
      //no complete packet received, read FIFO, store in data
98
      RFM12_Data[RFM12_Index++] = RFM12_trans(0xB000) & 0x00FF;
99
    }
100
    else
101
    {
102
      //packet completely received, turn off RX
103
      RFM12_trans(0x8208);
104
      RFM12_status.Rx = 0;
105
    }
106
    if(RFM12_Index >= RFM12_Data[0] + 3)
107
    {  
108
      //EOT
109
      //enough data in package?
110
      //note: will fail if Data[0] was received incorrectly
111
      //anyway, does not matter, crc will detect that.
112
      //end RX and signalize new packet
113
      RFM12_trans(0x8208);
114
      RFM12_status.Rx = 0;
115
      RFM12_status.New = 1;
116
    }
117
  }
118
  else if(RFM12_status.Tx)
119
  {
120
    //transmit next byte
121
    RFM12_trans(0xB800 | RFM12_Data[RFM12_Index]);
122

123
    if(!RFM12_Index)
124
    {
125
      //index=0? -> end TX
126
      RFM12_status.Tx = 0;
127
      RFM12_trans(0x8208);    // TX off
128
    }
129
    else
130
    {
131
      RFM12_Index--;
132
    }
133
  }
134
  else
135
  {
136
    RFM12_trans(0x0000);      //dummy read
137
  }
138

139
  LED_on(7);
140
}
141

142

143
void RFM12_init( void )
144
{
145
  char tmp_sreg;  
146

147
    // save SREG and diable interrupts
148
  //tmp_sreg = SREG;
149
  //cli();
150
  
151
  // CS_Pin as Output, RFM12 deselect
152
  //RFM12_CS_PORT |= (1<<RFM12_CS_PIN );
153
  //RFM12_CS_DDR |= (1<<RFM12_CS_PIN );
154
  GPIO_setdirection(GPIO_OUT,RFM12_CS_PIN);
155
  GPIO_setPin(RFM12_CS_PIN);
156

157

158
  // Interrupt-Pin as Input
159
  //RFM12_IRQ_PORT &= ~(1<<RFM12_IRQ_PIN );
160
  //RFM12_IRQ_DDR &= ~(1<<RFM12_IRQ_PIN );
161
  GPIO_clearPin(RFM12_IRQ_PIN);
162
  GPIO_setdirection(GPIO_IN,RFM12_IRQ_PIN);
163
  
164

165
  // SPI start
166
  SPI_init( RFM12_SPI_BUS_NUM );
167

168
  RFM12_trans(0xC0E0);      // AVR CLK: 10MHz
169
  RFM12_trans(0x80D7);      // Enable FIFO
170
  RFM12_trans(0xC2AB);      // Data Filter: internal
171
  RFM12_trans(0xCA81);      // Set FIFO mode
172
  RFM12_trans(0xE000);      // disable wakeuptimer
173
  RFM12_trans(0xC800);      // disable low duty cycle
174
  RFM12_trans(0xC4F7);      // AFC settings: autotuning: -10kHz...+7,5kHz
175

176
  RFM12_trans(0x0000);
177
  
178
  RFM12_status.Rx = 0;
179
  RFM12_status.Tx = 0;
180
  RFM12_status.New = 0;
181

182
    RFM12_config();
183
    // Register RFM12 as interruptsource
184
  // EXTINT_set ( RFM12_IRQ_EXINT_NUM , SENSE_LOW , RFM12_isr );  
185
  
186
  //test
187
  EXTINT_set ( &RFM12_IRQ_PORT, RFM12_IRQ_EXINT_NUM, SENSE_LOW, RFM12_isr );
188

189
  //SREG = tmp_sreg;
190
  
191
//  CLOCK_RegisterCallbackFunction ( rftransmit, SECOUND );
192
}
193

194
unsigned char RFM12_rxstart( void )
195
{
196
  if(RFM12_status.New)
197
    return(1);      //buffer not yet empty
198
  if(RFM12_status.Tx)
199
    return(2);      //tx in action
200
  if(RFM12_status.Rx)
201
    return(3);      //rx already in action
202

203
  RFM12_trans(0x82C8);    // RX on
204
  RFM12_trans(0xCA81);    // set FIFO mode
205
  RFM12_trans(0xCA83);    // enable FIFO
206
  
207
  //rf12_trans(0x0000);  //clear int
208

209
  RFM12_Index = 0;
210
  RFM12_status.Rx = 1;
211

212
  //MCUCR |= (1<<ISC01);
213
  //GICR |= (1<<INT0);
214
  return(0);        //all went fine
215
}
216

217

218
unsigned char RFM12_rxfinish( unsigned char *data )
219
{
220
  unsigned int crc, crc_chk = 0;
221
  unsigned char i;
222

223
  if( RFM12_status.Rx )
224
  {
225
    return( 255 );        //not finished yet
226
  }
227
  
228
  if( !RFM12_status.New )
229
  {
230
    return( 254 );        //old buffer
231
  }
232
  
233
  for( i = 0 ; i<RFM12_Data[0] + 1 ; i++ )
234
  {
235
    crc_chk = crcUpdate( crc_chk, RFM12_Data[ i ] );
236
  }
237
  
238
  crc = RFM12_Data[ i++ ];
239
  crc |= RFM12_Data[ i ] << 8;
240
  RFM12_status.New = 0;
241

242
/*  if( crc != crc_chk )
243
  {
244
    return( 253 );        //crc err -or- strsize
245
  }
246
  else
247
*/   {
248
    for( i = 0 ; i<RFM12_Data[ 0 ] ; i++ )
249
    {
250
      data[ i ] = RFM12_Data[ i+1 ];
251
    }
252
    return( RFM12_Data[ 0 ] );      //strsize
253
  }
254
}
255

256

257
unsigned char RFM12_txstart( unsigned char *data, unsigned char size )
258
{
259
  unsigned char i, l;
260
  unsigned int crc;
261

262
  if( RFM12_status.Tx )
263
  {
264
    return( 2 );      //tx in action
265
  }
266
  if( RFM12_status.Rx )
267
  {
268
    return( 3 );      //rx already in action
269
  }
270
  if( size > RFM12_DataLength )
271
  {
272
    return( 4 );      //str to big to transmit
273
  }
274
  
275
  RFM12_status.Tx = 1;
276
  RFM12_Index = size + 9;      //act -10 
277

278
  i = RFM12_Index;        
279
  RFM12_Data[ i-- ] = 0xAA;
280
  RFM12_Data[ i-- ] = 0xAA;
281
  RFM12_Data[ i-- ] = 0xAA;
282
  RFM12_Data[ i-- ] = 0x2D;
283
  RFM12_Data[ i-- ] = 0xD4;
284
  RFM12_Data[ i-- ] = size;
285
  crc = crcUpdate( 0 , size );
286
  for( l = 0 ; l<size ; l++ )
287
  {
288
    RFM12_Data[ i-- ] = data[ l ];
289
    crc = crcUpdate( crc, data[ l ] );
290
  }  
291
  RFM12_Data[ i-- ] = (crc & 0x00FF);
292
  RFM12_Data[ i-- ] = (crc >> 8);
293
  RFM12_Data[ i-- ] = 0xAA;
294
  RFM12_Data[ i-- ] = 0xAA;
295

296
  RFM12_trans(0x8238);      // TX on
297
  return( 0 );        //all went fine
298
}
299

300
unsigned char RFM12_txfinished( void )
301
{
302
  if(RFM12_status.Tx)
303
  {
304
    return( 255 );      //not yet finished
305
  }
306
  return(0);
307
}
308

309
void RFM12_allstop( void )
310
{
311
  //GICR &= ~(1<<INT0);    //disable int0  
312
  RFM12_status.Rx = 0;
313
  RFM12_status.Tx = 0;
314
  RFM12_status.New = 0;
315
  RFM12_trans(0x8208);    //shutdown all
316
  RFM12_trans(0x0000);    //dummy read
317
}
318

319
//-------------------------------------------------------------------------//
320
// internal used initialisation functions. 
321
// usually not called from elsewhere
322
void RFM12_config( void )
323
{
324
  RFM12_setfreq( RFM12FREQ( 433.92 ) );        // Send/ Receivefrequenzy 433,92MHz 
325
    RFM12_setbandwidth( RxBW200 , LNA_6 , RSSI_103 );  // 200kHz Bandwidth, -6dB Amplification, DRSSI threshold: -79dBm
326
    RFM12_setbaud( RFM12_BAUDRATE );          // 19200 baud
327
    RFM12_setpower( PWRdB_6 , TxBW120 );        // 1mW Power, 120kHz Frequenzyshift
328
}
329

330
void RFM12_setfreq(unsigned short freq)
331
{  
332
    if (freq<96)        // 430,2400MHz
333
  {
334
    freq=96;
335
  }
336
  else if (freq>3903)      // 439,7575MHz
337
  {
338
    freq=3903;
339
  }
340
  RFM12_trans(0xA000|freq);
341
}
342

343
void RFM12_setbandwidth( unsigned char bandwidth , unsigned char gain , unsigned char drssi )
344
{
345
  RFM12_trans( 0x9400 | ((bandwidth&7)<<5) | ((gain&3)<<3) | (drssi&7) );
346
}
347

348
void RFM12_setbaud(unsigned short baud)
349
{
350
  if ( baud<663 )
351
  {
352
    return;
353
  }
354
  if (baud<5400)          
355
  {
356
    // Baudrate= 344827,58621/(R+1)/(1+CS*7)
357
    RFM12_trans( 0xC680 | ( ( 43104/baud ) -1 ) );
358
  }
359
  else
360
  {
361
    RFM12_trans( 0xC600 | ( ( 344828UL/baud ) -1 ) );
362
  }
363
}
364

365

366
void RFM12_setpower( unsigned char power , unsigned char mod )
367
{  
368
  RFM12_trans( 0x9800 | (power&7) | ((mod&15)<<4) );
369
}
370

371
unsigned int crcUpdate(unsigned int crc, unsigned char serialData)
372
{
373
    unsigned int tmp;
374
    unsigned char j;
375

376
  tmp = serialData << 8;
377

378
  for (j=0; j<8; j++)
379
  {
380
        if((crc^tmp) & 0x8000)
381
    {
382
      crc = (crc<<1) ^ 0x1021;
383
    }
384
    else
385
    {
386
      crc = crc << 1;
387
    }
388
    tmp = tmp << 1;
389
    }
390
  return crc;
391
}
392

393
//-------------------------------------------------------------------------//
394
// hardware level functions
395
unsigned int RFM12_trans( unsigned int CMD )
396
{
397
    char tmp_sreg;
398
  int retval;
399
  CONVERTW val;
400

401
  val.w = CMD;
402
  
403
  
404
  //save SReg, clear Interrupts 
405
//  tmp_sreg = SREG;
406
//    cli();
407
    
408
  RFM12_select();
409
  
410
//retval = ( SPI_ReadWrite( RFM12_SPI_BUS_NUM , ( CMD>>8 ) & 0xff  ) ) << 8 ;
411

412
// TODO SP
413
  //SPDR = val.b[1];
414
  //while(!(SPSR & (1<<SPIF)));
415
  //val.b[1]=SPDR;
416
  
417
  val.b[0] = SPI_ReadWrite( RFM12_SPI_BUS_NUM , ( CMD>>8 ) & 0xff );
418

419
//    retval |= SPI_ReadWrite( RFM12_SPI_BUS_NUM , CMD & 0xff );
420
// TODO SP
421
  //SPDR = val.b[0];
422
  //while(!(SPSR & (1<<SPIF)));
423
  //val.b[0]=SPDR;
424

425
  val.b[1] = SPI_ReadWrite( RFM12_SPI_BUS_NUM , CMD & 0xff );
426

427
  RFM12_deselect();
428

429
  // restore interrupts
430
//    SREG = tmp_sreg;
431

432
  return( val.b[0]+(val.b[1] <<8));
433
}
434

435
void RFM12_select( void ){
436

437
  //RFM12_CS_PORT &= ~( 1<<RFM12_CS_PIN );
438
  GPIO_clearPin(RFM12_CS_PIN);
439
}
440

441
void RFM12_deselect( void ){
442

443
  //RFM12_CS_PORT |= ( 1<<RFM12_CS_PIN );
444
  GPIO_setPin(RFM12_CS_PIN);
445
}
446

447

448
void RFM12_printStatus(){
449
  //int ret = RFM12_trans(0x00);
450
  RFM12_select();
451
  //char i1 = SPI_ReadWrite(1,0x00);
452
  //char i2 = SPI_ReadWrite(1,0x00);
453
  int i = 0;
454
  i = RFM12_trans(0x0000);//i1 + (i2<<8);
455
  RFM12_deselect();
456
  
457
  
458
  printf("Status: 0b");
459
  for (int j = 0; j<16; j++){
460
    printf("%u",(i%2));
461
    i/=2;
462
    }
463
  printf("\r\n");
464
}
465

466
#endif

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren