Enabling output pin for TC4-WO0.

Hi,

I finally succeed configuring TC4 counter/comparer to generate a square signal of 38 khz, to drive an IR led.

Well, the problem is now how to output this wave. Acording to file 'Captura1', it seems i should enable Pin 31, but 2 questions are still pending:

1.Witch is the output pin on the MKR1000 corresponding to the processor's pin#31?. Acording to the wire diagram in 'Captura2', it has to be pin 0, isn't it?

2.How do i select function 'E' in the port function multiplexing?. I've found this 'defines' in the file pio\samd21g18a.h who could help (view 'Captura3').

Thanks for your time!

mephala.

Hi mephala,

Pin 31 of the MKR1000's processor is defined as I0 pin PA22 (on port A), which in turn is defined as pin 0 by Arduino. (I have a Arduino Zero rather than an MKR1000, but I guess the procedure is similiar).

To output the TC4 timer on pin 0, you need to first enable the pin's multiplexer:

// Enable the port multiplexer for the digital pin D0 
  PORT->Group[g_APinDescription[0].ulPort].PINCFG[g_APinDescription[0].ulPin].bit.PMUXEN = 1;

Then switch the multiplexer to your peripheral of choice (peripheral E):

// Connect the TC4 timer to the port output D0 - port pins are paired odd PMUXO and even PMUXE
  // Peripheral E specifies the TC timers, on this pin: TC4
  PORT->Group[g_APinDescription[0].ulPort].PMUX[g_APinDescription[0].ulPin >> 1].reg |= /*PORT_PMUX_PMUXO_E |*/ PORT_PMUX_PMUXE_E;

The next issue is the timer's mode. In normal frequency (NFRQ) mode the timer will toggle when the timer matches the value in the counter compare (CC0) register. This will result in only half your required output frequency and the duty cycle will be fixed at 50%.

There are a couple of possible solutions:

  1. Leave the timer in NFRQ mode and double its frequency, althought this will give you a fixed 50% duty cycle.

  2. Switch the timer to Normal PWM (NPWM) mode. Just add the TC_CTRLA_WAVEGEN_NPWM definition as you enable the timer in the CTRLA register. If the timer's in 8-bit mode then the PER register becomes the TOP value. The PER register determines the output waveform's frequency, while the CC0 register determines its duty cycle. Set CC0 to half the PER value for a 50% duty cycle.

Martin,
Thanks for your help. Let me comment the results.
1.Don't understand the behaviour of the bits Odd/Even in the MUX register, in order to select the function E. Finally, i implemented this way, and works fine:

PORT->Group[g_APinDescription[OUTPUT_IR_LED].ulPort].PMUX[g_APinDescription[OUTPUT_IR_LED].ulPin >> 1].reg |= (PORT_PMUX_PMUXO_E | PORT_PMUX_PMUXE_E);

2.The square wave at 38 khz was implemented this way (also working fine):

void timer_Config_KHZ(int freqKhz) {
// Posa el comptador de TC4 en mode 16 bits, generar senyal tipus MFRQ, Preescaler compta cada event, i habilitem TC4.
REG_TC4_CTRLA |= TC_CTRLA_MODE_COUNT16 | TC_CTRLA_WAVEGEN_MFRQ | TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_ENABLE;
while (REG_TC4_STATUS && TC_STATUS_SYNCBUSY);
REG_TC4_COUNT16_CC0 = TC_COUNT16_CC_CC(SYSCLOCK / 2000 / freqKhz); // Posa el comparador necessari per a generar una ona quadrada de freqKhz, 50% duty cycle.
while (REG_TC4_STATUS && TC_STATUS_SYNCBUSY);
}

So Martin, work done. My conditioned air is under control :slight_smile: . Thanks again for all your time.

mephala.