Forum: Mikrocontroller und Digitale Elektronik RFM12 an XMEGA


von Funker (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.