Hi all !
I recently faced an weird issue with a nRF5340 (on a DK board, and then a custom PCB).
When writting to the PWM peripheral, configured to some GPIO pins, some remained inactives.
First, let quote the documentation : nRF5340 PWM Peripheral, pins :
Pin configuration The OUT[n] (n=0..3) signals associated with each PWM channel are mapped to physical pins according to the configuration of PSEL.OUT[n] registers. If PSEL.OUT[n].CONNECT is set to Disconnected, the associated PWM module signal will not be connected to any physical pins. The PSEL.OUT[n] registers and their configurations are used as long as the PWM module is enabled and the PWM generation active (wave counter started). They are retained only as long as the device is in System ON mode (see the POWER section for more information about power modes). To ensure correct behavior in the PWM module, the pins that are used must be configured in the GPIO peripheral in the following way before the PWM module is enabled: Table 2. Recommended GPIO configuration before starting PWM generation PWM signal PWM pin Direction Output value Comment OUT[n] As specified in PSEL.OUT[n] (n=0..3) Output 0 Idle state defined in GPIO OUT register The idle state of a pin is defined by the OUT register in the GPIO module, to ensure that the pins used by the PWM module are driven correctly. If PWM generation is stopped by triggering a STOP task, the PWM module itself is temporarily disabled or the device temporarily enters System OFF. This configuration must be retained in the GPIO for the selected pins (I/Os) for as long as the PWM module is supposed to be connected to an external PWM circuit. Only one peripheral can be assigned to drive a particular GPIO pin at a time. Failing to do so may result in unpredictable behavior.
We can clearly see that the PWM output can be configured to any GPIO, but, and that's here the issue : This is not the case. I've tried this sample of code :
for (uint8_t k = 0; k < NRF_PWM_CHANNEL_COUNT; k++) err -= pwm_set(Target[k].dev, k, Target[k].period, pulses[k], Target->flags);
that configure pulse lenght (from a well defined algorithm that compute a list of pulses length (for each channels) from an input angle for a servo engine. Using a debugger, the computed values are perfectly fine.
But, when looking at the pins with a scope, I've seen something weird : Only some channels were working, remaining channels were not (but there were some activity right after boot (goes to '1' or '0').
After spending some hours to seeks, I found something on the devicetree.
This is the working one :
// Pin muxing configuration &pinctrl { // This first group is unused, and is pointing to the leds on the dk. pwm0_dk: pwm0_dk { group1 { psels = <NRF_PSEL(PWM_OUT0, 0, 28)>, <NRF_PSEL(PWM_OUT1, 0, 29)>, <NRF_PSEL(PWM_OUT2, 0, 30)>, <NRF_PSEL(PWM_OUT3, 0, 31)>; }; }; pwm0_topaze: pwm0_topaze { group1 { psels = <NRF_PSEL(PWM_OUT0, 1, 14)>, <NRF_PSEL(PWM_OUT1, 1, 12)>, <NRF_PSEL(PWM_OUT2, 1, 0)>, <NRF_PSEL(PWM_OUT3, 1, 4)>; }; }; };
And this one expose some defective channels (CH3, config 0)
// Pin muxing configuration &pinctrl { // This first group is unused, and is pointing to the leds on the dk. pwm0_dk: pwm0_dk { group1 { psels = <NRF_PSEL(PWM_OUT0, 0, 28)>, <NRF_PSEL(PWM_OUT1, 0, 29)>, <NRF_PSEL(PWM_OUT2, 0, 30)>, <NRF_PSEL(PWM_OUT3, 1, 1)>; }; }; pwm0_topaze: pwm0_topaze { group1 { psels = <NRF_PSEL(PWM_OUT0, 1, 14)>, <NRF_PSEL(PWM_OUT1, 1, 12)>, <NRF_PSEL(PWM_OUT2, 1, 0)>, <NRF_PSEL(PWM_OUT3, 1, 4)>; }; }; };
The only difference on the second is the fact that the PWM use at least a pin on both ports (and the non working pin was the channel 3, defined on another port...).
I haven't seen this limitation on the documentation (web or pdf file). After searching a little bit, I've seen such a limitation on the nRF54L15 ICs.
Since I've seen it on other chips, but not on the nRF5340, I suppose it's more an error on the datahseet rather than a software / hardware bug (in the meaning, it's perfectly normal and wanted behavior).
I didn't know where to post that, so I did just open an devzone forum, if it's not appropriate could you redirect me to the right place ?
Thanks !
HEYWANG Léonard.