Nano BLE33 PWM Control using nfrx_pwm callbacks

Hello

The Nano BLE has a built in PWM Management Chip that can do 4 groups of 4 signals. It also has the ability to read a PWM Sequence and send that out automatically (I assume the download LED indicator is doing this when it fades up and down while waiting for a download).

I am trying to form a BLDC motor waveform via the nfrx_pwm library calls.

  • I have a pre-loaded array of 360 Steps with 4 values each (an FOC waveform for 3 phases and a dud value)
  • I can load these and start these with no problem (the outputs will be driven via DMA calls from the PWM sub-processor without any interaction required from the program)

The code is below. It sends one wave to the RGB LED and the other to Hardware pins. There are two options for running
1- starting the waves with callbacks and letting the callbacks stop the waves at end of sequence
2- starting the waves without callbacks and hard stopping them in the middle of waves (not desired)

Code has 3 main sections in the loop and 2 callback routines
1- timing for change of top_value and stopping
2- starting of pwm1 if stopped
3- starting of pwm2 if stopped

When I run this without callbacks it functions correctly but will stop the waveforms in the middle of a wave and restart it. I would like to use the callbacks but it seems to somewhat hang the processor as all counting stops (waveforms will continue to process the DMA calls and PWM outputs continue work) but counting stops.

2 questions

1- I have not found an easy way to change the top_value of a waveform without stopping a PWM, uninitializing it, and starting it again - my means of controlling the frequency of the waveform. Anyone know a better way?

2- -The nrfx_pwm_stop command will stop the wave immediately in mid wave and I would like to stop this waveform at the end of its sequence. I have tried to implement the callback routines that should be called with the appropriate flags of - NRFX_PWM_FLAG_SIGNAL_END_SEQ0 and NRFX_PWM_FLAG_SIGNAL_END_SEQ1. I see in some other Nordic variations that there is a event clear but I do not see that in this file. Should I be trying to get the event register address and then set that to 0?

Any help would be appreciated.
BLE33_PWM_BLDC.ino (15.0 KB)

1 Like

I have tested a bit further with a simple digitalWrite as the first statement in the Interrupt handler and it appears that the handler is not even being called.

I did find some further instructions that may function but, without confirmation of the interrupt being called, I am somewhat stuck.

Does anyone have experience with interrupt calls from nfrx code that work within the Arduino code base?

Here is some new code for the interrupt but as I say - the simple digitalWrite does not even execute. This checks each event and clears the flag if set - I am assuming this would be required it the routine was called. Any thoughts?


void pwm1seqEventsHander(nrfx_pwm_evt_type_t pwm_event_type) {
      digitalWrite(4, HIGH);  // Enable Output On
    if(nrf_pwm_event_check(0, NRF_PWM_EVENT_STOPPED)) nrf_pwm_event_clear(0,NRF_PWM_EVENT_STOPPED);
    if(nrf_pwm_event_check(0, NRF_PWM_EVENT_SEQSTARTED0)) nrf_pwm_event_clear(0,NRF_PWM_EVENT_SEQSTARTED0);
    if(nrf_pwm_event_check(0, NRF_PWM_EVENT_SEQSTARTED1)) nrf_pwm_event_clear(0,NRF_PWM_EVENT_SEQSTARTED1);
    if(nrf_pwm_event_check(0, NRF_PWM_EVENT_SEQEND1)) nrf_pwm_event_clear(0,NRF_PWM_EVENT_SEQEND1);
    if(nrf_pwm_event_check(0, NRF_PWM_EVENT_LOOPSDONE)) nrf_pwm_event_clear(0,NRF_PWM_EVENT_LOOPSDONE);
    if(nrf_pwm_event_check(0, NRF_PWM_EVENT_PWMPERIODEND)) nrf_pwm_event_clear(0,NRF_PWM_EVENT_PWMPERIODEND);
    if(nrf_pwm_event_check(0, NRF_PWM_EVENT_SEQEND0)) {
      nrf_pwm_event_clear(0,NRF_PWM_EVENT_SEQEND0);
      if(pwm1stopreq == true) {
         nrfx_pwm_stop(&pwm1,false);
      }
    }
    return;
}

May be, that these nrfx_.. functions you are calling need some extra initialization, which is done inside the mbed-OS somewhere. Where is the interrupt of the accordingly periphery enabled?
Since a few weeks I try to use the nRF52840 directly with bypassing the mbed-OS. I had success with programming my own BLE beacon based on direct register access. But some hurdles have been very high (for me). So e.g. I had to switch on a special clock and power mode. Fortunately I have seen that in another forum. Without that hint, I would have failed.
Currently I try to program my own I2C (TWI) class based on interrupts and time out watching. And I will not use basic functions of the mbed-OS, because I do not understand their dependencies.

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