PWM Driver

Dear all,

I am trying to understand Riot by porting examples from Atmel Studio(SAMR21 board) to Riot( hopefully when I finish it I will upload it as a full example of Riot with threads, GPIOs, PWM, GNRC and what ever will come up on the way). Currently, I am trying to produce a waveform in an oscilosope, I read the [1], [2], [3]. However, I would like to use only pins PA18, PA19, BUT for each pin to set different period, waveform generation mode. The first step I suppose is to define as TCC0 and TCC1 the pin PA18 and PA19 only respectively[3]? or just use it as it is and in [2] instead of having a loop for each channel, to write seperately the configuration for it? I will need every possible help( i.e. where can I find the TCC_WAVE_WAVEGEN_NPWM value). Thank you in advance!

Best regards, Ilias

[1] https://github.com/RIOT-OS/RIOT/blob/master/tests/periph_pwm/main.c [2] https://github.com/RIOT-OS/RIOT/blob/master/cpu/samd21/periph/pwm.c [3] https://github.com/RIOT-OS/RIOT/blob/master/boards/samr21-xpro/include/periph_conf.h

Hi Ilias,

the periph_conf.h file should be the only one that you need to adapt. I didn't look it up but it might be that you need to make use of different PWM devices (TCC0 and TCC1) if you different periods and stuff. There is no need to adopt the loop in the driver. If you only want one channel per device, you can use this macro

https://github.com/RIOT-OS/RIOT/blob/master/boards/samr21-xpro/include/periph_conf.h#L140

and simply define one channel. Looking at the driver shows that TCC_WAVE_WAVEGEN_NPWM is not configurable:

https://github.com/RIOT-OS/RIOT/blob/master/cpu/samd21/periph/pwm.c#L139 .

Until now the "normal PWM mode" did suffice our needs. If you want that feature you should open a PR for that.

Best Peter

Hi Peter, Thank you very much for your reply, unfortunatelly I have some problems with github and cannot create pr. In my implementation of ([1],i) I use a parameter for the wave type, in the Atmel documentation, the value for a normal wave is 2, however I wasn’t able to find in RIOT where the #define TCC_WAVE_WAVEGEN_NPWM expresion for this parameter is, in order to validate the value. The idea is to implement as many features as possible on the pwm.c. Do you know any source of documentation for this driver Thank you for your understanding :slight_smile:

Best, Ilias

[1]https://github.com/RIOT-OS/RIOT/blob/master/cpu/samd21/periph/pwm.c#L139 [i] /* select the waveform generation mode -> normal PWM, wave is an int variable*/ _tcc(dev)->WAVE.reg = wave;

Hi Ilias,

it's defined in the CMSIS header and it has the value '2':

https://github.com/RIOT-OS/RIOT/blob/2c02520f73efd0b24b535f79414e43a0aa3f3553/cpu/sam0_common/include/cmsis/samr21/include/component/tcc.h#L1312 .

There is no further documentation about this single implementation. I guess you've already found the API description?!

https://riot-os.org/api/group__drivers__periph__pwm.html

In general we try to keep drivers as simple and efficient as possible. If you plan to implement and contribute code it might be worth to ask around if this kind of feature makes sense, before opening a PR that does not gain attraction.

What is the problem with GitHub? If you need help getting started with git and you don't know how to contribute code, you can find help by searching 'git' and 'Development procedures' in our wiki.

Best regards Peter

Thank you very much Peter!

Hi again :slight_smile:

I am trying to produce two different frequencies on two different pins. When I am trying [1] as it is but only changing the FREQU and STEPS, I get the correct results.(first trial to get 19khz and second trial to get 50khz) However, when I duplicate the method pwm_init(pwm_t dev, pwm_mode_t mode, uint32_t freq, uint16_t res), in order to initialize the two pins with different freq and period at the same time, I got double the freq and half the period. I think that the problem is that for both pins I am using the TCC devices in [2]. I created a duplicate of the pwm_config in [2] by only changing the TCC to TC (for the second instance ) but it didn’t work. Any suggestions? Thank you in advance!

Best regards, Ilias [1] https://github.com/RIOT-OS/RIOT/blob/master/tests/periph_pwm/main.c [2] https://github.com/RIOT-OS/RIOT/blob/master/boards/samr21-xpro/include/periph_conf.h

Hi Ilias,

did you already manage to get your setup working? I would recommend having a deeper look into the reference manual. IIRC it is not possible to configure the same PWM device with different frequencies, as you already indicated. So the question is which hardware PWM device can be configured in which way and run independently from others. This must be reflected in the peripheral configuration.

Best regards Peter

Hi Peter, unfortunately no, in [1] I have TCC0 & TCC1 in one I define pin18 and on the other pin19. What I tried and I would need your help is that both TCC0 & TCC1 are using the tcc module[2], I want to try to use for one pin(device) the tc module[3] and for the another the tcc. I tried to replicate the static const pwm_conf_t pwm_config in [1] for tc, but I received many errors. I think that this could be the solution. Thank you in advance!

Best regards, Ilias

[1] https://github.com/RIOT-OS/RIOT/blob/master/boards/samr21-xpro/include/periph_conf.h#L144 [2] https://github.com/RIOT-OS/RIOT/blob/master/cpu/sam0_common/include/vendor/samr21/include/component/tcc.h [3] https://github.com/RIOT-OS/RIOT/blob/master/cpu/sam0_common/include/vendor/samr21/include/component/tc.h