1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 | #include <avr/pgmspace.h>
|
4 | #include <avr/eeprom.h>
|
5 | #include <util/delay.h>
|
6 | #include <stdlib.h>
|
7 |
|
8 | #define BAUD 2400UL
|
9 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
|
10 |
|
11 |
|
12 |
|
13 | #define RFM02_CS PB5 // AVR MOSI
|
14 | #define RFM02_SDI PB6 // AVR MISO
|
15 | #define RFM02_SCK PB7 // AVR SCK
|
16 | #define RFM02_IRQ PB0
|
17 |
|
18 | #define RFM02_DDR DDRB
|
19 | #define RFM02_PORT PORTB
|
20 | #define RFM02_PIN PINB
|
21 |
|
22 |
|
23 | void rfm02_init();
|
24 | void rfm02_send_data(void);
|
25 | uint8_t rfm02_send_cmd(uint16_t);
|
26 | uint8_t rfm02_send_8bit(uint8_t);
|
27 |
|
28 |
|
29 | void uart_putc(unsigned char c)
|
30 | {
|
31 | while (!(UCSRA & (1<<UDRE))); /* warten bis Senden moeglich */
|
32 | UDR = c; /* sende Zeichen */
|
33 | }
|
34 |
|
35 | //######################################################################################################
|
36 |
|
37 |
|
38 | void uart_puts( char * s )
|
39 | {
|
40 | while(*s)
|
41 | { /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
|
42 | uart_putc(*s);
|
43 | s++;
|
44 | }
|
45 | }
|
46 |
|
47 |
|
48 | void uart_init()
|
49 | {
|
50 | UCSRB |= (1<<RXEN);
|
51 | UCSRB |= (1<<TXEN);
|
52 |
|
53 | UBRRH = UBRR_VAL >> 8;
|
54 | UBRRL = UBRR_VAL;
|
55 | }
|
56 |
|
57 |
|
58 |
|
59 | char buffer = 'B';
|
60 | void rfm02_init()
|
61 | {
|
62 |
|
63 | RFM02_PORT |= (1<<RFM02_IRQ) | (1<<RFM02_CS) | (1<<RFM02_SDI); // PullUp ein / Ausgang H
|
64 | RFM02_DDR |= (1<<RFM02_CS) | (1<<RFM02_SCK) | (1<<RFM02_SDI); // Ausgänge
|
65 | RFM02_DDR &= ~(1<<RFM02_IRQ); // Eingang
|
66 |
|
67 | rfm02_send_cmd(0xCC00); // Status read
|
68 |
|
69 | rfm02_send_cmd(0xC0E0); // Power Settings: Quarz ein, Synthesizer und PA ein bei Send-Command
|
70 | rfm02_send_cmd(0xC220); //ENABLE BIT SYNC
|
71 | rfm02_send_cmd(0x8883); // Control: 1MHz Clock Out, 12,5pF Last Quarz, 120kHz Shift
|
72 | rfm02_send_cmd(0xA620); // Frequenz: 860MHz + (0,005 * 0x620) -> 867,84MHz
|
73 | rfm02_send_cmd(0xB200); // Power 2 * -3dBm -> -6dBm
|
74 | rfm02_send_cmd(0xD2C0); // Set PLL: set 33%
|
75 | rfm02_send_cmd(0xC810); // Baudrate: 344827 / 19200 = 17 - 1 -> 0x10 // Status read
|
76 | rfm02_send_cmd(0xE500 + 200); // WakeUp-Timer 2^7 *234ms ~ 30s ???!! nicht 1ms sondern 10ms !!???
|
77 | rfm02_send_cmd(0xC002); // alles aus, WakeUp-Timer ein
|
78 |
|
79 | rfm02_send_cmd(0xC440); // sleep, noch 64 Takte
|
80 | }
|
81 |
|
82 | uint8_t rfm02_send_cmd(uint16_t command)
|
83 | {
|
84 | uint8_t status;
|
85 | RFM02_PORT &= ~(1<<RFM02_CS); // CS auf L
|
86 | rfm02_send_8bit(command >> 8); // H-Byte senden
|
87 | status = rfm02_send_8bit(command & 0xFF); // L-Byte senden
|
88 | RFM02_PORT |= (1<<RFM02_CS); // CS auf H
|
89 | return status;
|
90 | }
|
91 |
|
92 | //-----------------------------------------------------------------------------------------
|
93 |
|
94 | uint8_t rfm02_send_8bit(uint8_t byte)
|
95 | {
|
96 | uint8_t i;
|
97 |
|
98 | for (i=0; i<8; i++)
|
99 | {
|
100 | if (byte & 0x80)
|
101 | {
|
102 | RFM02_PORT |= (1<<RFM02_SDI); // DATA auf H als Ausgang
|
103 | }
|
104 | else
|
105 | {
|
106 | RFM02_PORT &= ~(1<<RFM02_SDI); // DATA auf L
|
107 | }
|
108 | asm("nop");
|
109 | RFM02_PORT |= (1<<RFM02_SCK); // CLK auf H
|
110 | asm("nop");
|
111 | asm("nop");
|
112 |
|
113 | byte = (byte << 1); // nächstes Bit nach oben
|
114 |
|
115 | if (RFM02_PIN & (1<<RFM02_IRQ)) // unteres Bit Status einlesen, H?
|
116 | {
|
117 | byte |= 0x01; // DATA war H
|
118 | }
|
119 | else
|
120 | {
|
121 | byte &= ~(0x01); // DATA war L
|
122 | }
|
123 | asm("nop");
|
124 | RFM02_PORT &= ~(1<<RFM02_SCK); // CLK auf L
|
125 | }
|
126 | return byte;
|
127 | }
|
128 |
|
129 | //-----------------------------------------------------------------------------------------
|
130 |
|
131 | void rfm02_send_byte(uint8_t byte)
|
132 | {
|
133 | uint8_t i;
|
134 |
|
135 | for (i=0; i<8; i++)
|
136 | {
|
137 | while (!(RFM02_PIN & (1<<RFM02_IRQ))) {
|
138 | uart_putc('6');
|
139 | } // warten bis IRQ L/H
|
140 |
|
141 | while (RFM02_PIN & (1<<RFM02_IRQ)) {
|
142 | uart_putc('7');
|
143 | } // warten bis IRQ Impuls zuende H/L
|
144 |
|
145 | if (byte & 0x80)
|
146 | {
|
147 | RFM02_PORT |= (1<<RFM02_SDI); // DATA auf H als Ausgang
|
148 | }
|
149 | else
|
150 | {
|
151 | RFM02_PORT &= ~(1<<RFM02_SDI); // DATA auf L
|
152 | }
|
153 | byte = (byte << 1); // Bit 7 rausschieben
|
154 | }
|
155 | uart_putc('1');
|
156 | }
|
157 |
|
158 | //-----------------------------------------------------------------------------------------
|
159 |
|
160 | void rfm02_send_data()
|
161 | {
|
162 | uint8_t i;
|
163 |
|
164 | rfm02_send_cmd(0xC0E0); // einschalten
|
165 |
|
166 | RFM02_PORT &= ~(1<<RFM02_CS); // CS auf L
|
167 |
|
168 | rfm02_send_8bit(0xC6); // Kommando Daten senden
|
169 |
|
170 | rfm02_send_byte(0xAA); // Sync
|
171 | rfm02_send_byte(0xAA);
|
172 | rfm02_send_byte(0xAA);
|
173 | rfm02_send_byte(0x2D); // Magic
|
174 | rfm02_send_byte(0xD4);
|
175 |
|
176 | rfm02_send_byte(buffer);
|
177 | while (!(RFM02_PIN & (1<<RFM02_IRQ))) {
|
178 | uart_putc('3');
|
179 | }
|
180 | // auf Ende sendes letztes Byte warten -> L/H
|
181 |
|
182 | while (RFM02_PIN & (1<<RFM02_IRQ)) {
|
183 | uart_putc('4');
|
184 | } // erledigt, wenn IRQ wieder -> H/L
|
185 |
|
186 | while (!(RFM02_PIN & (1<<RFM02_IRQ))) {
|
187 | uart_putc('5');
|
188 | } // auf Ende Power Off warten -> L/H
|
189 |
|
190 |
|
191 | RFM02_PORT |= (1<<RFM02_CS); // CS auf H
|
192 |
|
193 | rfm02_send_cmd(0xC002); // alles aus, WakeUp-Timer ein
|
194 | rfm02_send_cmd(0xC440); // sleep, noch 64 Takte
|
195 |
|
196 | }
|
197 |
|
198 | int main(void) {
|
199 |
|
200 | uart_init();
|
201 | sei();
|
202 | rfm02_init();
|
203 |
|
204 | while(1) {
|
205 | _delay_ms(100);
|
206 | uart_putc('2');
|
207 | rfm02_send_data();
|
208 | }
|
209 | return 0;
|
210 | }
|