123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- #include <stdbool.h>
- #include <avr/interrupt.h>
- #include <util/delay.h>
- #include "xt.h"
- #include "wait.h"
- #include "debug.h"
- static inline uint8_t pbuf_dequeue(void);
- static inline void pbuf_enqueue(uint8_t data);
- static inline bool pbuf_has_data(void);
- static inline void pbuf_clear(void);
- void xt_host_init(void) {
- XT_INT_INIT();
- XT_INT_OFF();
-
- #ifdef XT_RESET
- XT_RESET();
- #endif
-
- XT_DATA_LO();
- XT_CLOCK_LO();
- _delay_ms(20);
-
- XT_CLOCK_IN();
- XT_DATA_IN();
- XT_INT_ON();
- }
- uint8_t xt_host_recv(void) {
- if (pbuf_has_data()) {
- return pbuf_dequeue();
- } else {
- return 0;
- }
- }
- ISR(XT_INT_VECT) {
-
- static enum { START, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7 } state = START;
- static uint8_t data = 0;
- uint8_t dbit = XT_DATA_READ();
-
-
- switch (state) {
- case START:
-
- if (!dbit) return;
- break;
- case BIT0 ... BIT7:
- data >>= 1;
- if (dbit) data |= 0x80;
- break;
- }
- if (state++ == BIT7) {
- pbuf_enqueue(data);
- state = START;
- data = 0;
- }
- return;
- }
- #define PBUF_SIZE 32
- static uint8_t pbuf[PBUF_SIZE];
- static uint8_t pbuf_head = 0;
- static uint8_t pbuf_tail = 0;
- static inline void pbuf_enqueue(uint8_t data) {
- uint8_t sreg = SREG;
- cli();
- uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
- if (next != pbuf_tail) {
- pbuf[pbuf_head] = data;
- pbuf_head = next;
- } else {
- dprintf("pbuf: full\n");
- }
- SREG = sreg;
- }
- static inline uint8_t pbuf_dequeue(void) {
- uint8_t val = 0;
- uint8_t sreg = SREG;
- cli();
- if (pbuf_head != pbuf_tail) {
- val = pbuf[pbuf_tail];
- pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
- }
- SREG = sreg;
- return val;
- }
- static inline bool pbuf_has_data(void) {
- uint8_t sreg = SREG;
- cli();
- bool has_data = (pbuf_head != pbuf_tail);
- SREG = sreg;
- return has_data;
- }
- static inline void pbuf_clear(void) {
- uint8_t sreg = SREG;
- cli();
- pbuf_head = pbuf_tail = 0;
- SREG = sreg;
- }
|