1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <atomic.h> 18 #include <gpio.h> 19 #include <nanohubPacket.h> 20 #include <plat/exti.h> 21 #include <plat/gpio.h> 22 #include <platform.h> 23 #include <plat/syscfg.h> 24 #include <sensors.h> 25 #include <seos.h> 26 #include <spi.h> 27 #include <i2c.h> 28 #include <timer.h> 29 #include <stdlib.h> 30 #include <string.h> 31 32 #define LPS22HB_APP_ID APP_ID_MAKE(NANOHUB_VENDOR_STMICRO, 1) 33 #define LPS22HB_SPI_BUS_ID 1 34 #define LPS22HB_SPI_SPEED_HZ 8000000 35 36 /* Sensor defs */ 37 #define LPS22HB_INT_CFG_REG_ADDR 0x0B 38 #define LPS22HB_LIR_BIT 0x04 39 40 #define LPS22HB_WAI_REG_ADDR 0x0F 41 #define LPS22HB_WAI_REG_VAL 0xB1 42 43 #define LPS22HB_SOFT_RESET_REG_ADDR 0x11 44 #define LPS22HB_SOFT_RESET_BIT 0x04 45 46 #define LPS22HB_ODR_REG_ADDR 0x10 47 #define LPS22HB_ODR_ONE_SHOT 0x00 48 #define LPS22HB_ODR_1_HZ 0x10 49 #define LPS22HB_ODR_10_HZ 0x20 50 #define LPS22HB_ODR_25_HZ 0x30 51 #define LPS22HB_ODR_50_HZ 0x40 52 #define LPS22HB_ODR_75_HZ 0x50 53 54 #define LPS22HB_PRESS_OUTXL_REG_ADDR 0x28 55 #define LPS22HB_TEMP_OUTL_REG_ADDR 0x2B 56 57 #define LPS22HB_INT1_REG_ADDR 0x23 58 #define LPS22HB_INT2_REG_ADDR 0x24 59 60 #define LPS22HB_INT1_PIN GPIO_PA(4) 61 #define LPS22HB_INT2_PIN GPIO_PB(0) 62 63 #define LPS22HB_HECTO_PASCAL(baro_val) (baro_val/4096) 64 #define LPS22HB_CENTIGRADES(temp_val) (temp_val/100) 65 66 enum lps22hbSensorEvents 67 { 68 EVT_COMM_DONE = EVT_APP_START + 1, 69 EVT_INT1_RAISED, 70 EVT_SENSOR_BARO_TIMER, 71 EVT_SENSOR_TEMP_TIMER, 72 EVT_TEST, 73 }; 74 75 enum lps22hbSensorState { 76 SENSOR_BOOT, 77 SENSOR_VERIFY_ID, 78 SENSOR_INIT, 79 SENSOR_BARO_POWER_UP, 80 SENSOR_BARO_POWER_DOWN, 81 SENSOR_TEMP_POWER_UP, 82 SENSOR_TEMP_POWER_DOWN, 83 SENSOR_READ_SAMPLES, 84 }; 85 86 #define LPS22HB_USE_I2C 1 87 88 #if defined(LPS22HB_USE_I2C) 89 #define I2C_BUS_ID 0 90 #define I2C_SPEED 400000 91 #define LPS22HB_I2C_ADDR 0x5D 92 #else 93 #define SPI_READ 0x80 94 #define SPI_WRITE 0x00 95 #define SPI_MAX_PCK_NUM 1 96 #endif 97 98 enum lps22hbSensorIndex { 99 BARO = 0, 100 TEMP, 101 NUM_OF_SENSOR, 102 }; 103 104 //#define NUM_OF_SENSOR 1 105 106 struct lps22hbSensor { 107 uint32_t handle; 108 }; 109 110 /* Task structure */ 111 struct lps22hbTask { 112 uint32_t tid; 113 114 /* timer */ 115 uint32_t baroTimerHandle; 116 uint32_t tempTimerHandle; 117 118 /* sensor flags */ 119 bool baroOn; 120 bool baroReading; 121 bool baroWantRead; 122 bool tempOn; 123 bool tempReading; 124 bool tempWantRead; 125 126 //int sensLastRead; 127 128 #if defined(LPS22HB_USE_I2C) 129 #else 130 /* SPI */ 131 spi_cs_t cs; 132 struct SpiMode mode; 133 struct SpiDevice *spiDev; 134 struct SpiPacket spi_pck[SPI_MAX_PCK_NUM]; 135 #endif 136 unsigned char sens_buf[6]; 137 138 /* Communication functions */ 139 void (*comm_tx)(uint8_t addr, uint8_t data, uint32_t delay, void *cookie); 140 void (*comm_rx)(uint8_t addr, uint16_t len, uint32_t delay, void *cookie); 141 142 /* sensors */ 143 struct lps22hbSensor sensors[NUM_OF_SENSOR]; 144 }; 145 146 static struct lps22hbTask mTask; 147 148 #if defined(LPS22HB_USE_I2C) 149 static void i2cCallback(void *cookie, size_t tx, size_t rx, int err) 150 #else 151 static void spiCallback(void *cookie, int err) 152 #endif 153 { 154 osEnqueuePrivateEvt(EVT_COMM_DONE, cookie, NULL, mTask.tid); 155 } 156 157 #if defined(LPS22HB_USE_I2C) 158 static void i2c_read(uint8_t addr, uint16_t len, uint32_t delay, void *cookie) 159 { 160 mTask.sens_buf[0] = 0x80 | addr; 161 i2cMasterTxRx(I2C_BUS_ID, LPS22HB_I2C_ADDR, &mTask.sens_buf[0], 1, 162 &mTask.sens_buf[1], len, &i2cCallback, cookie); 163 } 164 165 static void i2c_write(uint8_t addr, uint8_t data, uint32_t delay, void *cookie) 166 { 167 mTask.sens_buf[0] = addr; 168 mTask.sens_buf[1] = data; 169 i2cMasterTx(I2C_BUS_ID, LPS22HB_I2C_ADDR, mTask.sens_buf, 2, &i2cCallback, cookie); 170 } 171 172 #else 173 static void spi_read(uint8_t addr, uint16_t len, uint32_t delay, void *cookie) 174 { 175 mTask.sens_buf[0] = SPI_READ | addr; 176 177 mTask.spi_pck[0].size = len + 1; 178 mTask.spi_pck[0].txBuf = mTask.spi_pck[0].rxBuf = &mTask.sens_buf[0]; 179 mTask.spi_pck[0].delay = delay * 1000; 180 181 spiMasterRxTx(mTask.spiDev, mTask.cs, &mTask.spi_pck[0], 1/*mTask.spi_pck_num*/, &mTask.mode, spiCallback, cookie); 182 } 183 184 static void spi_write(uint8_t addr, uint8_t data, uint32_t delay, void *cookie) 185 { 186 mTask.sens_buf[0] = SPI_WRITE | addr; 187 mTask.sens_buf[1] = data; 188 189 mTask.spi_pck[0].size = 2; 190 mTask.spi_pck[0].txBuf = mTask.spi_pck[0].rxBuf = &mTask.sens_buf[0]; 191 mTask.spi_pck[0].delay = delay * 1000; 192 193 spiMasterRxTx(mTask.spiDev, mTask.cs, &mTask.spi_pck[0], 1/*mTask.spi_pck_num*/, &mTask.mode, spiCallback, cookie); 194 } 195 196 static void spi_init(void) 197 { 198 mTask.mode.speed = LPS22HB_SPI_SPEED_HZ; 199 mTask.mode.bitsPerWord = 8; 200 mTask.mode.cpol = SPI_CPOL_IDLE_HI; 201 mTask.mode.cpha = SPI_CPHA_TRAILING_EDGE; 202 mTask.mode.nssChange = true; 203 mTask.mode.format = SPI_FORMAT_MSB_FIRST; 204 mTask.cs = GPIO_PB(12); 205 spiMasterRequest(LPS22HB_SPI_BUS_ID, &(mTask.spiDev)); 206 } 207 #endif 208 209 /* Sensor Info */ 210 static void sensorBaroTimerCallback(uint32_t timerId, void *data) 211 { 212 osEnqueuePrivateEvt(EVT_SENSOR_BARO_TIMER, data, NULL, mTask.tid); 213 } 214 215 static void sensorTempTimerCallback(uint32_t timerId, void *data) 216 { 217 osEnqueuePrivateEvt(EVT_SENSOR_TEMP_TIMER, data, NULL, mTask.tid); 218 } 219 220 #define DEC_INFO(name, type, axis, inter, samples, rates, raw, scale, bias) \ 221 .sensorName = name, \ 222 .sensorType = type, \ 223 .numAxis = axis, \ 224 .interrupt = inter, \ 225 .minSamples = samples, \ 226 .supportedRates = rates, \ 227 .rawType = raw, \ 228 .rawScale = scale, \ 229 .biasType = bias 230 231 static uint32_t lps22hbRates[] = { 232 SENSOR_HZ(1.0f), 233 SENSOR_HZ(10.0f), 234 SENSOR_HZ(25.0f), 235 SENSOR_HZ(50.0f), 236 SENSOR_HZ(75.0f), 237 0 238 }; 239 240 // should match "supported rates in length" and be the timer length for that rate in nanosecs 241 static const uint64_t lps22hbRatesRateVals[] = 242 { 243 1 * 1000000000ULL, 244 1000000000ULL / 10, 245 1000000000ULL / 25, 246 1000000000ULL / 50, 247 1000000000ULL / 75, 248 }; 249 250 251 static const struct SensorInfo lps22hbSensorInfo[NUM_OF_SENSOR] = 252 { 253 { DEC_INFO("Pressure", SENS_TYPE_BARO, NUM_AXIS_EMBEDDED, NANOHUB_INT_NONWAKEUP, 254 300, lps22hbRates, 0, 0, 0) }, 255 { DEC_INFO("Temperature", SENS_TYPE_TEMP, NUM_AXIS_EMBEDDED, NANOHUB_INT_NONWAKEUP, 256 20, lps22hbRates, 0, 0, 0) }, 257 }; 258 259 /* Sensor Operations */ 260 static bool baroPower(bool on, void *cookie) 261 { 262 bool oldMode = mTask.baroOn || mTask.tempOn; 263 bool newMode = on || mTask.tempOn; 264 uint32_t state = on ? SENSOR_BARO_POWER_UP : SENSOR_BARO_POWER_DOWN; 265 266 //osLog(LOG_INFO, "baro power %d (%d) %d %d\n", oldMode, newMode, mTask.baroOn, mTask.tempOn); 267 if (!on && mTask.baroTimerHandle) { 268 timTimerCancel(mTask.baroTimerHandle); 269 mTask.baroTimerHandle = 0; 270 mTask.baroReading = false; 271 } 272 273 if (oldMode != newMode) { 274 if (on) 275 mTask.comm_tx(LPS22HB_ODR_REG_ADDR, LPS22HB_ODR_10_HZ, 0, (void *)state); 276 else 277 mTask.comm_tx(LPS22HB_ODR_REG_ADDR, LPS22HB_ODR_ONE_SHOT, 0, (void *)state); 278 } else 279 sensorSignalInternalEvt(mTask.sensors[BARO].handle, 280 SENSOR_INTERNAL_EVT_POWER_STATE_CHG, on, 0); 281 282 mTask.baroReading = false; 283 mTask.baroOn = on; 284 return true; 285 } 286 287 static bool baroFwUpload(void *cookie) 288 { 289 return sensorSignalInternalEvt(mTask.sensors[BARO].handle, SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0); 290 } 291 292 static bool baroSetRate(uint32_t rate, uint64_t latency, void *cookie) 293 { 294 //osLog(LOG_INFO, "baro set rate %ld (%lld)\n", rate, latency); 295 if (mTask.baroTimerHandle) 296 timTimerCancel(mTask.baroTimerHandle); 297 298 mTask.baroTimerHandle = timTimerSet(sensorTimerLookupCommon(lps22hbRates, 299 lps22hbRatesRateVals, rate), 0, 50, sensorBaroTimerCallback, NULL, false); 300 301 return sensorSignalInternalEvt(mTask.sensors[BARO].handle, 302 SENSOR_INTERNAL_EVT_RATE_CHG, rate, latency); 303 } 304 305 static bool baroFlush(void *cookie) 306 { 307 return osEnqueueEvt(sensorGetMyEventType(SENS_TYPE_BARO), SENSOR_DATA_EVENT_FLUSH, NULL); 308 } 309 310 static bool tempPower(bool on, void *cookie) 311 { 312 bool oldMode = mTask.baroOn || mTask.tempOn; 313 bool newMode = on || mTask.baroOn; 314 uint32_t state = on ? SENSOR_TEMP_POWER_UP : SENSOR_TEMP_POWER_DOWN; 315 316 //osLog(LOG_INFO, "temp power %d (%d) %d %d\n", oldMode, newMode, mTask.baroOn, mTask.tempOn); 317 if (!on && mTask.tempTimerHandle) { 318 timTimerCancel(mTask.tempTimerHandle); 319 mTask.tempTimerHandle = 0; 320 mTask.tempReading = false; 321 } 322 323 if (oldMode != newMode) { 324 if (on) 325 mTask.comm_tx(LPS22HB_ODR_REG_ADDR, LPS22HB_ODR_10_HZ, 0, (void *)state); 326 else 327 mTask.comm_tx(LPS22HB_ODR_REG_ADDR, LPS22HB_ODR_ONE_SHOT, 0, (void *)state); 328 } else 329 sensorSignalInternalEvt(mTask.sensors[TEMP].handle, 330 SENSOR_INTERNAL_EVT_POWER_STATE_CHG, on, 0); 331 332 mTask.tempReading = false; 333 mTask.tempOn = on; 334 return true; 335 } 336 337 static bool tempFwUpload(void *cookie) 338 { 339 return sensorSignalInternalEvt(mTask.sensors[TEMP].handle, SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0); 340 } 341 342 static bool tempSetRate(uint32_t rate, uint64_t latency, void *cookie) 343 { 344 if (mTask.tempTimerHandle) 345 timTimerCancel(mTask.tempTimerHandle); 346 347 //osLog(LOG_INFO, "temp set rate %ld (%lld)\n", rate, latency); 348 mTask.tempTimerHandle = timTimerSet(sensorTimerLookupCommon(lps22hbRates, 349 lps22hbRatesRateVals, rate), 0, 50, sensorTempTimerCallback, NULL, false); 350 351 return sensorSignalInternalEvt(mTask.sensors[TEMP].handle, 352 SENSOR_INTERNAL_EVT_RATE_CHG, rate, latency); 353 } 354 355 static bool tempFlush(void *cookie) 356 { 357 return osEnqueueEvt(sensorGetMyEventType(SENS_TYPE_BARO), SENSOR_DATA_EVENT_FLUSH, NULL); 358 } 359 360 #define DEC_OPS(power, firmware, rate, flush, cal, cfg) \ 361 .sensorPower = power, \ 362 .sensorFirmwareUpload = firmware, \ 363 .sensorSetRate = rate, \ 364 .sensorFlush = flush, \ 365 .sensorCalibrate = cal, \ 366 .sensorCfgData = cfg 367 368 static const struct SensorOps lps22hbSensorOps[NUM_OF_SENSOR] = 369 { 370 { DEC_OPS(baroPower, baroFwUpload, baroSetRate, baroFlush, NULL, NULL) }, 371 { DEC_OPS(tempPower, tempFwUpload, tempSetRate, tempFlush, NULL, NULL) }, 372 }; 373 374 static uint8_t *wai; 375 static uint8_t *baro_samples; 376 static uint8_t *temp_samples; 377 static void handleCommDoneEvt(const void* evtData) 378 { 379 uint8_t i; 380 int baro_val; 381 short temp_val; 382 uint32_t state = (uint32_t)evtData; 383 union EmbeddedDataPoint sample; 384 385 switch (state) { 386 case SENSOR_BOOT: 387 mTask.comm_rx(LPS22HB_WAI_REG_ADDR, 1, 1, (void *)SENSOR_VERIFY_ID); 388 break; 389 390 case SENSOR_VERIFY_ID: 391 wai = &mTask.sens_buf[1]; 392 393 if (LPS22HB_WAI_REG_VAL != wai[0]) { 394 osLog(LOG_INFO, "WAI returned is: %02x\n", *wai); 395 break; 396 } 397 398 osLog(LOG_INFO, "Device ID is correct! (%02x)\n", *wai); 399 for (i = 0; i < NUM_OF_SENSOR; i++) 400 sensorRegisterInitComplete(mTask.sensors[i].handle); 401 402 /* TEST the environment in standalone mode */ 403 //osEnqueuePrivateEvt(EVT_TEST, NULL, NULL, mTask.tid); 404 break; 405 406 case SENSOR_INIT: 407 for (i = 0; i < NUM_OF_SENSOR; i++) 408 sensorRegisterInitComplete(mTask.sensors[i].handle); 409 break; 410 411 case SENSOR_BARO_POWER_UP: 412 sensorSignalInternalEvt(mTask.sensors[BARO].handle, 413 SENSOR_INTERNAL_EVT_POWER_STATE_CHG, true, 0); 414 break; 415 416 case SENSOR_BARO_POWER_DOWN: 417 sensorSignalInternalEvt(mTask.sensors[BARO].handle, 418 SENSOR_INTERNAL_EVT_POWER_STATE_CHG, false, 0); 419 break; 420 421 case SENSOR_TEMP_POWER_UP: 422 sensorSignalInternalEvt(mTask.sensors[TEMP].handle, 423 SENSOR_INTERNAL_EVT_POWER_STATE_CHG, true, 0); 424 break; 425 426 case SENSOR_TEMP_POWER_DOWN: 427 sensorSignalInternalEvt(mTask.sensors[TEMP].handle, 428 SENSOR_INTERNAL_EVT_POWER_STATE_CHG, false, 0); 429 break; 430 431 case SENSOR_READ_SAMPLES: 432 if (mTask.baroOn && mTask.baroWantRead) { 433 mTask.baroWantRead = false; 434 baro_samples = &mTask.sens_buf[1]; 435 436 baro_val = ((baro_samples[2] << 16) & 0xff0000) | 437 ((baro_samples[1] << 8) & 0xff00) | 438 (baro_samples[0]); 439 440 mTask.baroReading = false; 441 sample.fdata = LPS22HB_HECTO_PASCAL((float)baro_val); 442 //osLog(LOG_INFO, "baro: %p\n", sample.vptr); 443 osEnqueueEvt(sensorGetMyEventType(SENS_TYPE_BARO), sample.vptr, NULL); 444 } 445 446 if (mTask.tempOn && mTask.tempWantRead) { 447 mTask.tempWantRead = false; 448 temp_samples = &mTask.sens_buf[4]; 449 450 temp_val = ((temp_samples[1] << 8) & 0xff00) | 451 (temp_samples[0]); 452 453 mTask.tempReading = false; 454 sample.fdata = LPS22HB_CENTIGRADES((float)temp_val); 455 //osLog(LOG_INFO, "temp: %p\n", sample.vptr); 456 osEnqueueEvt(sensorGetMyEventType(SENS_TYPE_TEMP), sample.vptr, NULL); 457 } 458 459 break; 460 461 default: 462 break; 463 } 464 } 465 466 static void handleEvent(uint32_t evtType, const void* evtData) 467 { 468 switch (evtType) { 469 case EVT_APP_START: 470 osLog(LOG_INFO, "LPS22HB DRIVER: EVT_APP_START\n"); 471 osEventUnsubscribe(mTask.tid, EVT_APP_START); 472 473 mTask.comm_tx(LPS22HB_SOFT_RESET_REG_ADDR, 474 LPS22HB_SOFT_RESET_BIT, 0, (void *)SENSOR_BOOT); 475 break; 476 477 case EVT_COMM_DONE: 478 //osLog(LOG_INFO, "LPS22HB DRIVER: EVT_COMM_DONE %d\n", (int)evtData); 479 handleCommDoneEvt(evtData); 480 break; 481 482 case EVT_SENSOR_BARO_TIMER: 483 //osLog(LOG_INFO, "LPS22HB DRIVER: EVT_SENSOR_BARO_TIMER\n"); 484 485 mTask.baroWantRead = true; 486 487 /* Start sampling for a value */ 488 if (!mTask.baroReading && !mTask.tempReading) { 489 mTask.baroReading = true; 490 491 mTask.comm_rx(LPS22HB_PRESS_OUTXL_REG_ADDR, 5, 1, (void *)SENSOR_READ_SAMPLES); 492 } 493 494 break; 495 496 case EVT_SENSOR_TEMP_TIMER: 497 //osLog(LOG_INFO, "LPS22HB DRIVER: EVT_SENSOR_TEMP_TIMER\n"); 498 499 mTask.tempWantRead = true; 500 501 /* Start sampling for a value */ 502 if (!mTask.baroReading && !mTask.tempReading) { 503 mTask.tempReading = true; 504 505 mTask.comm_rx(LPS22HB_PRESS_OUTXL_REG_ADDR, 5, 1, (void *)SENSOR_READ_SAMPLES); 506 } 507 508 break; 509 510 case EVT_INT1_RAISED: 511 osLog(LOG_INFO, "LPS22HB DRIVER: EVT_INT1_RAISED\n"); 512 break; 513 514 case EVT_TEST: 515 osLog(LOG_INFO, "LPS22HB DRIVER: EVT_TEST\n"); 516 517 baroPower(true, NULL); 518 tempPower(true, NULL); 519 baroSetRate(SENSOR_HZ(1), 0, NULL); 520 tempSetRate(SENSOR_HZ(1), 0, NULL); 521 break; 522 523 default: 524 break; 525 } 526 527 } 528 529 static bool startTask(uint32_t task_id) 530 { 531 uint8_t i; 532 533 mTask.tid = task_id; 534 535 osLog(LOG_INFO, "LPS22HB DRIVER started\n"); 536 537 mTask.baroOn = mTask.tempOn = false; 538 mTask.baroReading = mTask.tempReading = false; 539 540 /* Init the communication part */ 541 #if defined(LPS22HB_USE_I2C) 542 i2cMasterRequest(I2C_BUS_ID, I2C_SPEED); 543 544 mTask.comm_tx = i2c_write; 545 mTask.comm_rx = i2c_read; 546 #else 547 spi_init(); 548 549 mTask.comm_tx = spi_write; 550 mTask.comm_rx = spi_read; 551 #endif 552 553 for (i = 0; i < NUM_OF_SENSOR; i++) { 554 mTask.sensors[i].handle = 555 sensorRegister(&lps22hbSensorInfo[i], &lps22hbSensorOps[i], NULL, false); 556 } 557 558 osEventSubscribe(mTask.tid, EVT_APP_START); 559 560 return true; 561 } 562 563 static void endTask(void) 564 { 565 osLog(LOG_INFO, "LPS22HB DRIVER ended\n"); 566 #if defined(LPS22HB_USE_I2C) 567 #else 568 spiMasterRelease(mTask.spiDev); 569 #endif 570 } 571 572 INTERNAL_APP_INIT(LPS22HB_APP_ID, 0, startTask, endTask, handleEvent); 573