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

questions about go into the interruption handle function

Hi Nordic, 

I am testing the sensor LSM9DS1 with the nrf52840. I try to make one pin attach to handle the interruption for the FIFO full interrupt.The FIFO handling function is"uint8_t read_out_FIFO_float(void)" in line No.41 to No.53.  But I find in the FIFO handling it did not finish all the logs, seems line 46 to 49 is not running correctly. Could you please help to check? I have attached my code here. 

the code is based on the example of "ble_app_uart_peripheral" 

//reference 
//https://github.com/cypresssemiconductorco/mtb-example-btsdk-sensorhub
//https://github.com/drvrh/nRF52-DK-and-LSM9DS1/blob/master/main.c

void lsm9ds1_niklas_fifo_setup(void)
{
	uint32_t ret;
        uint8_t value;
	lsm9ds1_fifo_mode_set(&dev_ctx_imu, LSM9DS1_STREAM_TO_FIFO_MODE);
	
	lsm9ds1_fifo_stop_on_wtm_set(&dev_ctx_imu,  28);
       
	lsm9ds1_pin_int1_route_t value_set;
        value_set.int1_drdy_xl=1;
        value_set.int1_drdy_g =1;
        value_set.int1_boot   =1;
        value_set.int1_fth    =0;
        value_set.int1_ovr    =1;
        value_set.int1_fss5   =0;
        value_set.int1_ig_xl  =0;
        value_set.int1_ig_g   =0;
	lsm9ds1_pin_int1_route_set(&dev_ctx_imu, value_set); // need to check the LSM9DS1documentation
        lsm9ds1_pin_int1_route_get(&dev_ctx_imu, &value_set); 

        value=(value_set.int1_drdy_xl<<7)+(value_set.int1_drdy_g <<6)+(value_set.int1_boot <<5)+ (value_set.int1_fth <<4)+(value_set.int1_ovr <<3)+(value_set.int1_fss5 <<2)+(value_set.int1_ig_xl  <<1)+value_set.int1_ig_g ;
        #ifdef DEBUG_FIFO_SIZE_INSIDE
        printf("i1_r_s= %02x\n", value);  nrf_delay_ms(1);
        #endif

        lsm9ds1_fifo_watermark_set(&dev_ctx_imu, 28);
        value=0;

        lsm9ds1_fifo_watermark_get(&dev_ctx_imu, &value);
        #ifdef DEBUG_FIFO_SIZE_INSIDE
        printf("wtm= %02x \n", value);  nrf_delay_ms(1);
        #endif
	
}

uint8_t read_out_FIFO_float(void)
{
  uint8_t i=0;
  uint8_t k=0;
  uint8_t unread_size;
  lsm9ds1_fifo_data_level_get(&dev_ctx_imu, &unread_size);
  #ifdef DEBUG_FIFO_SIZE_INSIDE
   printf("P1:%d", unread_size);nrf_delay_ms(10);
  #endif


  return unread_size;
}


void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
  printf("INTC\n");nrf_delay_ms(1);
  //read_out_FIFO_float();
  uint8_t unread_size;
  lsm9ds1_fifo_data_level_get(&dev_ctx_imu, &unread_size);
  #ifdef DEBUG_FIFO_SIZE_INSIDE
   printf("P1:%d", unread_size);nrf_delay_ms(1);
  #endif
}

static void interrupt_pin_init(void)
{
    ret_code_t err_code;

    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_config_t in_config =GPIOTE_RAW_CONFIG_IN_SENSE_LOTOHI(true);// GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
    in_config.pull = NRF_GPIO_PIN_PULLDOWN;//NRF_GPIO_PIN_PULLUP;

    err_code = nrf_drv_gpiote_in_init(PIN_INTERRUPT, &in_config, in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(PIN_INTERRUPT, true);
}
 

In the below is the main function code part

int main(void)
{
    bool erase_bonds;
        
    //Initialize.
    uart_init();
    log_init();

    //bsp_board_init(BSP_INIT_LEDS);
    timers_init();
    //buttons_leds_init(&erase_bonds);
    interrupt_pin_init();

    power_management_init();
    ble_stack_init();
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();

    // Start execution.
    printf("\r\nUART started.\r\n");nrf_delay_ms(1);
    NRF_LOG_INFO("Debug logging for UART over RTT started.");
    advertising_start();

    ret_code_t err_code;
    uint8_t sample_data;
    bool detected_device = false;
    uint32_t ret;

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    printf("\r\n SPI started.\r\n");nrf_delay_ms(1);
    spi_init();
    sensor_reset();

    //Initialize inertial sensors (IMU) driver interface 
    dev_ctx_mag.write_reg = platform_write;
    dev_ctx_mag.read_reg = platform_read;
    dev_ctx_mag.handle = (void*)&spi_add_mag;

    // Initialize magnetic sensors driver interface 
    dev_ctx_imu.write_reg = platform_write;
    dev_ctx_imu.read_reg = platform_read;
    dev_ctx_imu.handle = (void*)&spi_add_imu;

    // Check device ID 
    lsm9ds1_dev_id_get(&dev_ctx_mag, &dev_ctx_imu, &whoamI);
	nrf_delay_ms(1);
        printf("who imu= %X\n",whoamI.imu);nrf_delay_ms(1);//nrf_delay_ms(1);//app_uart_flush();
	printf("who mag= %X\n",whoamI.mag);nrf_delay_ms(1);//nrf_delay_ms(1);//app_uart_flush();

    if (whoamI.imu != LSM9DS1_IMU_ID || whoamI.mag != LSM9DS1_MAG_ID){
      while(1){
        printf("\r\nCannot find the LSM9DS1.********\r\n");nrf_delay_ms(1000);
        sensor_reset();
        lsm9ds1_dev_id_get(&dev_ctx_mag, &dev_ctx_imu, &whoamI);
      }
    }
    printf("Who am I register [IMU]: 0x%x [MAG]: 0x%x \r\n\n", whoamI.imu, whoamI.mag);  nrf_delay_ms(1);//app_uart_flush();

     printf("                 L0 \r\n");nrf_delay_ms(1);
     //Restore default configuration 
     lsm9ds1_dev_reset_set(&dev_ctx_mag, &dev_ctx_imu, PROPERTY_ENABLE);

     printf("                 L1 \r\n");nrf_delay_ms(1);
     do {
      lsm9ds1_dev_reset_get(&dev_ctx_mag, &dev_ctx_imu, &rst);
      printf("rst =:0x%x \r\n", rst);  nrf_delay_ms(500);
    } while (rst);

     printf("                 L2 \r\n");nrf_delay_ms(1);

    //Enable Block Data Update 
    lsm9ds1_block_data_update_set(&dev_ctx_mag, &dev_ctx_imu, PROPERTY_ENABLE);
     printf("                 L3 \r\n");nrf_delay_ms(1);

    //Set full scale 
    lsm9ds1_xl_full_scale_set(&dev_ctx_imu, LSM9DS1_4g);
    lsm9ds1_gy_full_scale_set(&dev_ctx_imu, LSM9DS1_2000dps);
    lsm9ds1_mag_full_scale_set(&dev_ctx_mag, LSM9DS1_16Ga);
    printf("                 L4 \r\n");nrf_delay_ms(1);

    //Configure filtering chain - See datasheet for filtering chain details 
    //Accelerometer filtering chain 
    lsm9ds1_xl_filter_aalias_bandwidth_set(&dev_ctx_imu, LSM9DS1_AUTO);
    lsm9ds1_xl_filter_lp_bandwidth_set(&dev_ctx_imu, LSM9DS1_LP_ODR_DIV_50);
    lsm9ds1_xl_filter_out_path_set(&dev_ctx_imu, LSM9DS1_LP_OUT);
    printf("                 L5 \r\n");nrf_delay_ms(1);
    //Gyroscope filtering chain 
    lsm9ds1_gy_filter_lp_bandwidth_set(&dev_ctx_imu, LSM9DS1_LP_ULTRA_LIGHT);//LSM9DS1_LP_STRONG);//
    lsm9ds1_gy_filter_hp_bandwidth_set(&dev_ctx_imu, LSM9DS1_HP_MEDIUM);
    lsm9ds1_gy_filter_out_path_set(&dev_ctx_imu, LSM9DS1_LPF1_HPF_LPF2_OUT);
    printf("                 L6 \r\n");nrf_delay_ms(1);

    //Set Output Data Rate / Power mode 
    lsm9ds1_imu_data_rate_set(&dev_ctx_imu, LSM9DS1_IMU_59Hz5);
    //lsm9ds1_imu_data_rate_set(&dev_ctx_imu, LSM9DS1_IMU_952Hz);

    lsm9ds1_mag_data_rate_set(&dev_ctx_mag, LSM9DS1_MAG_UHP_10Hz);
    //lsm9ds1_mag_data_rate_set(&dev_ctx_mag, LSM9DS1_MAG_LP_1000Hz);
    printf("                 L7 \r\n");nrf_delay_ms(1);

    lsm9ds1_niklas_fifo_setup();

    for (;;)
    {
        printf("\r\n1088\n");//nrf_delay_ms(1);
        idle_state_handle();
        printf("\r\n1090\n");//nrf_delay_ms(1);
     }
}

Thank you in advance. 

Parents Reply Children
  • Hi, If I put lsm9ds1_fifo_data_level_get(&dev_ctx_imu, &unread_size); into the in_pin_handler(), the code will stuck, it will only print "I" of the printf("INTC\n");nrf_delay_ms(1);

    If I remove the  lsm9ds1_fifo_data_level_get(&dev_ctx_imu, &unread_size); , it will print out INTC from the printf("INTC\n");nrf_delay_ms(1);

  • What happens inside lsm9ds1_fifo_data_level_get? Is the code stuck somewhere inside that function, or is there some error/HardFault?

  • Hi,

    When I run lsm9ds1_fifo_data_level_get without the interruption part, it works fine. I have tested this. 

  • Which priority is the GPIOTE interrupt running at? If lsm9ds1_fifo_data_level_get have some blocking call waiting for a lower (or equal) priority event it will cause a deadlock/loop.

  • Hi,

    Here is the initial code for the interruption, I am not sure for the the priority level

    static void interrupt_pin_init(void)
    {
    ret_code_t err_code;

    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);

    //nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(false);

    //err_code = nrf_drv_gpiote_out_init(PIN_OUT, &out_config);
    //APP_ERROR_CHECK(err_code);
    //GPIOTE_CONFIG_IN_SENSE_LOTOHI //GPIOTE_RAW_CONFIG_IN_SENSE_LOTOHI
    nrf_drv_gpiote_in_config_t in_config =GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);// GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
    in_config.pull = NRF_GPIO_PIN_PULLDOWN;//NRF_GPIO_PIN_PULLUP;

    err_code = nrf_drv_gpiote_in_init(PIN_INTERRUPT, &in_config, in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(PIN_INTERRUPT, true);

    }

    Here is the code for the spi init

    void spi_init(void)
    {
    /* 初始化SPI0 */
    nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.ss_pin = SPI_SS_PIN;//nRF52832只能使用GPIO作为片选,所以这个单独定义了SPI CS管脚
    spi_config.miso_pin = SPI_MISO_PIN;
    spi_config.mosi_pin = SPI_MOSI_PIN;
    spi_config.sck_pin = SPI_SCK_PIN;
    spi_config.frequency = NRF_DRV_SPI_FREQ_4M;
    nrf_gpio_cfg_output(IMU_CS_M_PIN);
    nrf_gpio_cfg_output(IMU_CS_AG_PIN);
    nrf_gpio_cfg_output(IMU_POWER_PIN);

    nrf_gpio_pin_set(IMU_CS_M_PIN);
    nrf_gpio_pin_set(IMU_CS_AG_PIN);
    nrf_gpio_pin_clear(IMU_POWER_PIN);
    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    //nrf_delay_ms(600);
    //nrf_gpio_pin_clear(IMU_POWER_PIN);

    }

Related