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

HardFault with GPIOTE & SD

Hi!

I am getting a HardFault when I try to read a GATTs value inside a GPIOTE ISR handler.

I already tried setting the ISR priority to low as suggested in various posts.

Here is my code:

#include "app_settings.h"

#include "control.h"
#include "services.h"
#include "nrf_drv_gpiote.h"
#include "ble_srv_common.h"
#include "app_util_platform.h"

APP_TIMER_DEF(m_control_timer_id);

static void on_zx(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action){
    UNUSED_PARAMETER(pin);
    UNUSED_PARAMETER(action);
    //nrf_drv_gpiote_in_event_disable(ZX_PIN);

    ret_code_t err_code = 0;

    // This ISR is called when a ZX interrupt occurs
    // Start a timer in _level_ proportional ticks to allow dimming

    // Disable Triac immediately
    //nrf_drv_gpiote_out_set(TRIAC_PIN);

    // Get level value from the GATT DB
    ble_gatts_value_t gatts_value;
    gatts_value.offset = 0;
    err_code = sd_ble_gatts_value_get(m_ctl.conn_handle, m_ctl.ctl_level_handles.value_handle, &gatts_value);
    APP_ERROR_CHECK(err_code);
    float level = *((float*)gatts_value.p_value);

    // Check level boundaries
    if(level > 1){
        level = 1;
    }
    if(level < 0){
        level = 0.1;
    }
    //nrf_drv_gpiote_in_event_enable(ZX_PIN, true);

    // Calculate wait time and start timer
    // float T2 = 1.0 / 100;
    // uint32_t wait_ms = (uint32_t)(T2 * (1 - level) * 1000);
    // err_code = app_timer_start(m_control_timer_id, wait_ms, NULL);
    // APP_ERROR_CHECK(err_code);
}

// static void on_timer(void * p_context){
//     // Enable Triac
//     nrf_drv_gpiote_out_clear(TRIAC_PIN);
// }

void init_ctl(void){
    ret_code_t err_code;

    // Init GPIOTE if not yet initialized
    if(!nrf_drv_gpiote_is_init()){
        err_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code);
    }

    // Init timer for phase angle
    //err_code = app_timer_create(&m_control_timer_id, APP_TIMER_MODE_SINGLE_SHOT, on_timer);

    // Init pin for triac on
    nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(false);
    err_code = nrf_drv_gpiote_out_init(TRIAC_PIN, &out_config);
    APP_ERROR_CHECK(err_code);

    // Init pin for ZX ISR
    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
    in_config.pull = NRF_GPIO_PIN_PULLDOWN;

    err_code = nrf_drv_gpiote_in_init(ZX_PIN, &in_config, on_zx);
    APP_ERROR_CHECK(err_code);

    // Lower IRQ prio so SD does not get fucked
    NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_LOW);

    // Enable ISR on ZX rising edge
    nrf_drv_gpiote_in_event_enable(ZX_PIN, true);
}

What I would like to do is having the ISR on a pin rising edge which starts a timer. The timer ISR should then set another pin to high. I am not quite sure how to make sure the priorities are set properly as apparently the priorities 0-5 are reserved for the SD. Also I do not like having to lower the priority for those said interrupts I want as they are timing critical. So using the app scheduler or the likes wont work either (as suggested in a few posts).

Thanks for any help in advance!

Best regards

Noah

Parents
    1. Yes I am saying that :) It can read the attribute during the first call (even tho the value is 0 instead of 1; yes the handles are correct, I checked that) the SD will go to the HardFault handler afterwards. (I am using SDK 14.0 and SD v5.0; maybe that's bad tho)
    2. Oh I really should have read better, thanks for the info!
    3. Ok that sounds very promising! I already have a working solution now, where I wont use the GATT DB but rather store the value myself upon write event. Maybe that solution is bad. Timing is no issue as tests have shown. But I will still try the PPI solution as it sounds great. I read about the PPI already and didn't quite understand what the purpose really is tbh. I felt like it was a messaging system but then I might have horribly mistaken. Is there a good read you can recommend, as just the bare function docs sometimes are not enough =)
Reply
    1. Yes I am saying that :) It can read the attribute during the first call (even tho the value is 0 instead of 1; yes the handles are correct, I checked that) the SD will go to the HardFault handler afterwards. (I am using SDK 14.0 and SD v5.0; maybe that's bad tho)
    2. Oh I really should have read better, thanks for the info!
    3. Ok that sounds very promising! I already have a working solution now, where I wont use the GATT DB but rather store the value myself upon write event. Maybe that solution is bad. Timing is no issue as tests have shown. But I will still try the PPI solution as it sounds great. I read about the PPI already and didn't quite understand what the purpose really is tbh. I felt like it was a messaging system but then I might have horribly mistaken. Is there a good read you can recommend, as just the bare function docs sometimes are not enough =)
Children
No Data
Related