Advertisement
Guest User

Untitled

a guest
Dec 18th, 2018
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.59 KB | None | 0 0
  1. enum rx_state {
  2.     RX_STATE_INIT,
  3.     RX_STATE_STARTBIT_BEGIN,
  4.     RX_STATE_STARTBIT_END,
  5.     RX_STATE_DATA_ENDED,
  6.     RX_STATE_STOPBIT_BEGIN,
  7. };
  8.  
  9. K_MSGQ_DEFINE(my_msgq, sizeof(u8_t), 10, 4);
  10.  
  11. void gpio_callback(struct device *port,
  12.            struct gpio_callback *cb, u32_t pins)
  13. {
  14.     static enum rx_state state = RX_STATE_INIT;
  15.     static u32_t prev_time = 0;
  16.     static u32_t prev_val = 0;
  17.     static u8_t recvbyte = 0;
  18.     static u32_t total_bits = 0;
  19.     u32_t bitdur = USEC_TO_HW_CYCLES(800);
  20.  
  21.     u32_t now = k_cycle_get_32();
  22.  
  23.     u32_t cur_val;
  24.     gpio_pin_read(port, GPIO_INT_PIN, &cur_val);
  25.  
  26.     u32_t delta = now - prev_time;
  27.     u32_t nbits = delta / bitdur;
  28.     bool iserr = false;
  29.  
  30.     if (prev_val == cur_val) {
  31.         iserr = true;
  32.     }
  33.  
  34.     while (!iserr && nbits) {
  35.         switch (state) {
  36.             case RX_STATE_INIT:
  37.                 if (prev_val == 0 && cur_val == 1 && nbits >= 10) {
  38.                     state = RX_STATE_STARTBIT_BEGIN;
  39.                     nbits = 0;
  40.                 }
  41.                 else {
  42.                     iserr = true;
  43.                 }
  44.                 break;
  45.  
  46.             case RX_STATE_STARTBIT_BEGIN:
  47.                 if (prev_val == 1 && cur_val == 0 && nbits > 0) {
  48.                     state = RX_STATE_STARTBIT_END;
  49.                     nbits--;
  50.                     recvbyte = 0;
  51.                     total_bits = 0;
  52.                 }
  53.                 else {
  54.                     //printk("start error prev=%u@%u cur=%u@%u nbits=%u delta=%u bitdur=%u\n", prev_val, prev_time, cur_val, now, nbits, delta, bitdur);
  55.                     iserr = true;
  56.                 }
  57.                 break;
  58.  
  59.             case RX_STATE_STARTBIT_END:
  60.                 if (total_bits + nbits > 9) {
  61.                     //printk("data: got too many bits: %u %u\n", total_bits, nbits);
  62.                     iserr = true;
  63.                     break;
  64.                 }
  65.  
  66.                 u32_t i;
  67.                 for (i = 0; i<nbits; i++) {
  68.                     if (cur_val == 1)
  69.                         recvbyte |= (1 << total_bits);
  70.                     total_bits++;
  71.  
  72.                     if (total_bits == 8) {
  73.                         state = RX_STATE_DATA_ENDED;
  74.                         break;
  75.                     }
  76.                 }
  77.  
  78.                 nbits -= i;
  79.  
  80.                 break;
  81.  
  82.             case RX_STATE_DATA_ENDED:
  83.                 if (prev_val == 1 && cur_val == 0 && nbits==1) {
  84.                     state = RX_STATE_STOPBIT_BEGIN;
  85.                     nbits--;
  86.                 }
  87.                 else {
  88.                     //printk("dataend error\n");
  89.                     iserr = true;
  90.                 }
  91.                 break;
  92.  
  93.             case RX_STATE_STOPBIT_BEGIN:
  94.                 if (prev_val == 0 && cur_val == 1 && nbits>=1) {
  95.                     state = RX_STATE_STARTBIT_BEGIN;
  96.                     nbits = 0;
  97.  
  98.                     while (k_msgq_put(&my_msgq, &recvbyte, K_NO_WAIT) != 0) {
  99.                         /* message queue is full: purge old data & try again */
  100.                         k_msgq_purge(&my_msgq);
  101.                     }
  102.  
  103.                     //printk("data: %02x\n", recvbyte);
  104.                 }
  105.                 else {
  106.                     //printk("stop error\n");
  107.                     iserr = true;
  108.                 }
  109.                 break;
  110.  
  111.             default:
  112.                 printk("state is invalid\n");
  113.                 iserr = true;
  114.                 break;
  115.         }
  116.     }
  117.  
  118.     if (iserr) {
  119.         state = RX_STATE_INIT;
  120.     }
  121.  
  122. out:
  123.     prev_val = cur_val;
  124.     prev_time = now;
  125. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement