basic command implementation traditional way
[cortex-from-scratch] / drivers / tsensor.c
index 6cd0ffd..9545e98 100644 (file)
@@ -1,12 +1,11 @@
 /* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
  * 
  * $LOG$
- * 2019/8/4 - ROBIN KRENS      
+ * 2019/8/28 - ROBIN KRENS     
  * PreInitial version 
  * 
  * $DESCRIPTION$
- * Temperature sensor 
- * [in dev]
+ * TIMERS, non-blocking...
  *
  * */
 
 
 #include <drivers/tsensor.h>
 
-#define PRESCALER 8000 // 1 kHz
+#define PRESCALER 8 // 1 MHz (1 microsecond)
+#define MAXBUF 10
 
-int *ccr1, *ccr2, *ccr1b, *ccr2b;
-bool s1, s2;
+int cnt;
+enum status { INIT, WAIT_INIT, INIT_DONE } current_status;
+enum rstatus { READ, READ_INIT, READ_DONE } read_status;
+
+static struct {
+       uint8_t buf[MAXBUF];
+       uint8_t pos;
+} readbuf;
+
+static struct {
+       char cmd;
+       uint8_t pos;
+} sensor_cmd;
+
+//
+void read_init();
+
+static void in_conf() {
+       rwrite(GPIOB_CRL, 0x44444444);
+}
+
+static void out_conf() {
+       rwrite(GPIOB_CRL, 0x46444444); // open drain (with pullup resistor)
+}
 
- void * update_handler() {
+/* set preload and generate update event */
+static void timer_config(uint16_t preload) {
+       rwrite(TIM4_ARR, preload);
+       rsetbit(TIM4_EGR, 0);
+}
+
+static void presence_pulse_conf() {
+
+       current_status = INIT;
+       out_conf();
+       rclrbit(GPIOB_ODR, 6); // low
+       timer_config(480); // > 480 us
+}
+
+static void presence_reply_conf() {
+
+       current_status = WAIT_INIT;
+       in_conf();
+       timer_config(60); // > 60 us
+}
 
-/*     s1 = false;
-       s2 = false;
-       ccr1 = 0xFFFFFFFF;
-               ccr2 = 0xFFFFFFFF;
-               ccr1b = 0xFFFFFFFF;
-               ccr2b = 0xFFFFFFFF;
+static void finish_init() {
+       current_status = INIT_DONE;
+       timer_config(480);
+} 
+
+/* Handlers for read, write and init pulses */
+
+void * write_handler() {
+
+
+
+       // i
+       // in_conf();
+
+
+
+       rclrbit(TIM4_SR1, 0);
+       rclrbit(TIM4_SR1, 1);
+       if (sensor_cmd.pos < 7) {
        
-       if(rchkbit(TIM4_SR1, 1)) {
-                       s1 = true;
-               //      printf("CCR1: %p\n", *TIM4_CCR1);
-               //      printf("CCR2: %p\n", *TIM4_CCR2);
-                       ccr1 = *TIM4_CCR1;
-                       ccr2 = *TIM4_CCR2;
-                       rclrbit(TIM4_SR1, 1); 
-       }
+               if ((sensor_cmd.cmd >> sensor_cmd.pos+1) & 0x01) {
+                       printf("1\n");
+                       rwrite(TIM4_CCR1, 5);
+                       rsetbit(TIM4_EGR, 0);
+               }
+                       
+               else {
+                       printf("0");
+                       rwrite(TIM4_CCR1, 60);
+                       rsetbit(TIM4_EGR, 0);
        
-       if(rchkbit(TIM4_SR1, 2)) {
-                       s2 = true;
-                       ccr1b = *TIM4_CCR1;
-                       ccr2b = *TIM4_CCR2;
-                       rclrbit(TIM4_SR1, 2);
+               }
+               sensor_cmd.pos++;
+       }
+       else {
+
+               read_init();
        }
        
-       if(rchkbit(TIM4_SR1, 6)) {
-       //              printf("TRIGGER\n");
-                       rclrbit(TIM4_SR1, 6);
+}
+
+void * reply_handler() {
+
+
+       cnt++;
+       if (cnt > 16) {
+               for(;;);
        }
 
        rclrbit(TIM4_SR1, 0);
-//     rclrbit(TIM4_SR1, 9); // OF
-//     rclrbit(TIM4_SR1, 10); // OF
+       rclrbit(TIM4_SR1, 1);
+       switch(read_status) {
+               case(READ_INIT):
+                       in_conf();
+                       read_status = READ;
+                       rsetbit(GPIOB_BSRR, 22); // low (<- reset) 
+                       if (rchkbit(GPIOB_IDR, 6)) {
+                                       printf("h\n");
+                       }
+                       else {
+                               printf("l\n");
+                       }
+                       timer_config(60);
+                       break;
+               case(READ):
+                       out_conf();
+                       rclrbit(GPIOB_ODR, 6); // low
+                       read_status = READ_INIT;
+                       timer_config(1);
+                       break;
+               case(READ_DONE):
+                       // terminate
+                       break;
+       }
+
+
+} 
+
+
+void read_init() {
+
+
+       rclrbit(TIM4_CR1, 0); // stop
+       rclrbit(TIM4_CCER, 0);
+       rclrbit(TIM4_CCER, 1);
 
-       // TODO clear overflow tag
+       //rwrite(GPIOB_CRL, 0x46444444); // floating
+       out_conf();
+       rsetbit(TIM4_CR1, 2); // only overflow generates update
+       read_status = READ_INIT;
+       timer_config(1); // init 1us
+
+       ivt_set_gate(46, reply_handler, 0);
+       rsetbit(NVIC_ISER0, 30); // interupt 41 - 32
        
-       printf("SR1/CCR1: %p\n", ccr1);
-       printf("SR1/CCR2: %p\n", ccr2);
-       printf("SR2/CCR1: %p\n", ccr1b);
-       printf("SR2/CCR2: %p\n", ccr2b);
-
-       if (s1)
-               printf("EDGE DOWN\n");
-       if (s2)
-               printf("EDGE UP\n");
-
-       s1 = false;
-       s2 = false; */
-}
+       //rclrbit(TIM4_DIER, 0);
+
+       rclrbit(GPIOB_ODR, 6); // low
+       rsetbit(TIM4_DIER, 0);
+
+       rsetbit(TIM4_CR1, 0);
 
-static void reset() {
-       rwrite(GPIOB_CRL, 0x44444444);
 }
 
-void * tmp_update_handler() {
 
-       printf("SR: %p\n", *TIM4_SR1);
+void write_init() {
+
+       sensor_cmd.cmd = 0x33;
+       sensor_cmd.pos = 0;
+
+       rsetbit(RCC_APB2ENR, 3); // GPIOB enable
+       rsetbit(RCC_APB1ENR, 2); // TIM4 enable
+       rsetbitsfrom(TIM4_CR1, 5, 0x00); // edge-aligned mode
+       rclrbit(TIM4_CR1, 4); // upcounter (clrbit! not needed to set)
+       rsetbit(TIM4_CR1, 2); // only overflow generates update
+       rwrite(TIM4_PSC, PRESCALER - 1);
+       rwrite(GPIOB_CRL, 0x4A444444);
        
-       rclrbit(TIM4_CR1, 0);   /* EMULATOR STOP */
-       rclrbit(TIM4_SR1, 0);
-       rclrbit(TIM4_SR1, 1);
-               reset();
-               tsensor_input(0xFFFF);
 
-//     if(rchkbit(TIM4_SR1, 1)) {
-//             printf("TEST\n");
-//     }
+       timer_config(61);       
+
+       if ((sensor_cmd.cmd >> sensor_cmd.pos) & 0x01) {
+               printf("1\n");
+               rwrite(TIM4_CCR1, 5); // < 15ms
+       }
+       else {
+               printf("0\n");
+               rwrite(TIM4_CCR1, 60);
+       }
+
+       rsetbitsfrom(TIM4_CCMR1, 4, 0x6); // forced high on match
+       
+       rsetbit(TIM4_CCER, 0);
+       rsetbit(TIM4_CCER, 1);
+       
+       // set write handler
+       ivt_set_gate(46, write_handler, 0);
+       rsetbit(NVIC_ISER0, 30); // interupt 41 - 32
+       
+       //rsetbit(TIM4_DIER, 1);
+       rsetbit(TIM4_DIER, 0);
+       rsetbit(TIM4_CR1, 0);
 
 }
 
-void * cnt_complete_handler() {
-       rclrbit(TIM4_CR1, 0);
+
+void * init_handler() {
+
+       switch(current_status) {
+                       case (INIT):
+                               printf("M: reset\n");
+                               presence_reply_conf();
+                               break;
+                       case (WAIT_INIT):
+                               if (!rchkbit(GPIOB_IDR, 6)) {
+                                       printf("S: yes\n");
+                               }
+                               else {
+                                       printf("S: no\n");
+                               }
+                               finish_init();
+                               break;
+
+                       case (INIT_DONE): 
+                               printf("M: fin\n");
+                               write_init();
+                               break;
+
+                       default:
+                               printf("no status\n");
+                       }
+
        rclrbit(TIM4_SR1, 0);
-       rclrbit(TIM4_DIER, 0);
-       rwrite(GPIOB_CRL, 0x44444444);
-       printf("CNT COMPLETE\n");
-       tsensor_input(0xFFFF);
-}
+} 
+
+/* TODO: write
+ * uint8_t cmd = 0x33
+ * if (cmd & 0x01)
+ *     1 slot
+ * else 0 slot
+ * cmd = cmd >> 1
+ *
+ * read, similar as pulse response */
 
-int cnt;
 
 void * bare_handler() {
 
@@ -126,139 +273,183 @@ void * bare_handler() {
        printf("Count event %d\n", cnt);
        int switchled = cnt % 2;
        if (switchled) {
+               rwrite(GPIOB_CRL, 0x46444444); //  open drain general for sensor?
                printf("setting low\n");
                rclrbit(GPIOB_ODR, 6); // low
        }
        else {
-               printf("setting high\n");
-               rsetbit(GPIOB_ODR, 6); // high
+               printf("pulling high \n");
+               rwrite(GPIOB_CRL, 0x44444444); //  open drain general for sensor?
+               //rsetbit(GPIOB_ODR, 6); // high
+               
        }
        rclrbit(TIM4_SR1, 0);
 }
 
+void send_cmd(unsigned char cmd) {
+
+
+       int pos = 0;
+
+       for (int i = 0; i < 8; i++) {
+               out_conf();
+               rclrbit(GPIOB_ODR, 6);
+               if ((cmd >> pos) & 0x01) {
+                       _block(5);
+                       in_conf();
+                       _block(60);
+               //      printf("1");
+               }
+               else {
+                       _block(60);
+                       in_conf();
+               //      printf("0");
+               }
+               pos++;
+       }
+}
 
-void tsensor_simple(uint16_t preload) {
-       
-       rsetbit(RCC_APB1ENR, 2); // TIM4 enable
-
-       rsetbitsfrom(TIM4_CR1, 5, 0x00); // edge-aligned mode
-       rclrbit(TIM4_CR1, 4); // upcounter (clrbit! not needed to set)
-       rsetbit(TIM4_CR1, 2); // only overflow generates update
+void read_reply() {
+
+       for (int i = 0; i < 64; i++) {
+               out_conf();
+               rclrbit(GPIOB_ODR, 6);
+               _block(3);
+               in_conf();
+               if (rchkbit(GPIOB_IDR,6))
+               {
+                       printf("1");
+               }       
+               else {
+                       printf("0");
+               }
+               _block(60);
+       }
 
-       rwrite(TIM4_PSC, PRESCALER - 1);
-       rwrite(TIM4_ARR, preload);
-       rsetbit(TIM4_EGR, 0);
-       
-       ivt_set_gate(46, bare_handler, 0);
-       rsetbit(NVIC_ISER0, 30); // interupt 41 - 32
+}
 
-//w    rsetbit(GPIOB_ODR, 6); // 
-       rsetbit(TIM4_DIER, 0);
-       rsetbit(TIM4_CR1, 0);
+void tsensor_init() {
 
+       rsetbit(RCC_APB2ENR, 3); // GPIOB enable
+       out_conf();     
+       rclrbit(GPIOB_ODR, 6); // loq 
+       _block(450);    
+       in_conf();
+       _block(60);
+       if (!rchkbit(GPIOB_IDR, 6)) {
+               printf("reply");
+       }
+       else {
+               printf("nothing");
+       }
+       _block(240);
+
+
+//     rsetbit(RCC_APB2ENR, 3); // GPIOB enable
+//     rsetbit(RCC_APB1ENR, 2); // TIM4 enable
+//
+//     rsetbitsfrom(TIM4_CR1, 5, 0x00); // edge-aligned mode
+//     rclrbit(TIM4_CR1, 4); // upcounter (clrbit! not needed to set)
+//     rsetbit(TIM4_CR1, 2); // only overflow generates update
+//
+//     rwrite(TIM4_PSC, PRESCALER - 1);
+//     presence_pulse_conf();
+////   rwrite(TIM4_ARR, preload);
+////   rsetbit(TIM4_EGR, 0);
+//     
+//     ivt_set_gate(46, init_handler, 0);
+//     rsetbit(NVIC_ISER0, 30); // interupt 41 - 32
+//
+////w  rsetbit(GPIOB_ODR, 6); // 
+//     rsetbit(TIM4_DIER, 0);
+//     rsetbit(TIM4_CR1, 0); // start
+
+} 
+
+void wait_for_sensor() {
+
+       out_conf();
+       rclrbit(GPIOB_ODR, 6);
+       _block(3);
+       in_conf();
+       while (!rchkbit(GPIOB_IDR, 6)) {
+               printf("c");
+               _block(60);
+               out_conf();
+               rclrbit(GPIOB_ODR, 6);
+               _block(3);
+               in_conf();
+       }
 }
 
 void run() {
 
-//w2   cnt = 0;
+       cnt = 0;
 //w2   rsetbit(RCC_APB2ENR, 3);
 //w2   rwrite(GPIOB_CRL, 0x48444444); // input with pull up down
 //w2   tsensor_simple(5000); 
 
-       cnt = 0;
-       rsetbit(RCC_APB2ENR, 3); // GPIOB enable
-       rwrite(GPIOB_CRL, 0x46444444); //  open drain general for sensor?
+       //cnt = 0;
+       //rsetbit(RCC_APB2ENR, 3); // GPIOB enable
+       //rwrite(GPIOB_CRL, 0x46444444); //  open drain general for sensor?
+
+       //rsetbit(GPIOB_BSRR, 22); // low (<- reset) 
 
-       rsetbit(GPIOB_BSRR, 22); // low (<- reset) 
+       tsensor_init();
+               send_cmd(0xCC);
+       send_cmd(0x44);
+       wait_for_sensor();
 
-       tsensor_simple(4000); // 2 second?
+       tsensor_init(); 
+       send_cmd(0xCC);
+       send_cmd(0xBE);
+       
+       //send_cmd(0xCC);
+       //send_cmd(0x44);
+       //wait_for_sensor();    
+       //send_cmd(0xBE);
+       //wait_for_sensor();
+       read_reply();
+       //send_cmd(0x33);
+       //read_reply();
+//     write_init();
 
 //     tsensor_output(580, 520);
 //     reset();
 //     tsensor_simple(580);
 }
 
-void tsensor_output(uint16_t preload, uint16_t compare/*, uint16_t pulses */) {
-
-       /* GPIO AND CLOCK */
-       rsetbit(RCC_APB2ENR, 3); // GPIOB enable
-       rwrite(GPIOB_CRL, 0x4A444444); // PB6 for Channel 1 TIM4 alternate 
-       rsetbit(RCC_APB1ENR, 2); // TIM4 enable
-       
-       rsetbitsfrom(TIM4_CR1, 5, 0x00); // edge-aligned mode
-       rclrbit(TIM4_CR1, 4); // upcounter (clrbit! not needed to set)
-       rsetbit(TIM4_CR1, 2); // only overflow generates update
-
-       rwrite(TIM4_PSC, PRESCALER - 1); // 1 MHz
-       rwrite(TIM4_ARR, preload); // preload 
-       rwrite(TIM4_CCR1, compare); // compare
-       //rwrite(TIM4_RCR, pulses - 1); /* repeat ONLY IN ADVANCED TIMER */
-       
-       rsetbit(TIM4_EGR, 0); // update generation  
-       
-       rsetbit(TIM4_CR1, 3); // one pulse mode
-       rsetbitsfrom(TIM4_CCMR1, 4, 0x6); // mode
-       
-       //rsetbit(TIM4_CCMR1, 3); // preload enable
-       //rsetbit(TIM4_CR1, 7); // buffered
-
-       rsetbit(TIM4_CCER, 0); // enable output channeli 1
-       rsetbit(TIM4_CCER, 1); // active low
-       rsetbit(TIM4_CR1, 0); // start counter
-
-       /* INTERRUPTS */        
-       ivt_set_gate(46, tmp_update_handler, 0);
-
-       rsetbit(TIM4_DIER, 1);
-       rsetbit(NVIC_ISER0, 30); // interupt 41 - 32
-       
-}
-
-void tsensor_input(uint16_t preload) {
-
-       //uint16_t timestamp;   
-       /* GPIO AND CLOCK */
-       //rsetbit(RCC_APB2ENR, 3); // GPIOB enable
-       //rwrite(GPIOB_CRL, 0x44444444); // Input floating (default state)
-       //rsetbit(RCC_APB1ENR, 2); // TIM4 enable
-       
-       //rsetbitsfrom(TIM4_CR1, 5, 0x00); // edge-aligned mode
-       //rclrbit(TIM4_CR1, 4); // upcounter (clrbit! not needed to set)
-
-       rwrite(TIM4_PSC, PRESCALER - 1); // 1 MHz
-       rwrite(TIM4_ARR, preload); // preload 
-
-       
-       rsetbit(TIM4_EGR, 0); // update generation  
-
-       rsetbit(TIM4_CCMR1, 0); // input on TI1
-       rsetbit(TIM4_CCMR1, 9); // another input TI2
-       rsetbit(TIM4_CCER, 1); // other polarity for T1, inverted
-
-       /* TODO: reg funct */
-       rsetbit(TIM4_SMCR, 4); // OLD: 101, new Edge detector
-       rsetbit(TIM4_SMCR, 6); // 
-       
-
-       // rsetbit(TIM4_SMCR, 2); // RESET rising edge triggers counter and generates update
-       rsetbit(TIM4_SMCR, 2); // OLD: 110
-       rsetbit(TIM4_SMCR, 1);
-       rsetbit(TIM4_SMCR, 0);
-       //rsetbit(TIM4_SMCR, 1); // 110
-
-       //rsetbit(TIM4_CR1, 3); // one pulse mode // NOTE: RESET after finised preload
-       // will catch multiple signal... can set fram
-       
-       rsetbit(TIM4_CCER, 0); // enable capture channel 1 (changed pos)
-       rsetbit(TIM4_CCER, 4); // enable capture channel 2 
-       /* Caught on rising edge, no need to change*/
-       /* Clear capture event flag */
-//     rsetbit(TIM4_CR1, 0); // RESET with no trigger mode start
-
-       // enable capture channel 1 interrupt
-       rsetbit(TIM4_DIER, 1);
-       rsetbit(TIM4_DIER, 2);
-        ivt_set_gate(46, update_handler, 0);
-       rsetbit(NVIC_ISER0, 30);
-
-}
+//void tsensor_output(uint16_t preload, uint16_t compare/*, uint16_t pulses */) {
+//     /* GPIO AND CLOCK */
+//     rsetbit(RCC_APB2ENR, 3); // GPIOB enable
+//     rwrite(GPIOB_CRL, 0x4A444444); // PB6 for Channel 1 TIM4 alternate 
+//     rsetbit(RCC_APB1ENR, 2); // TIM4 enable
+//     
+//     rsetbitsfrom(TIM4_CR1, 5, 0x00); // edge-aligned mode
+//     rclrbit(TIM4_CR1, 4); // upcounter (clrbit! not needed to set)
+//     rsetbit(TIM4_CR1, 2); // only overflow generates update
+//
+//     rwrite(TIM4_PSC, PRESCALER - 1); // 1 MHz
+//     rwrite(TIM4_ARR, preload); // preload 
+//     rwrite(TIM4_CCR1, compare); // compare
+//     //rwrite(TIM4_RCR, pulses - 1); /* repeat ONLY IN ADVANCED TIMER */
+//     
+//     rsetbit(TIM4_EGR, 0); // update generation  
+//     
+//     rsetbit(TIM4_CR1, 3); // one pulse mode
+//     rsetbitsfrom(TIM4_CCMR1, 4, 0x6); // mode
+//     
+//     //rsetbit(TIM4_CCMR1, 3); // preload enable
+//     //rsetbit(TIM4_CR1, 7); // buffered
+//
+//     rsetbit(TIM4_CCER, 0); // enable output channeli 1
+//     rsetbit(TIM4_CCER, 1); // active low
+//     rsetbit(TIM4_CR1, 0); // start counter
+//
+//     /* INTERRUPTS */        
+//     ivt_set_gate(46, tmp_update_handler, 0);
+//
+//     rsetbit(TIM4_DIER, 1);
+//     rsetbit(NVIC_ISER0, 30); // interupt 41 - 32
+//     
+//}