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)
i2cCallback(void * cookie,size_t tx,size_t rx,int err)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)
i2c_read(uint8_t addr,uint16_t len,uint32_t delay,void * cookie)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
i2c_write(uint8_t addr,uint8_t data,uint32_t delay,void * cookie)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
spi_read(uint8_t addr,uint16_t len,uint32_t delay,void * cookie)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
spi_write(uint8_t addr,uint8_t data,uint32_t delay,void * cookie)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
spi_init(void)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 */
sensorBaroTimerCallback(uint32_t timerId,void * data)210 static void sensorBaroTimerCallback(uint32_t timerId, void *data)
211 {
212 osEnqueuePrivateEvt(EVT_SENSOR_BARO_TIMER, data, NULL, mTask.tid);
213 }
214
sensorTempTimerCallback(uint32_t timerId,void * data)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 */
baroPower(bool on,void * cookie)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
baroFwUpload(void * cookie)287 static bool baroFwUpload(void *cookie)
288 {
289 return sensorSignalInternalEvt(mTask.sensors[BARO].handle, SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0);
290 }
291
baroSetRate(uint32_t rate,uint64_t latency,void * cookie)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
baroFlush(void * cookie)305 static bool baroFlush(void *cookie)
306 {
307 return osEnqueueEvt(sensorGetMyEventType(SENS_TYPE_BARO), SENSOR_DATA_EVENT_FLUSH, NULL);
308 }
309
tempPower(bool on,void * cookie)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
tempFwUpload(void * cookie)337 static bool tempFwUpload(void *cookie)
338 {
339 return sensorSignalInternalEvt(mTask.sensors[TEMP].handle, SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0);
340 }
341
tempSetRate(uint32_t rate,uint64_t latency,void * cookie)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
tempFlush(void * cookie)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;
handleCommDoneEvt(const void * evtData)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
handleEvent(uint32_t evtType,const void * evtData)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
startTask(uint32_t task_id)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
endTask(void)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