Hello Nordic,
I am trying to make NRF52840-DK Communication with MAX30003 ECG Board via SPI. I am using the SPI example and it works fine. Now I have made three SPI functions that I can use in my project:
- _Read_Data(int num_samples)
- _Reg_Write (unsigned char WRITE_ADDRESS, unsigned long data)
-_Reg_Read(uint8_t Reg_address)
I have made the following so far and the event handler works fine if I keep the original example code for the SPI transfer. It is just the _Reg_Read(uint8_t Reg_address) and _Reg_Write (unsigned char WRITE_ADDRESS, unsigned long data) function which doesn't work. I am sure it has something to do with my function arguments. I am not too familiar with using pointers. The code below compiles without errors, but the LED does not flash as it is the case with the original sample code. I have referred MAX30003 ECG working Arduino code. See my both code below.
Any help is appreciated.
Regards,
rohit
#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 "MAX30003.h" #include <math.h> #include <string.h> #define SPI_INSTANCE 0 /**< SPI instance index. */ #define ECG_FIFO ((uint8_t)0x21) #define RTOR ((uint8_t)0x25) static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */ static volatile bool spi_xfer_done; /**< Flag used to indicate that SPI instance completed the transfer. */ //FOr ECG Tx Buffer uint8_t SPI_RX_Buff[6]; /**< RX buffer. */ uint8_t SPI_TX_Buff[6]={6,5,4,3,2,25}; uint8_t ECG_length = sizeof(SPI_TX_Buff); uint8_t dataToSend[1]; uint8_t A[1]=0xFF; uint8_t A1[1]=0x00; uint8_t ECG_FIFO_BURST1; volatile char *SPI_RX_Buff_Ptr; int i=0; unsigned long uintECGraw = 0; signed long intECGraw=0; uint8_t DataPacketHeader[20]; uint8_t data_len = 8; signed long ecgdata; unsigned long data; char SPI_temp_32b[4]; char SPI_temp_Burst[100]; static const uint8_t m_board_led_list[LEDS_NUMBER] = SPI_LIST; /* As Reference from Aurdino Code */ //void bsp_board_toggle_pin(uint32_t pin_idx); void timerIsr(); void MAX30003_Reg_Write (unsigned char WRITE_ADDRESS, unsigned long data); void max30003_sw_reset(void); void max30003_synch(void); void MAX30003_Reg_Read(uint8_t Reg_address); void MAX30003_Read_Data(int num_samples); void MAX30003_begin(); void max30003_sw_reset(void) { nrf_gpio_pin_set(SPI_SS_PIN); //Slave select Set nrf_gpio_pin_clear(SPI_SS_PIN); //Slave select High MAX30003_Reg_Write(SW_RST,0x00); //As per Arduino Code } void max30003_synch(void){ MAX30003_Reg_Write(SYNCH,0x000000); //As per Arduino Code } void timerIsr(){ nrf_gpio_pin_toggle(NRF_FCLK_PIN); //As per Arduino Code } void MAX30003_begin(){ max30003_sw_reset(); nrf_delay_ms(100); MAX30003_Reg_Write(CNFG_GEN, 0x081007); nrf_delay_ms(100); MAX30003_Reg_Write(CNFG_CAL, 0x720000); // 0x700000 nrf_delay_ms(100); MAX30003_Reg_Write(CNFG_EMUX,0x0B0000); nrf_delay_ms(100); MAX30003_Reg_Write(CNFG_ECG, 0x005000); // d23 - d22 : 10 for 250sps , 00:500 sps nrf_delay_ms(100); MAX30003_Reg_Write(CNFG_RTOR1,0x3fc600); max30003_synch(); nrf_delay_ms(100); } void MAX30003_Reg_Write (unsigned char WRITE_ADDRESS, unsigned long data) //Its Completed //for main.oerror { nrf_gpio_pin_clear(SPI_SS_PIN); nrf_delay_ms(200); WRITE_ADDRESS= WRITE_ADDRESS | WREG; dataToSend[1]=WRITE_ADDRESS; memset(SPI_RX_Buff, 0, ECG_length); APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, (const uint8_t *)dataToSend[1], ECG_length, SPI_RX_Buff, ECG_length)); APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, (const uint8_t *)(data>>16), ECG_length, SPI_RX_Buff, ECG_length)); APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, (const uint8_t *)(data>>8), ECG_length, SPI_RX_Buff, ECG_length)); APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, (const uint8_t *)(data), ECG_length, SPI_RX_Buff, ECG_length)); nrf_delay_ms(200); nrf_gpio_pin_set(SPI_SS_PIN); } void MAX30003_Read_Data(int num_samples) //Its Completed { nrf_gpio_pin_clear(SPI_SS_PIN); // as per arduino code ECG_FIFO_BURST1 = (ECG_FIFO_BURST<<1 ) | RREG; APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, (const uint8_t *)ECG_FIFO_BURST1, ECG_length, SPI_RX_Buff, ECG_length)); for ( i = 0; i < num_samples*3; ++i) { SPI_temp_Burst[i] = (nrf_drv_spi_transfer(&spi, (const uint8_t *)A1[1], ECG_length, SPI_RX_Buff, ECG_length)); } nrf_gpio_pin_set(SPI_SS_PIN); //it make High } void MAX30003_Reg_Read(uint8_t Reg_address) //Its Completed { nrf_gpio_pin_clear(SPI_SS_PIN); // as per arduino code Reg_address= (Reg_address<<1 ) | RREG; APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, (const uint8_t *)Reg_address, ECG_length, SPI_RX_Buff, ECG_length)); for ( i = 0; i < 3; i++) { SPI_temp_32b[i]=(nrf_drv_spi_transfer(&spi, (const uint8_t *)A[1], ECG_length, SPI_RX_Buff, ECG_length)); } nrf_gpio_pin_set(SPI_SS_PIN); //it make High } void spi_event_handler(nrf_drv_spi_evt_t const * p_event, void * p_context) { nrf_gpio_pin_set(SPI_SS_PIN); spi_xfer_done = true; NRF_LOG_INFO("Transfer completed."); if (SPI_RX_Buff[0] != 0) { NRF_LOG_INFO(" Received:"); NRF_LOG_HEXDUMP_INFO(SPI_RX_Buff, strlen((const char *)SPI_RX_Buff)); } } int main(void) { char ECG_CHAR[30]; /*From Procentral upto line 222 */ MAX30003_Reg_Read(ECG_FIFO); //Its stuck unsigned long data0 = (unsigned long) (SPI_temp_32b[0]); data0 = data0 <<24; unsigned long data1 = (unsigned long) (SPI_temp_32b[1]); data1 = data1 <<16; unsigned long data2 = (unsigned long) (SPI_temp_32b[2]); data2 = data2 >>6; data2 = data2 & 0x03; data = (unsigned long) (data0 | data1 | data2); ecgdata = (signed long) (data); MAX30003_Reg_Read(RTOR); //Its stuck unsigned long RTOR_msb = (unsigned long) (SPI_temp_32b[0]); unsigned char RTOR_lsb = (unsigned char) (SPI_temp_32b[1]); unsigned long rtor = (RTOR_msb<<8 | RTOR_lsb); rtor = ((rtor >>2) & 0x3fff); float hr = 60 /((float)rtor*0.008); unsigned int HR = (unsigned int)hr; // type cast to int unsigned int RR = (unsigned int)rtor*8 ; //8ms DataPacketHeader[0] = 0x0A; DataPacketHeader[1] = 0xFA; DataPacketHeader[2] = 0x0C; DataPacketHeader[3] = 0; DataPacketHeader[4] = 0x02; DataPacketHeader[5] = ecgdata; DataPacketHeader[6] = ecgdata>>8; DataPacketHeader[7] = ecgdata>>16; DataPacketHeader[8] = ecgdata>>24; DataPacketHeader[9] = RR ; DataPacketHeader[10] = RR >>8; DataPacketHeader[11] = 0x00; DataPacketHeader[12] = 0x00; DataPacketHeader[13] = HR ; DataPacketHeader[14] = HR >>8; DataPacketHeader[15] = 0x00; DataPacketHeader[16] = 0x00; DataPacketHeader[17] = 0x00; DataPacketHeader[18] = 0x0b; bsp_board_init(BSP_INIT_LEDS); APP_ERROR_CHECK(NRF_LOG_INIT(NULL)); NRF_LOG_DEFAULT_BACKENDS_INIT(); nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; spi_config.ss_pin = SPI_SS_PIN; //29 spi_config.miso_pin = SPI_MISO_PIN; //28 spi_config.mosi_pin = SPI_MOSI_PIN; //4 spi_config.sck_pin = SPI_SCK_PIN; //3 nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL); NRF_LOG_INFO("SPI example started."); while (1) { // Reset rx buffer and transfer done flag memset(SPI_RX_Buff, 0, ECG_length); spi_xfer_done = false; for(i=0; i<19; i++) // transmit the data { APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, (const uint8_t *)SPI_TX_Buff, ECG_length, SPI_RX_Buff, ECG_length)); } while (!spi_xfer_done) { __WFE(); } NRF_LOG_FLUSH(); bsp_board_led_invert(BSP_BOARD_LED_0); nrf_delay_ms(200); } }
#include<SPI.h> #include <TimerOne.h> #include "MAX30003.h" #define MAX30003_CS_PIN 7 #define CLK_PIN 6 volatile char SPI_RX_Buff[5] ; volatile char *SPI_RX_Buff_Ptr; int i=0; unsigned long uintECGraw = 0; signed long intECGraw=0; uint8_t DataPacketHeader[20]; uint8_t data_len = 8; signed long ecgdata; unsigned long data; char SPI_temp_32b[4]; char SPI_temp_Burst[100]; // 32KHz clock using timer1 void timerIsr() { digitalWrite( CLK_PIN, digitalRead(CLK_PIN ) ^ 1 ); // toggle Digital6 attached to FCLK of MAX30003 } void setup() { Serial.begin(115200); //Serial begin pinMode(MAX30003_CS_PIN,OUTPUT); digitalWrite(MAX30003_CS_PIN,HIGH); //disable device SPI.begin(); SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE0); SPI.setClockDivider(SPI_CLOCK_DIV4); pinMode(CLK_PIN,OUTPUT); MAX30003_begin(); // initialize MAX30003 } void loop() { MAX30003_Reg_Read(ECG_FIFO); unsigned long data0 = (unsigned long) (SPI_temp_32b[0]); data0 = data0 <<24; unsigned long data1 = (unsigned long) (SPI_temp_32b[1]); data1 = data1 <<16; unsigned long data2 = (unsigned long) (SPI_temp_32b[2]); data2 = data2 >>6; data2 = data2 & 0x03; data = (unsigned long) (data0 | data1 | data2); ecgdata = (signed long) (data); MAX30003_Reg_Read(RTOR); unsigned long RTOR_msb = (unsigned long) (SPI_temp_32b[0]); // RTOR_msb = RTOR_msb <<8; unsigned char RTOR_lsb = (unsigned char) (SPI_temp_32b[1]); unsigned long rtor = (RTOR_msb<<8 | RTOR_lsb); rtor = ((rtor >>2) & 0x3fff) ; float hr = 60 /((float)rtor*0.008); unsigned int HR = (unsigned int)hr; // type cast to int unsigned int RR = (unsigned int)rtor*8 ; //8ms /*Serial.print(RTOR_msb); Serial.print(","); Serial.print(RTOR_lsb); Serial.print(","); Serial.print(rtor); Serial.print(","); Serial.print(rr); Serial.print(","); Serial.println(hr); */ DataPacketHeader[0] = 0x0A; DataPacketHeader[1] = 0xFA; DataPacketHeader[2] = 0x0C; DataPacketHeader[3] = 0; DataPacketHeader[4] = 0x02; DataPacketHeader[5] = ecgdata; DataPacketHeader[6] = ecgdata>>8; DataPacketHeader[7] = ecgdata>>16; DataPacketHeader[8] = ecgdata>>24; DataPacketHeader[9] = RR ; DataPacketHeader[10] = RR >>8; DataPacketHeader[11] = 0x00; DataPacketHeader[12] = 0x00; DataPacketHeader[13] = HR ; DataPacketHeader[14] = HR >>8; DataPacketHeader[15] = 0x00; DataPacketHeader[16] = 0x00; DataPacketHeader[17] = 0x00; DataPacketHeader[18] = 0x0b; for(i=0; i<19; i++) // transmit the data { Serial.write(DataPacketHeader[i]); } delay(1); } void MAX30003_Reg_Write (unsigned char WRITE_ADDRESS, unsigned long data) { // now combine the register address and the command into one byte: byte dataToSend = (WRITE_ADDRESS<<1) | WREG; // take the chip select low to select the device: digitalWrite(MAX30003_CS_PIN, LOW); delay(2); SPI.transfer(dataToSend); //Send register location SPI.transfer(data>>16); //number of register to wr SPI.transfer(data>>8); //number of register to wr SPI.transfer(data); //Send value to record into register delay(2); // take the chip select high to de-select: digitalWrite(MAX30003_CS_PIN, HIGH); } void max30003_sw_reset(void) { MAX30003_Reg_Write(SW_RST,0x000000); delay(100); } void max30003_synch(void) { MAX30003_Reg_Write(SYNCH,0x000000); } void MAX30003_Reg_Read(uint8_t Reg_address) { uint8_t SPI_TX_Buff; digitalWrite(MAX30003_CS_PIN, LOW); SPI_TX_Buff = (Reg_address<<1 ) | RREG; SPI.transfer(SPI_TX_Buff); //Send register location for ( i = 0; i < 3; i++) { SPI_temp_32b[i] = SPI.transfer(0xff); } digitalWrite(MAX30003_CS_PIN, HIGH); } void MAX30003_Read_Data(int num_samples) { uint8_t SPI_TX_Buff; digitalWrite(MAX30003_CS_PIN, LOW); SPI_TX_Buff = (ECG_FIFO_BURST<<1 ) | RREG; SPI.transfer(SPI_TX_Buff); //Send register location for ( i = 0; i < num_samples*3; ++i) { SPI_temp_Burst[i] = SPI.transfer(0x00); } digitalWrite(MAX30003_CS_PIN, HIGH); } void MAX30003_begin() { //Start CLK timer Timer1.initialize(16); // set a timer of length 100000 microseconds (or 0.1 sec - or 10Hz => the led will blink 5 times, 5 cycles of on-and-off, per second) Timer1.attachInterrupt( timerIsr ); // attach the service routine here max30003_sw_reset(); delay(100); MAX30003_Reg_Write(CNFG_GEN, 0x081007); delay(100); MAX30003_Reg_Write(CNFG_CAL, 0x720000); // 0x700000 delay(100); MAX30003_Reg_Write(CNFG_EMUX,0x0B0000); delay(100); MAX30003_Reg_Write(CNFG_ECG, 0x005000); // d23 - d22 : 10 for 250sps , 00:500 sps delay(100); MAX30003_Reg_Write(CNFG_RTOR1,0x3fc600); max30003_synch(); delay(100); }