Host software for the MAXREFDES220 Heart Rate Monitor Smart Sensor. Hosted on the MAX32630FTHR.

Dependencies:   max32630fthr USBDevice

Fork of MAXREFDES220_HEART_RATE_MONITOR by Maxim Integrated

Finger Heart Rate Monitor and SpO2 Monitor

The MAXREFDES220 Smart Sensor FeatherWing board is a integrated solution for providing finger-based heart rate measurements and SpO2 (blood oxygen saturation). This evaluation board interfaces to the host computer using the I2C interface. Heart rate outpu is available in beats per minute (BPM) and SpO2 is reported in percentages.; the PPG (photoplethysmography) raw data is also available. The board has an MAX30101 chip which is a low power heart rate monitor with adjustable sample rates and adjustable LED currents. The low cost MAX32664 microcontroller is pre-flashed with C code for finger-based pulse rate and SpO2 monitoring. Bootloader software is included to allow for future algorithms or updates to the algorithm from Maxim Integrated.

Ordering information will be available soon.

Note: SpO2 values are not calibrated. Calibration should be performed using the final end product.

Warning

The MAXREFDES220 source code listed is dated and only compatible with the 1.2.8a.msbl. The latest sample host source code is available on the MAX32664 website.

MAXREFDES220 FeatherWing Pinout Connections

/media/uploads/phonemacro/maxrefdes220_pinouts_heart_rate_monitor.jpg

main.cpp

Committer:
keremsahin
Date:
2018-07-02
Revision:
8:0f55f59ca341
Parent:
3:28fb38fe73c4
Child:
10:022b2cad9e9b

File content as of revision 8:0f55f59ca341:

#include "mbed.h"
#include "USBSerial.h"
#include "version.h"
#include "DSInterface.h"
#include "Peripherals.h"

#ifndef MAXIM_PLATFORM_NAME
#define MAXIM_PLATFORM_NAME "Pegasus"
#endif

#if ENABLE_LED_STATUS
#include "LEDStatus.h"
//Set yellow light during boot
LEDStatus ledStatus(LED1, LED_ON, LED2, LED_ON, LED3, LED_OFF);
#endif



#if defined(PLATFORM_MAX32630HSP)
	#include "max32630hsp.h"
#ifdef ENABLE_BLE
	#include "BLE_ICARUS.h"
#endif
	MAX32630HSP icarus(MAX32630HSP::VIO_1V8);
	//MAX32630HSP icarus(MAX32630HSP::VIO_3V3);
#elif defined(PLATFORM_MAX32630FTHR)
	#include "max32630fthr.h"
	MAX32630FTHR pegasus(MAX32630FTHR::VIO_1V8);
#endif

// Virtual serial port over USB
USBSerial microUSB(0x1f00, 0x2012, 0x0001, false);

DSInterface dsInterface(&microUSB);

#ifdef ENABLE_BLE
	#include "BLE.h"
	#include "BLE_ICARUS.h"
	#ifdef ENABLE_BLETEST_COMM
		#include "BleTestComm.h"
		BleTestComm bleTestComm(&microUSB);
	#endif
#endif

#ifdef LCD_LS013B7DH03
	// Sharp Display Configuration
	#include "LS013B7DH03.h"
	#include "mbed_logo.h"
	volatile bool refreshed = false;
	DigitalOut CS(P6_5);
	DigitalOut EXTCOM(P6_4);
	DigitalOut DISP(P6_6);
	SPI displaySPI(P6_2, P6_3, P6_1, NC);
	silabs::LS013B7DH03 display(&displaySPI, &CS, &EXTCOM);

	void refreshCallback(void) {
	    refreshed = true;
	}
#endif

#ifdef ACCEL_BMI160
	#include "bmi160.h"
	// Setup BMI160 Accelerometer
	//Setup I2C bus for IMU
	I2C I2CM2(P5_7, P6_0); /* SDA, SCL */
	BMI160_I2C bmi160_dev(&I2CM2, BMI160_I2C::I2C_ADRS_SDO_LO);
#endif

/// Pressure Sensor
#if defined(ENABLE_BMP280)
	#include "BMP280.h"
	BMP280 bmp280_dev(&I2CM2, (0xEC));
#endif



#ifdef ENABLE_PPG
	#include "PpgComm.h"
	PpgComm ppgCommHandler(&microUSB);

	#ifdef PPG_MAX8614X
		#include "MAX8614X.h"
		DigitalOut max8614x_cs(P5_3);
		PinName max8614x_int = P3_2;
		SPI max8614xSPI(P6_2, P6_3, P6_1, NC);
		MAX8614X max8614x(max8614xSPI, max8614x_cs, max8614x_int);
	#endif
#endif

#ifdef ENABLE_ECG
	#include "EcgComm.h"
	EcgComm ecgCommHandler(&microUSB);

	#ifdef ECG_MAX30001
		#include "MAX30001.h"
		#include "MAX30001_Helper.h"
		SPI max30001_spi(P5_1, P5_2, P5_0);
		DigitalOut max30001_cs(P5_3);
		MAX30001 max30001(&max30001_spi, &max30001_cs);
		InterruptIn max30001_InterruptB(P5_5);
		InterruptIn max30001_Interrupt2B(P6_2);
	#endif
#endif

#ifdef ENABLE_TP
	#include "TempComm.h"
	TempComm tpCommHandler(&microUSB);

	#ifdef TP_MAX30205
		#include "MAX30205.h"
		I2C i2c(P3_4, P3_5);
		MAX30205 max30205(&i2c, (0x90 >> 1));
		//enable the LDO for temp sensor
		DigitalOut max30205_LDO_EN(P7_1, 1);
		#endif
#endif

#ifdef ENABLE_SMARTSENSOR
	#include "SSInterface.h"
	I2C ssI2C(P3_4, P3_5);
	PinName ss_mfio(P5_4);
	PinName ss_reset(P5_6);
	SSInterface ssInterface(ssI2C, ss_mfio, ss_reset);

	#ifdef ENABLE_SS_BOOTLOADER
		#include "SSBootloaderComm.h"
		SSBootloaderComm ssBoot(&microUSB, &ssInterface, &dsInterface);
	#endif
	#ifdef ENABLE_SS_MAX30101
		#include "SSMAX30101Comm.h"
		SSMAX30101Comm ssMAX30101(&microUSB, &ssInterface, &dsInterface);
	#endif

	#ifdef ENABLE_SS_MAX8614X
		#include "SSMAX8614XComm.h"
		SSMAX8614XComm ssMAX8614X(&microUSB, &ssInterface, &dsInterface);
	#endif

	#ifdef ENABLE_SS_GENERICMDCOMM
		#include "SSGenericCmd.h"
		SSGenericCmd ssGenericCmd(&microUSB, &ssInterface, &dsInterface);
	#endif
#endif

// MX25U Flash Driver Definition
#ifdef ENABLE_MX25U
	#define MHZ_VALUE 1000000
	#define SPI_MHZ   24
	#define SPI_FREQUENCY (SPI_MHZ * MHZ_VALUE)
	#include "SPIFBlockDevice.h"
	SPIFBlockDevice spif(P1_1, P1_2, P1_0, P1_3, SPI_FREQUENCY);
#endif
// Hardware serial port over DAPLink
Serial daplink(USBTX, USBRX, 115200);

#ifdef ENABLE_TESTCOMM
#include "TestComm.h"
InterruptIn bmi160_int_pin(P3_6);
TestComm testCommHandler("test", &microUSB, &max30001_InterruptB, &max30001_Interrupt2B, &bmi160_int_pin);
#endif

#ifdef ENABLE_BLE
static void setup_ble()
{
	#if defined(PLATFORM_MAX32630HSP) || defined(PLATFORM_MAX32630FTHR)
	//Set up BLE communication
	BLE& ble = BLE::Instance();
	ble.init(bleInitComplete);
	while (BLE::Instance().hasInitialized() == false) { /* spin loop */ }
	BLE_Icarus_SetDSInterface(&dsInterface);

	char addr[6];
	BLE_ICARUS_Get_Mac_Address(addr);
	printf("BLE MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
	#endif

}

static void process_ble()
{
	#if defined(PLATFORM_MAX32630HSP) || defined(PLATFORM_MAX32630FTHR)
	if(BLE_Icarus_Interface_Exists()){
		BLE_Icarus_TransferDataFromQueue();
	}
	BLE::Instance().waitForEvent();
	#endif
}
#endif

void print_build_version()
{
	printf("\n\nICARUS mBED EVKit\r\n");
	printf("Fw version: %s, mbed version: %d\r\n", FIRMWARE_VERSION, MBED_VERSION);
	printf("Build source: (%s)  %s\r\n", BUILD_SOURCE_BRANCH, BUILD_SOURCE_HASH);
	printf("Build time: %s  %s\r\n\n", __TIME__, __DATE__);
}

// main() runs in its own thread in the OS
// (note the calls to Thread::wait below for delays)
int main()
{
	wait_ms(500);
	// set NVIC priorities for GPIO to prevent priority inversion
	daplink.printf("Init NVIC Priorities...\r\n");
	fflush(stdout);
	NVIC_SetPriority(GPIO_P0_IRQn, 5);
	NVIC_SetPriority(GPIO_P1_IRQn, 5);
	NVIC_SetPriority(GPIO_P2_IRQn, 5);
	NVIC_SetPriority(GPIO_P3_IRQn, 5);
	NVIC_SetPriority(GPIO_P4_IRQn, 5);
	NVIC_SetPriority(GPIO_P5_IRQn, 5);
	NVIC_SetPriority(GPIO_P6_IRQn, 5);
	// used by the MAX30001
	NVIC_SetPriority(SPIM2_IRQn, 0);
	//NVIC_SetPriority(SPIM2_IRQn, 0);
	print_build_version();
	daplink.printf("daplink serial port\r\n");
	microUSB.printf("micro USB serial port\r\n");

    dsInterface.set_fw_version(FIRMWARE_VERSION);
    dsInterface.set_fw_platform(MAXIM_PLATFORM_NAME);
	Peripherals::setUSBSerial(&microUSB);

#ifdef ENABLE_BLE
	setup_ble();
	#ifdef ENABLE_BLETEST_COMM
		dsInterface.add_sensor_comm(&bleTestComm);
	#endif
#endif

#ifdef LCD_LS013B7DH03
    // Push update to the display
	display.showBMP((uint8_t*)maxim_integrated_logo, 128, 128, 0, 0);
    refreshed = false;
    display.update(refreshCallback);
    // wait while doing the refreshing the screen
    while(refreshed == false){
    	// sleep();
    }
#endif



#ifdef ENABLE_PPG
	#ifdef PPG_MAX8614X
		//
		//MAX86140
		//
		ppgCommHandler.comm_init(&max8614x);
		//NOTE: setting SPI pin mapping here, since Sharp display uses same bus with different mapping
		SPI spi(P5_1, P5_2, P5_0); /* mosi, miso, sclk */
		max8614x.init();
		printf("Sensor: %s\r\n", max8614x.get_sensor_part_name());
	#endif
	#if ACCEL_BMI160
		ppgCommHandler.setBMI160(&bmi160_dev);
	#endif
	dsInterface.add_sensor_comm(&ppgCommHandler);
#endif

#ifdef ENABLE_ECG
	#ifdef ECG_MAX30001
		//
		// MAX30001
		//
		printf("Init MAX30001 callbacks, interrupts...\r\n");
		MAX30001_Helper m_max30001helper(&max30001, &max30001_InterruptB, &max30001_Interrupt2B);
		Peripherals::setMAX30001(&max30001);
		Peripherals::setMAX30001Helper(&m_max30001helper);
		ecgCommHandler.comm_init(&m_max30001helper);
	#endif
	dsInterface.add_sensor_comm(&ecgCommHandler);
#endif

#ifdef ENABLE_TP
	#ifdef TP_MAX30205
		//
		//MAX30205
		//
		tpCommHandler.comm_init(&max30205);
	#endif
	dsInterface.add_sensor_comm(&tpCommHandler);
#endif

#ifdef ENABLE_SMARTSENSOR
	//Configure mfio as a level based interrupt (no mbed API for this, must use Maxim-specific code)
	//gpio_cfg_t mfio_gpio_cfg = {PORT_5, PIN_4, GPIO_FUNC_GPIO, GPIO_PAD_INPUT_PULLUP};
	//GPIO_IntConfig(&mfio_gpio_cfg, GPIO_INT_LOW_LEVEL);
	ssI2C.frequency(400000);
	dsInterface.set_fw_platform(ssInterface.get_ss_platform_name());
	dsInterface.set_fw_version(ssInterface.get_ss_fw_version());
	#ifdef ENABLE_SS_BOOTLOADER
    	dsInterface.add_sensor_comm(&ssBoot);
	#endif
	#ifdef ENABLE_SS_MAX30101
		dsInterface.add_sensor_comm(&ssMAX30101);
	#endif
	#ifdef ENABLE_SS_MAX8614X
		dsInterface.add_sensor_comm(&ssMAX8614X);
	#endif
	#ifdef ENABLE_SS_GENERICMDCOMM
		dsInterface.add_sensor_comm(&ssGenericCmd);
	#endif
#endif

#ifdef ENABLE_LED_STATUS
	#ifdef ENABLE_SMARTSENSOR
		//Blink green if SmartSensor is present, yellow otherwise
		SS_STATUS status = ssInterface.ss_comm_check();
		if (status == SS_SUCCESS)
			ledStatus.set_state(LED_OFF, LED_ON, LED_OFF);
		else
			ledStatus.set_state(LED_ON, LED_ON, LED_OFF);
		ledStatus.blink(100, 1900);
	#else
		ledStatus.set_state(LED_OFF, LED_ON, LED_OFF);
	#endif
	ledStatus.blink(100, 1900);
#endif

#ifdef ENABLE_TESTCOMM
	//
	// Test class related variables
	//
	InterruptIn sw_one(P2_3);
	InterruptIn sw_two(P4_1);
	InterruptIn ss_mfio_int(P3_0);
	DigitalOut ss_reset_pin(P5_6, 1); // should this be pinname?
	testCommHandler.Test_AddAccBmi160(&bmi160_dev);
	testCommHandler.Test_AddTempMax30205(&max30205);
	testCommHandler.Test_AddFlashMx25U1(&spif);
	testCommHandler.Test_AddPressBMP280(&bmp280_dev);
	testCommHandler.Test_AddPmicMax20303(&icarus.max20303);
	testCommHandler.Test_AddECGMax30001(&max30001);
	testCommHandler.Test_AttachSWButtons(&sw_one, &sw_two);
	testCommHandler.Test_SetSSParameter(&i2c, &ss_mfio_int, &ss_reset_pin);
	dsInterface.add_sensor_comm(&testCommHandler);
#endif

	while(1) {
		USBSerial *serial = &microUSB;
		uint8_t ch;
		while (serial->readable()) {
			ch = serial->_getc();
			//dsInterface.enable_console_interface();
			dsInterface.enable_console_interface();
		    dsInterface.build_command(ch);
		}

		dsInterface.data_report_execute();
#ifdef ENABLE_BLE
		process_ble();
#endif
#ifdef ENABLE_LED_STATUS
		ledStatus.update();
#endif
	}
}