Author Topic: Atmel SAM D - TC and TCC (no ASF)  (Read 10360 times)

0 Members and 1 Guest are viewing this topic.

Offline Franc

  • Regular Contributor
  • *
  • Posts: 52
  • Country: br
Atmel SAM D - TC and TCC (no ASF)
« on: October 29, 2016, 07:29:10 pm »
Hi friends!

As I did not find any topic for TC/TCC in Atmel Sam D devices, I opened this.

I am in doubt If is possible I use the 'FOR routine' in TCC function as below taking same 'pulse' for both W0x.

My TCC0 is supplying 64Khz  direct to PA08 through WO[0]  and PA09 W0[1] . For W0[1] I want to act with a FOR routine as below.

Best regards!

Code: [Select]
#include "samd21.h"
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include "board_defs.h" //board definições 
 
 uint8_t delay_fase = 0;
 uint8_t angulo_fase;
 uint8_t pulsos;
 
void init_TCC0 (void)
 {

   PM->APBCMASK.reg |= PM_APBCMASK_TCC0; // Enable peripheral clock for TCC0

   GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_TCC0_TCC1; // Disable the GCLK
    while ((GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN));

//   Enable TCC0
   GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID (TCC0_GCLK_ID) | // TCC0 & TCC1 share same GCLK
                       GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN (0);
while (GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN); // Wait till enabled


//   TCC0->CTRLA.reg &= ~ (TCC_CTRLA_ENABLE); // Disable TCC0
   TCC0->CTRLA.reg = TCC_CTRLA_PRESCALER_DIV16 | TCC_CTRLA_PRESCSYNC_GCLK;
   TCC0->WAVE.reg = TCC_WAVE_WAVEGEN_MFRQ; // Normal PWM

// Initialize count to 0
   TCC0->COUNT.reg = 0;
//   TCC0->PER.reg = 100; // Set period

   TCC0->CC[0].reg = 21; // Atualiza a frequencia de saida. Atual 63khz
//   TCC0->WEXCTRL.bit.OTMX = 0x01; // Route CC0 to OTMX[6];

// Enable the timer
   TCC0->CTRLA.bit.ENABLE = 1;
    while (TCC0->SYNCBUSY.bit.ENABLE) ; // Wait till timer enabled

   GPIO_dirOut(DRIVE_R); 
   GPIO_pmuxen(DRIVE_R, PF_MUX_E);
   
   
   for (angulo_fase=0; angulo_fase<16; angulo_fase++)
     {
      ddDelay_us(delay_fase++);
  for (pulsos = 0; pulsos < 8; pulsos++)
  {
    GPIO_dirOut(MODU_OUT);
    GPIO_pmuxen(MODU_OUT, PF_MUX_E);
  }
      ddDelay_ms(1);
     }
 
  }
« Last Edit: October 29, 2016, 10:19:24 pm by Franc »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 7992
  • Country: us
    • Personal site
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #1 on: October 29, 2016, 08:40:01 pm »
Can you actually explain with words what you want to do?

Right now your code makes a pin an output many times in a loop. This will do absolutely nothing after the first iteration.

If you want to generate 64 kHz from software, then it is possible, but what it has to do with TC/TCC? And you may want to draw an actual timing diagram of what you want to do.
Alex
 

Offline Franc

  • Regular Contributor
  • *
  • Posts: 52
  • Country: br
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #2 on: October 29, 2016, 09:00:53 pm »
Hi ALex, how are you 8)

Basically, my TCC0 needs to generate 64Khz continuosly in PA08 (Working well).

Also, in same TCC0 I want to generate 64Khz no continuosly in PA09, because I want take same phase of PA08 (any delay in nano seconds between them is relevant to me)

In PA09 I will supply 8 pulses in 64Khz  in 16 times with 1ms delay between them .

Regards
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 7992
  • Country: us
    • Personal site
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #3 on: October 29, 2016, 09:23:25 pm »
Well, PWM switches the output when COUNT reaches CC[n]. So you need to configure CC[1] the same way as CC[0].

Now your main program must switch between PA09 being driven by the PORT and by the TCC at correct times. At 64 kHz it should be doable.

So basically you will have something like this:

Code: [Select]

void wait_start()
{
    uint32_t prev;

    do
    {
      prev = COUNT;
    } while (COUNT >= prev);
}

{
  PA9_out();
  PA9_clr();
  PA9_pmuxdis();

  for (int i = 0; i < 16; i++)
  {
    wait_start();
    // here we are synchronized with the output of the TCC

    PA9_pmuxen();

   // wait 8 transitions
  for (int j = 0; j < 8; j++)
    wait_start();

  PA9_pmuxdis();
  delay(1ms);
}
Alex
 
The following users thanked this post: Franc

Offline Franc

  • Regular Contributor
  • *
  • Posts: 52
  • Country: br
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #4 on: October 29, 2016, 10:18:28 pm »
Hi Alex,
Now my TCC0 is blocking my program. Pls see below.


Code: [Select]
void init_TCC0 (void)
 {

   PM->APBCMASK.reg |= PM_APBCMASK_TCC0; // Enable peripheral clock for TCC0

   GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_TCC0_TCC1; // Disable the GCLK
    while ((GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN));

//   Enable TCC0
   GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID (TCC0_GCLK_ID) | // TCC0 & TCC1 share same GCLK
                       GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN (0);
               while (GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN); // Wait till enabled


//   TCC0->CTRLA.reg &= ~ (TCC_CTRLA_ENABLE); // Disable TCC0
   TCC0->CTRLA.reg = TCC_CTRLA_PRESCALER_DIV16 | TCC_CTRLA_PRESCSYNC_GCLK;
   TCC0->WAVE.reg = TCC_WAVE_WAVEGEN_MFRQ; // Normal PWM

// Initialize count to 0
   TCC0->COUNT.reg = 0;
//   TCC0->PER.reg = 100; // Set period

   TCC0->CC[0].reg = 21; // Atualiza a frequencia de saida. Atual 63khz
   TCC0->CC[1].reg = 21;
//   TCC0->WEXCTRL.bit.OTMX = 0x01; // Route CC0 to OTMX[6];

// Enable the timer
   TCC0->CTRLA.bit.ENABLE = 1;
    while (TCC0->SYNCBUSY.bit.ENABLE) ; // Wait till timer enabled

   GPIO_dirOut(DRIVE_R); 
   GPIO_pmuxen(DRIVE_R, PF_MUX_E);
   
   GPIO_dirOut(MODU_OUT);
   
   for (int i = 0; i < 16; i++)
   {
   wait_start();
   // here we are synchronized with the output of the TCC

   GPIO_pmuxen(MODU_OUT, PF_MUX_E);

   // wait 8 transitions
   for (int j = 0; j < 8; j++)
   {
   wait_start();

   GPIO_pmuxen(MODU_OUT, PF_MUX_E);
   ddDelay_ms(1);
   }
   
   }

  }

void wait_start()
{
uint32_t prev;

do
{
prev = TCC0->COUNT.reg;
}
while (TCC0->COUNT.reg >= prev);
}
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 7992
  • Country: us
    • Personal site
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #5 on: October 29, 2016, 10:26:27 pm »
First of all, your code looks noting like my pseudocode.

I don't know what your pmux macros/functions are doing, but you have too many of them. Note that I disable PMUX in the loop, not just enable it all th time.

And you obviously need to debug. I gave you a general idea, not a final solution.
Alex
 

Offline Franc

  • Regular Contributor
  • *
  • Posts: 52
  • Country: br
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #6 on: October 31, 2016, 11:37:22 pm »
Today I tried to do my command 'FOR' but I don't know what happens.
My FOR is correct, I tested in another C compiler for PC and worked well my debug , but in SAM do not respond as wished.
 
It is very simple, just  take 8 pulses from my TCC0 while pressing the botton 1 of OLED Board. And command FOR also simple.
This compiler is strange or  I do not yet understand the muxes
 
Code: [Select]
  while (!GPIO_read (O_SW1))
{
           
             for (int j = 0; j < 8; j++) // wait 8 transitions of mux 'E' to PA09
             {
                 GPIO_pmuxen(MODU_OUT, PF_MUX_E); //MOD_OUT is PA09 .
             }
                           
              GPIO_pmuxdis(MODU_OUT); // disable PA09
              ddDelay_ms(1); //wait 1 ms.
   }

Regards!
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 7992
  • Country: us
    • Personal site
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #7 on: October 31, 2016, 11:39:50 pm »
Code: [Select]
{
             for (int j = 0; j < 8; j++) // wait 8 transitions of mux 'E' to PA09
             {
                 GPIO_pmuxen(MODU_OUT, PF_MUX_E); //MOD_OUT is PA09 .
             }
This code does not match the comment. It does not wait for anything and also does not make much sense, since after MUX is enabled once, consequtive enable requests do absolutely nothing.


Please describe in human words what you want pins to do. Draw timing diagrams. I feel like you don't fully understand what you want yourself.
Alex
 

Offline Franc

  • Regular Contributor
  • *
  • Posts: 52
  • Country: br
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #8 on: October 31, 2016, 11:53:58 pm »
yes friend, this is my doubt for pin Mux. Maybe a new topic for Pin Mux of Sam D?
It is very basic. I know I am confuse  |O but I started  few weeks ago with ARM.

Only for test for me understand, I want to toggle the PA09 8 times with the Mux 'E' from my TCC0 that supplying a signal of 64Khz.  After toggle 8 times, my software needs to wait 1ms.  This routine is continuos while my Botton 1 is pressed (just to me understand)



Regards!
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 7992
  • Country: us
    • Personal site
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #9 on: October 31, 2016, 11:57:43 pm »
Maybe a new topic for Pin Mux of Sam D?
Let's continue with this one.

I want to toggle the PA09 8 times with the Mux 'E' from my TCC0 that supplying a signal of 64Khz
You can't do this. The point of multiplexing is that only one peripheral controls the pin. If TCC controls it, then you can't do anything about it, it is under TCC control. All you can do is to read TCC state and try to guess what TCC is doing with the pin. Just as I've outlined in my code.

PS: https://en.wikipedia.org/wiki/Multiplexer
Alex
 

Offline Franc

  • Regular Contributor
  • *
  • Posts: 52
  • Country: br
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #10 on: November 01, 2016, 12:16:28 am »
Same TCC0 supply 64Khz to other pin PA08 continuosly through mux E.

Quote
You can't do this. The point of multiplexing is that only one peripheral controls the pin. If TCC controls it, then you can't do anything about it, it is under TCC control. All you can do is to read TCC state and try to guess what TCC is doing with the pin. Just as I've outlined in my code.

So, I cannot use a botton to start my test. But I tried direct without botton and no success. Sorry but I cannot act in the signal supplied to I/O from TCC? Is it? 

 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 7992
  • Country: us
    • Personal site
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #11 on: November 01, 2016, 12:19:58 am »
Same TCC0 supply 64Khz to other pin PA08 continuosly through mux E.
So?

So, I cannot use a botton to start my test.
What makes you think this? You can start the test using the button.

The problem here is that what you want to do in the test can't be done.

Sorry but I cannot act in the signal supplied to I/O from TCC?
No, you can't, unless you externally loop it back to another pin. But this is not necessary, as you can predict what the pin state is based on the TCC registers, just like my code does.
Alex
 

Offline Franc

  • Regular Contributor
  • *
  • Posts: 52
  • Country: br
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #12 on: November 01, 2016, 12:33:19 am »
Sorry Alex, still confuse to me his code above. Is your 'COUNT' the count register of TCC0?
In my understand you are manipulating the Mux similar I made above.
Regards!

Code: [Select]
PA9_out();
  PA9_clr();
PA9_pmuxdis()

  for (int i = 0; i < 16; i++)
  {
    wait_start();
    // here we are synchronized with the output of the TCC

    PA9_pmuxen();

   // wait 8 transitions
  for (int j = 0; j < 8; j++)
    wait_start();

  PA9_pmuxdis()
  delay(1ms);
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 7992
  • Country: us
    • Personal site
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #13 on: November 01, 2016, 12:38:36 am »
Sorry Alex, still confuse to me his code above. Is your 'COUNT' the count register of TCC0?
Correct.

In my understand you are manipulating the Mux similar I made above.
Your understanding is wrong.

I enable the mux, so that TCC can drive the pin, then I call wait_start() 8 times, this waits until TCC changes the state 8 times, then I disable the mux, so that PORT peripheral drives the pin, which makes it go low, because I previously set output to 0 (PA9_clr()).

The timer is still running and counting, it is just not in control of the pin anymore.

This method gives you accurate timing, since it is derived from the hardware, byt you still have control over number of pulses, you just need to be fast enough to take the output from the timer when it is time, but at 64 kHz it should not be a big problem.
Alex
 

Offline Franc

  • Regular Contributor
  • *
  • Posts: 52
  • Country: br
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #14 on: November 07, 2016, 10:19:45 pm »
Hi friend! Today I returned to my project but still no success.
My code below is blocking my program once I press the Button1.

My issue is in wait_start() function. I really think it.
Do you have any idea? Where I am missing?


Code: [Select]
b_btn1_state = !GPIO_read (O_SW1);
        while (!GPIO_read (O_SW1)) {
     
                        GPIO_pmuxen(MODU_OUT, PF_MUX_E);//enable Mux E
for (int j = 0; j < 8; j++)
{
wait_start();
}
   
  GPIO_pmuxdis(MODU_OUT); // disable Mux E
  ddDelay_ms(1);
        }

void wait_start()
{
uint32_t prev;

do
{
prev = TCC0->COUNT.reg;
}
while (TCC0->COUNT.reg >= prev);
}
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 7992
  • Country: us
    • Personal site
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #15 on: November 07, 2016, 10:25:45 pm »
Do you have any idea? Where I am missing?
You need to use a debugger or any other way of debugging (UART prints, led blinking, anything really).

I typed that function into the browser, I don't know why it may not work or block.

I see no reason for this, sooner or later COUNT will be reset to 0 and and will be less than previous value.
Alex
 

Offline Franc

  • Regular Contributor
  • *
  • Posts: 52
  • Country: br
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #16 on: November 07, 2016, 10:42:21 pm »
Yes Alex, I am using my XplainedPro SamD21 and testing the output pins with my Oscilloscope. Also i have a Display OLED, when I press the button the Display is blocking.  :-//

Quote
I see no reason for this, sooner or later COUNT will be reset to 0 and and will be less than previous value.
I think it. I don't like AS7, maybe any AS7 bug?


 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 7992
  • Country: us
    • Personal site
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #17 on: November 07, 2016, 10:46:02 pm »
I think it. I don't AS7, maybe any AS7 bug?
AS7 is an IDE, it uses GCC as a compiler. And blaming the compiler is the last thing you should be doing here.

You need to figure out why this function is blocking. Print the values of 'prev' and TCC0->COUNT.reg.

What are your timer settings? For this to work well, you want to prescale the timer as much as possible, so your PER and CC[n] values are as big as possible.
Alex
 

Offline Franc

  • Regular Contributor
  • *
  • Posts: 52
  • Country: br
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #18 on: November 07, 2016, 10:52:28 pm »
Quote
AS7 is an IDE, it uses GCC as a compiler. And blaming the compiler is the last thing you should be doing here.
Okay ALex!

Quote
You need to figure out why this function is blocking. Print the values of 'prev' and TCC0->COUNT.reg.
Sorry, I don't know how can I do that.

My Prescaler is /16 for 48Mhz clock  as below:

Code: [Select]
void init_drive_rod (void)
 {

   PM->APBCMASK.reg |= PM_APBCMASK_TCC0; // Enable peripheral clock for TCC0

   GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_TCC0_TCC1; // Disable the GCLK
    while ((GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN));

//   Enable TCC0
   GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID (TCC0_GCLK_ID) | // TCC0 & TCC1 share same GCLK
                       GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN (0);
while (GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN); // Wait till enabled


//   TCC0->CTRLA.reg &= ~ (TCC_CTRLA_ENABLE); // Disable TCC0
   TCC0->CTRLA.reg = TCC_CTRLA_PRESCALER_DIV16 | TCC_CTRLA_PRESCSYNC_GCLK;
   TCC0->WAVE.reg = TCC_WAVE_WAVEGEN_MFRQ; // Normal PWM

// Initialize count to 0
   TCC0->COUNT.reg = 0;
//   TCC0->PER.reg = 100; // Set period

   TCC0->CC[0].reg = 21; // Atualiza a frequencia de saida. Atual 63khz
   TCC0->CC[1].reg = 21;
//   TCC0->WEXCTRL.bit.OTMX = 0x01; // Route CC0 to OTMX[6];

// Enable the timer
   TCC0->CTRLA.bit.ENABLE = 1;
    while (TCC0->SYNCBUSY.bit.ENABLE) ; // Wait till timer enabled

   
   
     
  }
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 7992
  • Country: us
    • Personal site
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #19 on: November 07, 2016, 10:57:13 pm »
Sorry, I don't know how can I do that.
  Well, you will have to learn. My starter projects have examples of debug UART output, you can use that code as a starter.

My Prescaler is /16 for 48Mhz clock  as below:
Your code has PER setting commented out, so I have no idea how this thing is working in a first place.

Also, increase your prescaler.
Alex
 

Offline Lajon

  • Contributor
  • Posts: 31
  • Country: se
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #20 on: November 07, 2016, 10:58:12 pm »
About reading COUNT, this register for TCC needs read sync.
Quote
Note: Prior to any read access, this register must be synchronized by user by writing the according TCC
Command value to the Control B Set register (CTRLBSET.CMD=READSYNC).
So probably something like this before reading COUNT
Code: [Select]
while (TCC0->SYNCBUSY.bit.CTRLB);
TCC0->CTRLBSET.bit.CMD = TCC_CTRLBSET_CMD_READSYNC_Val;
while (TCC0->SYNCBUSY.bit.CTRLB);
/Lars
« Last Edit: November 07, 2016, 11:02:43 pm by Lajon »
 
The following users thanked this post: Franc

Online ataradov

  • Super Contributor
  • ***
  • Posts: 7992
  • Country: us
    • Personal site
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #21 on: November 07, 2016, 11:02:02 pm »
About reading COUNT, this register for TCC needs read sync.
If both peripherals are clocked from the same clock source, then it does not matter all that much. And even if not, we are not interested in exact correct value, we just need to know if it crossed back to 0.
Alex
 

Offline Lajon

  • Contributor
  • Posts: 31
  • Country: se
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #22 on: November 07, 2016, 11:04:40 pm »
It will not change without the CMD write in my experience (also not when looking at it in the debugger).
/Lars
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 7992
  • Country: us
    • Personal site
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #23 on: November 07, 2016, 11:05:34 pm »
It will not change without the CMD write in my experience (also not when looking at it in the debugger).
Yeah, it looks like it is the case. It worked fine with TC, but it looks like TCC needs mandatory synchronization.
Alex
 

Offline Franc

  • Regular Contributor
  • *
  • Posts: 52
  • Country: br
Re: Atmel SAM D - TC and TCC (no ASF)
« Reply #24 on: November 07, 2016, 11:38:04 pm »
Hi Lajon/Alex, thanks!

I tried again but no success. When I press the Button, my software is blocking in wait_start() function, that is, only doing PA09 muxed continuosly, then my OLED blocks.

Quote
Also, increase your prescaler.
I tested 64.

Quote
Your code has PER setting commented out, so I have no idea how this thing is working in a first place.
I thought it is not necessary to use because I want only the CC[] match.



Code: [Select]
b_btn1_state = !GPIO_read (O_SW1);
while (!GPIO_read (O_SW1))
 {
     
    GPIO_pmuxen(MODU_OUT, PF_MUX_E);//enable Mux E
    for (int j = 0; j < 8; j++)
        {
          wait_start();
        }
         
     GPIO_pmuxdis(MODU_OUT); // disable Mux E
     ddDelay_ms(1);
}

void wait_start()
{
 uint32_t prev;

 do
 {
  prev = TCC0->COUNT.reg;
 }
        while (TCC0->SYNCBUSY.bit.CTRLB);
TCC0->CTRLBSET.bit.CMD = TCC_CTRLBSET_CMD_READSYNC_Val;
while (TCC0->SYNCBUSY.bit.CTRLB);
while (TCC0->COUNT.reg >= prev);
}
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf