Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- enum rx_state {
- RX_STATE_INIT,
- RX_STATE_STARTBIT_BEGIN,
- RX_STATE_STARTBIT_END,
- RX_STATE_DATA_ENDED,
- RX_STATE_STOPBIT_BEGIN,
- };
- K_MSGQ_DEFINE(my_msgq, sizeof(u8_t), 10, 4);
- void gpio_callback(struct device *port,
- struct gpio_callback *cb, u32_t pins)
- {
- static enum rx_state state = RX_STATE_INIT;
- static u32_t prev_time = 0;
- static u32_t prev_val = 0;
- static u8_t recvbyte = 0;
- static u32_t total_bits = 0;
- u32_t bitdur = USEC_TO_HW_CYCLES(800);
- u32_t now = k_cycle_get_32();
- u32_t cur_val;
- gpio_pin_read(port, GPIO_INT_PIN, &cur_val);
- u32_t delta = now - prev_time;
- u32_t nbits = delta / bitdur;
- bool iserr = false;
- if (prev_val == cur_val) {
- iserr = true;
- }
- while (!iserr && nbits) {
- switch (state) {
- case RX_STATE_INIT:
- if (prev_val == 0 && cur_val == 1 && nbits >= 10) {
- state = RX_STATE_STARTBIT_BEGIN;
- nbits = 0;
- }
- else {
- iserr = true;
- }
- break;
- case RX_STATE_STARTBIT_BEGIN:
- if (prev_val == 1 && cur_val == 0 && nbits > 0) {
- state = RX_STATE_STARTBIT_END;
- nbits--;
- recvbyte = 0;
- total_bits = 0;
- }
- else {
- //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);
- iserr = true;
- }
- break;
- case RX_STATE_STARTBIT_END:
- if (total_bits + nbits > 9) {
- //printk("data: got too many bits: %u %u\n", total_bits, nbits);
- iserr = true;
- break;
- }
- u32_t i;
- for (i = 0; i<nbits; i++) {
- if (cur_val == 1)
- recvbyte |= (1 << total_bits);
- total_bits++;
- if (total_bits == 8) {
- state = RX_STATE_DATA_ENDED;
- break;
- }
- }
- nbits -= i;
- break;
- case RX_STATE_DATA_ENDED:
- if (prev_val == 1 && cur_val == 0 && nbits==1) {
- state = RX_STATE_STOPBIT_BEGIN;
- nbits--;
- }
- else {
- //printk("dataend error\n");
- iserr = true;
- }
- break;
- case RX_STATE_STOPBIT_BEGIN:
- if (prev_val == 0 && cur_val == 1 && nbits>=1) {
- state = RX_STATE_STARTBIT_BEGIN;
- nbits = 0;
- while (k_msgq_put(&my_msgq, &recvbyte, K_NO_WAIT) != 0) {
- /* message queue is full: purge old data & try again */
- k_msgq_purge(&my_msgq);
- }
- //printk("data: %02x\n", recvbyte);
- }
- else {
- //printk("stop error\n");
- iserr = true;
- }
- break;
- default:
- printk("state is invalid\n");
- iserr = true;
- break;
- }
- }
- if (iserr) {
- state = RX_STATE_INIT;
- }
- out:
- prev_val = cur_val;
- prev_time = now;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement