Exemplo n.º 1
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 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;
}
Exemplo n.º 2
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;
}