Sensor Fusion Library 0.6.1
Orientation sensing for Espressif (ESP32, ESP8266) processors
Loading...
Searching...
No Matches
hal_i2c.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3 * Copyright (c) 2016-2017 NXP
4 * Copyright (c) 2020 Bjarne Hansen
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 * Modified for Espressif ESP environment
10 * Fusion library requires methods to control and read from physical sensor ICs. These methods are
11 * found in files like driver_fxas21002.c and driver_fxos8700.c. For example,
12 * driver_fxas21002.c implements methods like FXAS21002_Init() using calls to Sensor_I2C_Write_List().
13 * This present file provides a Sensor_I2C_Write_List() that functions in the ESP environment.
14 */
15
22#include "Arduino.h"
23#include <Wire.h>
25#include "hal_i2c.h"
26
27
28/**************************************************************************/
36/**************************************************************************/
37bool I2CInitialize( int pin_sda, int pin_scl ) {
38
39 #ifdef ESP32
40 bool success = Wire.begin(pin_sda, pin_scl);
41#endif
42#ifdef ESP8266
43 Wire.begin(pin_sda, pin_scl);
44 bool success = true; //ESP8266 Wire library doesn't return value from begin()
45#endif
46 Wire.setClock(400000); // in ESP8266 library, can't set clock in same call
47 // that sets pins
48 return success;
49} // end I2CInitialize()
50
51/**************************************************************************/
56/**************************************************************************/
57bool I2CReadByte(byte address, byte reg, byte *destination) {
58 return I2CReadBytes(address, reg, destination, 1);
59} // end ReadByte()
60
61/**************************************************************************/
68/**************************************************************************/
69bool I2CReadBytes(byte address, byte reg, byte *destination, int num_bytes) {
70 if (NULL == destination) {
71 return false;
72 }
73 Wire.beginTransmission(address);
74 if (!Wire.write(reg)) {
75 Wire.endTransmission(true);
76 return false;
77 }
78 Wire.endTransmission(false);
79 if (num_bytes == Wire.requestFrom(address, (uint8_t)num_bytes)) {
80 int return_value;
81 for (int i=0; i < num_bytes; i++) {
82 return_value = Wire.read();
83 if (return_value >= 0) {
84 destination[i] = (byte)return_value;
85 } else {
86 return false;
87 }
88 }//loop through requested number of bytes
89 return true;
90 }
91 return false;
92
93} // end I2CReadBytes()
94
95
96/**************************************************************************/
101/**************************************************************************/
102bool I2CWriteByte(byte address, byte reg, byte value) {
103 Wire.beginTransmission(address);
104 Wire.write(reg);
105 Wire.write(value);
106 if (I2C_ERROR_OK == Wire.endTransmission()) {
107 return true;
108 } else {
109 return false;
110 }
111} // end I2CWriteByte()
112
113/**************************************************************************/
119/**************************************************************************/
120bool I2CWriteBytes(byte address, byte reg, const byte *value,
121 unsigned int num_bytes) {
122 Wire.beginTransmission(address);
123 Wire.write(reg);
124 if (num_bytes != Wire.write(value, num_bytes)) {
125 // error queueing up the bytes
126 Wire.endTransmission();
127 return false;
128 }
129 if( I2C_ERROR_OK == Wire.endTransmission() ){
130 return true;
131 }else {
132 return false;
133 }
134} // end I2CWriteBytes()
135
136/*
137Call sequence is:
138Wire:::endTransmission() ->
139 Wire:::writeTransmission() ->
140 HAL:::i2cWrite() ->
141 HAL:::i2cProcQueue() blocks until queue empty, or bus timeout
142*/
143
144//The interface function to write register data from list to a sensor.
145int8_t Sensor_I2C_Write_List(registerDeviceInfo_t *devInfo, uint16_t peripheralAddress,
146 const registerwritelist_t *pRegWriteList) {
147 // Validate handle
148 if (pRegWriteList == NULL) {
149 return SENSOR_ERROR_BAD_ADDRESS;
150 }
151
152 const registerwritelist_t *pCmd = pRegWriteList;
153 // Update register values based on register write list until the next Cmd is
154 // the list terminator.
155 // original method used Repeated starts, but try individual xactions for simplicity.
156 // repeatedStart = (pCmd + 1)->writeTo != 0xFFFF;
157 // Original method included a mask for the written
158 // value, but the mask was always 0x00 (no effect)
159 while (pCmd->writeTo != 0xFFFF) {
160 //
161 // Set the register based on the values in the register value pair
162 // was Register_I2C_Write(pCommDrv, devInfo, peripheralAddress, pCmd->writeTo,
163 // pCmd->value, pCmd->mask, repeatedStart);
164 if (!I2CWriteByte(peripheralAddress, pCmd->writeTo, pCmd->value)) {
165 return SENSOR_ERROR_WRITE;
166 }
167 ++pCmd;
168 };
169
170 return SENSOR_ERROR_NONE;
171} // end Sensor_I2C_Write_List()
172
173// Read register data from peripheralAddress, using register
174// location and number of bytes in pReadList.
175// Iterate through pReadList until number of bytes requested == 0
176// Data is placed sequentially starting at pOutBuffer.
178 uint16_t peripheralAddress,
179 const registerReadlist_t *pReadList,
180 uint8_t *pOutBuffer) {
181// int32_t status;
182 uint8_t *pBuf;
183
184 // Validate handle
185 if (pReadList == NULL || pOutBuffer == NULL) {
186 return SENSOR_ERROR_BAD_ADDRESS;
187 }
188 const registerReadlist_t *pCmd = pReadList;
189
190 // Traverse the read list and read the registers one by one unless the
191 // register read list numBytes is zero
192 for (pBuf = pOutBuffer; pCmd->numBytes != 0; pCmd++) {
193 // was Register_I2C_Read(pCommDrv, devInfo, peripheralAddress,
194 // pCmd->readFrom, pCmd->numBytes, pBuf);
195 if (!I2CReadBytes(peripheralAddress, pCmd->readFrom, pBuf,
196 pCmd->numBytes)) {
197 return SENSOR_ERROR_READ;
198 }
199 pBuf += pCmd->numBytes;
200 }
201 return SENSOR_ERROR_NONE;
202} // end Sensor_I2C_Read()
203
204int32_t Sensor_I2C_Read_Register(registerDeviceInfo_t *devInfo,
205 uint16_t peripheralAddress,
206 uint8_t offset,
207 uint8_t length,
208 uint8_t *pOutBuffer) {
209 //TODO - can toss the devInfo parameter, or use it for peripheralAddr
210 if(I2CReadBytes((byte)peripheralAddress, (byte)offset, pOutBuffer,
211 (int)length) )
212 { return SENSOR_ERROR_NONE;
213 } else
214 {
215 return SENSOR_ERROR_READ;
216 }
217
218}//end Sensor_I2C_Read_Register()
The driver_sensors_types.h file contains sensor state structs and error definitions.
bool I2CReadBytes(byte address, byte reg, byte *destination, int num_bytes)
Read num_bytes bytes from address starting at register. Assumes device auto-increments the register....
Definition hal_i2c.cc:69
bool I2CWriteBytes(byte address, byte reg, const byte *value, unsigned int num_bytes)
Write multiple bytes starting at register to I2C address Assumes device auto-increments the I2C regis...
Definition hal_i2c.cc:120
int8_t Sensor_I2C_Write_List(registerDeviceInfo_t *devInfo, uint16_t peripheralAddress, const registerwritelist_t *pRegWriteList)
Write register data to a sensor.
Definition hal_i2c.cc:145
bool I2CReadByte(byte address, byte reg, byte *destination)
Read single byte from address and place in destination Returns true if successful,...
Definition hal_i2c.cc:57
bool I2CWriteByte(byte address, byte reg, byte value)
Write single byte to register at address Returns true if successful, false if error.
Definition hal_i2c.cc:102
bool I2CInitialize(int pin_sda, int pin_scl)
Initialize the I2C system at max clock rate supported by sensors. pin_sda and pin_scl indicate the pi...
Definition hal_i2c.cc:37
int32_t Sensor_I2C_Read(registerDeviceInfo_t *devInfo, uint16_t peripheralAddress, const registerReadlist_t *pReadList, uint8_t *pOutBuffer)
Read register data from a sensor.
Definition hal_i2c.cc:177
The hal_i2c.h file declares low-level interface functions for reading and writing sensor registers us...
This structure defines the device specific info required by register I/O.
This structure defines the Read command List.
This structure defines the Write command List.