Re: [Zephyr-devel] Buggy PWM driver for nRF52


Felipe Neves
 

Hello guys.

@Vikrant you are right, the current implementation of nrf pwm's driver uses a software based PWM combined with the PPI.

Here in my work we are using zephyr built for nordic target with pwm, we don't implemented the driver on zepyr's model because we haven't time to validate and integrate it.

But here is a working code to setup the PWM at 1KHz clocked by 8MHz and a set duty function, I'm planning to move this to a PR later but if anyone wants to submit it, please feel free,

take a look:


/* pwm output pin */
#define PWM_OUT_PIN		(0 | 31)

/* pwm frequency and clk in Hz */
#define PWM_FREQUENCY			1000
#define PWM_CLK					8000000
#define PWM_TOP_VALUE_FIX		(PWM_CLK / PWM_FREQUENCY)
#define PWM_MAX_DUTY			0.30f /* 30 % */
#define PWM_MIN_DUTY			0.05   /* 5% */
#define PWM_PERCENT_RESOLUTION	0.0125 /* % */

/* polarity to be added on pwm sequencer */
#define PWM_POLARITY_OFFSET		(1 << 15)

/** private variables */
static uint16_t nrf_pwm_sequence[4] = {4096 + PWM_POLARITY_OFFSET , 0 + PWM_POLARITY_OFFSET, 0 + PWM_POLARITY_OFFSET, 0 + PWM_POLARITY_OFFSET};

/**
 * temp_pwm_init()
 *
 * @brief inits the pwm controller and route it to the heater
 * @param
 * @return
 */
static void temp_pwm_init(void)
{
	NRF_PWM0->PSEL.OUT[0] = PWM_OUT_PIN;

	/* pwm in upmode */
	NRF_PWM0->MODE = 0;

	/* sets pwm count top to be at 1 KHz  and decode pwm in common mode*/
	NRF_PWM0->COUNTERTOP = PWM_CLK / PWM_FREQUENCY;
	NRF_PWM0->DECODER =  0x00000002;
	NRF_PWM0->LOOP = 0;
	NRF_PWM0->SEQ[0].REFRESH = 0;
	NRF_PWM0->SEQ[0].ENDDELAY = 0;

	/* select clock source prescaler */
	NRF_PWM0->PRESCALER = 0x00000001;

	/* enables the PWM */
	NRF_PWM0->SEQ[0].PTR  = ((uint32_t)nrf_pwm_sequence);
	NRF_PWM0->SEQ[0].CNT  = sizeof(nrf_pwm_sequence) / sizeof(uint16_t);
	NRF_PWM0->ENABLE = 1;

	/* trigger it! */
	NRF_PWM0->TASKS_SEQSTART[0] = 1;
}

/**
 * temp_pwm_set_val()
 *
 * @brief set the pwm with a new duty cicle
 * @param
 * @return
 */
static void temp_pwm_set_val(float required_energy)
{

#ifndef TEMP_CLOSED_LOOP
	/* saturate the energy expected */
	if(required_energy < TEMP_MAINTENANCE_ENERGY)
		required_energy = TEMP_MAINTENANCE_ENERGY;

	if(required_energy > TEMP_MAXIMUM_ENERGY_AVAILABLE)
		required_energy = TEMP_MAXIMUM_ENERGY_AVAILABLE;

#else
	/* saturate the energy required to the bound values, note in closed loop
	 * we can increase the pwm output to the maximum during a cycle
	 */
	if(required_energy < TEMP_MAINTENANCE_ENERGY)
		required_energy = TEMP_MAINTENANCE_ENERGY;

	if(required_energy > TEMP_MAXIMUM_ENERGY_EXCURTION)
		required_energy = TEMP_MAXIMUM_ENERGY_EXCURTION;

#endif

	/* obtains the duty cicle  and sums it up with polarity offset */
	uint16_t duty = (uint16_t)((required_energy / TEMP_MAXIMUM_ENERGY_EXCURTION) * (float)PWM_TOP_VALUE_FIX);
	duty |= PWM_POLARITY_OFFSET;


	/* update the duty cicle */
	nrf_pwm_sequence[0] = duty;
	nrf_pwm_sequence[1] = duty;
	nrf_pwm_sequence[2] = duty;
	nrf_pwm_sequence[3] = duty;

	NRF_PWM0->TASKS_SEQSTART[0] = 1;
}


The nrf_pwm_sequence variable is a kind of PWM descriptor which holds the value of duty cycle concatenated with the polarity bit,
the 4096 value means near 50% of duty cicle on channel 0, please note each pwm instance can be mapped to any pin of
nordic chip and each instance has up to 4 channels.

Please let me know if this was helpful.

best

Felipe


2018-02-08 7:50 GMT-02:00 Vikrant More <vikrant8051@...>:

I'm not able to understand what you are saying.

Is that means Zephyr PWM (fade_led example) is using software to generate PWM instead of separate dedicated
SoC's internal PWM module ?

On Thu, Feb 8, 2018 at 3:01 PM, Chettimada, Vinayak Kariappa <vinayak.kariappa.chettimada@nordicsemi.no> wrote:

Your main.c uses pwm_nrf5_sw.c driver which has conflict with BT features on nRF52840...

I do not see use of NRF_PWM0 in you main.c, of course, yes your code in the devzone does, hope you get some help there and can contribute a Zephyr driver.

I am not familiar with NRF_PWM0, hence not much help for you.

We are in the process of contributing driver based on nRFx external interfaces, you may just have to wait for it.

 

From: Vikrant More [mailto:vikrant8051@...]
Sent: Thursday, February 08, 2018 10:21 AM
To: Chettimada, Vinayak Kariappa <vinayak.kariappa.chettimada@nordicsemi.no>
Cc: zephyr-devel@...ct.org; zephyr-users@...ct.org


Subject: Re: [Zephyr-devel] [Zephyr-users] Buggy PWM driver for nRF52

 

>> Again, I will like to iterate that for nRF52840, h/w PWM driver has to be used, feel free to contribute (isn’t it fun to develop than test ;) )

Means ??

I am using h/w PWM only !! Have you looked my main.c ?

Instead I used direct register access method to set PWM on

P0.13(LED_1) & P0.14(LED2)

Here too, I failed to create two PWM with different pulse_width using single instance i.e. PWM0

So I used PWM1 for LED2.

Nordic Datasheet is also not clear about it.

So I open new ticket on Nordic #devzone forum,

https://devzone.nordicsemi.com/f/nordic-q-a/30328/nrf52840-create-2-pwms-with-different-pulse-width-using-single-instance-by-direct-register-access

 

On Thu, Feb 8, 2018 at 2:32 PM, Chettimada, Vinayak Kariappa <vinayak.kariappa.chettimada@nordicsemi.no> wrote:

Hi Vikrant,

 

As i said, there is possible overlap of PPIs with BT Controller. PPI channel 16 and 17 overlap with Code PHY feature in nRF52840.

 

I will try to send a PR wherein you could (correctly) disable Coded PHY support in nRF52840 so as to have PPI Channels from 14 to 19 available for 3 LEDs.

 

Until then, use 3 LEDs and expect 2nd LED to malfunction.

 

Again, I will like to iterate that for nRF52840, h/w PWM driver has to be used, feel free to contribute (isn’t it fun to develop than test ;) )

 

Regards,

Vinayak

 

From: Vikrant More [mailto:vikrant8051@...]
Sent: Thursday, February 08, 2018 9:31 AM


To: Chettimada, Vinayak Kariappa <vinayak.kariappa.chettimada@nordicsemi.no>
Subject: Re: [Zephyr-devel] [Zephyr-users] Buggy PWM driver for nRF52

 

Hi Vinayak,

I also able to generate & vary PWM as you did.

Problem arises when we create two channels from PWM0.

One channel -> LED1

Second Channel -> LED2

When I vary LED1 pulse width, sometimes it affects intensity of LED2

Similarly, when I vary LED2 pulse width it affects intensity of LED1

For details I've attached my main.c. Please have a look.

Use nRF connect to send data

send 0100 (ascii string) -> it is for LED1

send 1100 (ascii string) -> it is for LED2

And you will find what I'm saying.

 

 

On Thu, Feb 8, 2018 at 1:37 PM, Chettimada, Vinayak Kariappa <vinayak.kariappa.chettimada@nordicsemi.no> wrote:

Hi Vikrant,

 

I have run the upstream fade_led sample on nrf52840-PDK, I see no regression, the brightness changes every second (up and then down so on).

I advice you to debug your implementation as I have no visibility to your design.

 

Regards,

Vinayak

 

 

From: Vikrant More [mailto:vikrant8051@...]
Sent: Thursday, February 08, 2018 8:55 AM
To: Chettimada, Vinayak Kariappa <vinayak.kariappa.chettimada@nordicsemi.no>

Subject: Re: [Zephyr-devel] [Zephyr-users] Buggy PWM driver for nRF52

 

Hi Vinayak,

I'm working nRF52840-PDK board.

 

On Thu, Feb 8, 2018 at 1:21 PM, Chettimada, Vinayak Kariappa <vinayak.kariappa.chettimada@nordicsemi.no> wrote:

Hi Vikrant,

 

Please try the PWM without the BT Controller included. There could be some PWM regression due to changes in controller implementation.

That said the nrf5_sw  driver is software variant designed for older nRF51 SoCs. For newer nRF52x series h/w PWM’s should be used.

 

Nrf5_sw will work provided careful mitigation of used PPI and timers between the driver and BT controller use.

 

Which SoC are you using?

 

Regards,

Vinayak

 

From: zephyr-devel-bounces@...hyrproject.org [mailto:zephyr-devel-bounces@lists.zephyrproject.org] On Behalf Of Vikrant More
Sent: Thursday, February 08, 2018 5:04 AM
To: Marti Bolivar <marti@...>
Cc: zephyr-users@...ct.org; zephyr-devel@...ct.org; Felipe Neves <ryukokki.felipe@...>
Subject: Re: [Zephyr-devel] [Zephyr-users] Buggy PWM driver for nRF52

 

Hi Marti,

>>Are you using the latest master?

Yes

 

On Thu, Feb 8, 2018 at 1:23 AM, Marti Bolivar <marti@...> wrote:

Hi Vikrant,

 

Are you using the latest master?

 

Three improvements to nRF PWM went in fairly recently:

 

3f1dbfda1 pwm: nrf5_sw: don't disable timer if another channel is still active

ab399a1cf pwm: nrf5_sw: do not use 'inversed' polarity by default

cec073c35 pwm: nrf5_sw: add support for SYS_LOG

 

Thanks,

Marti

 

On Wed, Feb 7, 2018 at 1:59 PM, Vikrant More <vikrant8051@...> wrote:

I took reference of $zephy/samples/samples/fade_led project

 

& add following parameters in my prj.conf

 

CONFIG_STDOUT_CONSOLE=y
CONFIG_PRINTK=y
CONFIG_PWM=y
CONFIG_SYS_LOG=y
CONFIG_SYS_LOG_PWM_LEVEL=4
 
Could you please inform me, what I should do besides this ??
 
Thank You !!

 

On Feb 7, 2018 11:36 PM, "Felipe Neves" <ryukokki.felipe@...> wrote:

Hi Vikrant,

Did you configure what pins are associated to pwm duty_cycles on the menuconfig?

Best

Felipe

 

 

2018-02-07 10:15 GMT-02:00 Vikrant More <vikrant8051@...>:

Hello World !!

I've added following lines in my project main ()

    pwm_dev = device_get_binding(PWM_DRIVER);

    if (!pwm_dev)
    {
        printk("Cannot find %s!\n", PWM_DRIVER);
        return;
    }

   
    while(1)
    {
   
        if(pwm_pin_set_usec(pwm_dev, PWM_CHANNEL0, PERIOD, pulse_width0))
        {
            printk("pwm pin set fails\n");
        }

        if(pwm_pin_set_usec(pwm_dev, PWM_CHANNEL1, PERIOD, pulse_width1))
        {
            printk("pwm pin set fails\n");
        }

        k_sleep(100);
    }

And using bluetooth updating value of pulse_width0 & pulse_width1. Those two are defined as global variables.

pulse_width0 --> LED_1 on nrf52840_PDK
pulse_width1 --> LED_2 on nrf52840_PDK

I'm able to update value of both these variables using Bluetooth.

I used printk to check it. My logic is perfect.

But if I vary pulse_width0 then it affects intensity of LED2
& if I vary pulse_width1 then it affects intensity of LED1.

Why ? Is anyone found this BUG ?


_______________________________________________
Zephyr-users mailing list
Zephyr-users@...ct.org
https://lists.zephyrproject.org/mailman/listinfo/zephyr-users




--

Felipe S. Neves 

Embedded software & systems engineer

Skype: fneves1989


_______________________________________________
Zephyr-users mailing list
Zephyr-users@...ct.org
https://lists.zephyrproject.org/mailman/listinfo/zephyr-users

 

 

 

 

 



_______________________________________________
Zephyr-users mailing list
Zephyr-users@lists.zephyrproject.org
https://lists.zephyrproject.org/mailman/listinfo/zephyr-users




--
Felipe S. Neves 
Embedded software & systems engineer
Skype: fneves1989
+55 11 96610 – 0855 

Join users@lists.zephyrproject.org to automatically receive all group messages.