SHARE
TWEET

Untitled

a guest Jan 20th, 2020 96 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <SPI.h>
  2. #include <stdint.h>
  3. #include <BLEPeripheral.h>
  4. #include "Adafruit_GFX.h"
  5. #include <nrf_nvic.h>//interrupt controller stuff
  6. #include <nrf_sdm.h>
  7. #include <nrf_soc.h>
  8. #include <WInterrupts.h>
  9. #include "SSD1306.h"
  10. #include <TimeLib.h>
  11. #include <nrf.h>
  12. #include <Wire.h>
  13. #include "i2csoft.h"
  14. #include "count_steps.h"
  15. #include "count_steps.c"
  16. //#include <Arduino.h>
  17. //#include "Timer.h"
  18. //#include "nrf_timer.h"
  19.  
  20. //  sd_nvic_SystemReset();
  21.  
  22. #define wdt_reset() NRF_WDT->RR[0] = WDT_RR_RR_Reload
  23. #define wdt_enable(timeout) \
  24.   NRF_WDT->CONFIG = NRF_WDT->CONFIG = (WDT_CONFIG_HALT_Pause << WDT_CONFIG_HALT_Pos) | ( WDT_CONFIG_SLEEP_Pause << WDT_CONFIG_SLEEP_Pos); \
  25.   NRF_WDT->CRV = (32768*timeout)/1000; \
  26.   NRF_WDT->RREN |= WDT_RREN_RR0_Msk;  \
  27.   NRF_WDT->TASKS_START = 1
  28.  
  29.  
  30. Adafruit_SSD1306 display(128, 32, &SPI, 28, 4, 29);
  31.  
  32. #define BUTTON_PIN              30
  33. #define BATTERY_PIN             3
  34.  
  35. boolean debug = false;
  36.  
  37. #define sleepDelay 10000
  38. #define sleepDelay1 50000
  39. #define refreshRate 100
  40.  
  41. bool fingerin;
  42. int menu;
  43. byte wert[65];
  44. volatile byte posi = 64;
  45. long startbutton;
  46. String bleSymbol = " ";
  47.  
  48. BLEPeripheral                   blePeripheral           = BLEPeripheral();
  49. BLEService                      batteryLevelService     = BLEService("180A");
  50. BLEUnsignedLongCharacteristic   batteryLevelChar        = BLEUnsignedLongCharacteristic("2A19", BLERead | BLENotify);
  51. BLEDescriptor                   batteryLevelDescriptor  = BLEDescriptor("2901", "Battery Level 0 - 100%");
  52. BLEService                      HRService               = BLEService("180D");
  53. BLEUnsignedLongCharacteristic   HRChar                  = BLEUnsignedLongCharacteristic("2A8D", BLERead | BLENotify);
  54. BLEDescriptor                   HRDescriptor            = BLEDescriptor("2901", "Heart Rate (BPM)");
  55. BLEIntCharacteristic            HRToggleChar("2A15", BLERead | BLEWrite);
  56. BLEDescriptor                   HRToggleWriteDescriptor = BLEDescriptor("2901", "Heart Rate Enable/Disable");
  57. BLEUnsignedLongCharacteristic   writeChar               = BLEUnsignedLongCharacteristic("2A15", BLERead | BLEWrite);
  58. BLEDescriptor                   writeDescriptor         = BLEDescriptor("2901", "Write UnixTime");
  59.  
  60. volatile bool buttonPressed = false;
  61. volatile int16_t level;
  62. volatile uint8_t batt;
  63.  
  64. unsigned long sleepTime, displayRefreshTime, rpmTime;
  65. volatile bool sleeping = false;
  66. volatile bool HR_disabled = false;
  67.  
  68. volatile int before1, before2, before3;
  69. volatile float accX, accY, accZ;
  70. volatile char reson;
  71. volatile bool readacc = true, afeoff, foot;
  72. byte sds;
  73.  
  74. volatile uint8_t prev_HR = 0;
  75. volatile uint8_t filtered_HR;
  76. uint8_t steps;
  77. float xval[100]={0};
  78. float yval[100]={0};
  79. float zval[100]={0};
  80. float xavg;
  81. float yavg;
  82. float zavg;
  83. float threshhold=80.0;
  84. int flag=0;
  85. byte x;
  86. byte y;
  87. byte z;
  88.  
  89. void buttonHandler() {
  90.   if (!sleeping) buttonPressed = true;
  91.   else menu = 0;
  92.   powerUp();
  93. }
  94.  
  95. void acclHandler() {
  96.   ReadRegister(0x17);
  97.   if (sleeping) {
  98.     menu = 0;
  99.     powerUp();
  100.   }
  101. }
  102.  
  103. void charge() {
  104.   if (sleeping)menu = 0;
  105.   powerUp();
  106. }
  107. //void acchandler() {
  108. //  readacc = true;
  109. //}
  110.  
  111. void updateBatteryLevel() {
  112.   level = analogRead(BATTERY_PIN);
  113.   batt = map(level, 370, 420, 0, 100);
  114.   batteryLevelChar.setValue(batt);
  115. }
  116.  
  117. void blePeripheralConnectHandler(BLECentral& central) {
  118.   if (debug)Serial.println("BLEconnected");
  119.   menu = 0;
  120.   powerUp();
  121.   bleSymbol = "B";
  122.   before1 = 1;
  123. }
  124.  
  125. void blePeripheralDisconnectHandler(BLECentral& central) {
  126.   if (debug)Serial.println("BLEdisconnected");
  127.   menu = 0;
  128.   powerUp();
  129.   bleSymbol = " ";
  130.   before1 = 0;
  131. }
  132.  
  133. void characteristicWritten(BLECentral& central, BLECharacteristic& characteristic) {
  134.   unsigned long pctime;
  135.   pctime = writeChar.value();
  136.   if ( pctime >= 1549906231) {
  137.     setTime(pctime);
  138.   } else {
  139.     setTime(1549906231);
  140.   }
  141. }
  142.  
  143. ///////////////////////////////////////////////////////////////////////////////////////////
  144.  
  145. void HRcharacteristicWritten(BLECentral& central, BLECharacteristic& characteristic){
  146.   int HRsetToggle;
  147.   HRsetToggle = HRToggleChar.value();
  148.   //testVar = HRsetToggle; /////////////////////////////////////////
  149.   if ( HRsetToggle == 1) {
  150.     Pah8001_PowerOn();
  151.     HR_disabled = false;
  152.     }
  153.   else if(HRsetToggle == 0){
  154.     HR_disabled = Pah8001_PowerOff();
  155.     }
  156.   }
  157. ///////////////////////////////////////////////////////////////////////////////////////////
  158.  
  159. float reads[4], sum;
  160. long int now1, ptr;
  161. float last, rawRate, start;
  162. float first, second1, third, before, print_value;
  163. bool rising;
  164. int rise_count;
  165. int n;
  166. long int last_beat;
  167. int lastHigh;
  168.  
  169. void setup() {
  170.   Serial.begin(115200);
  171.   // pinMode(16, OUTPUT);
  172.   // digitalWrite(16, LOW);
  173.   pinMode(BUTTON_PIN, INPUT);
  174.   pinMode(15, INPUT);
  175.   if (digitalRead(BUTTON_PIN) == LOW) {
  176.     NRF_POWER->GPREGRET = 0x01;
  177.     sd_nvic_SystemReset();
  178.   }
  179.   wdt_enable(5000);
  180.   blePeripheral.setLocalName("ATCDSD6");
  181.   blePeripheral.setAdvertisedServiceUuid(batteryLevelService.uuid());
  182.  
  183.   blePeripheral.setAdvertisedServiceUuid(HRService.uuid());
  184.  
  185.   blePeripheral.setAdvertisingInterval(400);
  186.   blePeripheral.setAppearance(0x0000);
  187.   blePeripheral.setConnectable(true);
  188.   blePeripheral.setDeviceName("ATCDSD6");
  189.   blePeripheral.addAttribute(batteryLevelService);
  190.   blePeripheral.addAttribute(batteryLevelChar);
  191.   blePeripheral.addAttribute(batteryLevelDescriptor);
  192.   blePeripheral.addAttribute(writeChar);
  193.   blePeripheral.addAttribute(writeDescriptor);
  194.  
  195.   blePeripheral.addAttribute(HRService);
  196.   blePeripheral.addAttribute(HRChar);
  197.   blePeripheral.addAttribute(HRDescriptor);
  198.   blePeripheral.addAttribute(HRToggleChar);
  199.   blePeripheral.addAttribute(HRToggleWriteDescriptor);
  200.  
  201.   writeChar.setEventHandler(BLEWritten, characteristicWritten);
  202.  
  203.   HRToggleChar.setEventHandler(BLEWritten, HRcharacteristicWritten);
  204.  
  205.   blePeripheral.setEventHandler(BLEConnected, blePeripheralConnectHandler);
  206.   blePeripheral.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);
  207.   blePeripheral.begin();
  208.   pinMode(25, OUTPUT);
  209.   digitalWrite(25, HIGH);
  210.   pinMode(26, OUTPUT);
  211.   digitalWrite(26, HIGH);
  212.   pinMode(BATTERY_PIN, INPUT);
  213.   //attachInterrupt(digitalPinToInterrupt(22), acchandler, FALLING);
  214.   attachInterrupt(digitalPinToInterrupt(2), charge, RISING);
  215.   attachInterrupt(digitalPinToInterrupt(15), acclHandler, RISING);
  216.   NRF_GPIO->PIN_CNF[15] &= ~((uint32_t)GPIO_PIN_CNF_SENSE_Msk);
  217.   NRF_GPIO->PIN_CNF[15] |= ((uint32_t)GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos);
  218.  
  219.   NRF_GPIO->PIN_CNF[2] &= ~((uint32_t)GPIO_PIN_CNF_SENSE_Msk);
  220.   NRF_GPIO->PIN_CNF[2] |= ((uint32_t)GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos);
  221.  
  222.   attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonHandler, FALLING);
  223.  
  224.   delay(100);
  225.   display.begin(SSD1306_SWITCHCAPVCC);
  226.   delay(100);
  227.   display.clearDisplay();
  228.   display.display();
  229.  
  230.   display.setTextSize(1);
  231.   display.setTextColor(WHITE);
  232.   display.setCursor(10, 0);
  233.   display.println("Start");
  234.   display.display();
  235.   digitalWrite(25, LOW);
  236.   Wire.begin();
  237.   delay(100);
  238.   Pah8001_Configure();
  239.  
  240.   for (int i = 0; i < 4; i++)reads[i] = 0;
  241.   sum = 0;
  242.   ptr = 0;
  243.  
  244.   HR_disabled = Pah8001_PowerOff();
  245.   initi2c();
  246.   initkx023();
  247.   //calibrateSteps();
  248. }
  249.  
  250. void disableWakeupByInterrupt(uint32_t pin) {
  251.   detachInterrupt(digitalPinToInterrupt(pin));
  252.   NRF_GPIO->PIN_CNF[pin] &= ~((uint32_t)GPIO_PIN_CNF_SENSE_Msk);
  253.   NRF_GPIO->PIN_CNF[pin] |= ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
  254. }
  255.  
  256. void loop() {
  257.   blePeripheral.poll();
  258.   wdt_reset();
  259.   if (sleeping) {
  260.     sd_nvic_ClearPendingIRQ(SD_EVT_IRQn);
  261.     sd_power_mode_set(NRF_POWER_MODE_LOWPWR);
  262.     sd_app_evt_wait();
  263.   } else {
  264.     if (millis() - displayRefreshTime > refreshRate) {
  265.       displayRefreshTime = millis();
  266.       switch (menu) {
  267.         case 0:
  268.           displayMenu0();
  269.           break;
  270.         case 1:
  271.           displayMenu1();
  272.           break;
  273.         case 2:
  274.           displayMenu2();
  275.           break;
  276.         case 3:
  277.           displayMenu3();
  278.           break;
  279.         case 4:
  280.           displayMenu4();
  281.           break;
  282.       }
  283.     }
  284.  
  285.     if (buttonPressed) {
  286.       buttonPressed = false;
  287.       switch (menu) {
  288.         case 0:
  289.           //startbutton = millis();
  290.           while (!digitalRead(BUTTON_PIN)) {}
  291.           if (millis() - startbutton > 1000) {
  292.             // Send notification to RPi after button hold!
  293.             delay(100);
  294.             while (1) {};
  295.             break;
  296.           } else {
  297.             menu = 0;
  298.           }
  299.           menu = 1;
  300.           break;
  301.         case 1:
  302.           menu = 2;
  303.           break;
  304.         case 2:
  305.           menu = 3;
  306.           break;
  307.         case 3:
  308.           menu = 4;
  309.           break;
  310.         case 4:
  311.           startbutton = millis();
  312.           while (!digitalRead(BUTTON_PIN)) {}
  313.           if (millis() - startbutton > 1000) {
  314.             delay(100);
  315.             int err_code = sd_power_gpregret_set(0x01);
  316.             sd_nvic_SystemReset();
  317.             while (1) {};
  318.             break;
  319.           } else {
  320.             menu = 0;
  321.           }
  322.       }
  323.     }
  324.  
  325.     switch (menu) {
  326.       case 0:
  327.         if (millis() - sleepTime > sleepDelay ) powerDown();
  328.         break;
  329.       case 1:
  330.         if (millis() - sleepTime > sleepDelay ) powerDown();
  331.         break;
  332.       case 2:
  333.         if (millis() - sleepTime > sleepDelay ) powerDown();
  334.         break;
  335.       case 3:
  336.         if (millis() - sleepTime > sleepDelay ) powerDown();
  337.         break;
  338.       case 4:
  339.         if (millis() - sleepTime > sleepDelay ) powerDown();
  340.         break;
  341.       case 5:
  342.         if (millis() - sleepTime > 20000 ) powerDown();
  343.         break;
  344.       case 77:
  345.         if (millis() - sleepTime > 3000 ) powerDown();
  346.         break;
  347.       case 88:
  348.         if (millis() - sleepTime > 3000 ) powerDown();
  349.         break;
  350.       case 99:
  351.         if (millis() - sleepTime > 6000 ) {
  352.           digitalWrite(25, LOW);
  353.           powerDown();
  354.         }
  355.         break;
  356.     }
  357.   }
  358.  
  359.   if(!HR_disabled){               //if not disabled
  360.     uint8_t buffer[13];
  361.     Pah8001_ReadRawData(buffer);
  362.     if (buffer[0]) {
  363.       if (buffer[8] == 128) {
  364.         rawRate = map(buffer[6], 0, 255, 1023, 0);
  365.         fingerin = true;
  366.         //HRChar.setValue((int)rawRate);
  367.         //testVar++;
  368.       } else fingerin = false;
  369.     }
  370.     if (millis() - rpmTime >= 20) {
  371.       rpmTime = millis();
  372.  
  373.       sum -= reads[ptr];
  374.       sum += rawRate;
  375.       reads[ptr] = rawRate;
  376.       last = sum / 4;
  377.  
  378.       if (last > before)
  379.       {
  380.         rise_count++;
  381.         if (!rising && rise_count > 5)
  382.         {
  383.           if (!rising)lastHigh = rawRate;
  384.           rising = true;
  385.           first = millis() - last_beat;
  386.           last_beat = millis();
  387.           print_value = 60000. / (0.4 * first + 0.3 * second1 + 0.3 * third);
  388.           third = second1;
  389.           second1 = first;
  390.         }
  391.       }
  392.       else
  393.       {
  394.         rising = false;
  395.         rise_count = 0;
  396.       }
  397.       before = last;
  398.  
  399.       ptr++;
  400.       ptr %= 4;
  401.      }
  402.      HRfilter(print_value);
  403.     }
  404. }
  405.  
  406. void PrintHex8(uint32_t *data, uint8_t length) // prints 8-bit data in hex with leading zeroes
  407. {
  408.   char tmp[16];
  409.   for (int i = 0; i < length; i++) {
  410.     sprintf(tmp, "%08X", data[i]);
  411.     display.print(tmp); display.println(" ");
  412.   }
  413. }
  414.  
  415. void HRfilter(volatile uint8_t unfilteredValue){
  416.   volatile uint8_t difference;
  417.   if((unfilteredValue >= 40) && (unfilteredValue <= 150)){
  418.     if(prev_HR == 0){
  419.       prev_HR = unfilteredValue;
  420.       }
  421.     difference = abs((prev_HR - unfilteredValue));
  422.     if(difference <= 20){
  423.       filtered_HR = unfilteredValue;
  424.       prev_HR = filtered_HR;
  425.       HRChar.setValue(filtered_HR);
  426.       }
  427.     }
  428.   }
  429.  
  430. void displayMenu0() {
  431.   //HRfilter((int)print_value);
  432.   display.clearDisplay();
  433.   display.setCursor(0, 0);
  434.   display.println("HeartRate");
  435.   display.println((int)rawRate);
  436.   //display.println((int)print_value);
  437.   if (fingerin) display.print(print_value); else display.print("No Finger");
  438.  
  439.   if (posi <= 63)posi++; else posi = 0;
  440.   wert[posi] = map(rawRate, lastHigh - 30, lastHigh + 10, 0, 32);
  441.   for (int i = 64; i <= 128; i++) {
  442.     display.drawLine( i, 32, i, 32 - wert[i - 64], WHITE);
  443.   }
  444.   display.drawLine( posi + 65, 0, posi + 65, 32, BLACK);
  445.   display.display();
  446. }
  447.  
  448. void displayMenu1() {
  449.   updateBatteryLevel();
  450.   display.clearDisplay();
  451.   display.setCursor(0, 0);
  452.   display.println("Menue 1");
  453.   char tmp[16];
  454.   sprintf(tmp, "%04X", NRF_FICR->DEVICEADDR[1] & 0xffff);
  455.   String MyID = tmp;
  456.   sprintf(tmp, "%08X", NRF_FICR->DEVICEADDR[0]);
  457.   MyID += tmp;
  458.   display.println(MyID);
  459.   display.print("Battery level: ");
  460.   display.println(batt);
  461.   display.display();
  462. }
  463.  
  464. void displayMenu2() {
  465.   /*uint8_t res[6];
  466.   softbeginTransmission(0x1F);
  467.   softwrite(0x06);
  468.   softendTransmission();
  469.   softrequestFrom(0x1F , 6);
  470.   res[0] = softread();
  471.   res[1] = softread();
  472.   res[2] = softread();
  473.   res[3] = softread();
  474.   res[4] = softread();
  475.   res[5] = softread();
  476.   byte x = (int16_t)((res[1] << 8) | res[0]) / 128;
  477.   byte y = (int16_t)((res[3] << 8) | res[2]) / 128;
  478.   byte z = (int16_t)((res[5] << 8) | res[4]) / 128;*/
  479.  
  480.   display.clearDisplay();
  481.   display.setCursor(0, 0);
  482.   //display.println("Menue 3");
  483.   display.print("testVar: ");
  484.   //HRfilter(print_value);
  485.   //display.println(filtered_HR);
  486.   display.println(String(x) + "," + String(y) + "," + String(z));
  487.   display.println(String(steps));
  488.   display.display();
  489. }
  490.  
  491. void displayMenu3() {
  492.   display.clearDisplay();
  493.   display.setCursor(0, 0);
  494.   display.println("Menue 4");
  495.   display.display();
  496. }
  497. void displayMenu4() {
  498.   display.clearDisplay();
  499.   display.setCursor(0, 0);
  500.   display.println("Hello From Arduino");
  501.   display.println("  :)");
  502.   display.println("Hold for Bootloader");
  503.   display.display();
  504. }
  505.  
  506.  
  507. void powerUp() {
  508.   if (sleeping) {
  509.     sleeping = false;
  510.     display.begin(SSD1306_SWITCHCAPVCC);
  511.     display.clearDisplay();
  512.     display.display();
  513.     if (debug)Serial.begin(115200);
  514.  
  515.     delay(5);
  516.   }
  517.   sleepTime = millis();
  518. }
  519.  
  520. void powerDown() {
  521.   if (!sleeping) {
  522.     //menu = 0;
  523.  
  524.     if (debug)NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Disabled;
  525.     sleeping = true;
  526.  
  527.     digitalWrite(28, LOW);
  528.     digitalWrite(5, LOW);
  529.     digitalWrite(6, LOW);
  530.     digitalWrite(29, LOW);
  531.     digitalWrite(4, LOW);
  532.     NRF_SAADC ->ENABLE = 0; //disable ADC
  533.     NRF_PWM0  ->ENABLE = 0; //disable all pwm instance
  534.     NRF_PWM1  ->ENABLE = 0;
  535.     NRF_PWM2  ->ENABLE = 0;
  536.   }
  537. }
  538.  
  539. void writeRegister(uint8_t addr, uint8_t data)
  540. {
  541.   Wire.beginTransmission(0x6b);
  542.   Wire.write(addr);
  543.   Wire.write(data);
  544.   Wire.endTransmission();
  545. }
  546.  
  547. uint8_t readRegister(uint8_t addr)
  548. {
  549.   Wire.beginTransmission(0x6b);
  550.   Wire.write(addr);
  551.   Wire.endTransmission();
  552.   Wire.requestFrom(0x6b, 1);
  553.   return Wire.read();
  554. }
  555.  
  556. static bool ppg_current_change = false;
  557.  
  558. #define PAH8001_LED_STEP_DELTA 2
  559. #define PAH8001_LED_EXPOSURE_MAX 496
  560. #define PAH8001_LED_EXPOSURE_MIN 32
  561. #define PAH8001_LED_EXPOSURE_BIG 420
  562. #define PAH8001_LED_EXPOSURE_SML 64
  563. #define PAH8001_LED_STEP_MAX 31
  564. #define PAH8001_LED_STEP_MIN 1
  565.  
  566. static const struct {
  567.   uint8_t reg;
  568.   uint8_t value;
  569. } config[] =
  570. {
  571.   { 0x27u, 0xFFu },
  572.   { 0x28u, 0xFAu },
  573.   { 0x29u, 0x0Au },
  574.   { 0x2Au, 0xC8u },
  575.   { 0x2Bu, 0xA0u },
  576.   { 0x2Cu, 0x8Cu },
  577.   { 0x2Du, 0x64u },
  578.   { 0x42u, 0x20u },
  579.   { 0x48u, 0x00u },
  580.   { 0x4Du, 0x1Au },
  581.   { 0x7Au, 0xB5u },
  582.   { 0x7Fu, 0x01u },
  583.   { 0x07u, 0x48u },
  584.   { 0x23u, 0x40u },
  585.   { 0x26u, 0x0Fu },
  586.   { 0x2Eu, 0x48u },
  587.   { 0x38u, 0xEAu },
  588.   { 0x42u, 0xA4u },
  589.   { 0x43u, 0x41u },
  590.   { 0x44u, 0x41u },
  591.   { 0x45u, 0x24u },
  592.   { 0x46u, 0xC0u },
  593.   { 0x52u, 0x32u },
  594.   { 0x53u, 0x28u },
  595.   { 0x56u, 0x60u },
  596.   { 0x57u, 0x28u },
  597.   { 0x6Du, 0x02u },
  598.   { 0x0Fu, 0xC8u },
  599.   { 0x7Fu, 0x00u },
  600.   { 0x5Du, 0x81u }
  601. };
  602.  
  603. static bool Pah8001_Configure()
  604. {
  605.   uint8_t value;
  606.  
  607.   writeRegister(0x06u, 0x82u);
  608.   delay(10);
  609.   writeRegister(0x09u, 0x5Au        );
  610.   writeRegister(0x05u, 0x99u        );
  611.   value = readRegister (0x17u);
  612.   writeRegister(0x17u, value | 0x80 );
  613.  
  614.   for (size_t i = 0; i < sizeof(config) / sizeof(config[0]); i++)
  615.   {
  616.     writeRegister(config[i].reg, config[i].value);
  617.   }
  618.  
  619.   value = readRegister(0x00);
  620.  
  621.   return true;
  622. }
  623.  
  624. static bool Pah8001_UpdateLed(bool touch)
  625. {
  626.   static bool ppg_sleep = true;
  627.   static uint8_t ppg_states = 0;
  628.   static uint8_t ppg_led_mode = 0;
  629.   static uint8_t ppg_led_step = 10;
  630.  
  631.   if (!touch)
  632.   {
  633.     writeRegister(0x7Fu, 0x00u);
  634.     writeRegister(0x05u, 0xB8u);
  635.     writeRegister(0x7Fu, 0x01u);
  636.     writeRegister(0x42u, 0xA0u);
  637.     writeRegister(0x38u, 0xE5u);
  638.  
  639.     ppg_led_step = 10;
  640.     ppg_sleep = true;
  641.     ppg_current_change = false;
  642.   }
  643.   else
  644.   {
  645.     uint8_t value;
  646.     uint16_t exposureTime;
  647.     writeRegister(0x7Fu, 0x00u);
  648.     writeRegister(0x05u, 0x98u);
  649.     writeRegister(0x7Fu, 0x01u);
  650.     writeRegister(0x42u, 0xA4u);
  651.     writeRegister(0x7Fu, 0x00u);
  652.  
  653.     // Read exposure time
  654.     value = readRegister(0x33);
  655.     exposureTime = (value & 0x3u) << 8;
  656.     value = readRegister(0x32);
  657.     exposureTime |= value;
  658.  
  659.     writeRegister(0x7Fu, 0x01u);
  660.     if (ppg_sleep)
  661.     {
  662.       writeRegister(0x38u, (0xE0u | 10));
  663.       ppg_sleep = false;
  664.     }
  665.  
  666.     if (ppg_states++ > 3)
  667.     {
  668.       ppg_states = 0;
  669.       if (ppg_led_mode == 0)
  670.       {
  671.         if (exposureTime >= PAH8001_LED_EXPOSURE_MAX
  672.             || exposureTime <= PAH8001_LED_EXPOSURE_MIN)
  673.         {
  674.           ppg_led_step = readRegister(0x38u);
  675.           ppg_led_step &= 0x1Fu;
  676.  
  677.           if (exposureTime >= PAH8001_LED_EXPOSURE_MAX &&
  678.               ppg_led_step < PAH8001_LED_STEP_MAX)
  679.           {
  680.             ppg_led_mode = 1;
  681.             if (ppg_led_step += PAH8001_LED_STEP_DELTA > PAH8001_LED_STEP_MAX) {
  682.               ppg_led_step = PAH8001_LED_STEP_MAX;
  683.             }
  684.             writeRegister(0x38u, ppg_led_step | 0xE0u);
  685.             ppg_current_change = true;
  686.           }
  687.           else if (exposureTime <= PAH8001_LED_EXPOSURE_MIN &&
  688.                    ppg_led_step > PAH8001_LED_STEP_MIN)
  689.           {
  690.             ppg_led_mode = 2;
  691.             if (ppg_led_step <= PAH8001_LED_STEP_MIN + PAH8001_LED_STEP_DELTA) {
  692.               ppg_led_step = PAH8001_LED_STEP_MIN;
  693.             }
  694.             else ppg_led_step -= PAH8001_LED_STEP_DELTA;
  695.  
  696.             writeRegister(0x38u, ppg_led_step | 0xE0u);
  697.             ppg_current_change = true;
  698.           }
  699.           else
  700.           {
  701.             ppg_led_mode = 0;
  702.             ppg_current_change = false;
  703.           }
  704.         }
  705.         else ppg_current_change = false;
  706.       }
  707.       else if (ppg_led_mode == 1)
  708.       {
  709.         if (exposureTime > PAH8001_LED_EXPOSURE_BIG)
  710.         {
  711.           if (ppg_led_step += PAH8001_LED_STEP_DELTA > PAH8001_LED_STEP_MAX)
  712.           {
  713.             ppg_led_mode = 0;
  714.             ppg_led_step = PAH8001_LED_STEP_MAX;
  715.           }
  716.           writeRegister(0x38u, ppg_led_step | 0xE0u);
  717.           ppg_current_change = true;
  718.         }
  719.         else
  720.         {
  721.           ppg_led_mode = 0;
  722.           ppg_current_change = false;
  723.         }
  724.       }
  725.       else
  726.       {
  727.         if (exposureTime < PAH8001_LED_EXPOSURE_SML)
  728.         {
  729.           ppg_led_mode = 2;
  730.           if (ppg_led_step <= PAH8001_LED_STEP_MIN + PAH8001_LED_STEP_DELTA)
  731.           {
  732.             ppg_led_mode = 0;
  733.             ppg_led_step = PAH8001_LED_STEP_MIN;
  734.           }
  735.           else ppg_led_step -= PAH8001_LED_STEP_DELTA;
  736.  
  737.           writeRegister(0x38u, ppg_led_step | 0xE0u);
  738.           ppg_current_change = true;
  739.         }
  740.         else
  741.         {
  742.           ppg_led_mode = 0;
  743.           ppg_current_change = false;
  744.         }
  745.       }
  746.     }
  747.     else {
  748.       ppg_current_change = false;
  749.     }
  750.   }
  751.   return true;
  752. }
  753.  
  754. uint8_t Pah8001_ReadRawData(uint8_t buffer[9])
  755. {
  756.   static uint8_t ppg_frame_count = 0, touch_cnt = 0;
  757.   uint8_t value;
  758.   writeRegister(0x7Fu, 0x00u);
  759.   value = readRegister(0x59u);
  760.   if (value == 0x80)
  761.     touch_cnt = 0;
  762.   if (touch_cnt++ < 250)
  763.     if (!Pah8001_UpdateLed(1)) return 0x13;
  764.     else
  765.     {
  766.       if (!Pah8001_UpdateLed(0)) return 0x13;
  767.       touch_cnt = 252;
  768.     }
  769.   writeRegister(0x7Fu, 0x01u);
  770.  
  771.   value = readRegister(0x68u);
  772.   buffer[0] = value & 0xFu;
  773.  
  774.  
  775.   if (buffer[0] != 0) //0 means no data, 1~15 mean have data
  776.   {
  777.     uint8_t tmp[4];
  778.     /* 0x7f is change bank register,
  779.       0x64~0x67 is HR_DATA
  780.       0x1a~0x1C is HR_DATA_Algo
  781.     */
  782.  
  783.     Wire.beginTransmission(0x6b);
  784.     Wire.write(0x64);
  785.     Wire.endTransmission();
  786.     Wire.requestFrom(0x6b, 4);
  787.  
  788.     buffer[1] = Wire.read() & 0xFFu;
  789.     buffer[2] = Wire.read() & 0xFFu;
  790.     buffer[3] = Wire.read() & 0xFFu;
  791.     buffer[4] = Wire.read() & 0xFFu;
  792.  
  793.     Wire.beginTransmission(0x6b);
  794.     Wire.write(0x1a);
  795.     Wire.endTransmission();
  796.     Wire.requestFrom(0x6b, 4);
  797.  
  798.     buffer[5] = Wire.read() & 0xFFu;
  799.     buffer[6] = Wire.read() & 0xFFu;
  800.     buffer[7] = Wire.read() & 0xFFu;
  801.  
  802.     writeRegister(0x7Fu, 0x00u);
  803.     value = readRegister(0x59u);
  804.     buffer[8] = value & 0x80u;
  805.   }
  806.   else
  807.   {
  808.     writeRegister(0x7Fu, 0x00u);
  809.     return 0x22;
  810.   }
  811.   return 0;
  812. }
  813.  
  814.  
  815. bool Pah8001_HRValid(void)
  816. {
  817.   uint8_t value;
  818.   value = readRegister(0x59u);
  819.   return value & 0x80u == 0x80u;
  820. }
  821.  
  822. bool Pah8001_PowerOff(void)
  823. {
  824.   writeRegister(0x7Fu, 0x00u);
  825.   writeRegister(0x06u, 0x0Au);
  826.   return true;
  827. }
  828.  
  829. bool Pah8001_PowerOn(void)
  830. {
  831.   writeRegister(0x7Fu, 0x00u);
  832.   writeRegister(0x06u, 0x02u);
  833.   writeRegister(0x05u, 0x99u);
  834. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top