示例#1
0
文件: icu_lld.c 项目: 0x00f/ChibiOS
/**
 * @brief   Configures and activates the ICU peripheral.
 *
 * @param[in] icup      pointer to the @p ICUDriver object
 *
 * @notapi
 */
void icu_lld_start(ICUDriver *icup) {

  chDbgAssert(get_emios0_active_channels() < 28, "icu_lld_start(), #1",
                "too many channels");

  chDbgAssert(get_emios1_active_channels() < 28, "icu_lld_start(), #2",
                "too many channels");

  if (icup->state == ICU_STOP) {
    /* Enables the peripheral.*/
#if SPC5_ICU_USE_EMIOS0_CH0
    if (&ICUD1 == icup)
      increase_emios0_active_channels();
#endif /* SPC5_ICU_USE_EMIOS0_CH0 */
#if SPC5_ICU_USE_EMIOS0_CH1
    if (&ICUD2 == icup)
      increase_emios0_active_channels();
#endif /* SPC5_ICU_USE_EMIOS0_CH1 */
#if SPC5_ICU_USE_EMIOS0_CH2
    if (&ICUD3 == icup)
      increase_emios0_active_channels();
#endif /* SPC5_ICU_USE_EMIOS0_CH2 */
#if SPC5_ICU_USE_EMIOS0_CH3
    if (&ICUD4 == icup)
      increase_emios0_active_channels();
#endif /* SPC5_ICU_USE_EMIOS0_CH3 */
#if SPC5_ICU_USE_EMIOS0_CH4
    if (&ICUD5 == icup)
      increase_emios0_active_channels();
#endif /* SPC5_ICU_USE_EMIOS0_CH4 */
#if SPC5_ICU_USE_EMIOS0_CH5
    if (&ICUD6 == icup)
      increase_emios0_active_channels();
#endif /* SPC5_ICU_USE_EMIOS0_CH5 */
#if SPC5_ICU_USE_EMIOS0_CH6
    if (&ICUD7 == icup)
      increase_emios0_active_channels();
#endif /* SPC5_ICU_USE_EMIOS0_CH6 */
#if SPC5_ICU_USE_EMIOS0_CH7
    if (&ICUD8 == icup)
      increase_emios0_active_channels();
#endif /* SPC5_ICU_USE_EMIOS0_CH7 */
#if SPC5_ICU_USE_EMIOS0_CH24
    if (&ICUD9 == icup)
      increase_emios0_active_channels();
#endif /* SPC5_ICU_USE_EMIOS0_CH24 */
#if SPC5_ICU_USE_EMIOS1_CH24
    if (&ICUD10 == icup)
      increase_emios1_active_channels();
#endif /* SPC5_ICU_USE_EMIOS1_CH24 */

    /* Set eMIOS0 Clock.*/
#if SPC5_ICU_USE_EMIOS0
    active_emios0_clock(icup, NULL);
#endif

    /* Set eMIOS1 Clock.*/
#if SPC5_ICU_USE_EMIOS1
    active_emios1_clock(icup, NULL);
#endif

  }
  /* Configures the peripheral.*/

  /* Channel enables.*/
  icup->emiosp->UCDIS.R &= ~(1 << icup->ch_number);

  /* Clear pending IRQs (if any).*/
  icup->emiosp->CH[icup->ch_number].CSR.R = EMIOSS_OVRC |
      EMIOSS_OVFLC | EMIOSS_FLAGC;

  /* Set clock prescaler and control register.*/
  uint32_t psc = (icup->clock / icup->config->frequency);
  chDbgAssert((psc <= 0xFFFF) &&
              (((psc) * icup->config->frequency) == icup->clock) &&
              ((psc == 1) || (psc == 2) || (psc == 3) || (psc == 4)),
              "icu_lld_start(), #3", "invalid frequency");

  icup->emiosp->CH[icup->ch_number].CCR.B.UCPEN = 0;
  icup->emiosp->CH[icup->ch_number].CCR.R |=
      EMIOSC_BSL(EMIOS_BSL_INTERNAL_COUNTER) |
      EMIOSC_EDSEL | EMIOS_CCR_MODE_SAIC;
  icup->emiosp->CH[icup->ch_number].CCR.B.UCPRE = psc - 1;
  icup->emiosp->CH[icup->ch_number].CCR.R |= EMIOSC_UCPREN;

  /* Set source polarity.*/
  if(icup->config->mode == ICU_INPUT_ACTIVE_HIGH){
    icup->emiosp->CH[icup->ch_number].CCR.R |= EMIOSC_EDPOL;
  } else {
    icup->emiosp->CH[icup->ch_number].CCR.R &= ~EMIOSC_EDPOL;
  }

  /* Direct pointers to the period and width registers in order to make
     reading data faster from within callbacks.*/
  icup->pccrp = &period;
  icup->wccrp = &width;

  /* Channel disables.*/
  icup->emiosp->UCDIS.R |= (1 << icup->ch_number);

}
示例#2
0
/**
 * @brief   Configures and activates the PWM peripheral.
 *
 * @param[in] pwmp      pointer to the @p PWMDriver object
 *
 * @notapi
 */
void pwm_lld_start(PWMDriver *pwmp) {

  uint32_t psc = 0;

  chDbgAssert(get_emios_active_channels() < SPC5_EMIOS_NUM_CHANNELS,
              "pwm_lld_start(), #1", "too many channels");

  if (pwmp->state == PWM_STOP) {
#if SPC5_PWM_USE_EMIOS_CH0
    if (&PWMD1 == pwmp) {
      increase_emios_active_channels();
    }
#endif /* SPC5_PWM_USE_EMIOS_CH0 */

#if SPC5_PWM_USE_EMIOS_CH8
    if (&PWMD2 == pwmp) {
      increase_emios_active_channels();
    }
#endif /* SPC5_PWM_USE_EMIOS_CH8 */

#if SPC5_PWM_USE_EMIOS_CH9
    if (&PWMD3 == pwmp) {
      increase_emios_active_channels();
    }
#endif /* SPC5_PWM_USE_EMIOS_CH9 */

#if SPC5_PWM_USE_EMIOS_CH10
    if (&PWMD4 == pwmp) {
      increase_emios_active_channels();
    }
#endif /* SPC5_PWM_USE_EMIOS_CH10 */

#if SPC5_PWM_USE_EMIOS_CH12
    if (&PWMD5 == pwmp) {
      increase_emios_active_channels();
    }
#endif /* SPC5_PWM_USE_EMIOS_CH12 */

#if SPC5_PWM_USE_EMIOS_CH14
    if (&PWMD6 == pwmp) {
      increase_emios_active_channels();
    }
#endif /* SPC5_PWM_USE_EMIOS_CH14 */

#if SPC5_PWM_USE_EMIOS_CH15
    if (&PWMD7 == pwmp) {
      increase_emios_active_channels();
    }
#endif /* SPC5_PWM_USE_EMIOS_CH15 */

#if SPC5_PWM_USE_EMIOS_CH23
    if (&PWMD8 == pwmp) {
      increase_emios_active_channels();
    }
#endif /* SPC5_PWM_USE_EMIOS_CH23 */

#if SPC5_EMIOS_NUM_CHANNELS == 24
#if SPC5_PWM_USE_EMIOS_CH19
    if (&PWMD9 == pwmp) {
      increase_emios_active_channels();
    }
#endif /* SPC5_PWM_USE_EMIOS_CH19 */

#if SPC5_PWM_USE_EMIOS_CH20
    if (&PWMD10 == pwmp) {
      increase_emios_active_channels();
    }
#endif /* SPC5_PWM_USE_EMIOS_CH20 */

#if SPC5_PWM_USE_EMIOS_CH21
    if (&PWMD11 == pwmp) {
      increase_emios_active_channels();
    }
#endif /* SPC5_PWM_USE_EMIOS_CH21 */

#if SPC5_PWM_USE_EMIOS_CH22
    if (&PWMD12 == pwmp) {
      increase_emios_active_channels();
    }
#endif /* SPC5_PWM_USE_EMIOS_CH22 */
#endif

    /* Set eMIOS Clock.*/
#if SPC5_PWM_USE_EMIOS
    pwm_active_emios_clock(pwmp);
#endif

  }
  /* Configures the peripheral.*/

  /* Channel enables.*/
  pwmp->emiosp->UCDIS.R &= ~(1 << pwmp->ch_number);

  /* Clear pending IRQs (if any).*/
  pwmp->emiosp->CH[pwmp->ch_number].CSR.R = EMIOSS_OVRC |
      EMIOSS_OVFLC | EMIOSS_FLAGC;

  /* Set clock prescaler and control register.*/
  psc = (SPC5_EMIOS_CLK / pwmp->config->frequency);
  chDbgAssert((psc <= 0xFFFF) &&
              (((psc) * pwmp->config->frequency) == SPC5_EMIOS_CLK) &&
              ((psc == 1) || (psc == 2) || (psc == 3) || (psc == 4)),
              "pwm_lld_start(), #1", "invalid frequency");

  if (pwmp->config->mode == PWM_ALIGN_EDGE) {
    pwmp->emiosp->CH[pwmp->ch_number].CCR.B.UCPREN = 0;
    pwmp->emiosp->CH[pwmp->ch_number].CCR.B.UCPRE = psc - 1U;
    pwmp->emiosp->CH[pwmp->ch_number].CCR.B.UCPREN = 1U;
    pwmp->emiosp->CH[pwmp->ch_number].CCNTR.R = 1U;
    pwmp->emiosp->CH[pwmp->ch_number].CADR.R = 0U;
    pwmp->emiosp->CH[pwmp->ch_number].CBDR.R = pwmp->config->period;
    pwmp->emiosp->CH[pwmp->ch_number].CCR.R |=
        EMIOSC_BSL(EMIOS_BSL_INTERNAL_COUNTER) | EMIOS_CCR_MODE_OPWFMB | 2U;
    pwmp->emiosp->CH[pwmp->ch_number].CCR.R |= EMIOSC_UCPREN;

    /* Set output polarity.*/
    if (pwmp->config->channels[0].mode == PWM_OUTPUT_ACTIVE_LOW) {
      pwmp->emiosp->CH[pwmp->ch_number].CCR.R |= EMIOSC_EDPOL;
    } else if (pwmp->config->channels[0].mode == PWM_OUTPUT_ACTIVE_HIGH) {
      pwmp->emiosp->CH[pwmp->ch_number].CCR.R &= ~EMIOSC_EDPOL;
    }

    /* Channel disables.*/
    pwmp->emiosp->UCDIS.R |= (1 << pwmp->ch_number);

  } else if (pwmp->config->mode == PWM_ALIGN_CENTER) {
    /* Not implemented.*/
  }

}