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

How to program an Analogic output on pin 18

Hello

I have seen in the various examples that most of the time the output are digital (0 or 1) . i program a PWM signal to make any DC output on the pin 18

but unfortunately, this occurs into a loop checking UART data coming. It is simple to let a pin at 0 or 1, but i need to constantly generate the PWM signal if something in between. if i write a while loop in this event handler, i cannot check if there is new data coming since my event handler is stuck doing the PWM. 

How is the best way to turn a pin as an analog output without condamning the event loop to detect if there is a BLE data coming to shut down this signal or modify its value?

Thanks

Philippe

  • The Board Support Package is just a driver for the DK buttons and LEDs and their interaction with our examples. If you want to use the LEDs is suggest you remove the BSP and control the GPIOs connected to the LEDs and buttons through the GPIO/GPIOTE peripherals. 

    "__WFE();

    // Clear the event register.
    __SEV();
    __WFE();"

    This sequence of calls is needed to put the system into the SystemON sleep state. A single __WFE() will not suffice. 

    You'll want to use the ARM CMSIS configuration wizard. It reads our sdk_config.h file and presents it in a simple GUI. You'll notice the headers/tags in the sdk_config.h file. They indicate what sections of the sdk_config.h file you'll need to merge a driver for instance. There is also a master sdk_config.h file in sdk15\config\nrf52832\config, who's easy to use with the CMSIS condiguration wizard.

    See https://www.youtube.com/watch?v=b0MxWaAjMco&index=4&list=PLx_tBuQ_KSqGHmzdEL2GWEOeix-S5rgTV 

  • Hello

    first of thanks a lot for the great information regarding the CMSIS configuration wizard. and for your explanation. Installation completed and working perfectl for that wizard

    I would love to come back on your suggestion regarding the BSP. this is true that this conflicts when i also tried to merge the ble_uart and pwm_library (much easier to understand than the pwm_driver). 

    Even though i start understanding the principle of the GPIO/GPIOTE  . would you please help me how to modify let say the pwm_library or pwm_driver to have that fixed? 

    sorry, my questions might look stupid to you. but i am really a beginner in that domain and i intended to use your example to understand how to merge two of them to make the UART modifiying a LED. I might not have the level to make the changes of your examples without having understood them fully. I am struggling more with the compiling of that merge than the source it self ... a clear example is really missing. 

    thanks again for your patience

  • May be the GPIOTE example is the best to merge with the BLE_UARTE? But i would need to add a PWM right. 

    Sincerely in all your examples, what it really misses are documentations. Could you please help me understanding what is happening in that code? There is almost no line of documentation.... 

    thanks for your understanding. I really want to learn how to manage your product...

    #include <stdbool.h>
    #include <stdint.h>
    #include "nrf.h"
    #include "nrf_gpiote.h"
    #include "nrf_gpio.h"
    #include "boards.h"
    #include "nrf_drv_ppi.h"
    #include "nrf_drv_timer.h"
    #include "nrf_drv_gpiote.h"
    #include "app_error.h"

    #ifdef BSP_LED_0
    #define GPIO_OUTPUT_PIN_NUMBER BSP_LED_0 /**< Pin number for output. */
    #endif
    #ifndef GPIO_OUTPUT_PIN_NUMBER
    #error "Please indicate output pin"
    #endif

    static nrf_drv_timer_t timer = NRF_DRV_TIMER_INSTANCE(0);

    void timer_dummy_handler(nrf_timer_event_t event_type, void * p_context){}

    static void led_blinking_setup()
    {
    uint32_t compare_evt_addr;
    uint32_t gpiote_task_addr;
    nrf_ppi_channel_t ppi_channel;
    ret_code_t err_code;
    nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);

    err_code = nrf_drv_gpiote_out_init(GPIO_OUTPUT_PIN_NUMBER, &config);
    APP_ERROR_CHECK(err_code);


    nrf_drv_timer_extended_compare(&timer, (nrf_timer_cc_channel_t)0, 200 * 1000UL, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);

    err_code = nrf_drv_ppi_channel_alloc(&ppi_channel);
    APP_ERROR_CHECK(err_code);

    compare_evt_addr = nrf_drv_timer_event_address_get(&timer, NRF_TIMER_EVENT_COMPARE0);
    gpiote_task_addr = nrf_drv_gpiote_out_task_addr_get(GPIO_OUTPUT_PIN_NUMBER);

    err_code = nrf_drv_ppi_channel_assign(ppi_channel, compare_evt_addr, gpiote_task_addr);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_enable(ppi_channel);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_out_task_enable(GPIO_OUTPUT_PIN_NUMBER);
    }

    /**
    * @brief Function for application main entry.
    */
    int main(void)
    {
    ret_code_t err_code;

    err_code = nrf_drv_ppi_init();
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    err_code = nrf_drv_timer_init(&timer, &timer_cfg, timer_dummy_handler);
    APP_ERROR_CHECK(err_code);
    #ifdef NRF51
    //Workaround for PAN-73.
    *(uint32_t *)0x40008C0C = 1;
    #endif

    // Setup PPI channel with event from TIMER compare and task GPIOTE pin toggle.
    led_blinking_setup();

    // Enable timer
    nrf_drv_timer_enable(&timer);

    while (true)
    {
    // Do Nothing - GPIO can be toggled without software intervention.
    }
    }

  • BSP_DEFINES_ONLY this option in both pwm_library (or in gpiote) examples is really messing things up when merge with ble_uart

  • First of it looks to me like your're using an old SDK, I suggest using SDK14.2 if you're a beginner. 

    Your main source of documentation is the SDK14.2 API Reference and the nRF52832 Product Specification. The chapter on PPI and EasyDMA are must reads for the nRF5x series of devices. 

    I suggest you stick to the peripheral examples until you've managed to create a PWM with a timer and gpiote. I also suggest you try out the SAADC or serial in order to test EasyDMA.

    The BLE examples are a bit more complex and I suggest you do not merge a peripheral's example into it until you've understood how the peripheral's example works on its own.

    I recommend that you read a peripheral's registers after you've initialized it's driver and compare it to what you'd expect them to be given the registers documentation in the datasheet. It will tell you if you've initialized the driver correctly. 

    Last tip; you need to read a peripheral's chapter in the datasheet in order to understand how it's driver is used. 

Related