Reputation: 149
I am trying to set a PWM signal on a GPIO pin on the Seeed Stuido XIAO BLE board.
To my understanding:
I am getting a NRFX_ERROR_INVALID_STATE when I initialize the PWM driver. Does anyone know what the direct cause of this error is? To my understanding it is due to when the PWM driver is in a state and an invalid operation is used on it. However at this point of the code I am not applying an operation that is not used in the default config code that is available in the library.
UPDATE: I have figured out from the nrfx documentation that the error return is because the driver has been initialized before hand, but how is this possible? I have not run any code prior to this to initialize? From the documentation I don't think the NRFX_PWM_INSTANCE macro initializes anything but returns a pointer to parameters of a driver.
The below is my code for the main script:
int main(void)
{
k_sleep(K_SECONDS(3));
int err;
int blink_status = 0;
err = dk_leds_init();
if (err) {
printk("LEDs init failed (err %d)\n", err);
}
nrfx_pwm_t pwm0 = NRFX_PWM_INSTANCE(0);
nrfx_pwm_config_t pwm0_config = {
.output_pins = {
2,
0xFF,
0xFF,
0xFF,
},
.pin_inverted = {
false,
false,
false,
false,
},
.irq_priority = NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY,
.base_clock = NRF_PWM_CLK_16MHz,
.count_mode = NRF_PWM_MODE_UP,
.top_value = PWM_TOP_VALUE,
.load_mode = NRF_PWM_LOAD_COMMON,
.step_mode = NRF_PWM_STEP_AUTO, //need to set the repeat value to one so this moves every time through the memory.
.skip_gpio_cfg = false,
.skip_psel_cfg = false
};
err = nrfx_pwm_init(&pwm0,&pwm0_config,NULL,NULL);
if (err != NRFX_SUCCESS){
printk("Error Occured when initializing the pwm: %d\n", err);
}
nrf_pwm_values_common_t* pulse_array = (nrf_pwm_values_common_t*)malloc(PWM_ARRAY_SIZE * sizeof(nrf_pwm_values_common_t));
if (pulse_array == NULL) {
printk("Error occured when intializing the pulse array in memory\n");
}
for (int i = 0; i < PWM_ARRAY_SIZE-1; i++){
pulse_array[i] = PWM_0;
}
pulse_array[PWM_ARRAY_SIZE-1] = 0;
nrf_pwm_sequence_t pw0_seq_config = {
.values = pulse_array, //this is suppose to be a 16 bit value but lets see how a 8 bit value impacts
.length = PWM_ARRAY_SIZE,
.repeats = 0, //only play the duty cycle in each cell once.
.end_delay = RESET_CODE_DURATION,
};
nrfx_pwm_simple_playback(&pwm0, &pw0_seq_config, 1, NRFX_PWM_FLAG_LOOP);
for (;;) {
dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
}
return 0;
}
The below is my configuration file code:
CONFIG_PWM=y
CONFIG_NRFX_PWM0=y
CONFIG_NRFX_PWM1=y
CONFIG_PWM_NRFX=y
CONFIG_COMMON_LIBC_MALLOC=y
CONFIG_DK_LIBRARY=y
Can anyone provide insight as to what the INVALID STATE Error could be referring to?
thank you in advance
Upvotes: 0
Views: 160
Reputation: 149
I have determined the main issue with my implementation was that I should have uninitiated the pwm driver before initiating the PWM driver.
I believe there was probably some residual register information that showed the pwm being active but when I used the driver to initialize the PWM channel it failed.
in order to do this you can use the following piece of code from the NRFX library:
//ensuring that a prior initialization is not present.
nrfx_pwm_uninit(&pwm0);
Furthermore, I ran into issue with the configuration files, due to some config modifiers not being compatible with others. The below is my final config to get the PWM code running:
CONFIG_COMMON_LIBC_MALLOC=y
CONFIG_DK_LIBRARY=y
CONFIG_PWM=y
CONFIG_PWM_NRFX=y
The below is my final code to get the PWM generation correctly:
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <nrfx_pwm.h>
#include <zephyr/kernel.h>
#include <zephyr/toolchain.h>
#include <nrfx.h>
#include <stdlib.h>
#include <dk_buttons_and_leds.h>
#define PWM_TOP_VALUE (20)
#define PWM_NUM_LED (1)
#define PWM_RESET_PERIODS (70)
#define PWM_PULSE_ARRAY_SIZE (PWM_NUM_LED*4*8)
#define PWM_ARRAY_SIZE PWM_PULSE_ARRAY_SIZE+PWM_RESET_PERIODS //need the last value for the reset
#define PWM_0 (PWM_TOP_VALUE - 5) //clock ticks at 16 MHz
#define PWM_1 (PWM_TOP_VALUE - 10) //clock ticks at 16 MHz
#define RESET_CODE_DURATION (10) //number of periods to hold low
#define RUN_LED_BLINK_INTERVAL (500)
#define RUN_STATUS_LED DK_LED1
int main(void)
{
k_sleep(K_SECONDS(2));
int err;
int blink_status = 0;
err = dk_leds_init();
if (err) {
printk("LEDs init failed (err %d)\n", err);
}
nrfx_pwm_t pwm0 = NRFX_PWM_INSTANCE(0);
nrfx_pwm_config_t pwm0_config = {
.output_pins = {
2,
NRF_PWM_PIN_NOT_CONNECTED,
NRF_PWM_PIN_NOT_CONNECTED,
NRF_PWM_PIN_NOT_CONNECTED,
},
.pin_inverted = {
false,
false,
false,
false,
},
.irq_priority = NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY,
.base_clock = NRF_PWM_CLK_16MHz,
.count_mode = NRF_PWM_MODE_UP,
.top_value = PWM_TOP_VALUE,
.load_mode = NRF_PWM_LOAD_COMMON,
.step_mode = NRF_PWM_STEP_AUTO, //need to set the repeat value to one so this moves every time through the memory.
.skip_gpio_cfg = false,
.skip_psel_cfg = false
};
//ensuring that a prior initialization is not present.
nrfx_pwm_uninit(&pwm0);
err = nrfx_pwm_init(&pwm0,&pwm0_config,NULL,NULL);
if (err != NRFX_SUCCESS){
printk("Error Occured when initializing the pwm: %d\n", err);
}
nrf_pwm_values_common_t* pulse_array = (nrf_pwm_values_common_t*)malloc(PWM_ARRAY_SIZE * sizeof(nrf_pwm_values_common_t));
if (pulse_array == NULL) {
printk("Error occured when intializing the pulse array in memory\n");
}
for (int i = 0; i < PWM_ARRAY_SIZE; i++){
if(i < PWM_PULSE_ARRAY_SIZE) {
pulse_array[i] = PWM_0;
} else {
pulse_array[i] = PWM_TOP_VALUE;
}
}
nrf_pwm_sequence_t pw0_seq_config = {
.values = pulse_array, //this is suppose to be a 16 bit value but lets see how a 8 bit value impacts
.length = PWM_ARRAY_SIZE,
.repeats = 0, //only play the duty cycle in each cell once.
.end_delay = RESET_CODE_DURATION,
};
nrfx_pwm_simple_playback(&pwm0, &pw0_seq_config, 1, NRFX_PWM_FLAG_LOOP);
for (;;) {
dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
}
return 0;
}
I hope this helps someone else save alot of time.
Thanks
Upvotes: 2