Mode1 Optical Validation

Dependencies:   max32630fthr

main.cpp

Committer:
phonemacro
Date:
2021-03-17
Revision:
0:6f65cae31c54
Child:
1:da792e46a385

File content as of revision 0:6f65cae31c54:

/*******************************************************************************
* Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*******************************************************************************
*/
//#include "max32630fthr.h"
//#include "USBSerial.h"

#include "mbed.h"
#include "platform/mbed_thread.h"

#define OB07 1
#ifdef OB07
  #define PPG_SZ 36  //maxm86146
#else
  #define PPG_SZ 18  //maxm86161, max86141
#endif
#define ACCEL_SZ 6  // accel
#define SENSOR_SZ (PPG_SZ+ACCEL_SZ)
#define ALGO_SZ 20  // 24 bytes is the algo normal size for 3x.12.0
//#define ALGO_SZ 24  // 24 bytes is the algo normal size fifo output
#define ALGO_ONLY 1
#ifdef ALGO_ONLY
  #define TTL_SZ (ALGO_SZ)
#else
  #define TTL_SZ (PPG_SZ+ACCEL_SZ+ALGO_SZ)
#endif

DigitalOut rLED(LED1);
DigitalOut gLED(LED2);
DigitalOut bLED(LED3);
#define RST_PIN   P5_6
#define MFIO_PIN  P5_4
DigitalOut rst(RST_PIN, PullUp);
DigitalOut mfio(MFIO_PIN, PullUp);
I2C i2c(P3_4, P3_5);

const int addr = 0xAA;//0x55;
int32_t Time_to_Read_PPG = 0;

#define BLINKING_RATE_MS 1000ms
void blink_timer(void) {
    gLED = !gLED;  /* blink the green LED */
}

void fifo_timer(void) {
    Time_to_Read_PPG = 1;
}

void read_ppg(void) {
    char cmd[8], i, j, samples;
    char rsp[3000];
    int32_t ppg[12];
    int32_t accel[3];
    int32_t status, opmode, hr, hr_conf, spo2, spo2_conf;
    int32_t scnt = 0; // sample set count
    int32_t ptr = 0;
    int32_t sptr = 0;

    mfio = 0;
    Time_to_Read_PPG = 0;
    wait_us(300);
#if 0
// 2.1
    cmd[0] = 0x00;
    cmd[1] = 0x00;
    i2c.write(addr, cmd, 2);
    wait_us(100);
    rsp[0] = 0xAA;
    rsp[1] = 0xAA;
    i2c.read(addr, rsp, 2);
//    printf("2.1 Status: %x %x\n", rsp[0], rsp[1]);
#endif
// 2.2
    cmd[0] = 0x12;
    cmd[1] = 0x00;
    i2c.write(addr, cmd, 2);
    wait_us(100);
    rsp[0] = 0xAA;
    rsp[1] = 0xAA;
    i2c.read(addr, rsp, 2);
//    printf("2.2 Status: %x %x\n", rsp[0], rsp[1]);
    samples = rsp[1];
//    printf("num samples %d, (num*ttl)+1 %d\n",  rsp[1], TTL_SZ*samples+1);
//    printf("num smpls %d \n",  samples);
    scnt = rsp[1];
// 2.3
    cmd[0] = 0x12;
    cmd[1] = 0x01;
    i2c.write(addr, cmd, 2);
    wait_us(100);
//    thread_sleep_for(1);
    i2c.read(addr, rsp, 1+(TTL_SZ*samples));
        status = rsp[0];
        
        sptr = 1;
        for (i = 0; i < scnt; i++) {
//            printf("ptr %d ttlsiz %d ", ptr, TTL_SZ);
#ifdef ALGO_ONLY
            ptr = sptr;
#else
            ptr = sptr + SENSOR_SZ;
#endif
            opmode = rsp[ptr];
            hr =  (rsp[ptr+1] << 8) + rsp[ptr+2];
            hr_conf = rsp[ptr+3];
            spo2_conf = rsp[ptr+10];
            spo2 = (rsp[ptr+11] << 8) + rsp[ptr+12];

            sptr += (TTL_SZ);

//            printf("HR %d, HR Conf %d, SpO2 %d, Spo2 Conf %d,", hr, hr_conf, spo2, spo2_conf);
            printf("%d, %d, %d, %d,", hr, hr_conf, spo2, spo2_conf);
            printf("\n");
        }
        mfio = 1;
}



int main()
{   
    i2c.frequency(200000);
    char cmd[8], i, j;
    char rsp[256];
    int32_t ppg[12];
        
    rLED = LED_OFF;
    gLED = LED_ON;
    bLED = LED_OFF;
    Ticker ticker;   // calls a callback repeatedly with a timeout
    //ticker.attach(callback(&blink_timer), BLINKING_RATE_MS);  /* set timer for one second */

//==========================================
#if 0  // BL, app switching
    // BL    
    rst = 0;
    mfio = 0;
    thread_sleep_for(10);
    rst = 1;
    thread_sleep_for(50);

    cmd[0] = 0x02;
    cmd[1] = 0x00;
    i2c.write(addr, cmd, 2);
    thread_sleep_for(2);
    rsp[0] = 0x00;
    rsp[1] = 0x00;
    i2c.read(addr, rsp, 2);
    printf("02 00 Status, Operating Mode: %x %x\n", rsp[0], rsp[1]);
// rd BL ver    
    cmd[0] = 0x81;
    cmd[1] = 0x00;
    i2c.write(addr, cmd, 2);
    thread_sleep_for(2);
    rsp[0] = 0xAA;
    rsp[1] = 0xAA;
    rsp[2] = 0xAA;
    rsp[3] = 0xAA;
    i2c.read(addr, rsp, 4);
    printf("Ver: %d %d %d %d\n", rsp[0], rsp[1], rsp[2], rsp[3]);

    // application
    rst = 0;
    mfio = 1;
    thread_sleep_for(10);
    rst = 1;
    thread_sleep_for(1500);

    mfio = 0;
    wait_us(300);

    cmd[0] = 0x02;
    cmd[1] = 0x00;
    i2c.write(addr, cmd, 2);
    mfio = 1;
    thread_sleep_for(2);
    mfio = 0;
    wait_us(300);
    rsp[0] = 0x00;
    rsp[1] = 0x00;
    i2c.read(addr, rsp, 2);
    mfio = 1;
    printf("02 00 Status, Operating Mode: %x %x\n", rsp[0], rsp[1]);
// rd ver    
    mfio = 0;
    wait_us(300);
    cmd[0] = 0xFF;
    cmd[1] = 0x03;
    i2c.write(addr, cmd, 2);
    mfio = 1;
    thread_sleep_for(2);
    mfio = 0;
    wait_us(300);
    rsp[0] = 0xAA;
    rsp[1] = 0xAA;
    rsp[2] = 0xAA;
    rsp[3] = 0xAA;
    i2c.read(addr, rsp, 4);
    mfio = 1;
    printf("Ver: %d %d %d %d\n", rsp[0], rsp[1], rsp[2], rsp[3]);
   
    
     // BL    
    rst = 0;
    mfio = 0;
    thread_sleep_for(10);
    rst = 1;
    thread_sleep_for(50);

    cmd[0] = 0x02;
    cmd[1] = 0x00;
    i2c.write(addr, cmd, 2);
    thread_sleep_for(2);
    rsp[0] = 0xAA;
    rsp[1] = 0xAA;
    i2c.read(addr, rsp, 2);
    printf("02 00 Status, Operating Mode: %x %x\n", rsp[0], rsp[1]);
// rd BL ver    
    cmd[0] = 0x81;
    cmd[1] = 0x00;
    i2c.write(addr, cmd, 2);
    thread_sleep_for(2);
    rsp[0] = 0xAA;
    rsp[1] = 0xAA;
    rsp[2] = 0xAA;
    rsp[3] = 0xAA;
    i2c.read(addr, rsp, 4);
    printf("Ver: %d %d %d %d\n", rsp[0], rsp[1], rsp[2], rsp[3]);
#endif  // end BL app switching
//==========================================
    // application
    rst = 0;
    mfio = 1;
    thread_sleep_for(10);
    rst = 1;
    thread_sleep_for(1500);

    mfio = 0;
    wait_us(300);

    cmd[0] = 0x02;
    cmd[1] = 0x00;
    i2c.write(addr, cmd, 2);
    mfio = 1;
    thread_sleep_for(2);
    mfio = 0;
    wait_us(300);
    rsp[0] = 0xAA;
    rsp[1] = 0xAA;
    i2c.read(addr, rsp, 2);
    mfio = 1;
    printf("02 00 Status, Operating Mode: %x %x\n", rsp[0], rsp[1]);
// rd ver    
    mfio = 0;
    wait_us(300);
    cmd[0] = 0xFF;
    cmd[1] = 0x03;
    i2c.write(addr, cmd, 2);
    mfio = 1;
    thread_sleep_for(2);
    mfio = 0;
    wait_us(300);
    rsp[0] = 0xAA;
    rsp[1] = 0xAA;
    rsp[2] = 0xAA;
    rsp[3] = 0xAA;
    i2c.read(addr, rsp, 4);
    mfio = 1;
    printf("Ver: %d %d %d %d\n", rsp[0], rsp[1], rsp[2], rsp[3]);


// aec mode
// 1.3 sensor and algo data
    mfio = 0;
    wait_us(300);
    cmd[0] = 0x10;
    cmd[1] = 0x00;
//    cmd[2] = 0x03;  // sensor + algo data
    cmd[2] = 0x02;  // algo data
    i2c.write(addr, cmd, 3);
    thread_sleep_for(2);
    rsp[0] = 0xAA;
    i2c.read(addr, rsp, 1);
    printf("1.3 Status: %x\n", rsp[0]);
//1.11 rd AFE part id
    cmd[0] = 0x41;
    cmd[1] = 0x00;
    cmd[2] = 0xFF;
    i2c.write(addr, cmd, 3);
    thread_sleep_for(2);
    i2c.read(addr, rsp, 2);
    printf("1.11 part id afe %x %x\n", rsp[0], rsp[1]);
//1.13 rd accel who
    cmd[0] = 0x41;
    cmd[1] = 0x04;
    cmd[2] = 0x0F;
    i2c.write(addr, cmd, 3);
    thread_sleep_for(2);
    i2c.read(addr, rsp, 2);
    printf("1.12 who accel %x %x\n", rsp[0], rsp[1]);

//Sec 4.1  map leds to slots for MAXM86146
    cmd[0] = 0x50;
    cmd[1] = 0x07;
    cmd[2] = 0x19;
    cmd[3] = 0x13;
    cmd[4] = 0x56;
    cmd[5] = 0x00;
    i2c.write(addr, cmd, 6);
    thread_sleep_for(2);
    i2c.read(addr, rsp, 1);
    printf("map leds to slots%x\n", rsp[0]);
//  map HR inputs to slots
    cmd[0] = 0x50;
    cmd[1] = 0x07;
    cmd[2] = 0x17;
    cmd[3] = 0x00;
    cmd[4] = 0x11;
    i2c.write(addr, cmd, 5);
    thread_sleep_for(2);
    i2c.read(addr, rsp, 1);
    printf("map HR to slots/PDs %x\n", rsp[0]);

//  map SpO2 inputs to slots
    cmd[0] = 0x50;
    cmd[1] = 0x07;
    cmd[2] = 0x18;
    cmd[3] = 0x30;
    cmd[4] = 0x20;
    i2c.write(addr, cmd, 5);
    thread_sleep_for(2);
    i2c.read(addr, rsp, 1);
    printf("map SpO2 to slots/PDs %x\n", rsp[0]);

// 1.14
    cmd[0] = 0x52;
    cmd[1] = 0x07;
    cmd[2] = 0x01;
    i2c.write(addr, cmd, 3);
    thread_sleep_for(465);
    rsp[0] = 0xAA;
    i2c.read(addr, rsp, 1);
    printf("1.14 status: %x\n", rsp[0]);
    mfio = 1;
    wait_us(300);

    ticker.attach(callback(&fifo_timer), 40ms);
    while (1) {
        if (Time_to_Read_PPG) {
            read_ppg();
        }
    }


}