main.c


1
/********************************************************************
2
RFM02-Funkmodul (Empfangen)
3
4
-----------------------
5
ATMEGA168PA       RFM01
6
-----------------------
7
XCK (PD4).........SCK
8
TXD (PD1).........SDI
9
PD7...............nSEL
10
RXD (PD0).........SDO
11
PB1...............nIRQ
12
PD3...............nFFS
13
14
PB5...............LED
15
PD2...............Module-Power
16
*********************************************************************/
17
18
#include <avr/io.h>
19
#include <util/delay.h>
20
#include <avr/interrupt.h>
21
22
#define DDR_XCK DDRD
23
#define XCK 4
24
#define DDR_LED DDRB
25
#define LED 5
26
#define DDR_BLED DDRC
27
#define BLED 0
28
#define DDR_MODULE DDRD
29
#define MODULE_POWER 2
30
#define DDR_nSEL DDRD
31
#define nSEL 7
32
#define DDR_nIRQ DDRB
33
#define nIRQ 1
34
#define DDR_nFFS DDRD
35
#define nFFS 3
36
37
38
#define LED_ON() PORTB |= (1<<LED)
39
#define LED_OFF() PORTB &= ~(1<<LED)
40
#define BLED_ON() PORTC |= (1<<BLED)
41
#define BLED_OFF() PORTC &= ~(1<<BLED)
42
43
#define MODULE_ON() PORTD |= (1<<MODULE_POWER)
44
#define MODULE_OFF() PORTD &= ~(1<<MODULE_POWER)
45
#define nSEL_HIGH() PORTD |= (1<<nSEL)
46
#define nSEL_LOW() PORTD &= ~(1<<nSEL)
47
#define nIRQ_HIGH() PINB&(1<<nIRQ)
48
#define nIRQ_LOW() !(PINB&(1<<nIRQ))
49
#define nFFS_HIGH() PORTD |= (1<<nFFS)
50
#define nFFS_LOW() PORTD &= ~(1<<nFFS)
51
52
#define FOSC 8000000 // Clock Speed
53
#define BAUD 1000
54
#define MYUBRR FOSC/(2*BAUD)-1
55
56
void init_gpio()
57
{
58
  // Initialize On-Board LED on PB5
59
  LED_OFF();
60
  DDR_LED |= (1<<LED);
61
  
62
  BLED_OFF();
63
  DDR_BLED |= (1<<BLED);
64
  
65
  // Initialize Module Power
66
  MODULE_OFF();
67
  DDR_MODULE |= (1<<MODULE_POWER);
68
  
69
  // Initialize nFFS FIFO Select
70
  nFFS_LOW();
71
  DDR_nFFS |= (1<<nFFS);
72
73
  // Initialize nSEL
74
  nSEL_LOW();
75
  DDR_nSEL |= (1<<nSEL);
76
  
77
  // Initialize nIRQ (Input)
78
  // Deactivate internal Pull-Up
79
  PORTB &= ~(1<<nIRQ);
80
  DDR_nIRQ &= ~(1<<nIRQ);
81
}
82
83
void init_usart_as_spi_for_cmd(unsigned int ubrr)
84
{
85
  // SPI MODE 0 -> Data sheet page 197
86
  // This mode is used to transmit commands
87
88
  // Disable transmitter and receiver
89
  UCSR0B &= ~((1<<TXEN0) | (1<<RXEN0));
90
  
91
  //Choose Baud Rate to zero for initialization
92
  UBRR0 = 0;
93
94
  // First: Activate the Clock Generation
95
  DDR_XCK |=(1<<XCK);
96
97
  // Use USART0 in Master SPI Mode (MSPIM)
98
  UCSR0C |= (1<<UMSEL01) | (1<<UMSEL00);
99
100
  // Define SPI Data Order, Clock Phase and Clock Polarity
101
  // Data Order of RF02: MSB first
102
  UCSR0C &= ~(1<<UCSZ01);
103
  // SPI Mode 0 (I found it out with data sheets)
104
  // Clock Phase: Data shifted in RF02 on Rising Edge of SCK
105
  UCSR0C &= ~(1<<UCSZ00);
106
  // Clock Polarity: Low is idle status
107
  UCSR0C &= ~(1<<UCPOL0);
108
109
  // Enable transmitter and receiver
110
  UCSR0B |= (1<<TXEN0) | (1<<RXEN0);
111
  //UCSR0B |= (1<<TXEN0);
112
113
  // Set Baud Rate
114
  //UBRR0 = MYUBRR;
115
  UBRR0 = 4095;
116
117
  // Data Register Empty Interrupt Enable
118
  //UCSR0B |= (1<<TXCIE0) | (1<<RXCIE0);
119
  //UCSR0B |= (1<<UDRIE0);
120
  //sei();
121
}
122
123
void init_usart_as_spi_for_read(unsigned int ubrr)
124
{
125
  // SPI MODE 1 -> Data sheet page 197
126
  // This mode is used to read status or received data
127
  
128
  // Disable transmitter and receiver
129
  UCSR0B &= ~((1<<TXEN0) | (1<<RXEN0));
130
  
131
  //Choose Baud Rate to zero for initialization
132
  UBRR0 = 0;
133
134
  // First: Activate the Clock Generation
135
  DDR_XCK |=(1<<XCK);
136
137
  // Use USART0 in Master SPI Mode (MSPIM)
138
  UCSR0C |= (1<<UMSEL01) | (1<<UMSEL00);
139
140
  // Define SPI Data Order, Clock Phase and Clock Polarity
141
  // Data Order of RF02: MSB first
142
  UCSR0C &= ~(1<<UCSZ01);
143
  // SPI Mode 1 (I found it out with data sheets)
144
  // Clock Phase: Data shifted out of RF01 on Falling Edge of SCK
145
  UCSR0C |= (1<<UCSZ00);
146
  // Clock Polarity: Low is idle status
147
  UCSR0C &= ~(1<<UCPOL0);
148
149
  // Enable transmitter and receiver
150
  UCSR0B |= (1<<TXEN0) | (1<<RXEN0);
151
  //UCSR0B |= (1<<TXEN0);
152
153
  // Set Baud Rate
154
  //UBRR0 = MYUBRR;
155
  UBRR0 = 4095;
156
157
  // Data Register Empty Interrupt Enable
158
  //UCSR0B |= (1<<TXCIE0) | (1<<RXCIE0);
159
  //UCSR0B |= (1<<UDRIE0);
160
  //sei();
161
}
162
163
void view_byte(uint8_t byte)
164
{
165
  unsigned wait = 700;
166
  for (int bit=0;bit<8;bit++)
167
  {
168
    LED_ON();
169
    if ((byte & 0b00000001)==0) BLED_OFF();
170
    else BLED_ON();
171
    _delay_ms(wait);
172
    LED_OFF();
173
    _delay_ms(wait);
174
    byte = byte>>1;
175
  }
176
  BLED_OFF();
177
}
178
179
void error()
180
{
181
  for (int i=0; i<20;i++)
182
  {
183
    LED_ON();
184
    _delay_ms(50);
185
    LED_OFF();
186
    _delay_ms(50);
187
  }
188
}
189
190
uint8_t receive_usart()
191
{
192
  if( UCSR0A & (1<<RXC0) ) return UDR0;
193
  else
194
  {
195
    error();
196
    return 0;
197
  }
198
199
}
200
201
void transmitCmd(uint16_t cmd)
202
{
203
  // Clear TXC0 flag for new transmission. It is not cleared automatically because no transmit complete interrupt is executed.
204
  // Clearing this bit by writing a one to its bit location <--- Yes, its true!
205
  UCSR0A |= (1<<TXC0);
206
207
  nSEL_LOW();
208
209
  uint8_t byteToSend = 0;
210
211
  // Wait for empty transmit buffer
212
  while ( !(UCSR0A & (1<<UDRE0)) );
213
214
  byteToSend = (cmd & 0b1111111100000000)>>8;
215
  UDR0 = byteToSend;
216
217
  // Wait for empty transmit buffer
218
  while ( !(UCSR0A & (1<<UDRE0)) );
219
220
  byteToSend = (cmd & 0b0000000011111111);
221
  UDR0 = byteToSend;
222
223
  //while ( !(UCSR0A & (1<<RXC0)) ) LED_ON();
224
  //LED_OFF();
225
  //_delay_ms(100);
226
  /* Get and return received data from buffer */
227
228
  while(!(UCSR0A & (1<<TXC0)));
229
  _delay_ms(1);
230
  nSEL_HIGH();
231
232
  // Wait for data to be received
233
  //while ( !(UCSR0A & (1<<RXC0)) );
234
  // Get and return received data from buffer
235
  //return UDR0;
236
}
237
238
/*
239
void transmitData(uint16_t data)
240
{
241
  uint8_t irq = 0;
242
  while(nIRQ_HIGH());
243
  for (int bit=0;bit<8;bit++)
244
  {
245
    if(data & 0b10000000) HIGH_BIT();
246
    else LOW_BIT();
247
    data = data<<1;
248
249
    if (nIRQ_LOW()) irq &= ~(1<<bit);
250
    while(nIRQ_LOW());
251
    if (nIRQ_HIGH()) irq |= (1<<bit);
252
    while(nIRQ_HIGH());
253
  }
254
  view_byte(irq);
255
}
256
*/
257
258
void clearTXBuffer()
259
{
260
  uint8_t tmp;
261
  while (UCSR0A & (1<<RXC0)) tmp = UDR0;
262
}
263
264
void init_rf01()
265
{
266
  // nFFS High recommended by data sheet
267
  nFFS_HIGH();
268
  
269
  // Switch on RF01
270
  MODULE_ON();
271
  
272
  // Initialize Module
273
  nSEL_HIGH();
274
}
275
276
void heartbeat()
277
{
278
  //LED_ON();
279
  BLED_ON();
280
  _delay_ms(200);
281
  //LED_OFF();
282
  BLED_OFF();
283
  _delay_ms(200);
284
  //LED_ON();
285
  BLED_ON();
286
  _delay_ms(200);
287
  //LED_OFF();
288
  BLED_OFF();
289
  _delay_ms(200);
290
}
291
292
int main(void)
293
{
294
  init_gpio();
295
  _delay_ms(1000);  
296
  init_rf01();
297
298
  heartbeat();
299
  _delay_ms(1000);
300
301
  uint8_t dataReceived = 0;
302
303
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
304
  ////////////////////////////////////////////////////////////// COMMANDS /////////////////////////////////////////////////////////////
305
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
306
307
  //  1: Configuration Setting Command: Frequency band, low battery detector, wake-up timer, crystal oscillator load capacitance, baseband filter bandwidth, clock output
308
  // 100 (CMD) 01 (433 MHz) 00 (Low Batteery Det Off) 1 (Crystal On During Sleep Mode) 1000 (x3-x0 Crystal Load Cap) 101 (Baseband Bandwidth) 0 (dc)
309
  uint16_t configSetCmd = 0b1000100110001010;
310
311
  //  2: Frequency Setting Command: Set the frequency of the local oscillator
312
  // 1010 (CMD) 0110 0100 0000 (F) -> f0 = 10 MHz * 1 * (43 + 1600(F)/4000) = 434 MHz
313
  // F = 96 to 3903
314
  uint16_t freqSetCmd = 0b1010011001000000;
315
316
  //  3: Receiver Setting Command: Set VDI source, LNA gain, RSSI threshold
317
  // 1100 0000 (CMD) 10 (Valid Data Indicator VDI Output) 00 (LNA Gain) 000 (RSSI Threshold) 0 (Enable Receiver Chain)
318
  uint16_t receiverSetCmd = 0b1100000010000000;
319
  uint16_t enableReceiverCmd = 0b1100000010000001;
320
321
  //  4: Wake-Up Timer Command: Wake-up time period
322
  uint16_t wakeUpTimerCmd = 0;
323
324
  //  5: Low Duty-Cycle Command: Set duty-cycle, enable low duty-cycle mode
325
  uint16_t lowDutyCycleCmd = 0;
326
327
  //  6: Low Battery Detector and Clock Divider Command: Set LBD threshold voltage and microcontroller clock division ratio
328
  // 1100 0010 (CMD) 010 (d2-d0 Clk Output Frequency) 00000 (t4-t0 Low Battery Threshold Voltage) -> V = 2.25V + T*0.1V
329
  uint16_t lowBatClockDivCmd = 0b1100001001000000;
330
  
331
  //  7: AFC Control Command: Set AFC parameters
332
  // 1100 0110 (CMD) 10 (Automatic Operation) 01 (Frequency Offset Limit) 1 (Strobe Edge) 0 (High accuracy mode) 1 (Output frequency offset register) 1 (Calculate offset frequency)
333
  uint16_t afcControlCmd = 0b1100011010011011;
334
  
335
  //  8: Data Filter Command: Set data filter type, clock recovery parameters
336
  // 1100 0100 (CMD) 0 (Clk Recovery Auto Lock Control) 0 (Clk Recovery Lock Control) 1 (x) 01 (Filter Type) 010 (f2-f0 DQD Threshold Parameter)
337
  uint16_t dataFilterCmd = 0b1100010000101010;
338
339
  //  9: Data Rate Command: Bit rate
340
  // 1100 1000 (CMD) 0 (cs) 100 0111 (R) -> BR = 10 MHz / 29 / (R+1) / (1+cs*7) = 10 MHz / 29 / (71+1) / (1+0*7) = 4,789 kbps
341
  // Data rate = 600 bps to 115,2 kbps
342
  uint16_t dataRateCmd = 0b1100100001000111;
343
  
344
  // 10: Output and FIFO Command: Set FIFO IT level, FIFO start control, FIFO enable and FIFO fill enable
345
  // 1100 1110 (CMD) 1000 (f3-f0 FIFO Interrupt IT Level) 01 (FIFO Fill Start Condition) 0 (Enables FIFO Fill After Synchron Word Reception) 0 (Enables 16 bit Deep FIFO Mode)
346
  uint16_t outputFifoCmd = 0b1100111010000100;
347
  uint16_t enableFifoCmd = 0b1100111010000111;
348
  
349
  // 11: Reset Mode Command: Enable / disable sensitive reset
350
  uint16_t resetModeCmd = 0;
351
352
  // 12: Status Register Command: Read status information
353
  uint16_t statusReadCmd = 0b0000000000000000;
354
355
356
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
357
  ////////////////////////////////////////////////////////// Configure RF02 ///////////////////////////////////////////////////////////
358
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
359
360
  uint16_t wait = 250;
361
362
363
  //transmitCmd(statusReadCmd);
364
  //dataReceived = receive_usart();
365
  //if(dataReceived != 0) view_byte(dataReceived);
366
  //dataReceived = receive_usart();
367
  //if(dataReceived != 0) view_byte(dataReceived);
368
/*
369
  //_delay_ms(wait);
370
  heartbeat();
371
  transmitCmd(configSetCmd);
372
  clearTXBuffer();
373
374
  //_delay_ms(wait);
375
  heartbeat();
376
  transmitCmd(freqSetCmd);
377
  clearTXBuffer();
378
379
  //_delay_ms(wait);
380
  heartbeat();
381
  transmitCmd(dataRateCmd);
382
  clearTXBuffer();
383
384
  //_delay_ms(wait);
385
  heartbeat();
386
  transmitCmd(afcControlCmd);
387
  clearTXBuffer();
388
389
  //_delay_ms(wait);
390
  heartbeat();
391
  transmitCmd(dataFilterCmd);
392
  clearTXBuffer();
393
394
  //_delay_ms(wait);
395
  heartbeat();
396
  transmitCmd(lowBatClockDivCmd);
397
  clearTXBuffer();
398
  
399
  //_delay_ms(wait);
400
  heartbeat();
401
  transmitCmd(receiverSetCmd);
402
  clearTXBuffer();
403
404
  //_delay_ms(wait);
405
  heartbeat();
406
  transmitCmd(outputFifoCmd);
407
  clearTXBuffer();
408
  
409
  //_delay_ms(wait);
410
  heartbeat();
411
  transmitCmd(enableFifoCmd);
412
  clearTXBuffer();
413
  
414
  //_delay_ms(wait);
415
  heartbeat();
416
  transmitCmd(enableReceiverCmd);
417
  clearTXBuffer();  
418
  */
419
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
420
  /////////////////////////////////////////////////////// Start Transmission //////////////////////////////////////////////////////////
421
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
422
  //_delay_ms(wait*4);
423
424
  init_usart_as_spi_for_cmd(MYUBRR);
425
  
426
  //transmitCmd(outputFifoCmd);
427
  //clearTXBuffer();
428
  
429
  while(1)
430
  {
431
    BLED_ON();
432
    _delay_ms(2000);
433
    BLED_OFF();
434
    _delay_ms(2000);
435
436
    transmitCmd(statusReadCmd);
437
    clearTXBuffer();
438
439
440
    /*
441
    if(dataReceived != 0) view_byte(dataReceived);
442
    dataReceived = receive_usart();
443
    if(dataReceived != 0) view_byte(dataReceived);
444
    */
445
446
  //transmitCmd(statusReadCmd);
447
  //clearTXBuffer();
448
  /*
449
    //dataReceived = receive_usart();
450
    //_delay_ms(2000);
451
452
    LED_ON();
453
    _delay_ms(2000);
454
    transmitCmd(powerManagementCmd);
455
    // Wait for PLL and Crystal Start
456
    _delay_ms(10);
457
    //_delay_ms(wait);
458
    transmitData(0b1010101010101010);
459
    //_delay_ms(wait);
460
    transmitCmd(standbyCmd);
461
    LED_OFF();
462
463
    _delay_ms(2000);
464
    heartbeat();
465
    _delay_ms(2000);
466
    */
467
  };
468
}
469
470
ISR (USART_TX_vect)
471
{
472
473
}
474
475
ISR (USART_RX_vect)
476
{
477
478
}