12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- /*
- * Receive an FM-modulated signal by using a timer with input capture
- */
- #include "usbcas.h"
- static uint16_t one_bit_lo, one_bit_hi; /* Range for an edge being a "1" */
- void fmrx_init(void)
- {
- /* Stop counter */
- TCCR1B = 0;
- /* Normal mode, no comparators */
- TCCR1A = 0;
- /* Enable interrupts on input capture */
- TIMSK1 = (1 << ICIE1);
- /* Clear timer counter */
- TCNT1 = 0;
- /* Input capture noise canceler on, no prescaler, normal mode;
- * start timer
- */
- TCCR1B = (1 << ICNC1) + (1 << CS10);
- }
- static uint16_t bytes;
- void fmrx_set_speed(uint32_t baudrate)
- {
- one_bit_lo = F_CPU / (4 * baudrate);
- one_bit_hi = 3 * one_bit_lo;
- bytes = 0;
- }
- /* We "hunt" for a block until we find this bit pattern; same as ABC800 */
- #define CAS_SYNC_PATTERN 0x0216
- #define CAS_BLOCK_LEN (1+1+2+253+1+2) /* STX+type+num+data+ETX+checksum */
- /* Interrupt routine for edge capture */
- ISR(TIMER1_CAPT_vect)
- {
- static uint16_t last_edge;
- static uint16_t data;
- static uint8_t bits;
- uint16_t edge, delta;
- TCCR1B ^= (1 << ICES1); /* Next edge -> opposite polarity */
- edge = ICR1;
- delta = edge - last_edge;
- last_edge = edge;
- if (delta < one_bit_lo) {
- /* Early edge, no action */
- return;
- } else if (delta < one_bit_hi) {
- /* A data bit edge */
- data |= 1;
- } else {
- /* Clock edge */
- if (bytes) {
- if (--bits == 0) {
- fmrx_recv_byte(data);
- data = 0; /* To avoid false sync */
- bits = 8;
- bytes--;
- }
- } else if (data == CAS_SYNC_PATTERN) {
- bits = 8;
- bytes = CAS_BLOCK_LEN;
- }
- data <<= 1;
- }
- }
|