SAMC21 - Cannot Use TC Capture Inputs in PPW or PW Modes

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

After wasting enough time on this, I've about convinced myself it can't be done, but has anyone had any success using any TC Capture Inputs (WO[0,1]) for any of the PWP, PPW, or PW modes?

 

I was able to get them to work using EIC and the Event system, but the datasheet seems to say you can use Event Inputs or Capture Inputs for any of these modes (depending on whether or not CTRLA.COPENx is set). They even list specific Event Actions that can only be triggered by Event Inputs (not including PPW, etc...). So far, setting EVACT to anything just stops the timer (unless I'm using the EVENT system). This seems to imply these modes only work with the Event System, but that seems strangely limited and misleading in the datasheet. I've even tried feeding the MC0 output event back into the TC0 event input since it was working with the EIC event input, but that didn't work either. 

 

The only thing I've been able to do with the Capture Inputs is save the COUNT value in CC0 with the rising edge of WO[0]. Since I need to measure pulse-width, I can't even use interrupts because I can't flip the edge-sensing direction without disabling the timer first. Currently I can't use the EIC method without a new PCB since EXTINT12 happens to be in use already as I thought I could use the WO[0] input for what I needed. I will probably make another PCB rev anyway, but I wanted some kind of confirmation that this can or cannot be done...

 

I'm using SAMC21J18A Rev D. No ASF.

 

Thanks for your input.

 

Last Edited: Sun. Sep 24, 2017 - 01:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tried it and unfortunately I can only confirm your result (I finally have a Rev D C21, no point testing this with my Xplained Pro which is Rev B where capture from input pins is in the errata).

/Lars

 

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

Hello,

 

I have the same problem with inputs which are probably not inputs at all. But I couldn't solve the problem also with Event system, PW is not working at all, PPW/PWP are working wrong and give no values for CC1 register.

Could you please post a part of your source code here?

Thank you in advance,

Alex

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include "sam.h"
#include <stdlib.h>

static volatile uint16_t cap0[128]; // Period with PPW capture
static volatile uint16_t cap1[128]; // Pulse width with PPW capture
static volatile size_t nCap;

void setupInput(void)
{
    MCLK->APBAMASK.bit.EIC_ = 1;
    GCLK->PCHCTRL[EIC_GCLK_ID].bit.GEN = 0;
    GCLK->PCHCTRL[EIC_GCLK_ID].bit.CHEN = 1;
    while(GCLK->PCHCTRL[EIC_GCLK_ID].bit.CHEN != 1);
    // Input on PA22 which is EXTINT6
    PORT->Group[0].PMUX[22/2].bit.PMUXE = MUX_PA22A_EIC_EXTINT6;
    const PORT_PINCFG_Type pincfg = {
        .bit.PMUXEN = 1,
        .bit.INEN = 1,
        .bit.PULLEN = 1
    };
    PORT->Group[0].PINCFG[22].reg = pincfg.reg;
    EIC->CONFIG[0].bit.SENSE6 = EIC_CONFIG_SENSE6_HIGH_Val;
    EIC->EVCTRL.bit.EXTINTEO = 1 << 6;
    EIC->CTRLA.bit.ENABLE = 1;
    while (EIC->SYNCBUSY.bit.ENABLE == 1);
}

void setupTimer(void)
{
    MCLK->APBCMASK.bit.TC0_ = 1;
    GCLK->PCHCTRL[TC0_GCLK_ID].bit.GEN = 0;
    GCLK->PCHCTRL[TC0_GCLK_ID].bit.CHEN = 1;
    while(GCLK->PCHCTRL[TC0_GCLK_ID].bit.CHEN != 1);
    
    TC0->COUNT16.CTRLA.bit.ENABLE = 0;
    while (TC0->COUNT16.SYNCBUSY.reg);
    TC0->COUNT16.CTRLA.bit.MODE = TC_CTRLA_MODE_COUNT16;
    TC0->COUNT16.CTRLA.bit.PRESCALER = TC_CTRLA_PRESCALER_DIV1_Val;
    TC0->COUNT16.CTRLA.bit.CAPTEN0 = 1;
    TC0->COUNT16.CTRLA.bit.CAPTEN1 = 1;
    TC0->COUNT16.CTRLA.bit.COPEN0 = 0;
    TC0->COUNT16.CTRLA.bit.COPEN1 = 0;
    while (TC0->COUNT16.SYNCBUSY.reg);

    TC0->COUNT16.EVCTRL.bit.TCEI = 1;
    TC0->COUNT16.EVCTRL.bit.EVACT = TC_EVCTRL_EVACT_PPW_Val;
    // Interrupts
    TC0->COUNT16.INTENSET.bit.MC0 = 1;
    TC0->COUNT16.INTENSET.bit.MC1 = 0; // Not needed, can read out both in MC0 interrupt
    
    // Enable TC
    TC0->COUNT16.CTRLA.bit.ENABLE = 1;
    while (TC0->COUNT16.SYNCBUSY.reg);
    
    // Enable InterruptVector
    NVIC_EnableIRQ(TC0_IRQn);

    MCLK->APBCMASK.bit.EVSYS_ = 1;
    // EVSYS GCLK is needed for interrupts and sync path (so not now)
    EVSYS->USER[EVSYS_ID_USER_TC0_EVU].bit.CHANNEL = 2; // Channel n-1 selected so 1 here
    while(!EVSYS->CHSTATUS.bit.USRRDY1);
    
    // EVSYS_CHANNEL_EDGSEL_BOTH_EDGES // not usable with  PATH_ASYNCHRONOUS
    EVSYS->CHANNEL[1].reg = EVSYS_CHANNEL_PATH_ASYNCHRONOUS|EVSYS_CHANNEL_EVGEN(EVSYS_ID_GEN_EIC_EXTINT_6);
    while(EVSYS->CHSTATUS.bit.CHBUSY1);
}

void TC0_Handler()
{
    if (TC0->COUNT16.INTFLAG.bit.MC0) {
        // The interrupt flag is cleared by reading CC
        cap0[nCap] = TC0->COUNT16.CC[0].bit.CC;
        cap1[nCap] = TC0->COUNT16.CC[1].bit.CC;
        if (++nCap == sizeof(cap0)/sizeof(cap0[0])) {
            static volatile size_t done;
            done++;
            nCap = 0;
        }
    }
}

int main(void)
{
    SystemInit();
    setupInput();
    setupTimer();
    while (1) {
    }
}

This is ported from a thread about this for SAMD21:

https://community.atmel.com/foru...

Works ok for me with SAMC21 Xplained Pro.

/Lars

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

Hello Lars,

 

thank you for your reply. I've found this manual on Microchip site:

https://microchipsupport.force.c...

It worked for my board, probably the problem was the External Interrupt, I have always configured it as Both edges, and the manual means it should be High level.

But anyway thanks!

 

Alex

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

Had similar issues.  I still don't know if it's possible to use the WOx pins for capture input for PPW or PWP capture.  Using a pin and making an EIC event for capture input, only HIGH or LOW for the pin SENSEx field completely work ie. CC0 having Period and CC1 having Pulse Width.  RISE, FALL, and BOTH only give partial information.

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

I'm about to start a similar project with a SAMC21, and from what I can find the only solution such as that above was to use an external interrupt and route it through the EVSYS into the TC or TCC.  

 

In my case, the h/w has been set and the input is PA08, which is the NMI, and I'm having trouble seeing how it plugs into EVSYS (I can see how the EXTINTs do it, but NMI?).  So I'm concerned it might not work entirely correctly. 

 

There might be an alternative, which sets up my question:

 

Has anybody succeeded in routing the event through the CCL instead of the external interrupt system?  Would there be any advantage/disadvantage to taking this route?

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

I agree that NMI has no connection with the event system. CCL should work and is in fact mentioned in the errata:

1.20.2 I/O Pins The input capture on I/O pins does not work.

Workaround Use the input capture through TC event and use the EIC or CCL as event generators.

No particular advantage I guess (except as in you case allowing input from a pin which is not an EXTINT).

/Lars

 

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

Lajon wrote:

I agree that NMI has no connection with the event system. CCL should work and is in fact mentioned in the errata:

1.20.2 I/O Pins The input capture on I/O pins does not work.

Workaround Use the input capture through TC event and use the EIC or CCL as event generators.

No particular advantage I guess (except as in you case allowing input from a pin which is not an EXTINT).

/Lars

 

 

Thanks.  I've been working on getting the CCL working and getting its events out.  The nice part is that once you are in the event system, you can pick whichever TC/TCC you want for capture - you aren't tied down due to I/O pins anymore. 

 

Figuring out how CCL truth tables work has been my largest stumbling block so far, but I found a writeup for the SAML that described it in much more useful detail than the SAMC datasheet.

 

Won't know for a couple weeks if my code is working, but if someone stumbles upon this post in the future and needs to route events thru CCL to TC/TCC, feel free to post and I'll help as I can.