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

max30003 afe with nrf52840

i am trying to read ecg values from afe, but gpiote is not working continously.can anyone help?

Parents Reply Children
  • i am interafcing afe using spi with nrf52840..i want to read ecg using lead off and lead on detection...but at first only lead on is detected and next interupt is not generated...i will post my code below..

  • #include <stdbool.h>
    #include <stdint.h>
    #include <string.h>
    #include "nordic_common.h"
    #include "nrf.h"
    #include "ble_hci.h"
    #include "ble_advdata.h"
    #include "ble_advertising.h"
    #include "ble_conn_params.h"
    #include "nrf_sdh.h"
    #include "nrf_sdh_soc.h"
    #include "nrf_sdh_ble.h"
    #include "nrf_ble_gatt.h"
    #include "nrf_ble_qwr.h"
    #include "app_timer.h"
    #include "ble_nus.h"
    #include "app_uart.h"
    #include "app_util_platform.h"
    #include "bsp_btn_ble.h"
    #include "nrf_pwr_mgmt.h"

    #include "nrf_gpio.h"
    #include "nrf_delay.h"
    #include "boards.h"
    #include "app_error.h"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    #include "max.h"
    #include "nrf_drv_clock.h"
    #include "nrf_gpiote.h"
    #include "nrf_drv_gpiote.h"

    //#include "nrf_dfu_ble_svci_bond_sharing.h"
    //#include "nrf_svci_async_function.h
    //#include "nrf_svci_async_handler.h"
    //#include "app_error.h"
    //#include "ble.h"
    //#include "ble_srv_common.h"
    #include "peer_manager.h"
    #include "peer_manager_handler.h"
    #include "ble_conn_state.h"
    #include "ble_dfu.h"
    #include "fds.h"
    #include "nrf_drv_clock.h"
    #include "nrf_power.h"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"

    #include "max.h"
    #include "nrf_drv_spi.h"
    #include "app_util_platform.h"
    #include "nrf_gpio.h"
    #include "nrf_delay.h"
    #include "boards.h"
    #include "app_error.h"
    #include <string.h>
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    #include "nrf_gpiote.h"
    #include "nrf_drv_gpiote.h"

    #define SPI_INSTANCE 1 /**< SPI instance index. */
    static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(1); /**< SPI instance. */
    static volatile bool spi_xfer_done; /**< Flag used to indicate that SPI instance completed the transfer. */

    #define NO_OP 0x00
    #define STATUS 0x01
    #define EN_INT 0x02
    #define EN_INT2 0x03
    #define MNGR_INT 0x04
    #define MNGR_DYN 0x05
    #define SW_RST 0x08
    #define SYNCH 0x09
    #define FIFO_RST 0x0A
    #define INFO 0x0F
    #define CNFG_GEN 0x10
    #define CNFG_CAL 0x12
    #define CNFG_EMUX 0x14
    #define CNFG_ECG 0x15
    #define CNFG_RTOR1 0x1D
    #define CNFG_RTOR2 0x1E
    #define ECG_FIFO_BURST 0x20
    #define ECG_FIFO 0x21
    #define RTOR 0x25
    #define NO_OP2 0x7F
    #define KK 0x3f
    #define ECG_FIFO_MASK 0X800000
    #define R2R_INTERRUPT_MASK 0x00000400
    #define LEAD_OFF_INTERRUPT_MASK 0x00100000
    #define LEAD_ON_INTERRUPT_MASK 0x00000800
    #define STATUS_PLL_UNLOCK_MASK 0x00000100
    #define valid 0

    volatile bool transfer_flag;
    volatile bool r2r_interrupt=false;
    volatile bool ecg_fifo_flag=false;
    volatile bool lead_off_interrupt=false;
    volatile bool lead_on_interrupt=false;
    volatile bool pll_unlocked=false;
    volatile bool etag_flag=false;
    volatile bool ecg_flag=false;
    volatile bool ecg_interrupt_flag=false;
    static void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action);
    void read_r2r();
    void read_ecg();

    void max_gpio_config()
    {
    nrf_gpio_cfg_output(TPS_CRTL);
    nrf_gpio_pin_set(TPS_CRTL);
    nrf_gpio_cfg_output(SPI_CS_PIN_MAX);

    //nrf_gpio_cfg_sense_input(LIS_INT1,NRF_GPIO_PIN_PULLDOWN,NRF_GPIO_PIN_SENSE_HIGH);
    }


    ret_code_t max_gpiote_init()
    {
    ret_code_t err_code;

    if(!nrfx_gpiote_is_init())
    {
    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);
    }

    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
    in_config.pull = NRF_GPIO_PIN_PULLUP;

    err_code = nrf_drv_gpiote_in_init(MAX_INT1, &in_config, in_pin_handler);//max_gpio_interrupt_handler);//MAX_INT1

    APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_in_event_enable(MAX_INT1, true);

    APP_ERROR_CHECK(err_code);

    }


    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
    ecg_interrupt_flag=true;
    NRF_LOG_INFO("ECG_INTERRUPT");

    }


    void check_active_interrupts()
    {
    uint32_t d=0;

    d=max_read_reg(STATUS);
    NRF_LOG_INFO("%d",d);


    if(d & ECG_FIFO_MASK)
    {

    NRF_LOG_INFO("FIFO INTERRUPT");
    // ecg_fifo_flag=true;
    //ecg_fifo_flag=false;
    NRF_LOG_INFO("READ ECG");
    read_ecg();
    }
    else
    {
    fifo_reset();
    }

    if(d & R2R_INTERRUPT_MASK)
    {
    NRF_LOG_INFO("R2R INTERRUPT");
    //r2r_interrupt = true;
    //r2r_interrupt=false;
    read_r2r();
    }

    if(d & LEAD_OFF_INTERRUPT_MASK)
    {


    NRF_LOG_INFO("LEAD OFF INTERRUPT");
    //lead_off_interrupt = true;
    nrf_gpio_cfg_output(23);
    nrf_gpio_pin_set(23);
    nrf_delay_ms(900);
    nrf_gpio_pin_clear(23);
    // lead_off_interrupt = false;
    lead_on_check();

    }

    if(d & LEAD_ON_INTERRUPT_MASK)
    {

    NRF_LOG_INFO("LEAD ON INTERRUPT");

    // lead_on_interrupt = true;
    nrf_gpio_cfg_output(13);
    nrf_gpio_pin_set(13);
    nrf_delay_ms(900);
    nrf_gpio_pin_clear(13);
    // lead_on_interrupt=false;
    pll_check();
    lead_off_check();
    }
    if(d & STATUS_PLL_UNLOCK_MASK)
    {

    NRF_LOG_INFO("PLL Interrupt");
    //pll_unlocked = true;
    pll_check();
    }

    }


    void lead_on_check()
    {

    uint32_t c=0;
    c=max_read_reg(CNFG_GEN);
    c&= 0X0007C000;
    c|= 0x00400000;
    max_write_reg(CNFG_GEN,c);
    //pll_check();
    max_write_reg(SYNCH, 0x00000000);
    c=max_read_reg(EN_INT);
    c&= 0x000ff0fc;
    c|= 0x00000901;
    max_write_reg(EN_INT, c);
    c=max_read_reg(STATUS);
    NRF_LOG_INFO("LON checking....");

    }

    void lead_off_check()
    {

    uint32_t c=0;
    c=max_read_reg(CNFG_GEN);
    c&= 0X0007C000;
    c|= 0X00081117;
    max_write_reg(CNFG_GEN,c);
    //pll_check();
    max_write_reg(SYNCH, 0x00000000);
    c=max_read_reg(EN_INT);
    c&= 0x000ff0fc;
    c|= 0x00100101;
    ///c=max_read_reg(EN_INT);
    max_write_reg(EN_INT, c);
    c=max_read_reg(STATUS);
    NRF_LOG_INFO("LEADOFF checking....");

    }

    void read_ecg()
    {
    NRF_LOG_INFO("READING ECG FIFO");
    uint8_t ecg_data[200];
    uint32_t i=0,c=0;
    uint8_t etag=0;
    memset(ecg_data,0,200*sizeof(ecg_data[0]));
    int8_t sample[3];


    do
    {
    uint32_t c = 0;
    c=max_read_reg(ECG_FIFO);
    etag=((c>>3) & 0x07);
    if(etag==valid)
    {

    etag_flag==true;
    ecg_data[i++]=((c>>16) & 0x3ffff);
    ecg_data[i++]=((c>>8) & 0xff);
    ecg_data[i++]=(c & 0x03);

    }
    else
    {
    max_write_reg(0x0a,0x00);
    etag_flag=false;
    }
    }
    while(etag_flag);
    }


    void read_r2r()
    {
    uint32_t c,r2r;
    c=max_read_reg(RTOR);
    float rr_temp =(c>>10);
    rr_temp = rr_temp * 7.8125;
    r2r = (uint16_t)rr_temp;
    NRF_LOG_INFO("R2R is %d",r2r);


    }


    void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
    void * p_context)
    {
    transfer_flag = true;
    //printf("\r\nTransfer completed\r\n");
    //NRF_LOG_INFO("Transfer completed.");
    }


    void max_spi()
    {

    nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.ss_pin = NULL;
    spi_config.miso_pin = SPI_MISO_PIN;
    spi_config.mosi_pin = SPI_MOSI_PIN;
    spi_config.sck_pin = SPI_SCK_PIN;
    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    NRF_LOG_INFO("SPI example started.");
    nrf_delay_ms(100);
    }

    uint32_t max_read_reg(int reg)
    {
    uint8_t RdBuf[4];
    uint8_t WrBuf[4];
    uint32_t Rd;
    WrBuf[0] = (((reg<<1) & 0XFF) | 0x01);
    transfer_flag = false;
    nrf_gpio_pin_clear(SPI_CS_PIN_MAX);
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, WrBuf, 1, RdBuf, 3));
    while (!transfer_flag)
    {
    __WFE();
    }
    nrf_gpio_pin_set(SPI_CS_PIN_MAX);
    Rd=(RdBuf[1]<<16) + (RdBuf[2]<<8) + (RdBuf[3]);
    return Rd;
    }
    /**@brief Function is used for writing to the registers of lis
    *
    * @param[in]Function use reg and val parameters to indicate the value and registers
    */

    void max_write_reg(uint8_t reg, uint32_t val)
    {

    uint8_t WrBuf[4];
    WrBuf[0] = (reg<<1) & 0xfe; //WREG | reg; //read GPIO reg
    WrBuf[1] = (val>>16);
    WrBuf[2] = (val>>8);
    WrBuf[3] = (val);
    transfer_flag = false;
    nrf_gpio_pin_clear(SPI_CS_PIN_MAX);
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, WrBuf, 4, NULL, 0));
    while (!transfer_flag)
    {
    __WFE();
    }

    nrf_gpio_pin_set(SPI_CS_PIN_MAX);
    }


    void max_setup(void)
    {
    uint32_t max30000_timeout = 0;
    uint32_t bit,c;
    uint32_t id;

    max_write_reg(SW_RST,0x000000);
    nrf_delay_ms(200);
    //
    id = max_read_reg(INFO);
    NRF_LOG_INFO("\r\n Device id=%x \r\n",id);
    //
    max_write_reg(CNFG_EMUX,0X00000000);
    max_write_reg(CNFG_CAL,0X000000);
    max_write_reg(0x14, 0x00);

    c = max_read_reg(CNFG_ECG);
    c &= 0x003c8fff;
    c |= 0x00400000; //250sps
    max_write_reg(CNFG_ECG, c);

    c=0;
    //R-to-R config
    c = max_read_reg(0x1D);
    c &= 0x00FF7FFF;
    c |= 0x00008000;
    max_write_reg(0x1D, c);
    nrf_delay_us(200);

    c=0;
    c = max_read_reg(0x04); //
    c &= 0x0007FF88;
    c |= 0x00f00010; //0x780010; //0x880010; //6= 0x280010; 18 = 0x880010 //0x10; // Clear RRint on RtoR readback 0x280010 0x080010 f80010
    max_write_reg(0x04, c);
    nrf_delay_us(100);

    max_write_reg(0x0A, 0x00);
    max_write_reg(0x09, 0x00);


    lead_on_check();


    }


    static void pll_check()
    {
    uint32_t c = 0;
    uint16_t delay_counter = 1000;
    do
    {
    c=max_read_reg(STATUS);

    nrf_delay_us(500);
    delay_counter--;
    } while ((c & STATUS_PLL_UNLOCK_MASK) && (delay_counter > 0));

    if (delay_counter > 0)
    {

    NRF_LOG_INFO("PLL Acquired Time Req %d ms", (1000 - delay_counter) * 2);

    }
    else
    NRF_LOG_INFO("PLL Fail");
    }

    void ecg()
    {

    if(ecg_interrupt_flag)
    {
    ecg_interrupt_flag=false;
    check_active_interrupts();
    //process_interrupts();
    }
    //nrf_delay_ms(10);
    }

    void fifo_reset()
    {
    max_write_reg(FIFO_RST, 0x000000);
    }

    void max_init()
    {

    max_gpio_config();
    nrf_delay_ms(20);
    max_gpiote_init();
    max_spi();
    nrf_delay_ms(200);
    max_setup();

    while(1)
    {
    ecg();
    }

    }
    /**@brief Application main function.

    */
    int main(void)
    {
    bool erase_bonds;

    // Initialize.
    //uart_init();
    log_init();
    timers_init();
    //buttons_leds_init(&erase_bonds);
    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_LOG_INFO("Debug logging for UART over RTT started.");
    //advertising_start();
    // idle_state_handle();
    NRF_LOG_INFO("MAX started.");
    max_init();
    // for(;;)
    // {idle_state_handle();
    // }

    }

  • I have looked at it, but I can't see any obvious reasons for this behavior. Can you post the full project for us to reproduce the behavior?

  • This is the full code..i have included ble for later use..ignore it..gpiote is not working and i cant figure it out..what are the sdk configurations for gpiote..

Related