/** * @brief 1-wire read bit callback. * @note Must be called from PWM's ISR. * * @param[in] pwmp pointer to the @p PWMDriver object * @param[in] owp pointer to the @p onewireDriver object * * @notapi */ static void ow_read_bit_cb(PWMDriver *pwmp, onewireDriver *owp) { if (true == owp->reg.final_timeslot) { osalSysLockFromISR(); pwmDisableChannelI(pwmp, owp->config->sample_channel); osalThreadResumeI(&owp->thread, MSG_OK); osalSysUnlockFromISR(); return; } else { *owp->buf |= ow_read_bit(owp) << owp->reg.bit; owp->reg.bit++; if (8 == owp->reg.bit) { owp->reg.bit = 0; owp->buf++; owp->reg.bytes--; if (0 == owp->reg.bytes) { owp->reg.final_timeslot = true; osalSysLockFromISR(); /* Only master channel must be stopped here. Sample channel will be stopped in next ISR call. It is still needed to generate final interrupt. */ pwmDisableChannelI(pwmp, owp->config->master_channel); osalSysUnlockFromISR(); } } } }
static void pwm3cb(PWMDriver *pwmp) { chSysLockFromIsr(); if (pwm_cycles > 8) { pwmDisableChannelI(pwmp, 2); pwmDisableChannelI(pwmp, 3); tmp1 = (&GPT_DRIVER)->tim->CNT; } chSysUnlockFromIsr(); }
/** * @brief 1-wire reset pulse callback. * @note Must be called from PWM's ISR. * * @param[in] pwmp pointer to the @p PWMDriver object * @param[in] owp pointer to the @p onewireDriver object * * @notapi */ static void ow_reset_cb(PWMDriver *pwmp, onewireDriver *owp) { owp->reg.slave_present = (PAL_LOW == ow_read_bit(owp)); osalSysLockFromISR(); pwmDisableChannelI(pwmp, owp->config->sample_channel); osalThreadResumeI(&owp->thread, MSG_OK); osalSysUnlockFromISR(); }
/** * @brief Disables a PWM channel and its notification. * @pre The PWM unit must have been activated using @p pwmStart(). * @post The channel is disabled and its output line returned to the * idle state. * @note Depending on the hardware implementation this function has * effect starting on the next cycle (recommended implementation) * or immediately (fallback implementation). * * @param[in] pwmp pointer to a @p PWMDriver object * @param[in] channel PWM channel identifier (0...channels-1) * * @api */ void pwmDisableChannel(PWMDriver *pwmp, pwmchannel_t channel) { osalDbgCheck((pwmp != NULL) && (channel < pwmp->channels)); osalSysLock(); osalDbgAssert(pwmp->state == PWM_READY, "not ready"); pwmDisableChannelI(pwmp, channel); osalSysUnlock(); }
/* * PWM callbacks. */ static void pwm1cb(PWMDriver *pwmp) { (void)pwmp; chSysLockFromIsr(); pwm_cycles++; if (pwm_cycles > 160) { pwmDisableChannelI(pwmp, 0); pwm_cycles = 0; extChannelEnableI(&EXT_DRIVER, ECHO); tmp2 = (&GPT_DRIVER)->tim->CNT; } chSysUnlockFromIsr(); }
/** * @brief 1-wire bit transmission callback. * @note Must be called from PWM's ISR. * * @param[in] pwmp pointer to the @p PWMDriver object * @param[in] owp pointer to the @p onewireDriver object * * @notapi */ static void ow_write_bit_cb(PWMDriver *pwmp, onewireDriver *owp) { if (8 == owp->reg.bit) { owp->buf++; owp->reg.bit = 0; owp->reg.bytes--; if (0 == owp->reg.bytes) { osalSysLockFromISR(); pwmDisableChannelI(pwmp, owp->config->master_channel); osalSysUnlockFromISR(); /* used to prevent premature timer stop from userspace */ owp->reg.final_timeslot = true; return; } } /* wait until timer generate last pulse */ if (true == owp->reg.final_timeslot) { #if ONEWIRE_USE_STRONG_PULLUP if (owp->reg.need_pullup) { owp->reg.state = ONEWIRE_PULL_UP; owp->config->pullup_assert(); owp->reg.need_pullup = false; } #endif osalSysLockFromISR(); osalThreadResumeI(&owp->thread, MSG_OK); osalSysUnlockFromISR(); return; } ow_write_bit_I(owp, (*owp->buf >> owp->reg.bit) & 1); owp->reg.bit++; }
/** * @brief 1-wire search ROM callback. * @note Must be called from PWM's ISR. * * @param[in] pwmp pointer to the @p PWMDriver object * @param[in] owp pointer to the @p onewireDriver object * * @notapi */ static void ow_search_rom_cb(PWMDriver *pwmp, onewireDriver *owp) { onewire_search_rom_t *sr = &owp->search_rom; if (0 == sr->reg.bit_step) { /* read direct bit */ sr->reg.bit_buf |= ow_read_bit(owp); sr->reg.bit_step++; } else if (1 == sr->reg.bit_step) { /* read complement bit */ sr->reg.bit_buf |= ow_read_bit(owp) << 1; sr->reg.bit_step++; switch(sr->reg.bit_buf){ case 0b11: /* no one device on bus or any other fail happened */ sr->reg.result = ONEWIRE_SEARCH_ROM_ERROR; goto THE_END; break; case 0b01: /* all slaves have 1 in this position */ store_bit(sr, 1); ow_write_bit_I(owp, 1); break; case 0b10: /* all slaves have 0 in this position */ store_bit(sr, 0); ow_write_bit_I(owp, 0); break; case 0b00: /* collision */ sr->reg.single_device = false; ow_write_bit_I(owp, collision_handler(sr)); break; } } else { /* start next step */ #if !ONEWIRE_SYNTH_SEARCH_TEST ow_write_bit_I(owp, 1); #endif sr->reg.bit_step = 0; sr->reg.bit_buf = 0; } /* one ROM successfully discovered */ if (64 == sr->reg.rombit) { sr->reg.devices_found++; sr->reg.search_iter = ONEWIRE_SEARCH_ROM_NEXT; if (true == sr->reg.single_device) sr->reg.result = ONEWIRE_SEARCH_ROM_LAST; goto THE_END; } return; /* next search bit iteration */ THE_END: #if ONEWIRE_SYNTH_SEARCH_TEST (void)pwmp; return; #else osalSysLockFromISR(); pwmDisableChannelI(pwmp, owp->config->master_channel); pwmDisableChannelI(pwmp, owp->config->sample_channel); osalThreadResumeI(&(owp)->thread, MSG_OK); osalSysUnlockFromISR(); #endif }