Hi,
I'm testing ads1292 sensor with nrf52832.
I got some problem when i use spi manager library.
I'm using ble_app_hrs project.
If i use spi manager without advertising, drdy interrupt and spi_read is working.
But, if i use spi manager after advertising started, drdy interrupt is not working.
my app works as below.
- start advertising
- start ads1292 continuous mode
- drdyEvent ocurred
- read data from ads1292 (Call ads1292ReadData() in drdyEvent())
drdyEvent() => gpio_in_event - drdyEvent ocurred
- read data from ads1292 (Call ads1292ReadData() in drdyEvent())
- drdy is not working
I set spi frequency to 250K, 500K, 1M and 2M.
And, i also changed sampling rate of ads1292 to 125sps, 250sps.
But, all state is not working.
I checked spi spec through this question before drawing schematic.
In this question, ovrebekk said "The nRF52832 should not have any problems matching this requirement. ".
Is this a problem with the spi library?
This is my code.
#include "ads1292.h" #include "nrf_drv_gpiote.h" #include "nrf_delay.h" #include "spi_controller.h" #include "port_define.h" #define ADS1292_TOTAL_WR_REG_COUNT 13 #define ADS1292_DATA_LEN 9 #define ADS1292_INIT_TRANSFER_COUNT 1 //////////////////////////// nrf_spi_mngr_callback_end_t data_callback; static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND mADSConfig[ADS1292_TOTAL_WR_REG_COUNT] = { 0x01 | 0x40, // reg_addr | 0x40 0x0B, //write length 0x00, //CONFIG1 : 250SPS 0xF0, //CONFIG2 : enable Lead-off comparator, enable reference buffer, reference 4V 0x10, //LOFF 0x67, //Channel1 0x67, //Channel2 0x25, //RLD_SENS 0x0F, //LOFF_SENS 0x40, //LOFF_STAT 0x02, //RESP1 0x03, //RESP2 0x03 //GPIO }; static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND read_all_reg[ADS1292_TOTAL_WR_REG_COUNT] = { 0x00 | 0x20, // reg_addr | 0x20 0x0B, //write length }; static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND rx_buf[ADS1292_DATA_LEN]; nrf_spi_mngr_transfer_t const ads1292_readReg_transfers[ADS1292_INIT_TRANSFER_COUNT] = { NRF_SPI_MNGR_TRANSFER(read_all_reg, sizeof(read_all_reg), rx_buf, sizeof(read_all_reg)) }; ///////////////////////// static void ads1292_cmd_cb(void * p_user_data) { __NOP(); } /////////////////////////////////////////////////////////// static void startConversion(void) { static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND cmd[]= {ADS1292_START_CMD}; static nrf_spi_mngr_transfer_t const transfer_cmd[] = { NRF_SPI_MNGR_TRANSFER(&cmd[0], 1, NULL, 0) }; static nrf_spi_mngr_transaction_t const transaction_cmd = { .begin_callback = ads1292_cmd_cb, .end_callback = NULL, .p_user_data = NULL, .p_transfers = &transfer_cmd[0], .number_of_transfers = 1, .p_required_spi_cfg = NULL }; scheduleSPI(&transaction_cmd); } static void stopConversion(void) { static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND cmd[] = {ADS1292_STOP_CMD}; static nrf_spi_mngr_transfer_t const transfer_cmd[] = { NRF_SPI_MNGR_TRANSFER(&cmd[0], 1, NULL, 0) }; static nrf_spi_mngr_transaction_t const transaction_cmd = { .begin_callback = ads1292_cmd_cb, .end_callback = NULL, .p_user_data = NULL, .p_transfers = &transfer_cmd[0], .number_of_transfers = 1, .p_required_spi_cfg = NULL }; scheduleSPI(&transaction_cmd); } static void readContinueMode(void){ static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND cmd[] = {ADS1292_RDATAC_CMD}; static nrf_spi_mngr_transfer_t const transfer_cmd[] = { NRF_SPI_MNGR_TRANSFER(&cmd[0], 1, NULL, 0) }; static nrf_spi_mngr_transaction_t const transaction_cmd = { .begin_callback = ads1292_cmd_cb, .end_callback = NULL, .p_user_data = NULL, .p_transfers = &transfer_cmd[0], .number_of_transfers = 1, .p_required_spi_cfg = NULL }; scheduleSPI(&transaction_cmd); } static void stopContinueMode(void){ static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND cmd[] = {ADS1292_SDATAC_CMD}; static nrf_spi_mngr_transfer_t const transfer_cmd[] = { NRF_SPI_MNGR_TRANSFER(&cmd[0], 1, NULL, 0) }; static nrf_spi_mngr_transaction_t const transaction_cmd = { .begin_callback = ads1292_cmd_cb, .end_callback = NULL, .p_user_data = NULL, .p_transfers = &transfer_cmd[0], .number_of_transfers = 1, .p_required_spi_cfg = NULL }; scheduleSPI(&transaction_cmd); } /////////////////////////////////////////////////////////// void ads1292ReadStart(void){ startConversion(); nrf_delay_us(10); readContinueMode(); nrf_drv_gpiote_in_event_enable(ADS_DRDY, true); } void ads1292ReadStop(void){ nrf_drv_gpiote_in_event_enable(ADS_DRDY, false); stopContinueMode(); nrf_delay_us(10); stopConversion(); } void ads1292SetReg(void){ static nrf_spi_mngr_transfer_t const ads1292_init_transfers[ADS1292_INIT_TRANSFER_COUNT] = { NRF_SPI_MNGR_TRANSFER(mADSConfig, sizeof(mADSConfig), NULL, 0) }; static nrf_spi_mngr_transaction_t const transaction_cmd = { .begin_callback = NULL, .end_callback = NULL, .p_user_data = NULL, .p_transfers = &ads1292_init_transfers[0], .number_of_transfers = 1, .p_required_spi_cfg = NULL }; scheduleSPI(&transaction_cmd); } static void ads1292_read_cb(ret_code_t result, void * p_user_data) { nrf_delay_us(100); } void ads1292ReadAllReg(void){ static nrf_spi_mngr_transfer_t const transfer_cmd[] = { NRF_SPI_MNGR_TRANSFER(read_all_reg, ADS1292_TOTAL_WR_REG_COUNT, rx_buf, ADS1292_TOTAL_WR_REG_COUNT) }; static nrf_spi_mngr_transaction_t const transaction_cmd = { .begin_callback = NULL, .end_callback = ads1292_read_cb, .p_user_data = NULL, .p_transfers = &transfer_cmd[0], .number_of_transfers = 1, .p_required_spi_cfg = NULL }; scheduleSPI(&transaction_cmd); } void ads1292DataReadCB(ret_code_t result, void * p_user_data) { data_callback(result, p_user_data); } void ads1292ReadData(void){ static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND cmd[] = {0, }; static nrf_spi_mngr_transfer_t const transfer_cmd[] = { NRF_SPI_MNGR_TRANSFER(cmd, ADS1292_DATA_LEN, rx_buf, ADS1292_DATA_LEN) }; static nrf_spi_mngr_transaction_t const transaction_cmd = { .begin_callback = NULL, .end_callback = ads1292DataReadCB, .p_user_data = rx_buf, .p_transfers = &transfer_cmd[0], .number_of_transfers = 1, .p_required_spi_cfg = NULL }; scheduleSPI(&transaction_cmd); } static void drdyEvent(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action){ ads1292ReadData(); } void initAds1292(nrf_spi_mngr_callback_end_t data_cb_fnc) { ret_code_t err_code; // set pwdn nrf_drv_gpiote_out_config_t outConfig = GPIOTE_CONFIG_OUT_SIMPLE(false); err_code = nrf_drv_gpiote_out_init(ADS_PWDN, &outConfig); APP_ERROR_CHECK(err_code); nrf_drv_gpiote_out_clear(ADS_PWDN); nrf_drv_gpiote_out_set(ADS_PWDN); nrf_delay_ms(1000); nrf_drv_gpiote_out_clear(ADS_PWDN); nrf_delay_ms(50); nrf_drv_gpiote_out_set(ADS_PWDN); nrf_delay_ms(50); // set drdy nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true); in_config.pull = NRF_GPIO_PIN_PULLUP; err_code = nrf_drv_gpiote_in_init(ADS_DRDY, &in_config, drdyEvent); //interrupt pin APP_ERROR_CHECK(err_code); nrf_drv_gpiote_in_event_enable(ADS_DRDY, false); stopContinueMode(); ads1292SetReg(); data_callback = data_cb_fnc; }
SDK version : 15.3.0
sd version : 6.1.1
#include "ads1292.h" #include "nrf_drv_gpiote.h" #include "nrf_delay.h" #include "spi_controller.h" #include "port_define.h" #define ADS1292_TOTAL_WR_REG_COUNT 13 #define ADS1292_DATA_LEN 9 #define ADS1292_INIT_TRANSFER_COUNT 1 //////////////////////////// nrf_spi_mngr_callback_end_t data_callback; static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND mADSConfig[ADS1292_TOTAL_WR_REG_COUNT] = { 0x01 | 0x40, // reg_addr | 0x40 0x0B, //write length 0x00, //CONFIG1 : 250SPS 0xF0, //CONFIG2 : enable Lead-off comparator, enable reference buffer, reference 4V 0x10, //LOFF 0x67, //Channel1 0x67, //Channel2 0x25, //RLD_SENS 0x0F, //LOFF_SENS 0x40, //LOFF_STAT 0x02, //RESP1 0x03, //RESP2 0x03 //GPIO }; static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND read_all_reg[ADS1292_TOTAL_WR_REG_COUNT] = { 0x00 | 0x20, // reg_addr | 0x20 0x0B, //write length }; static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND rx_buf[ADS1292_DATA_LEN]; nrf_spi_mngr_transfer_t const ads1292_readReg_transfers[ADS1292_INIT_TRANSFER_COUNT] = { NRF_SPI_MNGR_TRANSFER(read_all_reg, sizeof(read_all_reg), rx_buf, sizeof(read_all_reg)) }; ///////////////////////// static void ads1292_cmd_cb(void * p_user_data) { __NOP(); } /////////////////////////////////////////////////////////// static void startConversion(void) { static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND cmd[]= {ADS1292_START_CMD}; static nrf_spi_mngr_transfer_t const transfer_cmd[] = { NRF_SPI_MNGR_TRANSFER(&cmd[0], 1, NULL, 0) }; static nrf_spi_mngr_transaction_t const transaction_cmd = { .begin_callback = ads1292_cmd_cb, .end_callback = NULL, .p_user_data = NULL, .p_transfers = &transfer_cmd[0], .number_of_transfers = 1, .p_required_spi_cfg = NULL }; scheduleSPI(&transaction_cmd); } static void stopConversion(void) { static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND cmd[] = {ADS1292_STOP_CMD}; static nrf_spi_mngr_transfer_t const transfer_cmd[] = { NRF_SPI_MNGR_TRANSFER(&cmd[0], 1, NULL, 0) }; static nrf_spi_mngr_transaction_t const transaction_cmd = { .begin_callback = ads1292_cmd_cb, .end_callback = NULL, .p_user_data = NULL, .p_transfers = &transfer_cmd[0], .number_of_transfers = 1, .p_required_spi_cfg = NULL }; scheduleSPI(&transaction_cmd); } static void readContinueMode(void){ static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND cmd[] = {ADS1292_RDATAC_CMD}; static nrf_spi_mngr_transfer_t const transfer_cmd[] = { NRF_SPI_MNGR_TRANSFER(&cmd[0], 1, NULL, 0) }; static nrf_spi_mngr_transaction_t const transaction_cmd = { .begin_callback = ads1292_cmd_cb, .end_callback = NULL, .p_user_data = NULL, .p_transfers = &transfer_cmd[0], .number_of_transfers = 1, .p_required_spi_cfg = NULL }; scheduleSPI(&transaction_cmd); } static void stopContinueMode(void){ static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND cmd[] = {ADS1292_SDATAC_CMD}; static nrf_spi_mngr_transfer_t const transfer_cmd[] = { NRF_SPI_MNGR_TRANSFER(&cmd[0], 1, NULL, 0) }; static nrf_spi_mngr_transaction_t const transaction_cmd = { .begin_callback = ads1292_cmd_cb, .end_callback = NULL, .p_user_data = NULL, .p_transfers = &transfer_cmd[0], .number_of_transfers = 1, .p_required_spi_cfg = NULL }; scheduleSPI(&transaction_cmd); } /////////////////////////////////////////////////////////// void ads1292ReadStart(void){ startConversion(); nrf_delay_us(10); readContinueMode(); nrf_drv_gpiote_in_event_enable(ADS_DRDY, true); } void ads1292ReadStop(void){ nrf_drv_gpiote_in_event_enable(ADS_DRDY, false); stopContinueMode(); nrf_delay_us(10); stopConversion(); } void ads1292SetReg(void){ static nrf_spi_mngr_transfer_t const ads1292_init_transfers[ADS1292_INIT_TRANSFER_COUNT] = { NRF_SPI_MNGR_TRANSFER(mADSConfig, sizeof(mADSConfig), NULL, 0) }; static nrf_spi_mngr_transaction_t const transaction_cmd = { .begin_callback = NULL, .end_callback = NULL, .p_user_data = NULL, .p_transfers = &ads1292_init_transfers[0], .number_of_transfers = 1, .p_required_spi_cfg = NULL }; scheduleSPI(&transaction_cmd); } static void ads1292_read_cb(ret_code_t result, void * p_user_data) { nrf_delay_us(100); } void ads1292ReadAllReg(void){ static nrf_spi_mngr_transfer_t const transfer_cmd[] = { NRF_SPI_MNGR_TRANSFER(read_all_reg, ADS1292_TOTAL_WR_REG_COUNT, rx_buf, ADS1292_TOTAL_WR_REG_COUNT) }; static nrf_spi_mngr_transaction_t const transaction_cmd = { .begin_callback = NULL, .end_callback = ads1292_read_cb, .p_user_data = NULL, .p_transfers = &transfer_cmd[0], .number_of_transfers = 1, .p_required_spi_cfg = NULL }; scheduleSPI(&transaction_cmd); } void ads1292DataReadCB(ret_code_t result, void * p_user_data) { data_callback(result, p_user_data); } void ads1292ReadData(void){ static uint8_t NRF_SPI_MNGR_BUFFER_LOC_IND cmd[] = {0, }; static nrf_spi_mngr_transfer_t const transfer_cmd[] = { NRF_SPI_MNGR_TRANSFER(cmd, ADS1292_DATA_LEN, rx_buf, ADS1292_DATA_LEN) }; static nrf_spi_mngr_transaction_t const transaction_cmd = { .begin_callback = NULL, .end_callback = ads1292DataReadCB, .p_user_data = rx_buf, .p_transfers = &transfer_cmd[0], .number_of_transfers = 1, .p_required_spi_cfg = NULL }; scheduleSPI(&transaction_cmd); } static void drdyEvent(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action){ ads1292ReadData(); } void initAds1292(nrf_spi_mngr_callback_end_t data_cb_fnc) { ret_code_t err_code; // set pwdn nrf_drv_gpiote_out_config_t outConfig = GPIOTE_CONFIG_OUT_SIMPLE(false); err_code = nrf_drv_gpiote_out_init(ADS_PWDN, &outConfig); APP_ERROR_CHECK(err_code); nrf_drv_gpiote_out_clear(ADS_PWDN); nrf_drv_gpiote_out_set(ADS_PWDN); nrf_delay_ms(1000); nrf_drv_gpiote_out_clear(ADS_PWDN); nrf_delay_ms(50); nrf_drv_gpiote_out_set(ADS_PWDN); nrf_delay_ms(50); // set drdy nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true); in_config.pull = NRF_GPIO_PIN_PULLUP; err_code = nrf_drv_gpiote_in_init(ADS_DRDY, &in_config, drdyEvent); //interrupt pin APP_ERROR_CHECK(err_code); nrf_drv_gpiote_in_event_enable(ADS_DRDY, false); stopContinueMode(); ads1292SetReg(); data_callback = data_cb_fnc; }
#include "spi_controller.h" #include "port_define.h" #define SPI_INSTANCE_ID 0 NRF_SPI_MNGR_DEF(m_nrf_spi_mngr, 48, SPI_INSTANCE_ID); ret_code_t spi_init(void){ // SPI0 (with transaction manager) initialization. nrf_drv_spi_config_t const m_master0_config = { .sck_pin = SCLK_BUS, .mosi_pin = SIMO_BUS, .miso_pin = SOMI_BUS, .ss_pin = CS_ADS, .irq_priority = APP_IRQ_PRIORITY_LOWEST, .orc = 0xFF, .frequency = NRF_DRV_SPI_FREQ_2M, .mode = NRF_DRV_SPI_MODE_1, .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST }; return nrf_spi_mngr_init(&m_nrf_spi_mngr, &m_master0_config); } void performSPI(nrf_spi_mngr_transfer_t const * p_transfers, uint8_t number_of_transfers, void (* user_function)(void)){ ret_code_t err_code; err_code = nrf_spi_mngr_perform(&m_nrf_spi_mngr, NULL, p_transfers, number_of_transfers, user_function); APP_ERROR_CHECK(err_code); } void scheduleSPI(nrf_spi_mngr_transaction_t const * p_transaction){ uint32_t err_code; err_code = nrf_spi_mngr_schedule(&m_nrf_spi_mngr, p_transaction); APP_ERROR_CHECK(err_code); }