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

pwm dimming led rgb with trouble on third and thourth channel.

i am having trouble with pwm module 2. only two of the channels are working but not the third nor the fourth. i tried pwm module 1 but im having the same problem there. i cant tell what im missing :/

the third channel only works if i declare it on its with "NRF_PWM2->PSEL.OUT" and passing only zeros to other elements in "pwm_seq[4]" even tho i did not activate the other channels/assign them to any physical pin.

please help.

void initRgbPwm(int32_t pwmFreq)  
{                                      			
		rgbCounterTop = 0;	
		uint32_t baseFreq = 500000;
		uint8_t preSc = 5;
		while(rgbCounterTop <= 100 && baseFreq <= 16000000)
		{
			rgbCounterTop = (baseFreq / pwmFreq);
			if(rgbCounterTop <= 100 && baseFreq <= 16000000)
			{
				baseFreq = baseFreq * 2;
				preSc--;
			}	else break;
		}
		
		If(rgbCounterTop > 100)   
		{
				uint16_t pwm_seq[4] = {0, 0, 0, 0};
			
			NRF_PWM2->PSEL.OUT[0] = 0x0000001A;	// red rgb.
			NRF_PWM2->PSEL.OUT[1] = 0x00000006;	// green rgb.
			NRF_PWM2->PSEL.OUT[2] = 0x0000001B;	// blue rgb.
			
			NRF_PWM2->ENABLE = 1;   
			NRF_PWM2->MODE = 0;   
			NRF_PWM2->PRESCALER = preSc;   
			NRF_PWM2->COUNTERTOP = rgbCounterTop;    
			NRF_PWM2->LOOP = 0;   
			NRF_PWM2->DECODER = 0X00000102;    
			NRF_PWM2->SEQ[0].PTR  = ((uint32_t)(pwm_seq) << PWM_SEQ_PTR_PTR_Pos);    
			NRF_PWM2->SEQ[0].CNT  = ((sizeof(pwm_seq) / sizeof(uint16_t)) << PWM_SEQ_CNT_CNT_Pos);   
			NRF_PWM2->TASKS_SEQSTART[0] = 1;    
		}
}

void rgbPwm(uint8_t dutyCycleRed, uint8_t dutyCycleGreen, uint8_t dutyCycleBlue)
{
	uint16_t dutyCycleCh1 = (dutyCycleRed * rgbCounterTop)/100;  
	uint16_t dutyCycleCh2 = (dutyCycleGreen * rgbCounterTop)/100; 
	uint16_t dutyCycleCh3 = (dutyCycleBlue * rgbCounterTop)/100; 
	
	uint16_t pwm_seq[4] = {dutyCycleCh1  | 0x8000, dutyCycleCh2  | 0x8000, dutyCycleCh3  | 0x8000, 0};

	NRF_PWM2->SEQ[0].PTR  = ((uint32_t)(pwm_seq) << PWM_SEQ_PTR_PTR_Pos);
	NRF_PWM2->SEQ[0].CNT  = ((sizeof(pwm_seq) / sizeof(uint16_t)) << PWM_SEQ_CNT_CNT_Pos);
	NRF_PWM2->TASKS_SEQSTART[0] = 1;
}
Parents
  • Sorry, I gave you code that don't work. It will not work since dutyCycleCh1, 2 and 3 is not compile time constants. You cannot set the value of a static or global variable to a non compile constant (a variable), static uint16_t pwm_seq[4] = ... will only be run once at startup, not when the function is called. This is correct code:

    static uint16_t pwm_seq[4] = {0x8000, 0x8000, 0x8000, 0}; //initialize to 0 duty cycle
    
    uint16_t dutyCycleCh1 = (dutyCycleRed * rgbCounterTop)/100;  
    uint16_t dutyCycleCh2 = (dutyCycleGreen * rgbCounterTop)/100; 
    uint16_t dutyCycleCh3 = (dutyCycleBlue * rgbCounterTop)/100;
    
    pwm_seq[0] = dutyCycleCh1  | 0x8000;
    pwm_seq[1] = dutyCycleCh2  | 0x8000;
    pwm_seq[2] = dutyCycleCh3  | 0x8000;
    
Reply
  • Sorry, I gave you code that don't work. It will not work since dutyCycleCh1, 2 and 3 is not compile time constants. You cannot set the value of a static or global variable to a non compile constant (a variable), static uint16_t pwm_seq[4] = ... will only be run once at startup, not when the function is called. This is correct code:

    static uint16_t pwm_seq[4] = {0x8000, 0x8000, 0x8000, 0}; //initialize to 0 duty cycle
    
    uint16_t dutyCycleCh1 = (dutyCycleRed * rgbCounterTop)/100;  
    uint16_t dutyCycleCh2 = (dutyCycleGreen * rgbCounterTop)/100; 
    uint16_t dutyCycleCh3 = (dutyCycleBlue * rgbCounterTop)/100;
    
    pwm_seq[0] = dutyCycleCh1  | 0x8000;
    pwm_seq[1] = dutyCycleCh2  | 0x8000;
    pwm_seq[2] = dutyCycleCh3  | 0x8000;
    
Children
No Data
Related