This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

PWM - continuous waveform generation. NRF52

I am using the simple code below to generate a signal from a memory buffer.
I cannot generate a signal cyclically. If ONE sequence is used, then the buffer is played once. If use TWO sequences, the signal is generated continuously. How do I do continuous generation with ONE sequence?

Thank you

#define PWM                 NRF_PWM1

#define PWM_PIN             (17UL)

#define TIMER_RELOAD        10000
#define buffer_size 256

uint16_t pwm_buffer[ buffer_size ];

  for( uint16_t j = 0; j < buffer_size; j++) {
    pwm_buffer[j] = j << 4;
  }


	PWM->PSEL.OUT[0]  = (PWM_PIN << PWM_PSEL_OUT_PIN_Pos) |
	                    (PWM_PSEL_OUT_CONNECT_Connected << PWM_PSEL_OUT_CONNECT_Pos);
  
	PWM->ENABLE       = (PWM_ENABLE_ENABLE_Enabled << PWM_ENABLE_ENABLE_Pos);
	PWM->MODE         = (PWM_MODE_UPDOWN_Up << PWM_MODE_UPDOWN_Pos);
  
	PWM->DECODER      = (PWM_DECODER_LOAD_Common << PWM_DECODER_LOAD_Pos) |
                      (PWM_DECODER_MODE_RefreshCount << PWM_DECODER_MODE_Pos);

	PWM->PRESCALER    = (PWM_PRESCALER_PRESCALER_DIV_16 << PWM_PRESCALER_PRESCALER_Pos);
	PWM->COUNTERTOP   = (TIMER_RELOAD << PWM_COUNTERTOP_COUNTERTOP_Pos);
	
	PWM->SEQ[0].PTR   = ((uint32_t)(pwm_buffer) << PWM_SEQ_PTR_PTR_Pos);
	PWM->SEQ[0].CNT   = ((sizeof(pwm_buffer) / sizeof(uint16_t)) << PWM_SEQ_CNT_CNT_Pos);
 
	//PWM->SEQ[1].PTR   = ((uint32_t)(pwm_buffer) << PWM_SEQ_PTR_PTR_Pos);
	//PWM->SEQ[1].CNT   = ((sizeof(pwm_buffer) / sizeof(uint16_t)) << PWM_SEQ_CNT_CNT_Pos);

	PWM->SEQ[0].REFRESH = 0;
	PWM->SEQ[0].ENDDELAY = 0;

	//PWM->LOOP = (PWM_LOOP_CNT_Disabled << PWM_LOOP_CNT_Pos);
	PWM->LOOP = (4 << PWM_LOOP_CNT_Pos);

	PWM->SHORTS = PWM_SHORTS_LOOPSDONE_SEQSTART0_Msk;

	PWM->TASKS_SEQSTART[0] = 1;

Parents
  • I found the answer.

    SDK code:

    nrfx_pwm.c

    uint32_t nrfx_pwm_simple_playback(nrfx_pwm_t const *         p_instance,
                                      nrf_pwm_sequence_t const * p_sequence,
                                      uint16_t                   playback_count,
                                      uint32_t                   flags)
    {
    ...
    
        // To take advantage of the looping mechanism, we need to use both sequences
        // (single sequence can be played back only once).
        nrf_pwm_sequence_set(p_instance->p_registers, 0, p_sequence);
        nrf_pwm_sequence_set(p_instance->p_registers, 1, p_sequence);
    ...
    }

    For continuous playback, TWO sequences need to be initialized.

Reply
  • I found the answer.

    SDK code:

    nrfx_pwm.c

    uint32_t nrfx_pwm_simple_playback(nrfx_pwm_t const *         p_instance,
                                      nrf_pwm_sequence_t const * p_sequence,
                                      uint16_t                   playback_count,
                                      uint32_t                   flags)
    {
    ...
    
        // To take advantage of the looping mechanism, we need to use both sequences
        // (single sequence can be played back only once).
        nrf_pwm_sequence_set(p_instance->p_registers, 0, p_sequence);
        nrf_pwm_sequence_set(p_instance->p_registers, 1, p_sequence);
    ...
    }

    For continuous playback, TWO sequences need to be initialized.

Children
No Data
Related