Beispiel #1
0
/**
 * @brief   Enables a channel de-activation edge notification.
 * @pre     The PWM unit must have been activated using @p pwmStart().
 * @pre     The channel must have been activated using @p pwmEnableChannel().
 * @note    If the notification is already enabled then the call has no effect.
 *
 * @param[in] pwmp      pointer to a @p PWMDriver object
 * @param[in] channel   PWM channel identifier (0...channels-1)
 *
 * @api
 */
void pwmEnableChannelNotification(PWMDriver *pwmp, pwmchannel_t channel) {

  osalDbgCheck((pwmp != NULL) && (channel < pwmp->channels));

  osalSysLock();

  osalDbgAssert(pwmp->state == PWM_READY, "not ready");
  osalDbgAssert((pwmp->enabled & (1 << channel)) != 0,
                "channel not enabled");
  osalDbgAssert(pwmp->config->channels[channel].callback != NULL,
                "undefined channel callback");

  pwmEnableChannelNotificationI(pwmp, channel);

  osalSysUnlock();
}
Beispiel #2
0
/**
 * @brief     Read some bites from slave device.
 *
 * @param[in] owp       pointer to the @p onewireDriver object
 * @param[out] rxbuf    pointer to the buffer for read data
 * @param[in] rxbytes   amount of data to be received
 */
void onewireRead(onewireDriver *owp, uint8_t *rxbuf, size_t rxbytes) {
  PWMDriver *pwmd;
  PWMConfig *pwmcfg;
  size_t mch, sch;

  osalDbgCheck((NULL != owp) && (NULL != rxbuf));
  osalDbgCheck((rxbytes > 0) && (rxbytes <= ONEWIRE_MAX_TRANSACTION_LEN));
  osalDbgAssert(owp->reg.state == ONEWIRE_READY, "Invalid state");

  /* Buffer zeroing. This is important because of driver collects
     bits using |= operation.*/
  memset(rxbuf, 0, rxbytes);

  pwmd = owp->config->pwmd;
  pwmcfg = owp->config->pwmcfg;
  mch = owp->config->master_channel;
  sch = owp->config->sample_channel;

  owp->reg.bit = 0;
  owp->reg.final_timeslot = false;
  owp->buf = rxbuf;
  owp->reg.bytes = rxbytes;

  pwmcfg->period = ONEWIRE_ZERO_WIDTH + ONEWIRE_RECOVERY_WIDTH;
  pwmcfg->callback = NULL;
  pwmcfg->channels[mch].callback = NULL;
  pwmcfg->channels[mch].mode = owp->config->pwmmode;
  pwmcfg->channels[sch].callback = pwm_read_bit_cb;
  pwmcfg->channels[sch].mode = PWM_OUTPUT_ACTIVE_LOW;

  ow_bus_active(owp);
  osalSysLock();
  pwmEnableChannelI(pwmd, mch, ONEWIRE_ONE_WIDTH);
  pwmEnableChannelI(pwmd, sch, ONEWIRE_SAMPLE_WIDTH);
  pwmEnableChannelNotificationI(pwmd, sch);
  osalThreadSuspendS(&owp->thread);
  osalSysUnlock();

  ow_bus_idle(owp);
}
Beispiel #3
0
/**
 * @brief     Generate reset pulse on bus.
 *
 * @param[in] owp       pointer to the @p onewireDriver object
 *
 * @return              Bool flag denoting device presence.
 * @retval true         There is at least one device on bus.
 */
bool onewireReset(onewireDriver *owp) {
  PWMDriver *pwmd;
  PWMConfig *pwmcfg;
  size_t mch, sch;

  osalDbgCheck(NULL != owp);
  osalDbgAssert(owp->reg.state == ONEWIRE_READY, "Invalid state");

  /* short circuit on bus or any other device transmit data */
  if (PAL_LOW == ow_read_bit(owp))
    return false;

  pwmd = owp->config->pwmd;
  pwmcfg = owp->config->pwmcfg;
  mch = owp->config->master_channel;
  sch = owp->config->sample_channel;


  pwmcfg->period = ONEWIRE_RESET_LOW_WIDTH + ONEWIRE_RESET_SAMPLE_WIDTH;
  pwmcfg->callback = NULL;
  pwmcfg->channels[mch].callback = NULL;
  pwmcfg->channels[mch].mode = owp->config->pwmmode;
  pwmcfg->channels[sch].callback = pwm_reset_cb;
  pwmcfg->channels[sch].mode = PWM_OUTPUT_ACTIVE_LOW;

  ow_bus_active(owp);

  osalSysLock();
  pwmEnableChannelI(pwmd, mch, ONEWIRE_RESET_LOW_WIDTH);
  pwmEnableChannelI(pwmd, sch, ONEWIRE_RESET_SAMPLE_WIDTH);
  pwmEnableChannelNotificationI(pwmd, sch);
  osalThreadSuspendS(&owp->thread);
  osalSysUnlock();

  ow_bus_idle(owp);

  /* wait until slave release bus to discriminate short circuit condition */
  osalThreadSleepMicroseconds(500);
  return (PAL_HIGH == ow_read_bit(owp)) && (true == owp->reg.slave_present);
}
Beispiel #4
0
/**
 * @brief   Performs tree search on bus.
 * @note    This function does internal 1-wire reset calls every search
 *          iteration.
 *
 * @param[in] owp         pointer to a @p OWDriver object
 * @param[out] result     pointer to buffer for discovered ROMs
 * @param[in] max_rom_cnt buffer size in ROMs count for overflow prevention
 *
 * @return              Count of discovered ROMs. May be more than max_rom_cnt.
 * @retval 0            no ROMs found or communication error occurred.
 */
size_t onewireSearchRom(onewireDriver *owp, uint8_t *result,
                        size_t max_rom_cnt) {
  PWMDriver *pwmd;
  PWMConfig *pwmcfg;
  uint8_t cmd;
  size_t mch, sch;

  osalDbgCheck(NULL != owp);
  osalDbgAssert(ONEWIRE_READY == owp->reg.state, "Invalid state");
  osalDbgCheck((max_rom_cnt <= 256) && (max_rom_cnt > 0));

  pwmd = owp->config->pwmd;
  pwmcfg = owp->config->pwmcfg;
  cmd = ONEWIRE_CMD_SEARCH_ROM;
  mch = owp->config->master_channel;
  sch = owp->config->sample_channel;

  search_clean_start(&owp->search_rom);

  do {
    /* every search must be started from reset pulse */
    if (false == onewireReset(owp))
      return 0;

    /* initialize buffer to store result */
    if (owp->search_rom.reg.devices_found >= max_rom_cnt)
      owp->search_rom.retbuf = result + 8*(max_rom_cnt-1);
    else
      owp->search_rom.retbuf = result + 8*owp->search_rom.reg.devices_found;
    memset(owp->search_rom.retbuf, 0, 8);

    /* clean iteration state */
    search_clean_iteration(&owp->search_rom);

    /**/
    onewireWrite(&OWD1, &cmd, 1, 0);

    /* Reconfiguration always needed because of previous call onewireWrite.*/
    pwmcfg->period = ONEWIRE_ZERO_WIDTH + ONEWIRE_RECOVERY_WIDTH;
    pwmcfg->callback = NULL;
    pwmcfg->channels[mch].callback = NULL;
    pwmcfg->channels[mch].mode = owp->config->pwmmode;
    pwmcfg->channels[sch].callback = pwm_search_rom_cb;
    pwmcfg->channels[sch].mode = PWM_OUTPUT_ACTIVE_LOW;

    ow_bus_active(owp);
    osalSysLock();
    pwmEnableChannelI(pwmd, mch, ONEWIRE_ONE_WIDTH);
    pwmEnableChannelI(pwmd, sch, ONEWIRE_SAMPLE_WIDTH);
    pwmEnableChannelNotificationI(pwmd, sch);
    osalThreadSuspendS(&owp->thread);
    osalSysUnlock();

    ow_bus_idle(owp);

    if (ONEWIRE_SEARCH_ROM_ERROR != owp->search_rom.reg.result) {
      /* check CRC and return 0 (0 == error) if mismatch */
      if (owp->search_rom.retbuf[7] != onewireCRC(owp->search_rom.retbuf, 7))
        return 0;
      /* store cached result for usage in next iteration */
      memcpy(owp->search_rom.prev_path, owp->search_rom.retbuf, 8);
    }
  }
  while (ONEWIRE_SEARCH_ROM_SUCCESS == owp->search_rom.reg.result);

  /**/
  if (ONEWIRE_SEARCH_ROM_ERROR == owp->search_rom.reg.result)
    return 0;
  else
    return owp->search_rom.reg.devices_found;
}