/** * @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 = . icup->wccrp = &width; /* Channel disables.*/ icup->emiosp->UCDIS.R |= (1 << icup->ch_number); }
/** * @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.*/ } }