Data Logger BLE Cellular Board
Loading...
Searching...
No Matches
common.c
Go to the documentation of this file.
1/** \file common.c
2 *
3 * \brief Common utility functions and definitions for the BME68X sensor interface
4 *
5 * \copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
6 *
7 * \note SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10
11#include <stdint.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <zephyr/drivers/i2c.h>
15
16#include "bme68x.h"
17// #include "coines.h"
18#include "common.h"
19#include "jfet_common.h"
20
21/******************************************************************************/
22/*! Macro definitions */
23#define BME68X_SHUTTLE_ID 0x93 //!< BME68X shuttle board ID
24
25/******************************************************************************/
26/*! Static variable definition */
27static uint8_t dev_addr;
28
29#if 0
30/******************************************************************************/
31/*! User interface functions */
32
33/*!
34 * I2C read function map to COINES platform
35 */
36BME68X_INTF_RET_TYPE bme68x_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
37{
38 uint8_t device_addr = *(uint8_t*)intf_ptr;
39
40 (void)intf_ptr;
41
42 return coines_read_i2c(COINES_I2C_BUS_0, device_addr, reg_addr, reg_data, (uint16_t)len);
43}
44
45/*!
46 * I2C write function map to COINES platform
47 */
48BME68X_INTF_RET_TYPE bme68x_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
49{
50 uint8_t device_addr = *(uint8_t*)intf_ptr;
51
52 (void)intf_ptr;
53
54 return coines_write_i2c(COINES_I2C_BUS_0, device_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
55}
56
57/*!
58 * SPI read function map to COINES platform
59 */
60BME68X_INTF_RET_TYPE bme68x_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
61{
62 uint8_t device_addr = *(uint8_t*)intf_ptr;
63
64 (void)intf_ptr;
65
66 return coines_read_spi(COINES_SPI_BUS_0, device_addr, reg_addr, reg_data, (uint16_t)len);
67}
68
69/*!
70 * SPI write function map to COINES platform
71 */
72BME68X_INTF_RET_TYPE bme68x_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
73{
74 uint8_t device_addr = *(uint8_t*)intf_ptr;
75
76 (void)intf_ptr;
77
78 return coines_write_spi(COINES_SPI_BUS_0, device_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
79}
80
81/*!
82 * Delay function map to COINES platform
83 */
84void bme68x_delay_us(uint32_t period, void *intf_ptr)
85{
86 (void)intf_ptr;
87 coines_delay_usec(period);
88}
89
90void bme68x_check_rslt(const char api_name[], int8_t rslt)
91{
92 switch (rslt)
93 {
94 case BME68X_OK:
95
96 /* Do nothing */
97 break;
98 case BME68X_E_NULL_PTR:
99 printf("API name [%s] Error [%d] : Null pointer\r\n", api_name, rslt);
100 break;
101 case BME68X_E_COM_FAIL:
102 printf("API name [%s] Error [%d] : Communication failure\r\n", api_name, rslt);
103 break;
104 case BME68X_E_INVALID_LENGTH:
105 printf("API name [%s] Error [%d] : Incorrect length parameter\r\n", api_name, rslt);
106 break;
107 case BME68X_E_DEV_NOT_FOUND:
108 printf("API name [%s] Error [%d] : Device not found\r\n", api_name, rslt);
109 break;
110 case BME68X_E_SELF_TEST:
111 printf("API name [%s] Error [%d] : Self test error\r\n", api_name, rslt);
112 break;
113 case BME68X_W_NO_NEW_DATA:
114 printf("API name [%s] Warning [%d] : No new data found\r\n", api_name, rslt);
115 break;
116 default:
117 printf("API name [%s] Error [%d] : Unknown error code\r\n", api_name, rslt);
118 break;
119 }
120}
121
122int8_t bme68x_interface_init(struct bme68x_dev *bme, uint8_t intf)
123{
124 int8_t rslt = BME68X_OK;
125 struct coines_board_info board_info;
126
127 if (bme != NULL)
128 {
129 int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB, NULL);
130 if (result < COINES_SUCCESS)
131 {
132 printf(
133 "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n"
134 " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n");
135 exit(result);
136 }
137
138 result = coines_get_board_info(&board_info);
139
140#if defined(PC)
141 setbuf(stdout, NULL);
142#endif
143
144 if (result == COINES_SUCCESS)
145 {
146 if ((board_info.shuttle_id != BME68X_SHUTTLE_ID))
147 {
148 printf(
149 "! Warning invalid sensor shuttle : 0x%x (Expected : 0x%x) \n ," "This application will not support this sensor \n",
150 board_info.shuttle_id,
152 }
153 }
154
155 (void)coines_set_shuttleboard_vdd_vddio_config(0, 0);
156 coines_delay_msec(100);
157
158 /* Bus configuration : I2C */
159 if (intf == BME68X_I2C_INTF)
160 {
161 printf("I2C Interface\n");
162 dev_addr = BME68X_I2C_ADDR_LOW;
163 bme->read = bme68x_i2c_read;
164 bme->write = bme68x_i2c_write;
165 bme->intf = BME68X_I2C_INTF;
166
167 /* SDO pin is made low */
168 (void)coines_set_pin_config(COINES_SHUTTLE_PIN_SDO, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW);
169
170 (void)coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE);
171 }
172 /* Bus configuration : SPI */
173 else if (intf == BME68X_SPI_INTF)
174 {
175 printf("SPI Interface\n");
176 dev_addr = COINES_SHUTTLE_PIN_7;
177 bme->read = bme68x_spi_read;
178 bme->write = bme68x_spi_write;
179 bme->intf = BME68X_SPI_INTF;
180 (void)coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0);
181 }
182
183 coines_delay_msec(100);
184
185 (void)coines_set_shuttleboard_vdd_vddio_config(3300, 3300);
186
187 coines_delay_msec(100);
188
189 bme->delay_us = bme68x_delay_us;
190 bme->intf_ptr = &dev_addr;
191 bme->amb_temp = 25; /* The ambient temperature in deg C is used for defining the heater temperature */
192 }
193 else
194 {
195 rslt = BME68X_E_NULL_PTR;
196 }
197
198 return rslt;
199}
200
201void bme68x_coines_deinit(void)
202{
203 (void)fflush(stdout);
204
205 (void)coines_set_shuttleboard_vdd_vddio_config(0, 0);
206 coines_delay_msec(1000);
207
208 /* Coines interface reset */
209 coines_soft_reset();
210 coines_delay_msec(1000);
211 (void)coines_close_comm_intf(COINES_COMM_INTF_USB, NULL);
212}
213#else
214
215/** \fn BME68X_INTF_RET_TYPE bme68x_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
216 *
217 * @brief Function for reading the sensor's registers through I2C bus.
218 *
219 * @param[in] reg_addr : Register address.
220 * @param[out] reg_data : Pointer to the data buffer to store the read data.
221 * @param[in] len : No of bytes to read.
222 * @param[in] intf_ptr : Interface pointer
223 *
224 * @return Status of execution
225 * @retval = BME68X_INTF_RET_SUCCESS -> Success
226 * @retval != BME68X_INTF_RET_SUCCESS -> Failure Info
227 */
228BME68X_INTF_RET_TYPE bme68x_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) {
229 uint8_t device_addr = *(uint8_t *)intf_ptr;
230
231 (void)intf_ptr;
232 return i2c_read(i2c_dev, reg_data, len, device_addr);
233 // return coines_read_i2c(COINES_I2C_BUS_0, device_addr, reg_addr, reg_data, (uint16_t)len);
234}
235
236/** \fn BME68X_INTF_RET_TYPE bme68x_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
237 *
238 * @brief Function for writing the sensor's registers through I2C bus.
239 *
240 * @param[in] reg_addr : Register address.
241 * @param[in] reg_data : Pointer to the data buffer whose value is to be written.
242 * @param[in] len : No of bytes to write.
243 * @param[in] intf_ptr : Interface pointer
244 *
245 * @return Status of execution
246 * @retval = BME68X_INTF_RET_SUCCESS -> Success
247 * @retval != BME68X_INTF_RET_SUCCESS -> Failure Info
248 *
249 */
250BME68X_INTF_RET_TYPE bme68x_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) {
251 uint8_t device_addr = *(uint8_t *)intf_ptr;
252
253 (void)intf_ptr;
254 return i2c_write(i2c_dev, reg_data, len, device_addr);
255 // return coines_write_i2c(COINES_I2C_BUS_0, device_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
256}
257
258/** \fn BME68X_INTF_RET_TYPE bme68x_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
259 *
260 * @brief Function for reading the sensor's registers through SPI bus.
261 *
262 * @param[in] reg_addr : Register address.
263 * @param[out] reg_data : Pointer to the data buffer to store the read data.
264 * @param[in] len : No of bytes to read.
265 * @param[in] intf_ptr : Interface pointer
266 *
267 * @return Status of execution
268 * @retval = BME68X_INTF_RET_SUCCESS -> Success
269 * @retval != BME68X_INTF_RET_SUCCESS -> Failure Info
270 */
271BME68X_INTF_RET_TYPE bme68x_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) {
272 // uint8_t device_addr = *(uint8_t *)intf_ptr;
273 uint8_t i = 0;
274 int ret;
275
276 /* zero buffer and load the command */
277 for (i = 0; i < len; i++)
278 buffer_tx[i] = 0;
279 buffer_tx[0] = reg_addr;
280 tx_bufs[0].len = len + 1;
281 rx_bufs[0].len = len + 1;
282
283 /* enable CS and send command */
284 ret = spi_transceive(spi_dev, &spi_cfg2, &tx, &rx);
285
286 /* shift bytes back to caller byte 0 is not valid data */
287 for (i = 0; i < len; i++) {
288 reg_data[i] = buffer_rx[i + 1];
289 }
290
291 // myPrintkS("bme68x_spi_read reg_addr: 0x%02X reg_data: 0x%02X len: %d dev_addr: %d\r\n", reg_addr, reg_data[0], len, device_addr);
292 // if (len > 1)
293 // {
294 // for (int i = 0; i < len; i++)
295 // {
296 // myPrintkS("i: %d 0x%02X\r\n", i, reg_data[i]);
297 // }
298 // }
299 return ret;
300#if 0
301 return coines_read_spi(COINES_SPI_BUS_0, device_addr, reg_addr, reg_data, (uint16_t)len);
302#endif
303}
304
305/** \fn BME68X_INTF_RET_TYPE bme68x_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
306 *
307 * @brief Function for writing the sensor's registers through SPI bus.
308 *
309 * @param[in] reg_addr : Register address.
310 * @param[in] reg_data : Pointer to the data buffer whose data has to be written.
311 * @param[in] len : No of bytes to write.
312 * @param[in] intf_ptr : Interface pointer
313 *
314 * @return Status of execution
315 * @retval = BME68X_INTF_RET_SUCCESS -> Success
316 * @retval != BME68X_INTF_RET_SUCCESS -> Failure Info
317 */
318BME68X_INTF_RET_TYPE bme68x_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) {
319 // uint8_t device_addr = *(uint8_t *)intf_ptr;
320 uint8_t i = 0;
321
322 (void)intf_ptr;
323
324 buffer_tx[0] = reg_addr & BME68X_SPI_WR_MSK;
325 for (i = 0; i < len; i++) {
326 buffer_tx[i + 1] = reg_data[i];
327 }
328 tx_bufs[0].len = len + 1;
329 rx_bufs[0].len = len + 1;
330
331 /* enable CS and send command */
332 ret = spi_transceive(spi_dev, &spi_cfg2, &tx, &rx);
333 return ret;
334#if 0
335 return coines_write_spi(COINES_SPI_BUS_0, device_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
336#endif
337}
338
339/** \fn void bme68x_delay_us(uint32_t period, void *intf_ptr)
340 * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the
341 * APIs.
342 *
343 * @param[in] period : The required wait time in microsecond.
344 * @param[in] intf_ptr : Interface pointer
345 *
346 */
347void bme68x_delay_us(uint32_t period, void *intf_ptr) {
348 (void)intf_ptr;
349 // Use Zephyr kernel sleep for a microsecond delay.
350 // coines_delay_usec(period);
351 k_sleep(K_USEC(period));
352}
353
354/** \fn void bme68x_check_rslt(const char api_name[], int8_t rslt)
355 *
356 * \brief Log BME68X API result and error details.
357 *
358 * \param api_name Name of the called BME68X API.
359 * \param rslt Result code returned by the BME68X function.
360 */
361void bme68x_check_rslt(const char api_name[], int8_t rslt) {
362 switch (rslt) {
363 case BME68X_OK:
364 myPrintkS("BME688 API name [%s] OK\r\n", api_name, rslt);
365 /* Do nothing */
366 break;
367 case BME68X_E_NULL_PTR:
368 myPrintkS("BME688 API name [%s] Error [%d] : Null pointer\r\n", api_name, rslt);
369 break;
370 case BME68X_E_COM_FAIL:
371 myPrintkS("BME688 API name [%s] Error [%d] : Communication failure\r\n", api_name, rslt);
372 break;
373 case BME68X_E_INVALID_LENGTH:
374 myPrintkS("BME688 API name [%s] Error [%d] : Incorrect length parameter\r\n", api_name, rslt);
375 break;
376 case BME68X_E_DEV_NOT_FOUND:
377 myPrintkS("BME688 API name [%s] Error [%d] : Device not found\r\n", api_name, rslt);
378 break;
379 case BME68X_E_SELF_TEST:
380 myPrintkS("BME688 API name [%s] Error [%d] : Self test error\r\n", api_name, rslt);
381 break;
382 case BME68X_W_NO_NEW_DATA:
383 myPrintkS("BME688 API name [%s] Warning [%d] : No new data found\r\n", api_name, rslt);
384 break;
385 default:
386 myPrintkS("BME688 API name [%s] Error [%d] : Unknown error code\r\n", api_name, rslt);
387 break;
388 }
389}
390
391/*!
392 * @brief Function to select the interface between SPI and I2C.
393 *
394 * @param[in] bme : Structure instance of bme68x_dev
395 * @param[in] intf : Interface selection parameter
396 *
397 * @return Status of execution
398 * @retval 0 -> Success
399 * @retval < 0 -> Failure Info
400 */
401int8_t bme68x_interface_init(struct bme68x_dev *bme, uint8_t intf) {
402 int8_t rslt = BME68X_OK;
403 // struct coines_board_info board_info;
404
405 if (bme != NULL) {
406 // int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB, NULL);
407 // if (result < COINES_SUCCESS)
408 // {
409 // printf(
410 // "\n Unable to connect with Application Board ! \n"
411 // " 1. Check if the board is connected and powered on. \n"
412 // " 2. Check if Application Board USB driver is installed. \n"
413 // " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n");
414 // exit(result);
415 // }
416 //
417 // result = coines_get_board_info(&board_info);
418 //
419 // #if defined(PC)
420 // setbuf(stdout, NULL);
421 // #endif
422 //
423 // if (result == COINES_SUCCESS)
424 // {
425 // if ((board_info.shuttle_id != BME68X_SHUTTLE_ID))
426 // {
427 // printf(
428 // "! Warning invalid sensor shuttle : 0x%x (Expected : 0x%x) \n ,"
429 // "This application will not support this sensor \n",
430 // board_info.shuttle_id,
431 // BME68X_SHUTTLE_ID);
432 // }
433 // }
434 //
435 // (void)coines_set_shuttleboard_vdd_vddio_config(0, 0);
436 // coines_delay_msec(100);
437
438 /* Bus configuration : I2C */
439 if (intf == BME68X_I2C_INTF) {
440 myPrintkS("I2C Interface\n");
441 dev_addr = BME68X_I2C_ADDR_LOW;
442 bme->read = bme68x_i2c_read;
443 bme->write = bme68x_i2c_write;
444 bme->intf = BME68X_I2C_INTF;
445
446 // /* SDO pin is made low */
447 // (void)coines_set_pin_config(COINES_SHUTTLE_PIN_SDO, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW);
448 //
449 // (void)coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE);
450 }
451 /* Bus configuration : SPI */
452 else if (intf == BME68X_SPI_INTF) {
453 myPrintkS("SPI Interface %d\n", spics2n.pin);
454 // dev_addr = COINES_SHUTTLE_PIN_7;
455 dev_addr = spics2n.pin;
456 bme->read = bme68x_spi_read;
457 bme->write = bme68x_spi_write;
458 bme->intf = BME68X_SPI_INTF;
459 // (void)coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0);
460 }
461
462 // coines_delay_msec(100);
463 k_sleep(K_MSEC(100));
464 //
465 // (void)coines_set_shuttleboard_vdd_vddio_config(3300, 3300);
466 //
467 // coines_delay_msec(100);
468
469 bme->delay_us = bme68x_delay_us;
470 bme->intf_ptr = &dev_addr;
471 bme->amb_temp = 25; /* The ambient temperature in deg C is used for defining the heater temperature */
472 } else {
473 rslt = BME68X_E_NULL_PTR;
474 }
475
476 return rslt;
477}
478#endif
BME68X Sensor API header file.
static uint8_t dev_addr
Definition common.c:27
#define BME68X_SHUTTLE_ID
BME68X shuttle board ID.
Definition common.c:23
int8_t bme68x_interface_init(struct bme68x_dev *bme, uint8_t intf)
Function to select the interface between SPI and I2C.
Definition common.c:401
BME68X_INTF_RET_TYPE bme68x_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
Function for writing the sensor's registers through I2C bus.
Definition common.c:250
void bme68x_check_rslt(const char api_name[], int8_t rslt)
Log BME68X API result and error details.
Definition common.c:361
BME68X_INTF_RET_TYPE bme68x_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
Function for reading the sensor's registers through SPI bus.
Definition common.c:271
void bme68x_delay_us(uint32_t period, void *intf_ptr)
This function provides the delay for required time (Microsecond) as per the input provided in some of...
Definition common.c:347
BME68X_INTF_RET_TYPE bme68x_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
Function for writing the sensor's registers through SPI bus.
Definition common.c:318
BME68X_INTF_RET_TYPE bme68x_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
Function for reading the sensor's registers through I2C bus.
Definition common.c:228
void bme68x_coines_deinit(void)
Deinitializes coines platform.
struct spi_buf tx_bufs[]
SPI TX buffer structure.
Definition globals.c:111
const struct spi_buf_set rx
SPI RX buffer structure.
Definition globals.c:127
uint8_t buffer_rx[SPI_BUF_SIZE+8]
SPI receive buffer0.
Definition globals.c:43
const struct device *const spi_dev
Definition globals.c:79
int ret
Definition globals.c:41
const struct gpio_dt_spec spics2n
Definition globals.c:63
struct spi_config spi_cfg2
SPI configuration.
Definition globals.c:101
uint8_t buffer_tx[SPI_BUF_SIZE+8]
SPI transmit buffer.
Definition globals.c:42
struct spi_buf rx_bufs[]
SPI RX buffer structure.
Definition globals.c:118
const struct spi_buf_set tx
SPI TX buffer structure.
Definition globals.c:125
common struct, enum, externs, prototypes
int myPrintkS(char *restrict fmt,...)
prints a status message to the UART
Definition main.c:2419
const struct device *const i2c_dev
get the device structure for the I2C device defined by I2C_DEV_NODE
Definition main.c:106