/* Arduino Pro Mini 1-Wire connection */ #define WIRE1_DDR DDRB #define WIRE1_PORT PORTB #define WIRE1_PIN PINB /* OC1A/PCINT1 */ #define WIRE1_OUT PB1 /* (PCINT0/CLKO/ICP1) */ #define WIRE1_ICP PB0 #define WIRE1_IN_ICP PINB0 /* Active pullup PD7 */ #define WIRE1_PULLUP_DDR DDRD #define WIRE1_PULLUP_PORT PORTD #define WIRE1_PULLUP_OUT PD7 /* Presence detection in idle mode: external interrupt #0 */ #define WIRE1_IDLE_PRESENCE_DETECT_IRQ INT0_vect #define WIRE1_IDLE_PRESENCE_DETECT_EICRA_MASK (_BV(ISC01) | _BV(ISC00)) /* Presence detection in idle mode: low level generate IRQ */ #define WIRE1_IDLE_PRESENCE_DETECT_EICRA_ISC 0 #define WIRE1_IDLE_PRESENCE_DETECT_EIMSK_INT INT0 #define WIRE1_IDLE_PRESENCE_DETECT_EIFR_INTF INTF0 #define WIRE1_IDLE_PRESENCE_DETECT_DDR DDRD #define WIRE1_IDLE_PRESENCE_DETECT_PORT PORTD #define WIRE1_IDLE_PRESENCE_DETECT_PIN PIND #define WIRE1_IDLE_PRESENCE_DETECT_BIT PD2 #define WIRE1_TCNT TCNT1 #define WIRE1_TCCRA TCCR1A #define WIRE1_TCCRB TCCR1B #define WIRE1_TCCRC TCCR1C #define WIRE1_OCRA OCR1A #define WIRE1_OCRB OCR1B #define WIRE1_ICR ICR1 #define WIRE1_TIFR TIFR1 #define WIRE1_TIMSK TIMSK1 #define WIRE1_ICP_IRQ TIMER1_CAPT_vect #define WIRE1_OVF_IRQ TIMER1_OVF_vect #define WIRE1_COMPA_IRQ TIMER1_COMPA_vect #define WIRE1_COMPB_IRQ TIMER1_COMPB_vect #define WIRE1_POWER_ON() \ power_timer1_enable()
/* RESET TSLOT */ #define RESET_DURATION_TSLOTS 8 /* */ #define NORMAL_TLOWR_MIN 1 #define NORMAL_TLOWR_MAX 15 #define NORMAL_TSLOT_MIN 60 #define NORMAL_TSLOT_MAX 120 #define NORMAL_BIT1_MIN NORMAL_TLOWR_MIN #define NORMAL_BIT1_MAX NORMAL_TLOWR_MAX #define NORMAL_BIT0_MIN NORMAL_TSLOT_MIN #define NORMAL_BIT0_MAX NORMAL_TSLOT_MAX #define NORMAL_TREC_MIN 1 #define NORMAL_RESET (RESET_DURATION_TSLOTS * NORMAL_TSLOT_MIN) #define NORMAL_PRESENCE_START_MIN 15 #define NORMAL_PRESENCE_START_MAX 60 #define NORMAL_PRESENCE_MIN 60 #define NORMAL_PRESENCE_MAX 240 #define OVERDRIVE_TLOWR_MIN 1 #define OVERDRIVE_TLOWR_MAX 2 #define OVERDRIVE_TSLOT_MIN 6 #define OVERDRIVE_TSLOT_MAX 16 #define OVERDRIVE_BIT1_MIN OVERDRIVE_TLOWR_MIN #define OVERDRIVE_BIT1_MAX OVERDRIVE_TLOWR_MAX #define OVERDRIVE_BIT0_MIN OVERDRIVE_TSLOT_MIN #define OVERDRIVE_BIT0_MAX OVERDRIVE_TSLOT_MAX #define OVERDRIVE_TREC_MIN 1 #define OVERDRIVE_RESET (RESET_DURATION_TSLOTS * OVERDRIVE_TSLOT_MIN) #define OVERDRIVE_PRESENCE_START_MIN 2 #define OVERDRIVE_PRESENCE_START_MAX 6 #define OVERDRIVE_PRESENCE_MIN 8 #define OVERDRIVE_PRESENCE_MAX 24 /* */ #define WIRE1_MAX_PERIOD (NORMAL_TSLOT_MAX + NORMAL_TREC_MIN) /* (.. ) */ #define WIRE1_MIN_PRECISION (OVERDRIVE_TLOWR_MAX / 2) /* RESET */ #define WIRE1_RESET_PROCEDURE_DURATION (RESET_DURATION_TSLOTS * NORMAL_TSLOT_MIN * 2)
/* TOP NORMAL MODE */ #define PWM_NORMAL_MODE_TOP 0xFFFF /* TOP, */ #define PWM_FIXED_TOP_1 0xFF #define PWM_FIXED_TOP_2 0x1FF #define PWM_FIXED_TOP_3 0x3FF /* */ #define PWM_PRECISION(_n) \ ((_n) * 1000000UL / F_CPU) /* _cnt */ #define PWM_DURATION(_n, _cnt) \ ((_cnt) * (_n) * 1000000UL / F_CPU) /* */ #define PWM_PERIOD(_n, _t) \ ((_t) * 2 * (_n) * 1000000UL / F_CPU) /* */ #define PWM_COUNT_VALUE(_n, _t) \ (((F_CPU / (_n)) / 1000000UL) * (_t)) /* OCRA */ #define PWM_BOTTOM_VALUE(_n, _t) \ ((F_CPU / 2 / (_n) / 1000000UL) * (_t)) /* * TOP: * * A. * - .. >= WIRE1_MAX_PERIOD * - .. < WIRE1_MIN_PRECISION * * B. * - (.. TOP) */ #undef PWM_TOP /* 8 */ #if PWM_DURATION(8, PWM_FIXED_TOP_3) >= WIRE1_MAX_PERIOD #if PWM_PRECISION(8) < WIRE1_MIN_PRECISION #undef PWM_TOP #define PWM_TOP PWM_FIXED_TOP_3 #undef PWM_DIVIDER #define PWM_DIVIDER 8 #undef PWM_TCCRA #define PWM_TCCRA (_BV(WGM11) | _BV(WGM10)) #undef PWM_TCCRB #define PWM_TCCRB _BV(CS11) #endif #endif #if PWM_DURATION(8, PWM_FIXED_TOP_2) >= WIRE1_MAX_PERIOD #if PWM_PRECISION(8) < WIRE1_MIN_PRECISION #undef PWM_TOP #define PWM_TOP PWM_FIXED_TOP_2 #undef PWM_DIVIDER #define PWM_DIVIDER 8 #undef PWM_TCCRA #define PWM_TCCRA _BV(WGM11) #undef PWM_TCCRB #define PWM_TCCRB _BV(CS11) #endif #endif #if PWM_DURATION(8, PWM_FIXED_TOP_1) >= WIRE1_MAX_PERIOD #if PWM_PRECISION(8) < WIRE1_MIN_PRECISION #undef PWM_TOP #define PWM_TOP PWM_FIXED_TOP_1 #undef PWM_DIVIDER #define PWM_DIVIDER 8 #undef PWM_TCCRA #define PWM_TCCRA _BV(WGM10) #undef PWM_TCCRB #define PWM_TCCRB _BV(CS11) #endif #endif /* 1 */ #if PWM_DURATION(1, PWM_FIXED_TOP_3) >= WIRE1_MAX_PERIOD #if PWM_PRECISION(1) < WIRE1_MIN_PRECISION #undef PWM_TOP #define PWM_TOP PWM_FIXED_TOP_3 #undef PWM_DIVIDER #define PWM_DIVIDER 1 #undef PWM_TCCRA #define PWM_TCCRA (_BV(WGM11) | _BV(WGM10)) #undef PWM_TCCRB #define PWM_TCCRB _BV(CS10) #endif #endif #if PWM_DURATION(1, PWM_FIXED_TOP_2) >= WIRE1_MAX_PERIOD #if PWM_PRECISION(1) < WIRE1_MIN_PRECISION #undef PWM_TOP #define PWM_TOP PWM_FIXED_TOP_2 #undef PWM_DIVIDER #define PWM_DIVIDER 1 #undef PWM_TCCRA #define PWM_TCCRA _BV(WGM11) #undef PWM_TCCRB #define PWM_TCCRB _BV(CS10) #endif #endif #if PWM_DURATION(1, PWM_FIXED_TOP_1) >= WIRE1_MAX_PERIOD #if PWM_PRECISION(1) < WIRE1_MIN_PRECISION #undef PWM_TOP #define PWM_TOP PWM_FIXED_TOP_1 #undef PWM_DIVIDER #define PWM_DIVIDER 1 #undef PWM_TCCRA #define PWM_TCCRA _BV(WGM10) #undef PWM_TCCRB #define PWM_TCCRB _BV(CS10) #endif #endif #if !defined(PWM_TOP) #error "Can't build I/O procedure with current F_CPU value" #endif /* * RESET normal mode, * TOP RESET * */ #undef PWM_RESET_TCCRB /* 8 */ #if PWM_PERIOD(8, PWM_NORMAL_MODE_TOP) >= WIRE1_RESET_PROCEDURE_DURATION #undef PWM_RESET_DIVIDER #define PWM_RESET_DIVIDER 8 #undef PWM_RESET_TCCRB #define PWM_RESET_TCCRB _BV(CS11) #endif /* 1 */ #if PWM_PERIOD(1, PWM_NORMAL_MODE_TOP) >= WIRE1_RESET_PROCEDURE_DURATION #undef PWM_RESET_DIVIDER #define PWM_RESET_DIVIDER 1 #undef PWM_RESET_TCCRB #define PWM_RESET_TCCRB _BV(CS10) #endif #if !defined(PWM_RESET_TCCRB) #error "Can't build reset procedure with current F_CPU value" #endif
/* */ #define DRV_STOP_CLOCK() do { \ _SFR_BYTE(WIRE1_TCCRB) &= ~(_BV(CS12) | _BV(CS11) | _BV(CS10)); \ } while(0) /* "NORMAL MODE" */ #define DRV_TIMER_NORMAL_MODE() do { \ _SFR_BYTE(WIRE1_TCCRB) &= ~(_BV(WGM13) | _BV(WGM12)); \ _SFR_BYTE(WIRE1_TCCRA) &= ~(_BV(WGM11) | _BV(WGM10)); \ } while(0) /* OCRA (low level) */ #define DRV_DISCONNECT_OCRA_PIN() do { \ _SFR_BYTE(WIRE1_TCCRA) &= ~(_BV(COM1A1) | _BV(COM1A0)); } while(0) /* OCRA low level OCRA */ #define DRV_MATCH_OCRA_PIN_LOW() do { \ _SFR_BYTE(WIRE1_TCCRA) = \ (_SFR_BYTE(WIRE1_TCCRA) & ~_BV(COM1A0)) | _BV(COM1A1); } while(0) /* OCRA high level OCRA */ #define DRV_MATCH_OCRA_PIN_HIGH() do { \ _SFR_BYTE(WIRE1_TCCRA) |= _BV(COM1A1) | _BV(COM1A0); } while(0) /* (1 => 0) */ #define DRV_CAPTURE_FALLING_EDGE() do { \ _SFR_BYTE(WIRE1_TCCRB) &= ~_BV(ICES1); } while(0) /* (0 => 1) */ #define DRV_CAPTURE_RISING_EDGE() do { \ _SFR_BYTE(WIRE1_TCCRB) |= _BV(ICES1); } while(0) /* != 0, */ #define DRV_IS_CAPTURE_RISING() \ (_SFR_BYTE(WIRE1_TCCRB) & _BV(ICES1)) /* OCRA 1 normal */ #define NORMAL_BIT1_VALUE \ PWM_BOTTOM_VALUE(PWM_DIVIDER, (NORMAL_BIT1_MIN + NORMAL_BIT1_MAX) / 2) /* OCRA 1 overdrive */ #define OVERDRIVE_BIT1_VALUE \ PWM_BOTTOM_VALUE(PWM_DIVIDER, (OVERDRIVE_BIT1_MIN + OVERDRIVE_BIT1_MAX) / 2) /* OCRA 0 normal */ #define NORMAL_BIT0_VALUE \ PWM_BOTTOM_VALUE(PWM_DIVIDER, (NORMAL_BIT0_MIN + NORMAL_BIT0_MAX) / 2) /* OCRA 0 overdrive */ #define OVERDRIVE_BIT0_VALUE \ PWM_BOTTOM_VALUE(PWM_DIVIDER, (OVERDRIVE_BIT0_MIN + OVERDRIVE_BIT0_MAX) / 2) /* 1 normal */ #define NORMAL_BIT1_MIN_VALUE \ PWM_COUNT_VALUE(PWM_DIVIDER, NORMAL_BIT1_MIN) /* 1 overdrive */ #define OVERDRIVE_BIT1_MIN_VALUE \ PWM_COUNT_VALUE(PWM_DIVIDER, OVERDRIVE_BIT1_MIN) /* 1 normal */ #define NORMAL_BIT1_MAX_VALUE \ PWM_COUNT_VALUE(PWM_DIVIDER, NORMAL_BIT1_MAX) /* 1 overdrive */ #define OVERDRIVE_BIT1_MAX_VALUE \ PWM_COUNT_VALUE(PWM_DIVIDER, OVERDRIVE_BIT1_MAX) /* 0 normal */ #define NORMAL_BIT0_MAX_VALUE \ PWM_COUNT_VALUE(PWM_DIVIDER, NORMAL_BIT0_MAX) /* 0 overdrive */ #define OVERDRIVE_BIT0_MAX_VALUE \ PWM_COUNT_VALUE(PWM_DIVIDER, OVERDRIVE_BIT0_MAX)
/* */ typedef struct { /* , .. */ volatile uint8_t state; /* , */ union { /* RESET */ struct { /* presence TPDH */ volatile uint16_t tpdhMeasure; /* presence TPDL*/ volatile uint16_t tpdlMeasure; } reset; /* */ struct { /* , compare unit capture event */ volatile uint16_t icpOCRA; /* - , - */ volatile uint8_t value; /* - , */ volatile uint8_t pending; } io; } param; } drv_1wire_context_t; /* state: RESET */ #define DRV_1WIRE_STATE_RESET_COMPLETE 0b10000000 /* state: PRESENCE tpdhMeasure/tpdlMeasure */ #define DRV_1WIRE_STATE_PRESENCE_DETECTED 0b01000000 /* state: overdrive */ #define DRV_1WIRE_STATE_OVERDRIVE_DETECTED 0b00100000 /* state: */ #define DRV_1WIRE_STATE_IO_COMPLETE 0b00010000 /* state: */ #define DRV_1WIRE_STATE_IO_ERROR 0b00001000 /* state: parasite power */ #define DRV_1WIRE_STATE_BUS_PARASITE_POWER 0b00000100 /* state: - pullup. * */ #define DRV_1WIRE_STATE_ACTIVATE_PULLUP 0b00000010 /* state: : OCA high ICP low. * RESET. */ #define DRV_1WIRE_STATE_OCA_LOW_PASSED 0b00000010 /* state: : OCA low ICP high. * RESET. */ #define DRV_1WIRE_STATE_OCA_HIGH_PASSED 0b00000001 /* 1-wire. * RESET. */ #define DRV_1WIRE_STATE_1WIRE_DETECTED \ (DRV_1WIRE_STATE_OCA_LOW_PASSED | DRV_1WIRE_STATE_OCA_HIGH_PASSED) /* , */ #define DRV_1WIRE_STATE_DEVICE_DETECTED(_s) \ ((_s) & DRV_1WIRE_STATE_PRESENCE_DETECTED) /* , / */ #define DRV_1WIRE_STATE_IO_OK(_s) \ (((_s) & (DRV_1WIRE_STATE_PRESENCE_DETECTED | DRV_1WIRE_STATE_IO_ERROR)) == DRV_1WIRE_STATE_PRESENCE_DETECTED) #define DRV_1WIRE_TXBITS(_v, _n, _p) \ drv1WireStartIo((_v), (_n), (_p)) #define DRV_1WIRE_RXBITS(_n) \ DRV_1WIRE_TXBITS(0xFF, (_n), 0) /* */ #define DRV_1WIRE_TXBYTE(_v, _p) \ DRV_1WIRE_TXBITS((_v), 8, (_p)) #define DRV_1WIRE_RXBYTE() \ DRV_1WIRE_RXBITS(8) #define DRV_1WIRE_RESET() \ drv1WireStartReset(DRV_1WIRE_STATE() & DRV_1WIRE_STATE_OVERDRIVE_DETECTED) #if defined(WIRE1_PULLUP_OUT) #define DRV_1WIRE_PULLUP_ON() \ drv1WirePullupOn() #define DRV_1WIRE_PULLUP_OFF() \ drv1WirePullupOff() #else /* defined(WIRE1_PULLUP_OUT) */ #define DRV_1WIRE_PULLUP_ON() #define DRV_1WIRE_PULLUP_OFF() #endif /* defined(WIRE1_PULLUP_OUT) */
/* */ drv_1wire_context_t ctx1WireDriver; /** * RESET * * @param _flags - */ __INLINE void resetOperationComplete(uint8_t _flags) { /* , .. */ _SFR_BYTE(WIRE1_TIMSK) = 0; /* */ ctx1WireDriver.state |= _flags | DRV_1WIRE_STATE_RESET_COMPLETE; /* !? */ DRV_STOP_CLOCK(); /* OCA low ( high level) */ DRV_MATCH_OCRA_PIN_LOW(); _SFR_BYTE(WIRE1_TCCRC) |= _BV(FOC1A); /* precence */ VOS_KERNEL_FIRE_SIGNIFICANT_EVENT(VOS_SE_REASON_1WIRE_PRESENCE_DETECTOR); } /** * * * @param _flags */ __INLINE void ioOperationComplete(uint8_t _flags) { /* , .. */ _SFR_BYTE(WIRE1_TIMSK) = 0; /* */ ctx1WireDriver.state |= _flags | DRV_1WIRE_STATE_IO_COMPLETE; /* normal */ _SFR_BYTE(WIRE1_TCCRB) = 0; /* normal, OCA low */ _SFR_BYTE(WIRE1_TCCRA) = _BV(COM1A1); /* , OCA */ _SFR_BYTE(WIRE1_TCCRC) |= _BV(FOC1A); /* */ VOS_KERNEL_FIRE_SIGNIFICANT_EVENT(VOS_SE_REASON_1WIRE_IO_BYTE_COMPLETE); } /** * */ __INLINE __OPTIMIZE_SPEED void txBit() { if(ctx1WireDriver.param.io.value & 0x01) { /* 1 */ _SFR_WORD(WIRE1_OCRA) = (ctx1WireDriver.state & DRV_1WIRE_STATE_OVERDRIVE_DETECTED) ? OVERDRIVE_BIT1_VALUE : NORMAL_BIT1_VALUE; } else { /* 0 */ _SFR_WORD(WIRE1_OCRA) = (ctx1WireDriver.state & DRV_1WIRE_STATE_OVERDRIVE_DETECTED) ? OVERDRIVE_BIT0_VALUE : NORMAL_BIT0_VALUE; } } void drv1WireAttach() { /* */ WIRE1_POWER_ON(); /* */ DRV_STOP_CLOCK(); /* Z- pullup */ _SFR_BYTE(WIRE1_PORT) &= ~(_BV(WIRE1_OUT) | _BV(WIRE1_ICP)); /* OCA low ( high level) */ DRV_MATCH_OCRA_PIN_LOW(); _SFR_BYTE(WIRE1_TCCRC) |= _BV(FOC1A); /* Set WIRE1_OUT out direction and low signal level, force ICP is in direction */ _SFR_BYTE(WIRE1_DDR) = (_SFR_BYTE(WIRE1_DDR) & ~_BV(WIRE1_ICP)) | _BV(WIRE1_OUT); #if defined(WIRE1_IDLE_PRESENCE_DETECT_BIT) /* Z- pullup */ _SFR_BYTE(WIRE1_IDLE_PRESENCE_DETECT_PORT) &= ~_BV(WIRE1_IDLE_PRESENCE_DETECT_BIT); /* , presence idle mode */ _SFR_BYTE(WIRE1_IDLE_PRESENCE_DETECT_DDR) &= ~_BV(WIRE1_IDLE_PRESENCE_DETECT_BIT); #endif /* defined(WIRE1_IDLE_PRESENCE_DETECT_BIT) */ #if defined(WIRE1_PULLUP_OUT) /* Z- pullup */ drv1WirePullupOff(); /* pullup pin */ _SFR_BYTE(WIRE1_PULLUP_DDR) |= _BV(WIRE1_PULLUP_OUT); #endif /* defined(WIRE1_PULLUP_OUT) */ /* */ ctx1WireDriver.state = 0; } #if defined(WIRE1_PULLUP_OUT) void drv1WirePullupOn() { _SFR_BYTE(WIRE1_PULLUP_PORT) |= _BV(WIRE1_PULLUP_OUT); } void drv1WirePullupOff() { _SFR_BYTE(WIRE1_PULLUP_PORT) &= ~_BV(WIRE1_PULLUP_OUT); } #endif /* defined(WIRE1_PULLUP_OUT) */ /** * "RESET" * * @param _overdrive - OVERDRIVE ( != 0 - ) * * : * 1. NORMAL MODE TCNT = 0 * 2. OCRA = 0 FOCA * OCRA HIGH ( LOW) * 3. OCRA LOW * 4. OCRA * (.. HIGH) * 5. * * OCRA OCRA * LOW ( high) * */ void drv1WireStartReset(uint8_t _overdrive) { /* strong pullup, MOSFET */ DRV_1WIRE_PULLUP_OFF(); /* */ ctx1WireDriver.state &= ~(DRV_1WIRE_STATE_RESET_COMPLETE | DRV_1WIRE_STATE_PRESENCE_DETECTED | DRV_1WIRE_STATE_1WIRE_DETECTED); /* LOW, */ if(_overdrive) { ctx1WireDriver.param.reset.tpdhMeasure = PWM_COUNT_VALUE(PWM_RESET_DIVIDER, OVERDRIVE_RESET); } else { ctx1WireDriver.param.reset.tpdhMeasure = PWM_COUNT_VALUE(PWM_RESET_DIVIDER, NORMAL_RESET); } /* */ VOS_KERNEL_ENTER_MODE(VOS_KERNEL_RING_HARD); /* */ DRV_STOP_CLOCK(); /* NORMAL MODE */ DRV_TIMER_NORMAL_MODE(); /* */ _SFR_WORD(WIRE1_TCNT) = 0; /* OCRA high ( low level) */ DRV_MATCH_OCRA_PIN_HIGH(); _SFR_BYTE(WIRE1_TCCRC) |= _BV(FOC1A); /* LOW */ _SFR_WORD(WIRE1_OCRA) = ctx1WireDriver.param.reset.tpdhMeasure; /* */ _SFR_WORD(WIRE1_OCRB) = (ctx1WireDriver.param.reset.tpdhMeasure << 1); /* OCRA OCRA low ( high) */ DRV_MATCH_OCRA_PIN_LOW(); /* , OCRA OCRB ( 1) */ _SFR_BYTE(WIRE1_TIFR) |= _BV(OCF1A) | _BV(OCF1B); /* OCRA OCRB */ _SFR_BYTE(WIRE1_TIMSK) |= _BV(OCIE1A) | _BV(OCIE1B); /* ICP HIGH LOW */ DRV_CAPTURE_FALLING_EDGE(); /* ( noise canceller) */ _SFR_BYTE(WIRE1_TCCRB) |= PWM_RESET_TCCRB | _BV(ICNC1); /* , */ if(!(_SFR_BYTE(WIRE1_PIN) & _BV(WIRE1_ICP))) { /* , */ ctx1WireDriver.state |= DRV_1WIRE_STATE_OCA_LOW_PASSED; } /* */ VOS_KERNEL_ENTER_MODE(VOS_KERNEL_RING_SOFT); } /** * ( ) * * @param _value - * @param _bits - - ( 8) * @param _pullup - pullup * * , * OCA == 0 ( ). */ void drv1WireStartIo(uint8_t _value, uint8_t _bits, uint8_t _pullup) { /* strong pullup, MOSFET */ DRV_1WIRE_PULLUP_OFF(); /* : */ ctx1WireDriver.state &= ~(DRV_1WIRE_STATE_IO_COMPLETE | DRV_1WIRE_STATE_IO_ERROR); /* pullup */ if(_pullup) { ctx1WireDriver.state |= DRV_1WIRE_STATE_ACTIVATE_PULLUP; } else { ctx1WireDriver.state &= ~DRV_1WIRE_STATE_ACTIVATE_PULLUP; } /* */ ctx1WireDriver.param.io.value = _value; /* - , */ ctx1WireDriver.param.io.pending = _bits; /* */ VOS_KERNEL_ENTER_MODE(VOS_KERNEL_RING_HARD); /* , capture bottm reach ( 1) */ _SFR_BYTE(WIRE1_TIFR) |= _BV(ICF1) | _BV(TOV1); /* capture bottom */ _SFR_BYTE(WIRE1_TIMSK) |= _BV(ICIE1) | _BV(TOIE1); /* OCRA */ txBit(); /* 1 top, * 1 clock OCRA */ _SFR_WORD(WIRE1_TCNT) = PWM_TOP - 1; /* * : * Phase Correct PWM TOP, * OCA=1 OCRA * OCA=0 OCRA */ _SFR_BYTE(WIRE1_TCCRA) = PWM_TCCRA | _BV(COM1A1); /* * : * WGM13 WGM12 == 0 Phase Correct PWM TOP * * Input Capture Noise Canceler * capture ICP * * . */ _SFR_BYTE(WIRE1_TCCRB) = PWM_TCCRB | _BV(ICNC1) | _BV(ICES1); /* */ VOS_KERNEL_ENTER_MODE(VOS_KERNEL_RING_SOFT); } /** * BOTTOM, .. * Phase Correct PWM Mode. * BOTTOM OCRA, * * TOP. */ __OPTIMIZE_SPEED ISR(WIRE1_OVF_IRQ) { if(ctx1WireDriver.param.io.pending--) { /* */ ctx1WireDriver.param.io.value >>= 1; /* compare unit */ ctx1WireDriver.param.io.icpOCRA = _SFR_WORD(WIRE1_OCRA); /* OCRA , * . * TOP. */ if(ctx1WireDriver.param.io.pending) { txBit(); } else { /* , */ } } else { /* capture . * . */ ioOperationComplete(DRV_1WIRE_STATE_IO_ERROR); } } /** * capture */ __OPTIMIZE_SPEED ISR(WIRE1_ICP_IRQ) { if(ctx1WireDriver.state & DRV_1WIRE_STATE_RESET_COMPLETE) { /* * RESET . - , * . * ICP 0 1. * (, ) * io.icpOCRA + _SFR_WORD(WIRE1_ICR) . * * .. 255, * uint8_t. */ /* */ uint16_t lowDuration = ctx1WireDriver.param.io.icpOCRA + _SFR_WORD(WIRE1_ICR); if(ctx1WireDriver.state & DRV_1WIRE_STATE_OVERDRIVE_DETECTED) { /* OVERDRIVE */ if((lowDuration < OVERDRIVE_BIT1_MIN_VALUE) || (lowDuration > OVERDRIVE_BIT0_MAX_VALUE)) { /* */ ioOperationComplete(DRV_1WIRE_STATE_IO_ERROR); /* */ return; } /* */ if(lowDuration < OVERDRIVE_BIT1_MAX_VALUE) { /* . 1*/ ctx1WireDriver.param.io.value |= 0x80; } } else { /* */ if((lowDuration < NORMAL_BIT1_MIN_VALUE) || (lowDuration > NORMAL_BIT0_MAX_VALUE)) { /* */ ioOperationComplete(DRV_1WIRE_STATE_IO_ERROR); /* */ return; } /* */ if(lowDuration < NORMAL_BIT1_MAX_VALUE) { /* . 1*/ ctx1WireDriver.param.io.value |= 0x80; } } if(!ctx1WireDriver.param.io.pending) { /* (, , ) - */ if(ctx1WireDriver.state & DRV_1WIRE_STATE_ACTIVATE_PULLUP) { /* pullup */ DRV_1WIRE_PULLUP_ON(); } /* / */ ioOperationComplete(0); } } else { /* RESET. * ICP HIGH LOW. * presence pulse. */ if(DRV_IS_CAPTURE_RISING()) { /* ICES , */ /* TPDL */ ctx1WireDriver.param.reset.tpdlMeasure = _SFR_WORD(WIRE1_ICR) - ctx1WireDriver.param.reset.tpdlMeasure; /* .. , * OCR * . */ ctx1WireDriver.state |= DRV_1WIRE_STATE_OCA_HIGH_PASSED; /* , presence */ resetOperationComplete(DRV_1WIRE_STATE_PRESENCE_DETECTED); } else { /* ICES , */ ctx1WireDriver.param.reset.tpdlMeasure = _SFR_WORD(WIRE1_ICR); /* TPDH */ ctx1WireDriver.param.reset.tpdhMeasure = ctx1WireDriver.param.reset.tpdlMeasure - ctx1WireDriver.param.reset.tpdhMeasure; /* */ DRV_CAPTURE_RISING_EDGE(); } } } /** * OCRA */ __OPTIMIZE_SPEED ISR(WIRE1_COMPA_IRQ) { /* OCRA RESET. * , OCRA * low, high. * , * high low (.. * presence pulse, ). */ /* ICF ( 1) */ _SFR_BYTE(WIRE1_TIFR) |= _BV(ICF1); /* capture */ _SFR_BYTE(WIRE1_TIMSK) |= _BV(ICIE1); } /** * OCRB * * RESET * PRESENCE. */ __OPTIMIZE_SPEED ISR(WIRE1_COMPB_IRQ) { /* OCRB RESET. * , presence * . * 1-wire * . */ if(_SFR_BYTE(WIRE1_PIN) & _BV(WIRE1_ICP)) { /* , */ ctx1WireDriver.state |= DRV_1WIRE_STATE_OCA_HIGH_PASSED; } /* , presence */ resetOperationComplete(0); }
Source: https://habr.com/ru/post/322710/
All Articles