added rf433ctl
[svn42.git] / rf433ctl / rf433ctl.pde
1 #include <avr/io.h>
2 #include <avr/interrupt.h>
3 #include <inttypes.h>
4
5 //********************************************************************//
6
7 #define DATA_OUT_PIN 13
8
9 typedef struct {
10   byte offset;
11   byte state;
12 } rf_bit_t;
13
14 // offset is number of alphas (0.08ms)
15
16 const rf_bit_t zero_bit[] = { {  4, 1 },
17                               { 16, 0 },
18                               { 20, 1 },
19                               { 32, 0 },
20                               {  0, 0 } };
21
22 const rf_bit_t one_bit[] = { { 12, 1 },
23                              { 16, 0 },
24                              { 28, 1 },
25                              { 32, 0 },
26                              {  0, 0 } };
27
28 const rf_bit_t float_bit[] = { {  4, 1 },
29                                { 16, 0 },
30                                { 28, 1 },
31                                { 32, 0 },
32                                {  0, 0 } };
33
34 const rf_bit_t sync_bit[] = { {   4, 1 },
35                               { 128, 0 },
36                               {   0, 0 } };
37
38 typedef enum { ZERO = 0, ONE , FLOAT , SYNC } adbit_t;
39 typedef byte ad_bit_t;
40 #define WORD_LEN 13
41 typedef ad_bit_t word_t[WORD_LEN];
42
43 const rf_bit_t* bit_defs[] = { zero_bit, one_bit, float_bit, sync_bit };
44
45 byte alpha_cnt = 0;
46 byte bit_cnt = 0;
47 byte chunk_cnt = 0;
48 byte word_cnt = 0;
49 const ad_bit_t* current_word;
50 byte volatile frame_finished = 1;
51
52 #define FRAME_LEN 8
53
54 #define A1_ON  0
55 #define A1_OFF 1
56 #define A2_ON  2
57 #define A2_OFF 3
58
59 #define B1_ON  4
60 #define B1_OFF 5
61 #define B2_ON  6
62 #define B2_OFF 7
63
64 #define C1_ON  8
65 #define C1_OFF 9
66 #define C2_ON  10
67 #define C2_OFF 11
68
69 #define D1_ON  12
70 #define D1_OFF 13
71 #define D2_ON  14
72 #define D2_OFF 15
73
74 const word_t words[]  = { 
75 { ZERO,  ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A1_ON
76 { ZERO,  ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // A1_OFF
77 { ZERO,  ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A2_ON
78 { ZERO,  ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // A2_OFF
79
80 { FLOAT, ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B1_ON
81 { FLOAT, ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // B1_OFF
82 { FLOAT, ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B2_ON
83 { FLOAT, ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // B2_OFF
84
85 { ZERO,  FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C1_ON
86 { ZERO,  FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // C1_OFF
87 { ZERO,  FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C2_ON
88 { ZERO,  FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // C2_OFF
89
90 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D1_ON
91 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // D1_OFF
92 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D2_ON
93 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }  // D2_OFF
94 };
95
96
97 //********************************************************************//
98
99 void start_timer()
100 {
101   // timer 1: 2 ms
102   TCCR1A = 0;                    // prescaler 1:8, WGM = 4 (CTC)
103   TCCR1B = 1<<WGM12 | 1<<CS11;   // 
104   OCR1A = 159;        // (1+159)*8 = 1280 -> 0.08ms @ 16 MHz -> 1*alpha
105 //  OCR1A = 207;        // (1+207)*8 = 1664 -> 0.104ms @ 16 MHz -> 1*alpha
106   TCNT1 = 0;          // reseting timer
107   TIMSK1 = 1<<OCIE1A; // enable Interrupt
108 }
109
110 void stop_timer() // stop the timer
111 {
112   // timer1
113   TCCR1B = 0; // no clock source
114   TIMSK1 = 0; // disable timer interrupt
115 }
116
117 void init_word(const word_t w)
118 {
119   current_word = w;
120   alpha_cnt = 0;
121   chunk_cnt = 0;
122   bit_cnt = 0;
123
124   if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
125     digitalWrite(DATA_OUT_PIN, HIGH);
126   else
127     digitalWrite(DATA_OUT_PIN, LOW);
128
129   start_timer();
130 }
131
132 ISR(TIMER1_COMPA_vect)
133 {
134   alpha_cnt++;
135   if(alpha_cnt < bit_defs[current_word[bit_cnt]][chunk_cnt].offset)
136     return;
137
138   chunk_cnt++;
139   if(bit_defs[current_word[bit_cnt]][chunk_cnt].offset != 0) {
140     if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
141       digitalWrite(DATA_OUT_PIN, HIGH);
142     else
143       digitalWrite(DATA_OUT_PIN, LOW);
144     return;
145   }
146   
147   bit_cnt++;
148   if(bit_cnt < WORD_LEN) {
149     alpha_cnt = 0;
150     chunk_cnt = 0;
151     if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
152       digitalWrite(DATA_OUT_PIN, HIGH);
153     else
154       digitalWrite(DATA_OUT_PIN, LOW);
155     return;
156   }
157   stop_timer();
158   digitalWrite(DATA_OUT_PIN, LOW);
159
160   word_cnt++;
161   if(word_cnt < FRAME_LEN)
162     init_word(current_word);
163
164   frame_finished = 1;
165 }
166
167 //***********//
168
169
170 void send_frame(const word_t w)
171 {
172   word_cnt = 0;
173   frame_finished = 0;
174   init_word(w);
175
176   for(;;)
177     if(frame_finished)
178       break;
179 }
180
181 //********************************************************************//
182
183 void setup()
184 {
185   pinMode(DATA_OUT_PIN, OUTPUT);
186   digitalWrite(DATA_OUT_PIN, LOW);
187   Serial.begin(9600);
188 }
189
190 void loop()
191 {
192   if(Serial.available()) {
193     char command = Serial.read();
194     
195     if(command == 'q')
196       send_frame(words[A1_ON]);
197     else if(command == 'a')
198       send_frame(words[A1_OFF]);
199     else if(command == 'w')
200       send_frame(words[A2_ON]);
201     else if(command == 's')
202       send_frame(words[A2_OFF]);
203
204     else if(command == 'e')
205       send_frame(words[B1_ON]);
206     else if(command == 'd')
207       send_frame(words[B1_OFF]);
208     else if(command == 'r')
209       send_frame(words[B2_ON]);
210     else if(command == 'f')
211       send_frame(words[B2_OFF]);
212
213     else if(command == 't')
214       send_frame(words[C1_ON]);
215     else if(command == 'g')
216       send_frame(words[C1_OFF]);
217     else if(command == 'z')
218       send_frame(words[C2_ON]);
219     else if(command == 'h')
220       send_frame(words[C2_OFF]);
221
222     else if(command == 'u')
223       send_frame(words[D1_ON]);
224     else if(command == 'j')
225       send_frame(words[D1_OFF]);
226     else if(command == 'i')
227       send_frame(words[D2_ON]);
228     else if(command == 'k')
229       send_frame(words[D2_OFF]);
230
231   }
232 }