unio_value_t _unio_read() { /* release the bus */ PAOUT |= UNIO_PIN; /* try to read in middle of low or high period */ delay_micros(unio_half_bitdelay); if (PAIN & UNIO_PIN) { /* high */ delay_micros(unio_bitdelay); if (!(PAIN & UNIO_PIN)) { /* low */ delay_micros(unio_half_bitdelay); return UNIO_ZERO; } } else { /* low */ delay_micros(unio_bitdelay); if (PAIN & UNIO_PIN) { /* high */ delay_micros(unio_half_bitdelay); return UNIO_ONE; } } return UNIO_NONE; }
void _unio_write_1() { /* low-to-high */ PAOUT &= ~UNIO_PIN; delay_micros(unio_bitdelay); PAOUT |= UNIO_PIN; delay_micros(unio_bitdelay); }
void _unio_write_0() { /* high-to-low */ PAOUT |= UNIO_PIN; delay_micros(unio_bitdelay); PAOUT &= ~UNIO_PIN; delay_micros(unio_bitdelay); }
void unio_header() { /* drive bus low for at least 5 us */ PAOUT &= ~UNIO_PIN; delay_micros(/* 18.432 * 5 us = */ 92); unio_transmit(0x55, 1); }
void delay_micros (uint n) { const uint function_overhead = 6; while (n > 1000) // To avoid timer overflow { delay_micros (1000); n -= 1000; } if (n > function_overhead) { TMR1 = 0; // Reset timer to 0 PR1 = (n - function_overhead) * (PBCLK_FREQUENCY / 1000) / 1000; IFS0bits.T1IF = 0; // Clear overflow flag T1CONbits.ON = 1; // Turn timer on while (! IFS0bits.T1IF) // Wait until overflow flag is set ; } }
void unio_standby() { /* drive bus high for at least 600 us */ PAOUT |= UNIO_PIN; delay_micros(/* 18.432 * 600 us = */ 11059); }
void delay_millis (uint n) { while (n --) delay_micros (1000); }