SAML21 TCC0 PWM

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

I have a SAML21e18b and an RGB LED on PA09/PA10/PA11

I can control them on/off with GPIO (i.e. yes the hardware works)

I'd like to PWM them with TCC0

Here's what I've got, but it doesn't work.  what am I doing wrong?

 

void init_rgb(void) {
    // PA09 // TCC0/WO[1] // E // 0x4
    PORT->Group[0].PMUX[9/2].bit.PMUXO = 4;
    // PA10 // TCC0/WO[2] // F // 0x5
    PORT->Group[0].PMUX[10/2].bit.PMUXE = 5;
    // PA11 // TCC0/WO[3] // F // 0x5
    PORT->Group[0].PMUX[10/2].bit.PMUXO = 5;
    
    TCC0->PER.reg = 256;
    TCC0->CC[1].reg = 64; // red
    TCC0->CC[2].reg = 64; // blue
    TCC0->CC[3].reg = 64; // green
    
    // ENABLE TCC bus clock (CLK_TCC0_APB) (is this right? how?)

    TCC0->WAVE.bit.WAVEGEN = TCC_WAVE_WAVEGEN_NPWM_Val;
    TCC0->CTRLA.bit.CPTEN1 = 1;
    TCC0->CTRLA.bit.CPTEN2 = 1;
    TCC0->CTRLA.bit.CPTEN3 = 1;
    TCC0->CTRLA.bit.ENABLE = 1;
}

Last Edited: Fri. Mar 15, 2019 - 02:14 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This seems to do what I want, but see "is there a better way?" below

void init_rgb(void) {
     struct tcc_config config_tcc;
     tcc_get_config_defaults(&config_tcc, TCC0);
     config_tcc.counter.clock_prescaler = TCC_CLOCK_PRESCALER_DIV256;
     config_tcc.counter.period = 0xFF;
     config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
     
     config_tcc.compare.match[1] = 64;
     config_tcc.compare.match[2] = 64;
     config_tcc.compare.match[3] = 64;
     
     config_tcc.pins.enable_wave_out_pin[1] = true;
     config_tcc.pins.enable_wave_out_pin[2] = true;
     config_tcc.pins.enable_wave_out_pin[3] = true;
     
     config_tcc.pins.wave_out_pin[1] = 9;
     config_tcc.pins.wave_out_pin[2] = 10;
     config_tcc.pins.wave_out_pin[3] = 11;
     
     config_tcc.pins.wave_out_pin_mux[1] = 4;
     config_tcc.pins.wave_out_pin_mux[2] = 5;
     config_tcc.pins.wave_out_pin_mux[3] = 5;
     
     tcc_init(&tcc_instance, TCC0, &config_tcc);
     tcc_enable(&tcc_instance);
}

void rgb(uint8_t r, uint8_t g, uint8_t b) { // is there a better way???
        TCC0->CC[1].reg = r; // red
        TCC0->CC[2].reg = b; // blue
        TCC0->CC[3].reg = g; // green
}