Arduino nano 33 iot serial communication issue while ussing TCC1

I am new here, started using samd21 based arduino nano 33 iot recently was changing a code intended for arduino uno/mega AVR MCU to work on samd21 based arduino nano but i am facing an issue with serial communiction. after i upload code i dont see any serial communication in serial monitor, any help will be appriciated.

#define N 160             //How many frequencies

float results[N];         //-Filtered result buffer
float freq[N];            //-Filtered result buffer
int sizeOfArray = N;

volatile unsigned int d;

void setup()
{
  Serial.begin(115200);

  delay(1000); // prevents usb driver crash on startup, do not omit this
  while (!SERIAL) ;  // Wait for serial terminal to open port before starting program

  Serial.println("");
  Serial.println("******************************");
  Serial.println("        Program start         ");
  Serial.println("******************************");
  Serial.flush();
  
  GCLK->GENCTRL.reg = GCLK_GENCTRL_IDC |          // Improve duty cycle
                      GCLK_GENCTRL_GENEN |        // Enable generic clock gen
                      GCLK_GENCTRL_SRC_DFLL48M |  // Select 48MHz as source
                      GCLK_GENCTRL_ID(4);         // Select GCLK4
  while (GCLK->STATUS.bit.SYNCBUSY);              // Wait for synchronization

  // Set clock divider of 3 to generic clock generator 4
  GCLK->GENDIV.reg = GCLK_GENDIV_DIV(3) |         // Divide 48 MHz by 3 = 16Mhz
                     GCLK_GENDIV_ID(4);           // Apply to GCLK4 4
  while (GCLK->STATUS.bit.SYNCBUSY);              // Wait for synchronization
  
  // Enable GCLK4 and connect it to TCC1 and TCC1
  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |        // Enable generic clock
                      GCLK_CLKCTRL_GEN_GCLK4 |    // Select GCLK4
                      GCLK_CLKCTRL_ID_TCC0_TCC1;  // Feed GCLK4 to TCC0/1
  while (GCLK->STATUS.bit.SYNCBUSY);              // Wait for synchronization

  // Use "Normal PWM" (single-slope PWM): count up to PER, match on CC[n]
  TCC1->WAVE.reg = TCC_WAVE_WAVEGEN_NPWM;         // Select NPWM as waveform
  while (TCC1->SYNCBUSY.bit.WAVE);                // Wait for synchronization
  
    // Configure PA18 (D10 on Arduino Zero) to be output
  PORT->Group[PORTA].DIRSET.reg = PORT_PA18;      // Set pin as output
  PORT->Group[PORTA].OUTCLR.reg = PORT_PA18;      // Set pin to low

  // Enable the port multiplexer for PA18
  PORT->Group[PORTA].PINCFG[18].reg |= PORT_PINCFG_PMUXEN;

  // Connect TCC1 timer to PA18.
  PORT->Group[PORTA].PMUX[9].reg = PORT_PMUX_PMUXE_F;

  // Set the period (the number to count to (TOP) before resetting timer)
  TCC1->PER.reg = 110;
  while (TCC1->SYNCBUSY.bit.PER);

  // Set PWM signal to output 50% duty cycle
  TCC1->CC[2].reg = 55;
  while (TCC1->SYNCBUSY.bit.CC2);

  // Enable output (start PWM)
  TCC1->CTRLA.reg |= (TCC_CTRLA_ENABLE);
  while (TCC1->SYNCBUSY.bit.ENABLE);              // Wait for synchronization
  
  for(int i=0;i<N;i++)      //-Preset results
    results[i]=0;         //-+
}

void loop()
{
    
  for(d=0;d<N;d++)
  {
    int v=analogRead(0);    //-Read response signal
    
    TCC1->CTRLA.reg &= ~TCC_CTRLA_ENABLE;               // Disable TC
    while (TCC1->SYNCBUSY.bit.ENABLE);                  // wait for sync 
    
    TCC1->CTRLA.reg = TC_CTRLA_SWRST;                  // Reset TCC1
    while (TCC2->CTRLA.bit.SWRST);                     // Wait for completion
    
    TCC1->PER.reg = d;                             // ICR1=d; Set the period (PER) register for a PWM period of 1s
    while (TCC2->SYNCBUSY.bit.PER);                    // Wait for synchronization                 // |
    
    TCC1->CC[0].reg = d/2;                           // OCR1A=d/2; Set the duty cycle to 50%
    while (TCC2->SYNCBUSY.bit.CC0);                    // Wait for synchronization OCR1A=d/2;              //-+
    
    TCC1->CTRLA.reg |= (TCC_CTRLA_ENABLE);          // Enable output
    while (TCC1->SYNCBUSY.bit.ENABLE);              // Wait for synchronization

    results[d]=results[d]*0.5+(float)(v)*0.5; //Filter results
   
    freq[d] = d;

     //   plot(v,0);              //-Display
     //   plot(results[d],1);
     // delayMicroseconds(1);
     }
  
 // PlottArray(1,freq,results); 

}

Hi @saimshuja

Please could you describe what the code is trying to achieve.

hi @MartinL Thankyou for reply.

Bro it is generating pwm signal using TCC1 with variable frequancy, it sweeps from 16Mhz to 100Khz on pin D10 (PA18) and analog reads on A0. it sends the read value over serial to pc over serial.

but when i upload this code to the Nano serial monitor stays blank, no data is recived even the " Program start " in the setup function is not recived.

actually i am in the process of porting the following code to samd21
my starting point was this code below

#define SET(x,y) (x |=(1<<y))        //-Bit set/clear macros
#define CLR(x,y) (x &= (~(1<<y)))           // |
#define CHK(x,y) (x & (1<<y))               // |
#define TOG(x,y) (x^=(1<<y))                //-+



#define N 160  //How many frequencies

float results[N];         //-Filtered result buffer
float freq[N];            //-Filtered result buffer
int sizeOfArray = N;

void setup()
{
 TCCR1A=0b10000010;        //-Set up frequency generator
 TCCR1B=0b00011001;        //-+
 ICR1=110;
 OCR1A=55;

 pinMode(9,OUTPUT);        //-Signal generator pin
 pinMode(8,OUTPUT);        //-Sync (test) pin

 Serial.begin(115200);

 for(int i=0;i<N;i++)      //-Preset results
   results[i]=0;         //-+
}

void loop()
{
 unsigned int d;

 int counter = 0;
 for(unsigned int d=0;d<N;d++)
 {
   int v=analogRead(0);    //-Read response signal
   CLR(TCCR1B,0);          //-Stop generator
   TCNT1=0;                //-Reload new frequency
   ICR1=d;                 // |
   OCR1A=d/2;              //-+
   SET(TCCR1B,0);          //-Restart generator

   results[d]=results[d]*0.5+(float)(v)*0.5; //Filter results
  
   freq[d] = d;

    //   plot(v,0);              //-Display
    //   plot(results[d],1);
    // delayMicroseconds(1);
    }
 
 PlottArray(1,freq,results); 
 TOG(PORTB,0);            //-Toggle pin 8 after each sweep (good for scope)
}

Hi @saimshuja

The SAMD21's ADC has a maximum sample rate of 350kHz, therefore it's not going to be able to deal with PWM signals in the mid to high kilohertz (kHz) or megahertz (MHz) frequency range.

If you're trying to view the output, you'll need an oscilloscope.

please help me understand. i am using TCC1 Compare and capture , right and it should toggle pin acording to TCC1->PER.reg = 110; and TCC1->CC[2].reg = 55;

ADC is utilised to read the A0 pin , it is not concerned with the pwm frequancy.

Does serial have any problem with usage of TCC1? it should output data to serial monitor shouldnt it?

what if i put Serial.println("hello"); in loop(){} it should show up in the serial monitor.

yes you are right about the ADC, but ADC is just reading an analog value from the A0 pin , it is not conserned with the PWM frequancy.

can this line be causing issue? should it be TCC1->CC[0].reg = 55; instead
what do you think ?

Hi @saimshuja

My apologies, I think I got the wrong end of the stick regarding the ADC.

If you're using port pin PA18, then you'll need to use timer TCC0 channel 2 instead. Just do a Ctrl-F on the Arduino IDE and replace all the TCC1 entries with TCC0.

By the way, in you code above these lines:

    // Configure PA18 (D10 on Arduino Zero) to be output
  PORT->Group[PORTA].DIRSET.reg = PORT_PA18;      // Set pin as output
  PORT->Group[PORTA].OUTCLR.reg = PORT_PA18;      // Set pin to low

...aren't necessary, since (unlike the AVR based Uno/Mega) on the SAMD21 you don't need to configure the GPIO pins as outputs.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.