NRF52840 nrf nrfx PWM glitching complex waveform

I need to create some complex waveforms and my strategy is to use nrfx_pwm_complex_playback to play one waveform then the other as a seamless loop; and I'll manipulate the sequence that's not currently being played and it should then switch in at the end of the current sequence.

I've set up the most simple case with two sequences. It's looping but the waveform is not good - single pulses popping up. This isn't finished code but should be complete.

What am I missing? Thanks!

static nrf_pwm_values_common_t sequence_data[ 2 ][ 100 ];

static nrf_pwm_sequence_t sequences[ 2 ];


static nrfx_pwm_config_t const config_motor =
{
.output_pins =
{
IO_PIN_MOTOR_PWM, // channel 0
NRFX_PWM_PIN_NOT_USED, // channel 1
NRFX_PWM_PIN_NOT_USED, // channel 2
NRFX_PWM_PIN_NOT_USED // channel 3
},
.irq_priority = 5,
.base_clock = NRF_PWM_CLK_8MHz, // Originally 8MHz
//.base_clock = NRF_PWM_CLK_1MHz, // Originally 8MHz
//.base_clock = NRF_PWM_CLK_125kHz,
.count_mode = NRF_PWM_MODE_UP,
//.top_value = 2500,
.top_value = 255,
.load_mode = NRF_PWM_LOAD_COMMON,
.step_mode = NRF_PWM_STEP_AUTO
};

  nrfx_pwm_init(&pwm_motor, &config_motor, NULL, NULL);

void io_spwm_motor_complex_flat( uint8_t seqIndex , uint32_t duty , uint16_t periods ) {
duty = 255 - duty;

sequence_data[ seqIndex ][ 0 ] = (duty <= 255 ) ? duty : 255 ;

sequences[ seqIndex ] = ( nrf_pwm_sequence_t )
{
.values.p_common = sequence_data[ seqIndex ],
.length = 1,
.repeats = periods,
.end_delay = 0
};
nrfx_pwm_sequence_update( &pwm_motor , seqIndex , &sequences[ seqIndex ] );
}

void io_spwm_complex_restart(uint32_t duty )
{
io_spwm_motor_complex_flat( 0 , 64 , 4 );
io_spwm_motor_complex_flat( 1 , 250 , 4 );

(void)nrfx_pwm_complex_playback(&pwm_motor, &sequences[ 0 ] , &sequences[ 1 ] , 2 , NRFX_PWM_FLAG_LOOP );

//(void)nrfx_pwm_simple_playback(&pwm_motor, &sequences[ 1 ] , 1, NRFX_PWM_FLAG_LOOP);

}

io_spwm_complex_restart( 1 );

Parents
  • Hi Nick

    I don't quite understand which pulses you are talking about by looking at the figure. 

    If I understand your code correctly the PWM switches between 64/255, which are the short pulses, and 250/255, which is the other state where it is mostly high but will drop down shortly for each PWM period. 

    To me the diagram looks OK, but maybe it is something I am missing?

    If you can share your code as a C file I can also try to reproduce the issue here. 

    Best regards
    Torbjørn

  • After some more thinking. The loop mechanism uses the short circuit task to restart sequence 0; this appears to ignore the .repeats value in sequence 1. Is the task being triggered once the PWM value is loaded, i.e. before it is repeated? So maybe it's playing only the first value from sequence 1, then the task triggers to start sequence 0?

    Thinking on this, I set end_delay on sequence 1 to the number of periods required and this still did not extend sequence 1. I I think sequence 0 is being triggered as soon as the final value in sequence 1 is loaded so .repeats and .end_delay are ignored. How do I get around this?

Reply
  • After some more thinking. The loop mechanism uses the short circuit task to restart sequence 0; this appears to ignore the .repeats value in sequence 1. Is the task being triggered once the PWM value is loaded, i.e. before it is repeated? So maybe it's playing only the first value from sequence 1, then the task triggers to start sequence 0?

    Thinking on this, I set end_delay on sequence 1 to the number of periods required and this still did not extend sequence 1. I I think sequence 0 is being triggered as soon as the final value in sequence 1 is loaded so .repeats and .end_delay are ignored. How do I get around this?

Children
No Data
Related