SAMD21E - TC Timer Counter - 2PWM outputs

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear all,

 

I am currently working with a SAMD21E17 and trying to output PWM to two pins using a TC module. Here is my setup:

 

Pin configuration:

PA24, FUNCTIONE -> TC5-WO[0]

PA25, FUNCTIONE -> TC5-WO[1]

 

Timer/counter configuration:

pm->APBCMASK |= (1<<13)

generic_clk_channel_init(0, 0x1c);

TC5->(CTRLA = (1 << 8) | (2 << 5) | (1 << 2);

TC5->READREQ = (1 << 14) | (0x10);

TC5->CTRLC = (1 << 1);

TC5->PER = 0xff;

TC5->CC0 = 0;

TC5->CTRLA |= (1 << 1);

TC5->CTRLBSET = (1<< 6);

 

Here are my two questions:

1) From analyzing the datasheet I concluded: although TC's have two CCx controls, in Normal Pulse-Width Modulation Operation (NPWM) only CC0 can be used as period register [SAMD21 Datasheet, Section: 30.8.14.1], hence, I can only output one kind of PWM with TCs. Is that correct?

2) I managed to output the PWM to one pin (PA24), however, for some reason I cannot output the PWM to the other pin (PA25) or both pins (PA24 & PA25). Is that supposed to be? If not, how do I link TC's PWM to output pins? At least from my experience with TCC, the TCC module got an extra register for output pin configuration [SAMD21 Datasheet, Section: 31.6.4, Table 31-4].

 

Thank you for your support,

 

Best,

MPN

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A dumb question on my part:

 You want to see two PWM outputs. Since you're using one TC the outputs will have the same frequency.

What should the waveforms on each output look like?

Jerry

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1. If 8 bit PWM is enough then two outputs are possible (the period is from the PER register in this case). Configure mode COUNT8 in the CTRLA register.

2. You can have two outputs in 8-bit mode.

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@jerryr: ideally: one TC with two independent PWM outputs. In the worst case: one PWM linked to two outputs. So far, I only managed to configure one PWM on only one of the two outputs.

@Lars: Thanks. I will have a try and let you know how it went. 8-bit would be sufficient.

 

-MPN

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@Lars: I am realizing that I already configured CTRLA in 8-bit mode:

 

TC5->(CTRLA = (1 << 8) | (2 << 5) | (1 << 2);

 

​in other words:

 

TC5->(CTRLA = (DIV2 << 8) | (NPWM << 5) | (COUNT8 << 2);

 

then I do:

 

volatile uint32_t* ccptrs{

&(TC5->CC0),

&(TC5->CC1)

};

 

*ccpters[0] = 10;

*ccpters[1] = 10;

 

and I measure:

a 10/255 PWM signal on pin PA24 with an oscilloscope, but 3V3 on PA25.

 

Ay idea what I am doing wrong? Thanks.

 

MPN

 

 

 

 

 

Last Edited: Sat. Mar 24, 2018 - 09:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This works for me (but tested with a D21 xPlained pro so D21J)
 

	PM->APBCMASK.reg |= PM_APBCMASK_TC5;
	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN  | GCLK_CLKCTRL_ID_TC4_TC5;
	while(GCLK->STATUS.bit.SYNCBUSY);
	REG_TC5_CTRLA = TC_CTRLA_MODE_COUNT8 | TC_CTRLA_PRESCALER_DIV2 | TC_CTRLA_WAVEGEN_NPWM;
	REG_TC5_CTRLC = TC_CTRLC_INVEN1;
	REG_TC5_COUNT8_PER = 0xff;
	REG_TC5_COUNT8_CC0 = 10;
	REG_TC5_COUNT8_CC1 = 10;
	REG_TC5_CTRLA |= TC_CTRLA_ENABLE;
	PORT->Group[0].PMUX[24/2].bit.PMUXE = MUX_PA24E_TC5_WO0;
	PORT->Group[0].PMUX[25/2].bit.PMUXO = MUX_PA25E_TC5_WO1;
	const PORT_PINCFG_Type pincfg = {
		.bit.PMUXEN = 1,
	};
	PORT->Group[0].PINCFG[24].reg = pincfg.reg;
	PORT->Group[0].PINCFG[25].reg = pincfg.reg;

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I assume this:

	PORT->Group[0].PMUX[24/2].bit.PMUXE = MUX_PA24E_TC5_WO0;
	PORT->Group[0].PMUX[25/2].bit.PMUXO = MUX_PA25E_TC5_WO1;
	const PORT_PINCFG_Type pincfg = {
		.bit.PMUXEN = 1,
	};
	PORT->Group[0].PINCFG[24].reg = pincfg.reg;
	PORT->Group[0].PINCFG[25].reg = pincfg.reg;

configures pins PA24/25 for usage functione.

 

Why did you invert TC5[1]?

REG_TC5_CTRLC = TC_CTRLC_INVEN1;

This exact example leaves me with a 10/255 PWM on TC5[0] and VSS on TC5[1]. I still have not achieved 2xPWM on TC5[0/1].

 

Thanks for your support. I appreciate it.

 

-MPN

 

Correction: your example does work! For some reason writing new PWM values into the TC5->C1 register after initialization shuts down the entire signal.

 

 

Last Edited: Sun. Mar 25, 2018 - 08:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mpn1989 wrote:
Why did you invert TC5[1]?

Because you did that

TC5->CTRLC = (1 << 1);

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you are writing the CC registers using this setup
 

volatile uint32_t* ccptrs{

&(TC5->CC0),

&(TC5->CC1)

};

then that is the problem, the CC registers are 8 bits wide in the 8 bit mode.

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

All problems solved.

 

Thank you a lot Lars!

 

-MPN