/** * \brief Initialize one PWM channel. * * \param p_pwm Pointer to a PWM instance. * \param p_channel Configurations of the specified PWM channel. * * \retval 0 if initialization succeeds, otherwise fails. */ uint32_t pwm_channel_init(Pwm *p_pwm, pwm_channel_t *p_channel) { uint32_t tmp_reg = 0; uint32_t ch_num = p_channel->channel; /* Channel Mode/Clock Register */ tmp_reg = (p_channel->ul_prescaler & 0xF) | (p_channel->polarity << 9) | #if (SAM3U || SAM3S || SAM3XA || SAM4S || SAM4E || SAMV70 || SAMV71 || SAME70 || SAMS70) (p_channel->counter_event) | (p_channel->b_deadtime_generator << 16) | (p_channel->b_pwmh_output_inverted << 17) | (p_channel->b_pwml_output_inverted << 18) | #endif (p_channel->alignment); p_pwm->PWM_CH_NUM[ch_num].PWM_CMR = tmp_reg; /* Channel Duty Cycle Register */ p_pwm->PWM_CH_NUM[ch_num].PWM_CDTY = p_channel->ul_duty; /* Channel Period Register */ p_pwm->PWM_CH_NUM[ch_num].PWM_CPRD = p_channel->ul_period; #if (SAM3U || SAM3S || SAM3XA || SAM4S || SAM4E || SAMV70 || SAMV71 || SAME70 || SAMS70) /* Channel Dead Time Register */ if (p_channel->b_deadtime_generator) { p_pwm->PWM_CH_NUM[ch_num].PWM_DT = PWM_DT_DTL(p_channel-> us_deadtime_pwml) | PWM_DT_DTH(p_channel-> us_deadtime_pwmh); } /* Output Selection Register */ tmp_reg = p_pwm->PWM_OS & (~((PWM_OS_OSH0 | PWM_OS_OSL0) << ch_num)); tmp_reg |= ((p_channel->output_selection.b_override_pwmh) << ch_num) | (((p_channel->output_selection.b_override_pwml) << ch_num) << 16); p_pwm->PWM_OS = tmp_reg; /* Output Override Value Register */ tmp_reg = p_pwm->PWM_OOV & (~((PWM_OOV_OOVH0 | PWM_OOV_OOVL0) << ch_num)); tmp_reg |= ((p_channel->output_selection.override_level_pwmh) << ch_num) | (((p_channel->output_selection.override_level_pwml) << ch_num) << 16); p_pwm->PWM_OOV = tmp_reg; /* Sync Channels Mode Register */ uint32_t channel = (1 << ch_num); if (p_channel->b_sync_ch) { p_pwm->PWM_SCM |= channel; } else { p_pwm->PWM_SCM &= ~((uint32_t) channel); } /* Fault Protection Value Register */ #if (SAM4E || SAMV70 || SAMV71 || SAME70 || SAMS70) if (p_channel->ul_fault_output_pwmh == PWM_HIGHZ) { p_pwm->PWM_FPV2 |= (0x01 << ch_num); } else { p_pwm->PWM_FPV2 &= ~(0x01 << ch_num); if (p_channel->ul_fault_output_pwmh == PWM_HIGH) { p_pwm->PWM_FPV1 |= (0x01 << ch_num); } else { p_pwm->PWM_FPV1 &= (~(0x01 << ch_num)); } } if (p_channel->ul_fault_output_pwml == PWM_HIGHZ) { p_pwm->PWM_FPV2 |= ((0x01 << ch_num) << 16); } else { p_pwm->PWM_FPV2 &= ~((0x01 << ch_num) << 16); if (p_channel->ul_fault_output_pwml == PWM_HIGH) { p_pwm->PWM_FPV1 |= ((0x01 << ch_num) << 16); } else { p_pwm->PWM_FPV1 &= (~((0x01 << ch_num) << 16)); } } #else if (p_channel->ul_fault_output_pwmh == PWM_HIGH) { p_pwm->PWM_FPV |= (0x01 << ch_num); } else { p_pwm->PWM_FPV &= (~(0x01 << ch_num)); } if (p_channel->ul_fault_output_pwml == PWM_HIGH) { p_pwm->PWM_FPV |= ((0x01 << ch_num) << 16); } else { p_pwm->PWM_FPV &= (~((0x01 << ch_num) << 16)); } #endif /* Fault Protection Enable Register */ uint32_t fault_enable_reg = 0; #if (SAM3XA) if (ch_num < 4) { ch_num *= 8; fault_enable_reg = p_pwm->PWM_FPE1; fault_enable_reg &= ~(0xFF << ch_num); fault_enable_reg |= ((p_channel->fault_id) << ch_num); p_pwm->PWM_FPE1 = fault_enable_reg; } else { ch_num -= 4; ch_num *= 8; fault_enable_reg = p_pwm->PWM_FPE2; fault_enable_reg &= ~(0xFF << ch_num); fault_enable_reg |= ((p_channel->fault_id) << ch_num); p_pwm->PWM_FPE2 = fault_enable_reg; } #endif #if (SAM3U || SAM3S || SAM4S || SAM4E || SAMV70 || SAMV71 || SAME70 || SAMS70) ch_num *= 8; fault_enable_reg = p_pwm->PWM_FPE; fault_enable_reg &= ~(0xFF << ch_num); fault_enable_reg |= ((p_channel->fault_id) << ch_num); p_pwm->PWM_FPE = fault_enable_reg; #endif #endif #if SAM4E if (!ch_num) { if (p_channel->spread_spectrum_mode == PWM_SPREAD_SPECTRUM_MODE_RANDOM) { p_pwm->PWM_SSPR = PWM_SSPR_SPRD(p_channel->ul_spread) | PWM_SSPR_SPRDM; } else { p_pwm->PWM_SSPR = PWM_SSPR_SPRD(p_channel->ul_spread); } } p_pwm->PWM_CH_NUM_0X400[ch_num].PWM_CAE = PWM_CAE_ADEDGV(p_channel->ul_additional_edge) | p_channel->additional_edge_mode; #elif (SAMV70 || SAMV71 || SAME70 || SAMS70) if (!ch_num) { if (p_channel->spread_spectrum_mode == PWM_SPREAD_SPECTRUM_MODE_RANDOM) { p_pwm->PWM_SSPR = PWM_SSPR_SPRD(p_channel->ul_spread) | PWM_SSPR_SPRDM; } else { p_pwm->PWM_SSPR = PWM_SSPR_SPRD(p_channel->ul_spread); } } p_pwm->PWM_CH_NUM[ch_num].PWM_CMR &= (~PWM_CMR_PPM); p_pwm->PWM_CH_NUM[ch_num].PWM_CMR |= (p_channel->ul_ppm_mode & PWM_CMR_PPM); #endif return 0; }
/** * \brief Initialize one PWM channel. * * \param p_pwm Pointer to a PWM instance. * \param p_channel Configurations of the specified PWM channel. * * \retval 0 if initialization succeeds, otherwise fails. */ uint32_t pwm_channel_init(Pwm *p_pwm, pwm_channel_t *p_channel) { uint32_t ch_mode_reg = 0; uint32_t ch_num = p_channel->channel; uint32_t channel = (1 << ch_num); /* Channel Mode/Clock Register */ ch_mode_reg = (p_channel->ul_prescaler & 0xF) | (p_channel->polarity << 9) | #if (SAM3U || SAM3S || SAM3XA || SAM4S) (p_channel->counter_event) | (p_channel->b_deadtime_generator << 16) | (p_channel->b_pwmh_output_inverted << 17) | (p_channel->b_pwml_output_inverted << 18) | #endif (p_channel->alignment); p_pwm->PWM_CH_NUM[ch_num].PWM_CMR = ch_mode_reg; /* Channel Duty Cycle Register */ p_pwm->PWM_CH_NUM[ch_num].PWM_CDTY = p_channel->ul_duty; /* Channel Period Register */ p_pwm->PWM_CH_NUM[ch_num].PWM_CPRD = p_channel->ul_period; #if (SAM3U || SAM3S || SAM3XA || SAM4S) /* Channel Dead Time Register */ if (p_channel->b_deadtime_generator) { p_pwm->PWM_CH_NUM[ch_num].PWM_DT = PWM_DT_DTL(p_channel-> us_deadtime_pwml) | PWM_DT_DTH(p_channel-> us_deadtime_pwmh); } /* Output Selection Register */ p_pwm->PWM_OS = ((p_channel->output_selection. b_override_pwmh) << ch_num) | (((p_channel->output_selection.b_override_pwml) << ch_num) << 16); /* Output Override Value Register */ p_pwm->PWM_OOV = ((p_channel->output_selection. override_level_pwmh) << ch_num) | (((p_channel->output_selection.override_level_pwml) << ch_num) << 16); /* Sync Channels Mode Register */ if (p_channel->b_sync_ch) { p_pwm->PWM_SCM |= channel; } else { p_pwm->PWM_SCM &= ~((uint32_t) channel); } /* Fault Protection Value Register */ p_pwm->PWM_FPV = ((p_channel->ul_fault_output_pwmh) << ch_num) | (((p_channel->ul_fault_output_pwml) << ch_num) << 16); /* Fault Protection Enable Register */ uint32_t fault_enable_reg = 0; #if (SAM3XA) if (ch_num < 4) { ch_num *= 8; fault_enable_reg = p_pwm->PWM_FPE1; fault_enable_reg &= ~(0xFF << ch_num); fault_enable_reg |= ((p_channel->fault_id) << ch_num); p_pwm->PWM_FPE1 = fault_enable_reg; } else { ch_num -= 4; ch_num *= 8; fault_enable_reg = p_pwm->PWM_FPE2; fault_enable_reg &= ~(0xFF << ch_num); fault_enable_reg |= ((p_channel->fault_id) << ch_num); p_pwm->PWM_FPE2 = fault_enable_reg; } #endif #if (SAM3U || SAM3S || SAM4S) ch_num *= 8; fault_enable_reg = p_pwm->PWM_FPE; fault_enable_reg &= ~(0xFF << ch_num); fault_enable_reg |= ((p_channel->fault_id) << ch_num); p_pwm->PWM_FPE = fault_enable_reg; #endif #endif return 0; }