This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Cannot Read MAX30003WING Board using SPI communication

Hello,

I tried to check SPI communication with a test board.

However, I couldn't read the device info from the max30003wing board.

Board: NRF52840DK --> MAX30003WING Using SPI.

SDK: nRF5_SDK_17.1.0_ddde560

this is my code 

#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"

#define HIGH  1
#define LOW   0

#define WREG 0x00
#define RREG 0x01

#define SPI_TIMEOUT       50000

#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_OP           0x7F

#define MAX30003_CLK_PIN  3
#define MAX30003_MOSI_PIN 4
#define MAX30003_MISO_PIN 28
#define MAX30003_CS_PIN   29

#define RTOR_INTR_MASK     0x04

#define AFE_SPI_INSTANCE  0
const nrf_drv_spi_t afe_spi = NRF_DRV_SPI_INSTANCE(AFE_SPI_INSTANCE);  /**< SPI instance. */

volatile bool afe_spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */

unsigned int heartRate;
unsigned int RRinterval;
signed long ecgdata;

typedef enum
{
  SAMPLINGRATE_128 = 128, SAMPLINGRATE_256 = 256, SAMPLINGRATE_512 = 512
}sampRate;

void max30003RegWrite (unsigned char WRITE_ADDRESS, unsigned long data)
{
	uint32_t err_code;
	uint32_t timeout = SPI_TIMEOUT;
	uint8_t dataToSend[4] = {0x00,} ;

	afe_spi_xfer_done = false;

    // now combine the register address and the command into one byte:
    dataToSend[0] = (WRITE_ADDRESS<<1) | WREG;
	dataToSend[1] = (data>>16);
	dataToSend[2] = (data>>8);
	dataToSend[3] = (data);

     // take the chip select low to select the device:
    nrf_gpio_pin_write(MAX30003_CS_PIN, LOW);    

    nrf_delay_ms(2);
	err_code = nrf_drv_spi_transfer(&afe_spi, &dataToSend, 4, NULL, 0);
    nrf_delay_ms(2);
    // take the chip select high to de-select:
    nrf_gpio_pin_write(MAX30003_CS_PIN, HIGH);    	
    while((!afe_spi_xfer_done) && --timeout);
    if(!timeout) return NRF_ERROR_TIMEOUT;   

}



void max30003SwReset(void)
{
    max30003RegWrite(SW_RST,0x000000);
    nrf_delay_ms(100);
}

void max30003Synch(void)
{
    max30003RegWrite(SYNCH,0x000000);
}

void max30003RegRead(uint8_t Reg_address, uint8_t * buff)
{
	uint32_t err_code;
	uint32_t timeout = SPI_TIMEOUT;	
    uint8_t spiTxBuff;	

	afe_spi_xfer_done = false;
	nrf_gpio_pin_write(MAX30003_CS_PIN, LOW);
	nrf_delay_ms(2);
    spiTxBuff = (Reg_address<<1 ) | RREG;
	err_code = nrf_drv_spi_transfer(&afe_spi, &spiTxBuff, 1, buff, 4);
	nrf_delay_ms(2);
    nrf_gpio_pin_write(MAX30003_CS_PIN, HIGH);
	if(err_code != NRF_SUCCESS) return err_code;
	while((!afe_spi_xfer_done) && --timeout);
	if(!timeout) return NRF_ERROR_TIMEOUT;
}

ret_code_t max30003ReadStatus(void)
{
	uint32_t err_code;
	uint32_t timeout = SPI_TIMEOUT;
    uint8_t spiTxBuff;
    uint8_t readBuff[4] ;

	afe_spi_xfer_done = false;
	spiTxBuff = (STATUS << 1 ) | RREG;

    nrf_gpio_pin_write(MAX30003_CS_PIN, LOW);    
   	nrf_delay_ms(2);
	err_code = nrf_drv_spi_transfer(&afe_spi, &spiTxBuff, 1, readBuff, 4);
	nrf_delay_ms(2);	
	nrf_gpio_pin_write(MAX30003_CS_PIN, HIGH);
	if(err_code != NRF_SUCCESS) return err_code;
	while((!afe_spi_xfer_done) && --timeout);
	if(!timeout) return NRF_ERROR_TIMEOUT;

    return NRF_SUCCESS;
}

ret_code_t max30003ReadInfo(void)
{
	uint32_t err_code;
	uint32_t timeout = SPI_TIMEOUT;
    uint8_t spiTxBuff;
    uint8_t readBuff[4] = {0x00,} ;
	afe_spi_xfer_done = false;
	spiTxBuff = (INFO << 1 ) | RREG;

    nrf_gpio_pin_write(MAX30003_CS_PIN, LOW);    
	nrf_delay_ms(2);    
	err_code = nrf_drv_spi_transfer(&afe_spi, &spiTxBuff, 1, readBuff, 4);
	nrf_delay_ms(2);	
	nrf_gpio_pin_write(MAX30003_CS_PIN, HIGH);
	if(err_code != NRF_SUCCESS) return err_code;
	while((!afe_spi_xfer_done) && --timeout);
	if(!timeout) return NRF_ERROR_TIMEOUT;
	//afe_spi_xfer_done = false;


    if((readBuff[0]&0xf0) == 0x50 ){

      NRF_LOG_INFO("max30003 is ready");
      NRF_LOG_INFO("Rev ID:  0x%02x", (readBuff[0]&0xf0));      
    }else{
      NRF_LOG_INFO("max30003 read info error\n");
      NRF_LOG_INFO("Rev ID:  0x%02x", (readBuff[0]&0xf0));      
	  return NRF_ERROR_NOT_FOUND;
    }

    return NRF_SUCCESS;
}

void max30003ReadData(int num_samples, uint8_t * readBuffer)
{
	uint32_t err_code;
	uint32_t timeout = SPI_TIMEOUT;
    uint8_t spiTxBuff;
    uint8_t readBuff[4] ;

    nrf_gpio_pin_write(MAX30003_CS_PIN, LOW);
	nrf_delay_ms(2);

    spiTxBuff = (ECG_FIFO_BURST<<1 ) | RREG;
	err_code = nrf_drv_spi_transfer(&afe_spi, &spiTxBuff, 1, readBuff, 4);
	nrf_delay_ms(2);	
	nrf_gpio_pin_write(MAX30003_CS_PIN, HIGH);
	if(err_code != NRF_SUCCESS) return err_code;

	while((!afe_spi_xfer_done) && --timeout);
	if(!timeout) return NRF_ERROR_TIMEOUT;
}

void max30003Begin()
{
    max30003SwReset();
    nrf_delay_ms(100);
    max30003RegWrite(CNFG_GEN, 0x081007);
    nrf_delay_ms(100);
    max30003RegWrite(CNFG_CAL, 0x720000);  // 0x700000
    nrf_delay_ms(100);
    max30003RegWrite(CNFG_EMUX,0x0B0000);
    nrf_delay_ms(100);
    max30003RegWrite(CNFG_ECG, 0x805000);  // d23 - d22 : 10 for 250sps , 00:500 sps
    nrf_delay_ms(100);

    max30003RegWrite(CNFG_RTOR1,0x3fc600);
    max30003Synch();
    nrf_delay_ms(100);
}

void max30003BeginRtorMode()
{
    max30003SwReset();
    nrf_delay_ms(100);
    max30003RegWrite(CNFG_GEN, 0x080004);
    nrf_delay_ms(100);
    max30003RegWrite(CNFG_CAL, 0x720000);  // 0x700000
    nrf_delay_ms(100);
    max30003RegWrite(CNFG_EMUX,0x0B0000);
    nrf_delay_ms(100);
    max30003RegWrite(CNFG_ECG, 0x805000);  // d23 - d22 : 10 for 250sps , 00:500 sps
    nrf_delay_ms(100);
    max30003RegWrite(CNFG_RTOR1,0x3fc600);
    nrf_delay_ms(100);
    max30003RegWrite(EN_INT, 0x000401);
    nrf_delay_ms(100);
    max30003Synch();
    nrf_delay_ms(100);
}

//not tested
void max30003SetsamplingRate(uint16_t samplingRate)
{
    uint8_t regBuff[4] = {0};
    max30003RegRead(CNFG_ECG, regBuff);

    switch(samplingRate){
        case SAMPLINGRATE_128:
                regBuff[0] = (regBuff[0] | 0x80 );
            break;

        case SAMPLINGRATE_256:
                regBuff[0] = (regBuff[0] | 0x40 );
            break;

        case SAMPLINGRATE_512:
                regBuff[0] = (regBuff[0] | 0x00 );
            break;

        default :            
            break;
    }

    unsigned long cnfgEcg;
    memcpy(&cnfgEcg, regBuff, 4);

    max30003RegWrite(CNFG_ECG, (cnfgEcg >> 8));
}

void getEcgSamples(void)
{
    uint8_t regReadBuff[4];
    max30003RegRead(ECG_FIFO, regReadBuff);

    unsigned long data0 = (unsigned long) (regReadBuff[0]);
    data0 = data0 <<24;
    unsigned long data1 = (unsigned long) (regReadBuff[1]);
    data1 = data1 <<16;
    unsigned long data2 = (unsigned long) (regReadBuff[2]);
    data2 = data2 >>6;
    data2 = data2 & 0x03;

    unsigned long data = (unsigned long) (data0 | data1 | data2);
    ecgdata = (signed long) (data);
	printf("ecgdata(%d) \r\n", ecgdata);
}


void getHRandRR(void)
{
    uint8_t regReadBuff[4];
    max30003RegRead(RTOR, regReadBuff);

    unsigned long RTOR_msb = (unsigned long) (regReadBuff[0]);
    unsigned char RTOR_lsb = (unsigned char) (regReadBuff[1]);
    unsigned long rtor = (RTOR_msb<<8 | RTOR_lsb);
    rtor = ((rtor >>2) & 0x3fff) ;

    float hr =  60 /((float)rtor*0.0078125);
    heartRate = (unsigned int)hr;

    unsigned int RR = (unsigned int)rtor* (7.8125) ;  //8ms
    RRinterval = RR;
}

void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                       void *                    p_context)
{
    afe_spi_xfer_done = true;
}


int main(void)
{
	uint32_t err_code;

    bsp_board_init(BSP_INIT_LEDS);

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();
    nrf_gpio_cfg_output(MAX30003_CS_PIN);
    nrf_gpio_pin_write(MAX30003_CS_PIN, 1);

    nrfx_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.frequency      = NRF_SPI_FREQ_1M;
    spi_config.ss_pin         = MAX30003_CS_PIN;
    spi_config.miso_pin       = MAX30003_MISO_PIN;
    spi_config.mosi_pin       = MAX30003_MOSI_PIN;
    spi_config.sck_pin        = MAX30003_CLK_PIN;
	//spi_config.mode			    = NRF_SPI_MODE_0;

    APP_ERROR_CHECK(nrf_drv_spi_init(&afe_spi, &spi_config, spi_event_handler, NULL));
    //APP_ERROR_CHECK(nrf_drv_spi_init(&afe_spi, &spi_config, NULL, NULL));

    NRF_LOG_INFO("NRFX SPI example started.");
	 nrf_delay_ms(2);
	 err_code = max30003ReadInfo();
	 nrf_delay_ms(2);
	 
    while (1)
    {
        // Reset rx buffer and transfer done flag
        //memset(m_rx_buf, 0, m_length);
        //spi_xfer_done = false;

        //APP_ERROR_CHECK(nrfx_spim_xfer_dcx(&spi, &xfer_desc, 0, 15));
		
        while (!afe_spi_xfer_done)
        {
            __WFE();
        }

        NRF_LOG_FLUSH();

        bsp_board_led_invert(BSP_BOARD_LED_0);
        nrf_delay_ms(200);
        #endif
    }
}

I don't know what is wrong. Is the problems with the SPI read function?

Please any help is appreciated.

Regards,

ray

Related