9545e983e72d59259efe2a529768c4d31f608197
[cortex-from-scratch] / drivers / tsensor.c
1 /* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
2  * 
3  * $LOG$
4  * 2019/8/28 - ROBIN KRENS      
5  * PreInitial version 
6  * 
7  * $DESCRIPTION$
8  * TIMERS, non-blocking...
9  *
10  * */
11
12 #include <stdbool.h>
13 #include <stddef.h>
14 #include <stdint.h>
15
16 #include <sys/mmap.h>
17 #include <sys/robsys.h>
18
19 #include <lib/regfunc.h>
20 #include <lib/string.h>
21 #include <lib/tinyprintf.h>
22
23 #include <drivers/tsensor.h>
24
25 #define PRESCALER 8 // 1 MHz (1 microsecond)
26 #define MAXBUF 10
27
28 int cnt;
29 enum status { INIT, WAIT_INIT, INIT_DONE } current_status;
30 enum rstatus { READ, READ_INIT, READ_DONE } read_status;
31
32 static struct {
33         uint8_t buf[MAXBUF];
34         uint8_t pos;
35 } readbuf;
36
37 static struct {
38         char cmd;
39         uint8_t pos;
40 } sensor_cmd;
41
42 //
43 void read_init();
44
45 static void in_conf() {
46         rwrite(GPIOB_CRL, 0x44444444);
47 }
48
49 static void out_conf() {
50         rwrite(GPIOB_CRL, 0x46444444); // open drain (with pullup resistor)
51 }
52
53 /* set preload and generate update event */
54 static void timer_config(uint16_t preload) {
55         rwrite(TIM4_ARR, preload);
56         rsetbit(TIM4_EGR, 0);
57 }
58
59 static void presence_pulse_conf() {
60
61         current_status = INIT;
62         out_conf();
63         rclrbit(GPIOB_ODR, 6); // low
64         timer_config(480); // > 480 us
65 }
66
67 static void presence_reply_conf() {
68
69         current_status = WAIT_INIT;
70         in_conf();
71         timer_config(60); // > 60 us
72 }
73
74 static void finish_init() {
75         current_status = INIT_DONE;
76         timer_config(480);
77
78
79 /* Handlers for read, write and init pulses */
80
81 void * write_handler() {
82
83
84
85         // i
86         // in_conf();
87
88
89
90         rclrbit(TIM4_SR1, 0);
91         rclrbit(TIM4_SR1, 1);
92         if (sensor_cmd.pos < 7) {
93         
94                 if ((sensor_cmd.cmd >> sensor_cmd.pos+1) & 0x01) {
95                         printf("1\n");
96                         rwrite(TIM4_CCR1, 5);
97                         rsetbit(TIM4_EGR, 0);
98                 }
99                         
100                 else {
101                         printf("0");
102                         rwrite(TIM4_CCR1, 60);
103                         rsetbit(TIM4_EGR, 0);
104         
105                 }
106                 sensor_cmd.pos++;
107         }
108         else {
109
110                 read_init();
111         }
112         
113 }
114
115 void * reply_handler() {
116
117
118         cnt++;
119         if (cnt > 16) {
120                 for(;;);
121         }
122
123         rclrbit(TIM4_SR1, 0);
124         rclrbit(TIM4_SR1, 1);
125         switch(read_status) {
126                 case(READ_INIT):
127                         in_conf();
128                         read_status = READ;
129                         rsetbit(GPIOB_BSRR, 22); // low (<- reset) 
130                         if (rchkbit(GPIOB_IDR, 6)) {
131                                         printf("h\n");
132                         }
133                         else {
134                                 printf("l\n");
135                         }
136                         timer_config(60);
137                         break;
138                 case(READ):
139                         out_conf();
140                         rclrbit(GPIOB_ODR, 6); // low
141                         read_status = READ_INIT;
142                         timer_config(1);
143                         break;
144                 case(READ_DONE):
145                         // terminate
146                         break;
147         }
148
149
150
151
152
153 void read_init() {
154
155
156         rclrbit(TIM4_CR1, 0); // stop
157         rclrbit(TIM4_CCER, 0);
158         rclrbit(TIM4_CCER, 1);
159
160         //rwrite(GPIOB_CRL, 0x46444444); // floating
161         out_conf();
162         rsetbit(TIM4_CR1, 2); // only overflow generates update
163         read_status = READ_INIT;
164         timer_config(1); // init 1us
165
166         ivt_set_gate(46, reply_handler, 0);
167         rsetbit(NVIC_ISER0, 30); // interupt 41 - 32
168         
169         //rclrbit(TIM4_DIER, 0);
170
171         rclrbit(GPIOB_ODR, 6); // low
172         rsetbit(TIM4_DIER, 0);
173
174         rsetbit(TIM4_CR1, 0);
175
176 }
177
178
179 void write_init() {
180
181         sensor_cmd.cmd = 0x33;
182         sensor_cmd.pos = 0;
183
184         rsetbit(RCC_APB2ENR, 3); // GPIOB enable
185         rsetbit(RCC_APB1ENR, 2); // TIM4 enable
186         rsetbitsfrom(TIM4_CR1, 5, 0x00); // edge-aligned mode
187         rclrbit(TIM4_CR1, 4); // upcounter (clrbit! not needed to set)
188         rsetbit(TIM4_CR1, 2); // only overflow generates update
189         rwrite(TIM4_PSC, PRESCALER - 1);
190         rwrite(GPIOB_CRL, 0x4A444444);
191         
192
193         timer_config(61);       
194
195         if ((sensor_cmd.cmd >> sensor_cmd.pos) & 0x01) {
196                 printf("1\n");
197                 rwrite(TIM4_CCR1, 5); // < 15ms
198         }
199         else {
200                 printf("0\n");
201                 rwrite(TIM4_CCR1, 60);
202         }
203
204         rsetbitsfrom(TIM4_CCMR1, 4, 0x6); // forced high on match
205         
206         rsetbit(TIM4_CCER, 0);
207         rsetbit(TIM4_CCER, 1);
208         
209         // set write handler
210         ivt_set_gate(46, write_handler, 0);
211         rsetbit(NVIC_ISER0, 30); // interupt 41 - 32
212         
213         //rsetbit(TIM4_DIER, 1);
214         rsetbit(TIM4_DIER, 0);
215         rsetbit(TIM4_CR1, 0);
216
217 }
218
219
220 void * init_handler() {
221
222         switch(current_status) {
223                         case (INIT):
224                                 printf("M: reset\n");
225                                 presence_reply_conf();
226                                 break;
227                         case (WAIT_INIT):
228                                 if (!rchkbit(GPIOB_IDR, 6)) {
229                                         printf("S: yes\n");
230                                 }
231                                 else {
232                                         printf("S: no\n");
233                                 }
234                                 finish_init();
235                                 break;
236
237                         case (INIT_DONE): 
238                                 printf("M: fin\n");
239                                 write_init();
240                                 break;
241
242                         default:
243                                 printf("no status\n");
244                         }
245
246         rclrbit(TIM4_SR1, 0);
247
248
249 /* TODO: write
250  * uint8_t cmd = 0x33
251  * if (cmd & 0x01)
252  *      1 slot
253  * else 0 slot
254  * cmd = cmd >> 1
255  *
256  * read, similar as pulse response */
257
258
259 void * bare_handler() {
260
261 //w2    cnt += 1;
262 //w2    printf("CHECKING STATUS\n");
263 //w2
264 //w2    if(rchkbit(GPIOB_IDR, 6)) {
265 //w2            printf("port high\n");
266 //w2    }
267 //w2    else {
268 //w2            printf("port low\n");
269 //w2    }
270         
271
272         cnt += 1;
273         printf("Count event %d\n", cnt);
274         int switchled = cnt % 2;
275         if (switchled) {
276                 rwrite(GPIOB_CRL, 0x46444444); //  open drain general for sensor?
277                 printf("setting low\n");
278                 rclrbit(GPIOB_ODR, 6); // low
279         }
280         else {
281                 printf("pulling high \n");
282                 rwrite(GPIOB_CRL, 0x44444444); //  open drain general for sensor?
283                 //rsetbit(GPIOB_ODR, 6); // high
284                 
285         }
286         rclrbit(TIM4_SR1, 0);
287 }
288
289 void send_cmd(unsigned char cmd) {
290
291
292         int pos = 0;
293
294         for (int i = 0; i < 8; i++) {
295                 out_conf();
296                 rclrbit(GPIOB_ODR, 6);
297                 if ((cmd >> pos) & 0x01) {
298                         _block(5);
299                         in_conf();
300                         _block(60);
301                 //      printf("1");
302                 }
303                 else {
304                         _block(60);
305                         in_conf();
306                 //      printf("0");
307                 }
308                 pos++;
309         }
310 }
311
312 void read_reply() {
313
314         for (int i = 0; i < 64; i++) {
315                 out_conf();
316                 rclrbit(GPIOB_ODR, 6);
317                 _block(3);
318                 in_conf();
319                 if (rchkbit(GPIOB_IDR,6))
320                 {
321                         printf("1");
322                 }       
323                 else {
324                         printf("0");
325                 }
326                 _block(60);
327         }
328
329 }
330
331 void tsensor_init() {
332
333         rsetbit(RCC_APB2ENR, 3); // GPIOB enable
334         out_conf();     
335         rclrbit(GPIOB_ODR, 6); // loq 
336         _block(450);    
337         in_conf();
338         _block(60);
339         if (!rchkbit(GPIOB_IDR, 6)) {
340                 printf("reply");
341         }
342         else {
343                 printf("nothing");
344         }
345         _block(240);
346
347
348 //      rsetbit(RCC_APB2ENR, 3); // GPIOB enable
349 //      rsetbit(RCC_APB1ENR, 2); // TIM4 enable
350 //
351 //      rsetbitsfrom(TIM4_CR1, 5, 0x00); // edge-aligned mode
352 //      rclrbit(TIM4_CR1, 4); // upcounter (clrbit! not needed to set)
353 //      rsetbit(TIM4_CR1, 2); // only overflow generates update
354 //
355 //      rwrite(TIM4_PSC, PRESCALER - 1);
356 //      presence_pulse_conf();
357 ////    rwrite(TIM4_ARR, preload);
358 ////    rsetbit(TIM4_EGR, 0);
359 //      
360 //      ivt_set_gate(46, init_handler, 0);
361 //      rsetbit(NVIC_ISER0, 30); // interupt 41 - 32
362 //
363 ////w   rsetbit(GPIOB_ODR, 6); // 
364 //      rsetbit(TIM4_DIER, 0);
365 //      rsetbit(TIM4_CR1, 0); // start
366
367
368
369 void wait_for_sensor() {
370
371         out_conf();
372         rclrbit(GPIOB_ODR, 6);
373         _block(3);
374         in_conf();
375         while (!rchkbit(GPIOB_IDR, 6)) {
376                 printf("c");
377                 _block(60);
378                 out_conf();
379                 rclrbit(GPIOB_ODR, 6);
380                 _block(3);
381                 in_conf();
382         }
383 }
384
385 void run() {
386
387         cnt = 0;
388 //w2    rsetbit(RCC_APB2ENR, 3);
389 //w2    rwrite(GPIOB_CRL, 0x48444444); // input with pull up down
390 //w2    tsensor_simple(5000); 
391
392         //cnt = 0;
393         //rsetbit(RCC_APB2ENR, 3); // GPIOB enable
394         //rwrite(GPIOB_CRL, 0x46444444); //  open drain general for sensor?
395
396         //rsetbit(GPIOB_BSRR, 22); // low (<- reset) 
397
398         tsensor_init();
399         send_cmd(0xCC);
400         send_cmd(0x44);
401         wait_for_sensor();
402
403         tsensor_init(); 
404         send_cmd(0xCC);
405         send_cmd(0xBE);
406         
407         //send_cmd(0xCC);
408         //send_cmd(0x44);
409         //wait_for_sensor();    
410         //send_cmd(0xBE);
411         //wait_for_sensor();
412         read_reply();
413         //send_cmd(0x33);
414         //read_reply();
415 //      write_init();
416
417 //      tsensor_output(580, 520);
418 //      reset();
419 //      tsensor_simple(580);
420 }
421
422 //void tsensor_output(uint16_t preload, uint16_t compare/*, uint16_t pulses */) {
423 //      /* GPIO AND CLOCK */
424 //      rsetbit(RCC_APB2ENR, 3); // GPIOB enable
425 //      rwrite(GPIOB_CRL, 0x4A444444); // PB6 for Channel 1 TIM4 alternate 
426 //      rsetbit(RCC_APB1ENR, 2); // TIM4 enable
427 //      
428 //      rsetbitsfrom(TIM4_CR1, 5, 0x00); // edge-aligned mode
429 //      rclrbit(TIM4_CR1, 4); // upcounter (clrbit! not needed to set)
430 //      rsetbit(TIM4_CR1, 2); // only overflow generates update
431 //
432 //      rwrite(TIM4_PSC, PRESCALER - 1); // 1 MHz
433 //      rwrite(TIM4_ARR, preload); // preload 
434 //      rwrite(TIM4_CCR1, compare); // compare
435 //      //rwrite(TIM4_RCR, pulses - 1); /* repeat ONLY IN ADVANCED TIMER */
436 //      
437 //      rsetbit(TIM4_EGR, 0); // update generation  
438 //      
439 //      rsetbit(TIM4_CR1, 3); // one pulse mode
440 //      rsetbitsfrom(TIM4_CCMR1, 4, 0x6); // mode
441 //      
442 //      //rsetbit(TIM4_CCMR1, 3); // preload enable
443 //      //rsetbit(TIM4_CR1, 7); // buffered
444 //
445 //      rsetbit(TIM4_CCER, 0); // enable output channeli 1
446 //      rsetbit(TIM4_CCER, 1); // active low
447 //      rsetbit(TIM4_CR1, 0); // start counter
448 //
449 //      /* INTERRUPTS */        
450 //      ivt_set_gate(46, tmp_update_handler, 0);
451 //
452 //      rsetbit(TIM4_DIER, 1);
453 //      rsetbit(NVIC_ISER0, 30); // interupt 41 - 32
454 //      
455 //}