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);
}