Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BLE_API mbed nRF51822 paw8001motion25_nrf51_mbed_keil
Fork of BLE_HeartRate by
main.cpp@51:464a019d3191, 2015-01-23 (annotated)
- Committer:
- rgrover1
- Date:
- Fri Jan 23 10:28:48 2015 +0000
- Revision:
- 51:464a019d3191
- Parent:
- 50:f7808934677c
importing demo from Hill Chen's tar file.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ktownsend | 0:87a7fc231fae | 1 | /* mbed Microcontroller Library |
ktownsend | 0:87a7fc231fae | 2 | * Copyright (c) 2006-2013 ARM Limited |
ktownsend | 0:87a7fc231fae | 3 | * |
ktownsend | 0:87a7fc231fae | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
ktownsend | 0:87a7fc231fae | 5 | * you may not use this file except in compliance with the License. |
ktownsend | 0:87a7fc231fae | 6 | * You may obtain a copy of the License at |
ktownsend | 0:87a7fc231fae | 7 | * |
ktownsend | 0:87a7fc231fae | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
ktownsend | 0:87a7fc231fae | 9 | * |
ktownsend | 0:87a7fc231fae | 10 | * Unless required by applicable law or agreed to in writing, software |
ktownsend | 0:87a7fc231fae | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
ktownsend | 0:87a7fc231fae | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
ktownsend | 0:87a7fc231fae | 13 | * See the License for the specific language governing permissions and |
ktownsend | 0:87a7fc231fae | 14 | * limitations under the License. |
ktownsend | 0:87a7fc231fae | 15 | */ |
ktownsend | 0:87a7fc231fae | 16 | |
ktownsend | 0:87a7fc231fae | 17 | #include "mbed.h" |
Rohit Grover |
10:2436164b692e | 18 | #include "BLEDevice.h" |
rgrover1 | 39:6390604f904c | 19 | #include "HeartRateService.h" |
rgrover1 | 42:06ebef2e0e44 | 20 | #include "BatteryService.h" |
rgrover1 | 42:06ebef2e0e44 | 21 | #include "DeviceInformationService.h" |
ktownsend | 0:87a7fc231fae | 22 | |
Rohit Grover |
10:2436164b692e | 23 | BLEDevice ble; |
rgrover1 | 47:430545f41113 | 24 | DigitalOut led1(LED1); |
rgrover1 | 51:464a019d3191 | 25 | /* --------------------------------------------------------------- |
rgrover1 | 51:464a019d3191 | 26 | * Below for PAH8001 code |
rgrover1 | 51:464a019d3191 | 27 | *///-------------------------------------------------------------- |
rgrover1 | 51:464a019d3191 | 28 | #include "app_util_platform.h" |
rgrover1 | 51:464a019d3191 | 29 | #include "nrf_soc.h" |
rgrover1 | 51:464a019d3191 | 30 | #include "app_util.h" |
rgrover1 | 51:464a019d3191 | 31 | #include "PAH8001Set.h" |
rgrover1 | 51:464a019d3191 | 32 | extern "C" |
rgrover1 | 51:464a019d3191 | 33 | { |
rgrover1 | 51:464a019d3191 | 34 | #include "pxialg.h" |
rgrover1 | 51:464a019d3191 | 35 | } |
rgrover1 | 51:464a019d3191 | 36 | Serial pc(USBTX, USBRX); |
rgrover1 | 51:464a019d3191 | 37 | I2C i2c(I2C_SDA0, I2C_SCL0); |
rgrover1 | 51:464a019d3191 | 38 | Ticker ticker; |
rgrover1 | 51:464a019d3191 | 39 | /* Power optimized, 1.0mA @disconnection, 4.5mA @connection */ |
rgrover1 | 51:464a019d3191 | 40 | #define MIN_CONN_INTERVAL MSEC_TO_UNITS(379, UNIT_1_25_MS) /**< Minimum connection interval (379 ms) */ |
rgrover1 | 51:464a019d3191 | 41 | #define MAX_CONN_INTERVAL MSEC_TO_UNITS(399, UNIT_1_25_MS) /**< Maximum connection interval (399 ms). */ |
rgrover1 | 51:464a019d3191 | 42 | #define SLAVE_LATENCY 4 /**< Slave latency. */ |
rgrover1 | 51:464a019d3191 | 43 | #define CONN_SUP_TIMEOUT MSEC_TO_UNITS(6000, UNIT_10_MS) /**< Connection supervisory timeout (6 seconds). */ |
rgrover1 | 51:464a019d3191 | 44 | /* --------------------------------------------------------------- |
rgrover1 | 51:464a019d3191 | 45 | * End of PAH8001 code |
rgrover1 | 51:464a019d3191 | 46 | *///-------------------------------------------------------------- |
ktownsend | 0:87a7fc231fae | 47 | |
rgrover1 | 51:464a019d3191 | 48 | const static char DEVICE_NAME[] = "PixArt_HRmbed"; |
rgrover1 | 42:06ebef2e0e44 | 49 | static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE, |
rgrover1 | 42:06ebef2e0e44 | 50 | GattService::UUID_BATTERY_SERVICE, |
rgrover1 | 42:06ebef2e0e44 | 51 | GattService::UUID_DEVICE_INFORMATION_SERVICE}; |
rgrover1 | 51:464a019d3191 | 52 | /* --------------------------------------------------------------- |
rgrover1 | 51:464a019d3191 | 53 | * Below for PAH8001 code |
rgrover1 | 51:464a019d3191 | 54 | *///-------------------------------------------------------------- |
rgrover1 | 39:6390604f904c | 55 | static volatile bool triggerSensorPolling = false; |
rgrover1 | 41:9cef0129da5f | 56 | void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) |
ktownsend | 0:87a7fc231fae | 57 | { |
rgrover1 | 46:ee7c55907f36 | 58 | ble.startAdvertising(); // restart advertising |
rgrover1 | 51:464a019d3191 | 59 | triggerSensorPolling = false; |
rgrover1 | 51:464a019d3191 | 60 | } |
rgrover1 | 51:464a019d3191 | 61 | void onconnectionCallback(Gap::Handle_t handle, Gap::addr_type_t peerAddrType, const Gap::address_t peerAddr, const Gap::ConnectionParams_t *p_conn_param) |
rgrover1 | 51:464a019d3191 | 62 | { |
rgrover1 | 51:464a019d3191 | 63 | triggerSensorPolling = true; |
rgrover1 | 51:464a019d3191 | 64 | Gap::ConnectionParams_t gap_conn_params; |
rgrover1 | 51:464a019d3191 | 65 | gap_conn_params.minConnectionInterval = MIN_CONN_INTERVAL; |
rgrover1 | 51:464a019d3191 | 66 | gap_conn_params.maxConnectionInterval = MAX_CONN_INTERVAL; |
rgrover1 | 51:464a019d3191 | 67 | gap_conn_params.slaveLatency = SLAVE_LATENCY; |
rgrover1 | 51:464a019d3191 | 68 | gap_conn_params.connectionSupervisionTimeout = CONN_SUP_TIMEOUT; |
rgrover1 | 51:464a019d3191 | 69 | ble.updateConnectionParams(handle, &gap_conn_params); |
rgrover1 | 7:daab8ba5139e | 70 | } |
Rohit Grover |
3:24e2b056d229 | 71 | |
Rohit Grover |
11:1d9aafee4984 | 72 | void periodicCallback(void) |
rgrover1 | 51:464a019d3191 | 73 | { |
rgrover1 | 51:464a019d3191 | 74 | if(triggerSensorPolling == true){ |
rgrover1 | 51:464a019d3191 | 75 | HR_Cnt++; |
rgrover1 | 51:464a019d3191 | 76 | CRITICAL_REGION_ENTER(); |
rgrover1 | 51:464a019d3191 | 77 | Pixart_HRD(); |
rgrover1 | 51:464a019d3191 | 78 | CRITICAL_REGION_EXIT(); |
rgrover1 | 51:464a019d3191 | 79 | } |
rgrover1 | 51:464a019d3191 | 80 | else |
rgrover1 | 51:464a019d3191 | 81 | HR_Cnt = 0; |
Rohit Grover |
11:1d9aafee4984 | 82 | } |
Rohit Grover |
11:1d9aafee4984 | 83 | |
ktownsend | 0:87a7fc231fae | 84 | int main(void) |
rgrover1 | 51:464a019d3191 | 85 | { uint8_t tmp; |
rgrover1 | 51:464a019d3191 | 86 | pc.baud (115200); |
rgrover1 | 51:464a019d3191 | 87 | pc.printf("\n\rStart initialization\n\r"); |
rgrover1 | 51:464a019d3191 | 88 | |
rgrover1 | 47:430545f41113 | 89 | led1 = 1; |
rgrover1 | 51:464a019d3191 | 90 | PAH8001_init(); //PAH8001 initialization |
ktownsend | 0:87a7fc231fae | 91 | |
Rohit Grover |
15:7ba28817e31e | 92 | ble.init(); |
rgrover1 | 7:daab8ba5139e | 93 | ble.onDisconnection(disconnectionCallback); |
rgrover1 | 51:464a019d3191 | 94 | ble.onConnection(onconnectionCallback); |
ktownsend | 0:87a7fc231fae | 95 | |
rgrover1 | 45:98c5a34b07a4 | 96 | /* Setup primary service. */ |
rgrover1 | 45:98c5a34b07a4 | 97 | uint8_t hrmCounter = 100; |
rgrover1 | 45:98c5a34b07a4 | 98 | HeartRateService hrService(ble, hrmCounter, HeartRateService::LOCATION_FINGER); |
rgrover1 | 45:98c5a34b07a4 | 99 | |
rgrover1 | 45:98c5a34b07a4 | 100 | /* Setup auxiliary services. */ |
rgrover1 | 45:98c5a34b07a4 | 101 | BatteryService battery(ble); |
rgrover1 | 45:98c5a34b07a4 | 102 | DeviceInformationService deviceInfo(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1"); |
rgrover1 | 45:98c5a34b07a4 | 103 | |
rgrover1 | 45:98c5a34b07a4 | 104 | /* Setup advertising. */ |
Rohit Grover |
29:76d865c718a6 | 105 | ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); |
rgrover1 | 40:e73130c6f2bb | 106 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); |
rgrover1 | 42:06ebef2e0e44 | 107 | ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR); |
Rohit Grover |
29:76d865c718a6 | 108 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); |
rgrover1 | 7:daab8ba5139e | 109 | ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
rgrover1 | 40:e73130c6f2bb | 110 | ble.setAdvertisingInterval(1600); /* 1000ms; in multiples of 0.625ms. */ |
rgrover1 | 7:daab8ba5139e | 111 | ble.startAdvertising(); |
rgrover1 | 51:464a019d3191 | 112 | |
rgrover1 | 51:464a019d3191 | 113 | pc.printf("Before while 1\n\r"); |
Rohit Grover |
11:1d9aafee4984 | 114 | while (true) { |
rgrover1 | 51:464a019d3191 | 115 | if(triggerSensorPolling == true){ |
rgrover1 | 51:464a019d3191 | 116 | if(!isFIFOEmpty()) |
rgrover1 | 51:464a019d3191 | 117 | { |
rgrover1 | 51:464a019d3191 | 118 | led1 = 1; |
rgrover1 | 51:464a019d3191 | 119 | //pc.printf("PPG[8]: %d\n\r", ppg_mems_data.HRD_Data[8]); |
rgrover1 | 51:464a019d3191 | 120 | if(Pop(&ppg_mems_data)) //Get data from FIFO |
rgrover1 | 51:464a019d3191 | 121 | { |
rgrover1 | 51:464a019d3191 | 122 | MEMS_Data[0] = ppg_mems_data.MEMS_Data[0]; |
rgrover1 | 51:464a019d3191 | 123 | MEMS_Data[1] = ppg_mems_data.MEMS_Data[1]; |
rgrover1 | 51:464a019d3191 | 124 | MEMS_Data[2] = ppg_mems_data.MEMS_Data[2]; |
rgrover1 | 51:464a019d3191 | 125 | |
rgrover1 | 51:464a019d3191 | 126 | tmp = PxiAlg_Process(ppg_mems_data.HRD_Data, MEMS_Data); |
rgrover1 | 51:464a019d3191 | 127 | //if( tmp == FLAG_DATA_READY) |
rgrover1 | 51:464a019d3191 | 128 | if( tmp != FLAG_DATA_READY) |
rgrover1 | 51:464a019d3191 | 129 | { |
rgrover1 | 51:464a019d3191 | 130 | pc.printf("AlgoProcssRtn: %d\n\r", tmp); |
rgrover1 | 51:464a019d3191 | 131 | pc.printf("PPG[8]: %d\n\r", ppg_mems_data.HRD_Data[8]); |
rgrover1 | 51:464a019d3191 | 132 | } |
rgrover1 | 51:464a019d3191 | 133 | else |
rgrover1 | 51:464a019d3191 | 134 | { |
rgrover1 | 51:464a019d3191 | 135 | //Check Flag |
rgrover1 | 51:464a019d3191 | 136 | } |
rgrover1 | 51:464a019d3191 | 137 | |
rgrover1 | 51:464a019d3191 | 138 | //ready_flag = PxiAlg_GetReadyFlag(); |
rgrover1 | 51:464a019d3191 | 139 | //motion_flag = PxiAlg_GetMotionFlag() ; |
rgrover1 | 51:464a019d3191 | 140 | } |
rgrover1 | 51:464a019d3191 | 141 | led1 = 0; |
rgrover1 | 51:464a019d3191 | 142 | } |
rgrover1 | 51:464a019d3191 | 143 | if(HR_Cnt > HR_Rpt) |
rgrover1 | 51:464a019d3191 | 144 | { |
rgrover1 | 51:464a019d3191 | 145 | HR_Cnt = 0; |
rgrover1 | 51:464a019d3191 | 146 | PxiAlg_HrGet(&myHR); |
rgrover1 | 51:464a019d3191 | 147 | pc.printf("HR: %d\n\r", (uint8_t)myHR); |
rgrover1 | 51:464a019d3191 | 148 | |
rgrover1 | 51:464a019d3191 | 149 | hrmCounter = (uint8_t)myHR; |
rgrover1 | 51:464a019d3191 | 150 | hrService.updateHeartRate(hrmCounter); |
rgrover1 | 51:464a019d3191 | 151 | } |
rgrover1 | 51:464a019d3191 | 152 | } |
rgrover1 | 51:464a019d3191 | 153 | else |
rgrover1 | 51:464a019d3191 | 154 | ble.waitForEvent(); |
rgrover1 | 51:464a019d3191 | 155 | } |
rgrover1 | 51:464a019d3191 | 156 | } |
rgrover1 | 51:464a019d3191 | 157 | |
rgrover1 | 51:464a019d3191 | 158 | |
rgrover1 | 51:464a019d3191 | 159 | |
rgrover1 | 51:464a019d3191 | 160 | void PAH8001_init() |
rgrover1 | 51:464a019d3191 | 161 | { uint8_t q; |
rgrover1 | 51:464a019d3191 | 162 | uint8_t bank=0, temp; |
rgrover1 | 51:464a019d3191 | 163 | |
rgrover1 | 51:464a019d3191 | 164 | if(readRegister(0x00) == 0x30) |
rgrover1 | 51:464a019d3191 | 165 | pc.printf("PAH8001 I2C Link Successful!\n\r"); |
rgrover1 | 51:464a019d3191 | 166 | else |
rgrover1 | 51:464a019d3191 | 167 | pc.printf("PAH8001 I2C Link Fail!\n\r"); |
rgrover1 | 51:464a019d3191 | 168 | |
rgrover1 | 51:464a019d3191 | 169 | alg_version = PxiAlg_Version(); |
rgrover1 | 51:464a019d3191 | 170 | pc.printf("Algo Ver: %d\n\r", alg_version); |
rgrover1 | 51:464a019d3191 | 171 | PxiAlg_EnableFastOutput(true); |
rgrover1 | 51:464a019d3191 | 172 | |
rgrover1 | 51:464a019d3191 | 173 | #ifdef DEBUG_8001 |
rgrover1 | 51:464a019d3191 | 174 | writeRegister(0x09, 0x5A); writeRegister(0x54, 0xEE); |
rgrover1 | 51:464a019d3191 | 175 | pc.printf("\n\r~~~Start Test Pattern~~~ \n\r"); |
rgrover1 | 51:464a019d3191 | 176 | pc.printf("Reg0x09: %d\n\r", readRegister(0x09)); |
rgrover1 | 51:464a019d3191 | 177 | pc.printf("Reg0x54: %d\n\r", readRegister(0x54)); |
rgrover1 | 51:464a019d3191 | 178 | pc.printf("Reg0x1E: %d\n\r", readRegister(0x1E)); |
rgrover1 | 51:464a019d3191 | 179 | |
rgrover1 | 51:464a019d3191 | 180 | float MEMS_Data[3] = {0 ,0, 0}; //apply test pattern |
rgrover1 | 51:464a019d3191 | 181 | float myHR = 0 ; |
rgrover1 | 51:464a019d3191 | 182 | for(q=0;q<PPG_PATTERN_SIZE;q++) |
rgrover1 | 51:464a019d3191 | 183 | PxiAlg_Process((unsigned char*)PPG_Data[q], MEMS_Data); |
rgrover1 | 51:464a019d3191 | 184 | PxiAlg_HrGet(&myHR); |
rgrover1 | 51:464a019d3191 | 185 | pc.printf("HR: %f\n\r", myHR); |
rgrover1 | 51:464a019d3191 | 186 | pc.printf("~~~End of Test Pattern~~~ \n\r"); |
rgrover1 | 51:464a019d3191 | 187 | while(1); |
rgrover1 | 51:464a019d3191 | 188 | #endif |
rgrover1 | 51:464a019d3191 | 189 | |
rgrover1 | 51:464a019d3191 | 190 | #ifndef DEBUG_8001 |
rgrover1 | 51:464a019d3191 | 191 | ticker.attach_us(&periodicCallback, PAH8001_Poll*1000); |
rgrover1 | 51:464a019d3191 | 192 | |
rgrover1 | 51:464a019d3191 | 193 | pc.printf("\n\r~~~Start Real-time HRM~~~ \n\r"); |
rgrover1 | 51:464a019d3191 | 194 | //Initialization settings |
rgrover1 | 51:464a019d3191 | 195 | writeRegister(0x06, 0x82); //Reset sensor |
rgrover1 | 51:464a019d3191 | 196 | wait_ms(10); //make a delay |
rgrover1 | 51:464a019d3191 | 197 | |
rgrover1 | 51:464a019d3191 | 198 | for(q=0;q<INIT_PPG_REG_ARRAY_SIZE;q++){ |
rgrover1 | 51:464a019d3191 | 199 | if(init_ppg_register_array[q][0] == 0x7F) |
rgrover1 | 51:464a019d3191 | 200 | bank = init_ppg_register_array[q][1]; |
rgrover1 | 51:464a019d3191 | 201 | |
rgrover1 | 51:464a019d3191 | 202 | if((bank == 0) && (init_ppg_register_array[q][0] == 0x17) ) |
rgrover1 | 51:464a019d3191 | 203 | { |
rgrover1 | 51:464a019d3191 | 204 | //read and write bit7=1 |
rgrover1 | 51:464a019d3191 | 205 | temp = readRegister(0x17); |
rgrover1 | 51:464a019d3191 | 206 | temp |= 0x80 ; |
rgrover1 | 51:464a019d3191 | 207 | writeRegister(0x17, temp) ; |
rgrover1 | 51:464a019d3191 | 208 | } |
rgrover1 | 51:464a019d3191 | 209 | else |
rgrover1 | 51:464a019d3191 | 210 | writeRegister(init_ppg_register_array[q][0], init_ppg_register_array[q][1]); |
rgrover1 | 51:464a019d3191 | 211 | } |
rgrover1 | 51:464a019d3191 | 212 | #endif |
rgrover1 | 51:464a019d3191 | 213 | } |
rgrover1 | 51:464a019d3191 | 214 | |
rgrover1 | 51:464a019d3191 | 215 | void writeRegister(uint8_t addr, uint8_t data) |
rgrover1 | 51:464a019d3191 | 216 | { |
rgrover1 | 51:464a019d3191 | 217 | char data_write[2]; |
rgrover1 | 51:464a019d3191 | 218 | |
rgrover1 | 51:464a019d3191 | 219 | data_write[0] = addr; |
rgrover1 | 51:464a019d3191 | 220 | data_write[1] = data; |
rgrover1 | 51:464a019d3191 | 221 | i2c.write(I2C_ADDR, data_write, 2, 0); |
rgrover1 | 51:464a019d3191 | 222 | } |
rgrover1 | 51:464a019d3191 | 223 | uint8_t readRegister(uint8_t addr) |
rgrover1 | 51:464a019d3191 | 224 | { |
rgrover1 | 51:464a019d3191 | 225 | char data_write[2]; |
rgrover1 | 51:464a019d3191 | 226 | char data_read[2]; |
rgrover1 | 51:464a019d3191 | 227 | |
rgrover1 | 51:464a019d3191 | 228 | data_write[0] = addr; |
rgrover1 | 51:464a019d3191 | 229 | i2c.write(I2C_ADDR, data_write, 1, 0); |
rgrover1 | 51:464a019d3191 | 230 | i2c.read(I2C_ADDR, data_read, 1, 0); |
rgrover1 | 51:464a019d3191 | 231 | return data_read[0]; |
rgrover1 | 51:464a019d3191 | 232 | } |
rgrover1 | 51:464a019d3191 | 233 | |
rgrover1 | 51:464a019d3191 | 234 | bool Pixart_HRD(void) |
rgrover1 | 51:464a019d3191 | 235 | { |
rgrover1 | 51:464a019d3191 | 236 | uint8_t tmp=0; |
rgrover1 | 51:464a019d3191 | 237 | char data_write[2]; |
rgrover1 | 51:464a019d3191 | 238 | char data_read[4]; |
rgrover1 | 51:464a019d3191 | 239 | ppg_mems_data_t ppg_mems_data; |
rgrover1 | 51:464a019d3191 | 240 | //Check Touch Status for power saving |
rgrover1 | 51:464a019d3191 | 241 | writeRegister(0x7F,0x00); //bank0 |
rgrover1 | 51:464a019d3191 | 242 | tmp = readRegister(0x00); |
rgrover1 | 51:464a019d3191 | 243 | tmp = readRegister(0x59)&0x80; |
rgrover1 | 51:464a019d3191 | 244 | led_ctrl(tmp); |
rgrover1 | 51:464a019d3191 | 245 | |
rgrover1 | 51:464a019d3191 | 246 | //writeRegister(0x7F,0x01); //bank1 |
rgrover1 | 51:464a019d3191 | 247 | ppg_mems_data.HRD_Data[0]=readRegister(0x68)&0x0f; //check status: 0 is not ready, 1 is ready, 2 is loss one data? |
rgrover1 | 51:464a019d3191 | 248 | |
rgrover1 | 51:464a019d3191 | 249 | if(ppg_mems_data.HRD_Data[0] ==0) |
rgrover1 | 51:464a019d3191 | 250 | { |
rgrover1 | 51:464a019d3191 | 251 | writeRegister(0x7F,0x00); //bank0 |
rgrover1 | 51:464a019d3191 | 252 | return false; |
rgrover1 | 51:464a019d3191 | 253 | } |
rgrover1 | 51:464a019d3191 | 254 | else |
rgrover1 | 51:464a019d3191 | 255 | { |
rgrover1 | 51:464a019d3191 | 256 | //Only support burst read (0x64~0x67), when using I2C interface |
rgrover1 | 51:464a019d3191 | 257 | data_write[0] = 0x64; |
rgrover1 | 51:464a019d3191 | 258 | i2c.write(PAH8001_ADDR, data_write, 1, 1); |
rgrover1 | 51:464a019d3191 | 259 | i2c.read(PAH8001_ADDR, data_read, 4, 0); |
rgrover1 | 51:464a019d3191 | 260 | ppg_mems_data.HRD_Data[1]=data_read[0]&0xff; |
rgrover1 | 51:464a019d3191 | 261 | ppg_mems_data.HRD_Data[2]=data_read[1]&0xff; |
rgrover1 | 51:464a019d3191 | 262 | ppg_mems_data.HRD_Data[3]=data_read[2]&0xff; |
rgrover1 | 51:464a019d3191 | 263 | ppg_mems_data.HRD_Data[4]=data_read[3]&0xff; |
Rohit Grover |
36:ea2a1b4f51c1 | 264 | |
rgrover1 | 51:464a019d3191 | 265 | //Only support burst read (0x1A~0x1C), when using I2C interface |
rgrover1 | 51:464a019d3191 | 266 | data_write[0] = 0x1A; |
rgrover1 | 51:464a019d3191 | 267 | i2c.write(PAH8001_ADDR, data_write, 1, 1); |
rgrover1 | 51:464a019d3191 | 268 | i2c.read(PAH8001_ADDR, data_read, 3, 0); |
rgrover1 | 51:464a019d3191 | 269 | ppg_mems_data.HRD_Data[5]=data_read[0]&0xff; |
rgrover1 | 51:464a019d3191 | 270 | ppg_mems_data.HRD_Data[6]=data_read[1]&0xff; |
rgrover1 | 51:464a019d3191 | 271 | ppg_mems_data.HRD_Data[7]=data_read[2]&0xff; |
rgrover1 | 51:464a019d3191 | 272 | |
rgrover1 | 51:464a019d3191 | 273 | ppg_mems_data.HRD_Data[8]=Frame_Count++; |
rgrover1 | 51:464a019d3191 | 274 | ppg_mems_data.HRD_Data[9]=40; |
rgrover1 | 51:464a019d3191 | 275 | ppg_mems_data.HRD_Data[10]=_led_current_change_flag; |
rgrover1 | 51:464a019d3191 | 276 | writeRegister(0x7F,0x00); //bank0 |
rgrover1 | 51:464a019d3191 | 277 | //bit7 is Touch Flag (bit7=1 is meant Touch, and bit7=0 is meant No Touch) |
rgrover1 | 51:464a019d3191 | 278 | ppg_mems_data.HRD_Data[11]=(readRegister(0x59)&0x80); //Check Touch Flag |
rgrover1 | 51:464a019d3191 | 279 | ppg_mems_data.HRD_Data[12]= ppg_mems_data.HRD_Data[6]; |
rgrover1 | 51:464a019d3191 | 280 | |
rgrover1 | 51:464a019d3191 | 281 | //If no G sensor, please set G_Sensor_Data[3] = {0}; |
rgrover1 | 51:464a019d3191 | 282 | ppg_mems_data.MEMS_Data[0] = 0;//ReadGSensorX(); |
rgrover1 | 51:464a019d3191 | 283 | ppg_mems_data.MEMS_Data[1] = 0;//ReadGSensorY(); |
rgrover1 | 51:464a019d3191 | 284 | ppg_mems_data.MEMS_Data[2] = 0;//ReadGSensorZ(); |
rgrover1 | 51:464a019d3191 | 285 | Push(&ppg_mems_data); //Save data into FIFO |
rgrover1 | 51:464a019d3191 | 286 | |
rgrover1 | 51:464a019d3191 | 287 | return true; |
rgrover1 | 51:464a019d3191 | 288 | } |
rgrover1 | 51:464a019d3191 | 289 | } |
rgrover1 | 51:464a019d3191 | 290 | |
rgrover1 | 51:464a019d3191 | 291 | bool isFIFOEmpty(void) |
rgrover1 | 51:464a019d3191 | 292 | { |
rgrover1 | 51:464a019d3191 | 293 | return (_write_index == _read_index); |
rgrover1 | 51:464a019d3191 | 294 | } |
rgrover1 | 51:464a019d3191 | 295 | |
rgrover1 | 51:464a019d3191 | 296 | bool Push(ppg_mems_data_t *data) |
rgrover1 | 51:464a019d3191 | 297 | { |
rgrover1 | 51:464a019d3191 | 298 | int tmp = _write_index; |
rgrover1 | 51:464a019d3191 | 299 | tmp++; |
rgrover1 | 51:464a019d3191 | 300 | if(tmp >= FIFO_SIZE) |
rgrover1 | 51:464a019d3191 | 301 | tmp = 0; |
rgrover1 | 51:464a019d3191 | 302 | if(tmp == _read_index) |
rgrover1 | 51:464a019d3191 | 303 | return false; |
rgrover1 | 51:464a019d3191 | 304 | _ppg_mems_data[tmp] = *data; |
rgrover1 | 51:464a019d3191 | 305 | _write_index = tmp; |
rgrover1 | 51:464a019d3191 | 306 | |
rgrover1 | 51:464a019d3191 | 307 | return true; |
rgrover1 | 51:464a019d3191 | 308 | } |
rgrover1 | 51:464a019d3191 | 309 | |
rgrover1 | 51:464a019d3191 | 310 | bool Pop(ppg_mems_data_t *data) |
rgrover1 | 51:464a019d3191 | 311 | { |
rgrover1 | 51:464a019d3191 | 312 | int tmp; |
rgrover1 | 51:464a019d3191 | 313 | if(isFIFOEmpty()) |
rgrover1 | 51:464a019d3191 | 314 | return false; |
rgrover1 | 51:464a019d3191 | 315 | *data = _ppg_mems_data[_read_index]; |
rgrover1 | 51:464a019d3191 | 316 | tmp = _read_index + 1; |
rgrover1 | 51:464a019d3191 | 317 | if(tmp >= FIFO_SIZE) |
rgrover1 | 51:464a019d3191 | 318 | tmp = 0; |
rgrover1 | 51:464a019d3191 | 319 | _read_index = tmp; |
rgrover1 | 51:464a019d3191 | 320 | |
rgrover1 | 51:464a019d3191 | 321 | return true; |
rgrover1 | 51:464a019d3191 | 322 | } |
rgrover1 | 51:464a019d3191 | 323 | |
rgrover1 | 51:464a019d3191 | 324 | /***********************LED Control Start***********************************/ |
rgrover1 | 51:464a019d3191 | 325 | void led_ctrl(uint8_t touch) { |
rgrover1 | 51:464a019d3191 | 326 | if(touch == 0x80) { |
rgrover1 | 51:464a019d3191 | 327 | uint8_t data; |
rgrover1 | 51:464a019d3191 | 328 | //uint16_t Frame_Average, EP_L, EP_H, Exposure_Line; |
rgrover1 | 51:464a019d3191 | 329 | uint16_t EP_L, EP_H, Exposure_Line; |
rgrover1 | 51:464a019d3191 | 330 | writeRegister(0x7f,0x00); |
rgrover1 | 51:464a019d3191 | 331 | writeRegister(0x05,0x98); |
rgrover1 | 51:464a019d3191 | 332 | writeRegister(0x7f,0x01); |
rgrover1 | 51:464a019d3191 | 333 | //writeRegister(0x42,0xA4); |
rgrover1 | 51:464a019d3191 | 334 | writeRegister(0x7f,0x00); |
rgrover1 | 51:464a019d3191 | 335 | data = readRegister(0x33); |
rgrover1 | 51:464a019d3191 | 336 | EP_H=data&0x03; |
rgrover1 | 51:464a019d3191 | 337 | data = readRegister(0x32); |
rgrover1 | 51:464a019d3191 | 338 | EP_L=data; |
rgrover1 | 51:464a019d3191 | 339 | Exposure_Line=(EP_H<<8)+EP_L; |
rgrover1 | 51:464a019d3191 | 340 | writeRegister(0x7f,0x01); |
rgrover1 | 51:464a019d3191 | 341 | if(_sleepflag==1) { |
rgrover1 | 51:464a019d3191 | 342 | writeRegister(0x38, (0xE0|DEFAULT_LED_STEP)); |
rgrover1 | 51:464a019d3191 | 343 | _sleepflag = 0 ; |
rgrover1 | 51:464a019d3191 | 344 | } |
rgrover1 | 51:464a019d3191 | 345 | |
rgrover1 | 51:464a019d3191 | 346 | if (_state_count <= STATE_COUNT_TH) { |
rgrover1 | 51:464a019d3191 | 347 | _state_count++; |
rgrover1 | 51:464a019d3191 | 348 | _led_current_change_flag = 0; |
rgrover1 | 51:464a019d3191 | 349 | } |
rgrover1 | 51:464a019d3191 | 350 | else { |
rgrover1 | 51:464a019d3191 | 351 | _state_count = 0; |
rgrover1 | 51:464a019d3191 | 352 | if(_state == 0) { |
rgrover1 | 51:464a019d3191 | 353 | if( (Exposure_Line>=LED_CTRL_EXPO_TIME_HI_BOUND) || (Exposure_Line<=LED_CTRL_EXPO_TIME_LOW_BOUND) ) { |
rgrover1 | 51:464a019d3191 | 354 | //writeRegister(0x7f,0x01); |
rgrover1 | 51:464a019d3191 | 355 | data = readRegister(0x38); |
rgrover1 | 51:464a019d3191 | 356 | _led_step=data&0x1f; |
rgrover1 | 51:464a019d3191 | 357 | if( (Exposure_Line>=LED_CTRL_EXPO_TIME_HI_BOUND) && (_led_step < LED_CURRENT_HI) ) { |
rgrover1 | 51:464a019d3191 | 358 | _state = 1 ; |
rgrover1 | 51:464a019d3191 | 359 | _led_step=_led_step+LED_INC_DEC_STEP; |
rgrover1 | 51:464a019d3191 | 360 | |
rgrover1 | 51:464a019d3191 | 361 | if(_led_step>LED_CURRENT_HI) |
rgrover1 | 51:464a019d3191 | 362 | _led_step=LED_CURRENT_HI; |
rgrover1 | 51:464a019d3191 | 363 | writeRegister(0x38, (_led_step|0xE0)); |
rgrover1 | 51:464a019d3191 | 364 | _led_current_change_flag = 1; |
rgrover1 | 51:464a019d3191 | 365 | } |
rgrover1 | 51:464a019d3191 | 366 | else if((Exposure_Line<=LED_CTRL_EXPO_TIME_LOW_BOUND) && (_led_step > LED_CURRENT_LOW) ) { |
rgrover1 | 51:464a019d3191 | 367 | _state = 2 ; |
rgrover1 | 51:464a019d3191 | 368 | if(_led_step<=(LED_CURRENT_LOW+LED_INC_DEC_STEP)) |
rgrover1 | 51:464a019d3191 | 369 | _led_step=LED_CURRENT_LOW; |
rgrover1 | 51:464a019d3191 | 370 | else |
rgrover1 | 51:464a019d3191 | 371 | _led_step=_led_step-LED_INC_DEC_STEP; |
rgrover1 | 51:464a019d3191 | 372 | writeRegister(0x38, (_led_step|0xE0)); |
rgrover1 | 51:464a019d3191 | 373 | _led_current_change_flag = 1; |
rgrover1 | 51:464a019d3191 | 374 | } |
rgrover1 | 51:464a019d3191 | 375 | else { |
rgrover1 | 51:464a019d3191 | 376 | _state = 0 ; |
rgrover1 | 51:464a019d3191 | 377 | _led_current_change_flag = 0; |
rgrover1 | 51:464a019d3191 | 378 | } |
rgrover1 | 51:464a019d3191 | 379 | } |
rgrover1 | 51:464a019d3191 | 380 | else { |
rgrover1 | 51:464a019d3191 | 381 | _led_current_change_flag = 0; |
rgrover1 | 51:464a019d3191 | 382 | } |
Rohit Grover |
36:ea2a1b4f51c1 | 383 | } |
rgrover1 | 51:464a019d3191 | 384 | else if(_state == 1) { |
rgrover1 | 51:464a019d3191 | 385 | if(Exposure_Line > LED_CTRL_EXPO_TIME_HI) { |
rgrover1 | 51:464a019d3191 | 386 | _state = 1 ; |
rgrover1 | 51:464a019d3191 | 387 | _led_step=_led_step+LED_INC_DEC_STEP; |
rgrover1 | 51:464a019d3191 | 388 | if(_led_step>=LED_CURRENT_HI) { |
rgrover1 | 51:464a019d3191 | 389 | _state = 0 ; |
rgrover1 | 51:464a019d3191 | 390 | _led_step=LED_CURRENT_HI; |
rgrover1 | 51:464a019d3191 | 391 | } |
rgrover1 | 51:464a019d3191 | 392 | writeRegister(0x38, (_led_step|0xE0)); |
rgrover1 | 51:464a019d3191 | 393 | _led_current_change_flag = 1; |
rgrover1 | 51:464a019d3191 | 394 | } |
rgrover1 | 51:464a019d3191 | 395 | else { |
rgrover1 | 51:464a019d3191 | 396 | _state = 0 ; |
rgrover1 | 51:464a019d3191 | 397 | _led_current_change_flag = 0; |
rgrover1 | 51:464a019d3191 | 398 | } |
rgrover1 | 51:464a019d3191 | 399 | } |
rgrover1 | 51:464a019d3191 | 400 | else { |
rgrover1 | 51:464a019d3191 | 401 | if(Exposure_Line < LED_CTRL_EXPO_TIME_LOW) { |
rgrover1 | 51:464a019d3191 | 402 | _state = 2 ; |
rgrover1 | 51:464a019d3191 | 403 | if(_led_step<=(LED_CURRENT_LOW+LED_INC_DEC_STEP)) { |
rgrover1 | 51:464a019d3191 | 404 | _state = 0 ; |
rgrover1 | 51:464a019d3191 | 405 | _led_step=LED_CURRENT_LOW; |
rgrover1 | 51:464a019d3191 | 406 | } |
rgrover1 | 51:464a019d3191 | 407 | else |
rgrover1 | 51:464a019d3191 | 408 | _led_step=_led_step-LED_INC_DEC_STEP; |
rgrover1 | 51:464a019d3191 | 409 | writeRegister(0x38, (_led_step|0xE0)); |
rgrover1 | 51:464a019d3191 | 410 | _led_current_change_flag = 1; |
rgrover1 | 51:464a019d3191 | 411 | } |
rgrover1 | 51:464a019d3191 | 412 | else { |
rgrover1 | 51:464a019d3191 | 413 | _state = 0; |
rgrover1 | 51:464a019d3191 | 414 | _led_current_change_flag = 0; |
rgrover1 | 51:464a019d3191 | 415 | } |
rgrover1 | 51:464a019d3191 | 416 | } |
Rohit Grover |
36:ea2a1b4f51c1 | 417 | } |
ktownsend | 0:87a7fc231fae | 418 | } |
rgrover1 | 51:464a019d3191 | 419 | else { |
rgrover1 | 51:464a019d3191 | 420 | writeRegister(0x7f,0x00); |
rgrover1 | 51:464a019d3191 | 421 | writeRegister(0x05,0xB8); |
rgrover1 | 51:464a019d3191 | 422 | writeRegister(0x7F,0x01); |
rgrover1 | 51:464a019d3191 | 423 | //writeRegister(0x42,0xA0); |
rgrover1 | 51:464a019d3191 | 424 | _led_step = DEFAULT_LED_STEP; |
rgrover1 | 51:464a019d3191 | 425 | writeRegister(0x38, 0xFF); |
rgrover1 | 51:464a019d3191 | 426 | _sleepflag = 1; |
rgrover1 | 51:464a019d3191 | 427 | _led_current_change_flag = 0; |
rgrover1 | 51:464a019d3191 | 428 | } |
ktownsend | 0:87a7fc231fae | 429 | } |
rgrover1 | 51:464a019d3191 | 430 | /***********************LED Control End ***********************************/ |
rgrover1 | 51:464a019d3191 | 431 | /* --------------------------------------------------------------- |
rgrover1 | 51:464a019d3191 | 432 | * End of PAH8001 code |
rgrover1 | 51:464a019d3191 | 433 | *///-------------------------------------------------------------- |