コード例 #1
0
ファイル: iofirmware.cpp プロジェクト: jmachuca77/ardupilot
void AP_IOMCU_FW::heater_update()
{
    uint32_t now = AP_HAL::millis();
    if (!has_heater) {
        // use blue LED as heartbeat
        if (now - last_blue_led_ms > 500) {
            palToggleLine(HAL_GPIO_PIN_HEATER);
            last_blue_led_ms = now;
        }
    } else if (reg_setup.heater_duty_cycle == 0 || (now - last_heater_ms > 3000UL)) {
        palWriteLine(HAL_GPIO_PIN_HEATER, 0);
    } else {
        uint8_t cycle = ((now / 10UL) % 100U);
        palWriteLine(HAL_GPIO_PIN_HEATER, !(cycle >= reg_setup.heater_duty_cycle));
    }
}
コード例 #2
0
ファイル: iofirmware.cpp プロジェクト: jmachuca77/ardupilot
/*
  update safety state
 */
void AP_IOMCU_FW::safety_update(void)
{
    uint32_t now = AP_HAL::millis();
    if (now - safety_update_ms < 100) {
        // update safety at 10Hz
        return;
    }
    safety_update_ms = now;

    bool safety_pressed = palReadLine(HAL_GPIO_PIN_SAFETY_INPUT);
    if (safety_pressed) {
        if (reg_status.flag_safety_off && (reg_setup.arming & P_SETUP_ARMING_SAFETY_DISABLE_ON)) {
            safety_pressed = false;
        } else if ((!reg_status.flag_safety_off) && (reg_setup.arming & P_SETUP_ARMING_SAFETY_DISABLE_OFF)) {
            safety_pressed = false;
        }
    }
    if (safety_pressed) {
        safety_button_counter++;
    } else {
        safety_button_counter = 0;
    }
    if (safety_button_counter == 10) {
        // safety has been pressed for 1 second, change state
        reg_status.flag_safety_off = !reg_status.flag_safety_off;
    }

    led_counter = (led_counter+1) % 16;
    const uint16_t led_pattern = reg_status.flag_safety_off?0xFFFF:0x5500;
    palWriteLine(HAL_GPIO_PIN_SAFETY_LED, (led_pattern & (1U << led_counter))?0:1);
}
コード例 #3
0
ファイル: main.c プロジェクト: oh3eqn/ChibiOS
static THD_FUNCTION(spi_thread_2, p) {

  (void)p;
  chRegSetThreadName("SPI thread 2");
  while (true) {
    spiAcquireBus(&PORTAB_SPI1);        /* Acquire ownership of the bus.    */
    palWriteLine(PORTAB_LINE_LED1, PORTAB_LED_OFF);
    spiStart(&PORTAB_SPI1, &ls_spicfg); /* Setup transfer parameters.       */
    spiSelect(&PORTAB_SPI1);            /* Slave Select assertion.          */
    spiExchange(&PORTAB_SPI1, 512,
                txbuf, rxbuf);          /* Atomic transfer operations.      */
    spiUnselect(&PORTAB_SPI1);          /* Slave Select de-assertion.       */
    spiReleaseBus(&PORTAB_SPI1);        /* Ownership release.               */
  }
}
コード例 #4
0
ファイル: hal_pwm_lld.c プロジェクト: YuriTr/ChibiOS-Contrib
/**
 * @brief   Enables a PWM channel.
 * @pre     The PWM unit must have been activated using @p pwmStart().
 * @post    The channel is active using the specified configuration.
 * @note    The function has effect at the next cycle start.
 * @note    Channel notification is not enabled.
 *
 * @param[in] pwmp      pointer to a @p PWMDriver object
 * @param[in] channel   PWM channel identifier (0...channels-1)
 * @param[in] width     PWM pulse width as clock pulses number
 *
 * @notapi
 */
void pwm_lld_enable_channel(PWMDriver *pwmp,
                            pwmchannel_t channel,
                            pwmcnt_t width) {
#if NRF5_PWM_USE_GPIOTE_PPI
  const PWMChannelConfig *cfg_channel = &pwmp->config->channels[channel];
  const uint8_t  gpiote_channel = cfg_channel->gpiote_channel;
  const uint8_t *ppi_channel    = cfg_channel->ppi_channel;
  
  uint32_t outinit;
  switch(cfg_channel->mode & PWM_OUTPUT_MASK) {
  case PWM_OUTPUT_ACTIVE_LOW : outinit = GPIOTE_CONFIG_OUTINIT_Low;  break;
  case PWM_OUTPUT_ACTIVE_HIGH: outinit = GPIOTE_CONFIG_OUTINIT_High; break;
  case PWM_OUTPUT_DISABLED   : /* fall-through */
  default                    : goto no_output_config;
  }

  /* Deal with corner case: 0% and 100% */
  if ((width <= 0) || (width >= pwmp->period)) {
      /* Disable GPIOTE/PPI task */
    NRF_GPIOTE->CONFIG[gpiote_channel] = GPIOTE_CONFIG_MODE_Disabled;
    NRF_PPI->CHENCLR = ((1 << ppi_channel[0]) | (1 << ppi_channel[1]));
    /* Set Line */
    palWriteLine(cfg_channel->ioline,
           ((width <= 0) ^
            ((cfg_channel->mode & PWM_OUTPUT_MASK) == PWM_OUTPUT_ACTIVE_HIGH)));

  /* Really doing PWM */
  } else {
    const uint32_t gpio_pin = PAL_PAD(cfg_channel->ioline);
    const uint32_t polarity = GPIOTE_CONFIG_POLARITY_Toggle;

    /* Program tasks (one for duty cycle, one for periode) */
    NRF_PPI->CH[ppi_channel[0]].EEP =
      (uint32_t)&pwmp->timer->EVENTS_COMPARE[channel];
    NRF_PPI->CH[ppi_channel[0]].TEP =
      (uint32_t)&NRF_GPIOTE->TASKS_OUT[gpiote_channel];
    NRF_PPI->CH[ppi_channel[1]].EEP =
      (uint32_t)&pwmp->timer->EVENTS_COMPARE[pwmp->channels];
    NRF_PPI->CH[ppi_channel[1]].TEP =
      (uint32_t)&NRF_GPIOTE->TASKS_OUT[gpiote_channel];
    NRF_PPI->CHENSET = ((1 << ppi_channel[0]) | (1 << ppi_channel[1]));

    /* Something Old, something New */
    const uint32_t old_width = pwmp->timer->CC[channel];
    const uint32_t new_width = width;

    /* Check GPIOTE state */
    const bool gpiote = (NRF_GPIOTE->CONFIG[gpiote_channel] &
                   GPIOTE_CONFIG_MODE_Msk) != GPIOTE_CONFIG_MODE_Disabled;

    /* GPIOTE is currently running */
    if (gpiote) {
      uint32_t current;
      while (true) {
        pwmp->timer->TASKS_CAPTURE[PWM_GPIOTE_PPI_CC] = 1;
        current = pwmp->timer->CC[PWM_GPIOTE_PPI_CC];

        if (pwm_within_safe_margins(pwmp, current, old_width) &&
            pwm_within_safe_margins(pwmp, current, new_width))
          break;
      }
      if (((old_width <= current) && (current < new_width)) ||
          ((new_width <= current) && (current < old_width))) {
        NRF_GPIOTE->TASKS_OUT[gpiote_channel] = 1;
      }

    /* GPIOTE need to be restarted */
    } else {
      /* Create GPIO Task */
      NRF_GPIOTE->CONFIG[gpiote_channel] =
        (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
        ((gpio_pin << GPIOTE_CONFIG_PSEL_Pos    ) & GPIOTE_CONFIG_PSEL_Msk    )|
        ((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk)|
        ((outinit  << GPIOTE_CONFIG_OUTINIT_Pos ) & GPIOTE_CONFIG_OUTINIT_Msk );

      pwmp->timer->TASKS_CAPTURE[PWM_GPIOTE_PPI_CC] = 1;
      if (pwmp->timer->CC[PWM_GPIOTE_PPI_CC] > width)
        NRF_GPIOTE->TASKS_OUT[gpiote_channel] = 1;
    }
  }

 no_output_config:
#endif

  pwmp->timer->CC[channel] = width;
}