349 lines
15 KiB
C
349 lines
15 KiB
C
/*
|
|
* Copyright (c) 2018, Sensirion AG
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* * Neither the name of Sensirion AG nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef SENSIRION_I2C_H
|
|
#define SENSIRION_I2C_H
|
|
|
|
#include "sensirion_config.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define CRC_ERROR 1
|
|
#define I2C_BUS_ERROR 2
|
|
#define I2C_NACK_ERROR 3
|
|
#define BYTE_NUM_ERROR 4
|
|
|
|
#define CRC8_POLYNOMIAL 0x31
|
|
#define CRC8_INIT 0xFF
|
|
#define CRC8_LEN 1
|
|
|
|
#define SENSIRION_COMMAND_SIZE 2
|
|
#define SENSIRION_WORD_SIZE 2
|
|
#define SENSIRION_NUM_WORDS(x) (sizeof(x) / SENSIRION_WORD_SIZE)
|
|
#define SENSIRION_MAX_BUFFER_WORDS 32
|
|
|
|
uint8_t sensirion_i2c_generate_crc(const uint8_t* data, uint16_t count);
|
|
|
|
int8_t sensirion_i2c_check_crc(const uint8_t* data, uint16_t count,
|
|
uint8_t checksum);
|
|
|
|
/**
|
|
* sensirion_i2c_general_call_reset() - Send a general call reset.
|
|
*
|
|
* @warning This will reset all attached I2C devices on the bus which support
|
|
* general call reset.
|
|
*
|
|
* @return NO_ERROR on success, an error code otherwise
|
|
*/
|
|
int16_t sensirion_i2c_general_call_reset(void);
|
|
|
|
/**
|
|
* sensirion_i2c_fill_cmd_send_buf() - create the i2c send buffer for a command
|
|
* and a set of argument words. The output buffer interleaves argument words
|
|
* with their checksums.
|
|
* @buf: The generated buffer to send over i2c. Then buffer length must
|
|
* be at least SENSIRION_COMMAND_LEN + num_args *
|
|
* (SENSIRION_WORD_SIZE + CRC8_LEN).
|
|
* @cmd: The i2c command to send. It already includes a checksum.
|
|
* @args: The arguments to the command. Can be NULL if none.
|
|
* @num_args: The number of word arguments in args.
|
|
*
|
|
* @return The number of bytes written to buf
|
|
*/
|
|
uint16_t sensirion_i2c_fill_cmd_send_buf(uint8_t* buf, uint16_t cmd,
|
|
const uint16_t* args,
|
|
uint8_t num_args);
|
|
|
|
/**
|
|
* sensirion_i2c_read_words() - read data words from sensor
|
|
*
|
|
* @address: Sensor i2c address
|
|
* @data_words: Allocated buffer to store the read words.
|
|
* The buffer may also have been modified in case of an error.
|
|
* @num_words: Number of data words to read (without CRC bytes)
|
|
*
|
|
* @return NO_ERROR on success, an error code otherwise
|
|
*/
|
|
int16_t sensirion_i2c_read_words(uint8_t address, uint16_t* data_words,
|
|
uint16_t num_words);
|
|
|
|
/**
|
|
* sensirion_i2c_read_words_as_bytes() - read data words as byte-stream from
|
|
* sensor
|
|
*
|
|
* Read bytes without adjusting values to the uP's word-order.
|
|
*
|
|
* @address: Sensor i2c address
|
|
* @data: Allocated buffer to store the read bytes.
|
|
* The buffer may also have been modified in case of an error.
|
|
* @num_words: Number of data words(!) to read (without CRC bytes)
|
|
* Since only word-chunks can be read from the sensor the size
|
|
* is still specified in sensor-words (num_words = num_bytes *
|
|
* SENSIRION_WORD_SIZE)
|
|
*
|
|
* @return NO_ERROR on success, an error code otherwise
|
|
*/
|
|
int16_t sensirion_i2c_read_words_as_bytes(uint8_t address, uint8_t* data,
|
|
uint16_t num_words);
|
|
|
|
/**
|
|
* sensirion_i2c_write_cmd() - writes a command to the sensor
|
|
* @address: Sensor i2c address
|
|
* @command: Sensor command
|
|
*
|
|
* @return NO_ERROR on success, an error code otherwise
|
|
*/
|
|
int16_t sensirion_i2c_write_cmd(uint8_t address, uint16_t command);
|
|
|
|
/**
|
|
* sensirion_i2c_write_cmd_with_args() - writes a command with arguments to the
|
|
* sensor
|
|
* @address: Sensor i2c address
|
|
* @command: Sensor command
|
|
* @data: Argument buffer with words to send
|
|
* @num_words: Number of data words to send (without CRC bytes)
|
|
*
|
|
* @return NO_ERROR on success, an error code otherwise
|
|
*/
|
|
int16_t sensirion_i2c_write_cmd_with_args(uint8_t address, uint16_t command,
|
|
const uint16_t* data_words,
|
|
uint16_t num_words);
|
|
|
|
/**
|
|
* sensirion_i2c_delayed_read_cmd() - send a command, wait for the sensor to
|
|
* process and read data back
|
|
* @address: Sensor i2c address
|
|
* @cmd: Command
|
|
* @delay: Time in microseconds to delay sending the read request
|
|
* @data_words: Allocated buffer to store the read data
|
|
* @num_words: Data words to read (without CRC bytes)
|
|
*
|
|
* @return NO_ERROR on success, an error code otherwise
|
|
*/
|
|
int16_t sensirion_i2c_delayed_read_cmd(uint8_t address, uint16_t cmd,
|
|
uint32_t delay_us, uint16_t* data_words,
|
|
uint16_t num_words);
|
|
/**
|
|
* sensirion_i2c_read_cmd() - reads data words from the sensor after a command
|
|
* is issued
|
|
* @address: Sensor i2c address
|
|
* @cmd: Command
|
|
* @data_words: Allocated buffer to store the read data
|
|
* @num_words: Data words to read (without CRC bytes)
|
|
*
|
|
* @return NO_ERROR on success, an error code otherwise
|
|
*/
|
|
int16_t sensirion_i2c_read_cmd(uint8_t address, uint16_t cmd,
|
|
uint16_t* data_words, uint16_t num_words);
|
|
|
|
/**
|
|
* sensirion_i2c_add_command_to_buffer() - Add a command to the buffer at
|
|
* offset. Adds 2 bytes to the buffer.
|
|
*
|
|
* @param buffer Pointer to buffer in which the write frame will be prepared.
|
|
* Caller needs to make sure that there is enough space after
|
|
* offset left to write the data into the buffer.
|
|
* @param offset Offset of the next free byte in the buffer.
|
|
* @param command Command to be written into the buffer.
|
|
*
|
|
* @return Offset of next free byte in the buffer after writing the data.
|
|
*/
|
|
uint16_t sensirion_i2c_add_command_to_buffer(uint8_t* buffer, uint16_t offset,
|
|
uint16_t command);
|
|
|
|
/**
|
|
* sensirion_i2c_add_command16_to_buffer() - Add a command to the buffer at
|
|
* the specified offset. This function is equivalent to the
|
|
* function sensirion_i2c_add_command_to_buffer().
|
|
*
|
|
* @param buffer Pointer to buffer in which the write frame will be prepared.
|
|
* Caller needs to make sure that there is enough space after
|
|
* offset left to write the data into the buffer.
|
|
* @param offset Offset of the next free byte in the buffer.
|
|
* @param command Command to be written into the buffer.
|
|
*
|
|
* @return Offset of next free byte in the buffer after writing the data.
|
|
*/
|
|
uint16_t sensirion_i2c_add_command16_to_buffer(uint8_t* buffer, uint16_t offset,
|
|
uint16_t command);
|
|
|
|
/**
|
|
* sensirion_i2c_add_command8_to_buffer() - Add a command to the buffer at
|
|
* offset. Adds one bytes command to the buffer.
|
|
* This is used for sensor that only take one command byte such as
|
|
* SHT.
|
|
*
|
|
* @param buffer Pointer to buffer in which the write frame will be prepared.
|
|
* Caller needs to make sure that there is enough space after
|
|
* offset left to write the data into the buffer.
|
|
* @param offset Offset of the next free byte in the buffer.
|
|
* @param command Command to be written into the buffer.
|
|
*
|
|
* @return Offset of next free byte in the buffer after writing the data.
|
|
*/
|
|
uint16_t sensirion_i2c_add_command8_to_buffer(uint8_t* buffer, uint16_t offset,
|
|
uint8_t command);
|
|
|
|
/**
|
|
* sensirion_i2c_add_uint32_t_to_buffer() - Add a uint32_t to the buffer at
|
|
* offset. Adds 6 bytes to the buffer.
|
|
*
|
|
* @param buffer Pointer to buffer in which the write frame will be prepared.
|
|
* Caller needs to make sure that there is enough space after
|
|
* offset left to write the data into the buffer.
|
|
* @param offset Offset of the next free byte in the buffer.
|
|
* @param data uint32_t to be written into the buffer.
|
|
*
|
|
* @return Offset of next free byte in the buffer after writing the data.
|
|
*/
|
|
uint16_t sensirion_i2c_add_uint32_t_to_buffer(uint8_t* buffer, uint16_t offset,
|
|
uint32_t data);
|
|
|
|
/**
|
|
* sensirion_i2c_add_int32_t_to_buffer() - Add a int32_t to the buffer at
|
|
* offset. Adds 6 bytes to the buffer.
|
|
*
|
|
* @param buffer Pointer to buffer in which the write frame will be prepared.
|
|
* Caller needs to make sure that there is enough space after
|
|
* offset left to write the data into the buffer.
|
|
* @param offset Offset of the next free byte in the buffer.
|
|
* @param data int32_t to be written into the buffer.
|
|
*
|
|
* @return Offset of next free byte in the buffer after writing the data.
|
|
*/
|
|
uint16_t sensirion_i2c_add_int32_t_to_buffer(uint8_t* buffer, uint16_t offset,
|
|
int32_t data);
|
|
|
|
/**
|
|
* sensirion_i2c_add_uint16_t_to_buffer() - Add a uint16_t to the buffer at
|
|
* offset. Adds 3 bytes to the buffer.
|
|
*
|
|
* @param buffer Pointer to buffer in which the write frame will be prepared.
|
|
* Caller needs to make sure that there is enough space after
|
|
* offset left to write the data into the buffer.
|
|
* @param offset Offset of the next free byte in the buffer.
|
|
* @param data uint16_t to be written into the buffer.
|
|
*
|
|
* @return Offset of next free byte in the buffer after writing the data.
|
|
*/
|
|
uint16_t sensirion_i2c_add_uint16_t_to_buffer(uint8_t* buffer, uint16_t offset,
|
|
uint16_t data);
|
|
|
|
/**
|
|
* sensirion_i2c_add_int16_t_to_buffer() - Add a int16_t to the buffer at
|
|
* offset. Adds 3 bytes to the buffer.
|
|
*
|
|
* @param buffer Pointer to buffer in which the write frame will be prepared.
|
|
* Caller needs to make sure that there is enough space after
|
|
* offset left to write the data into the buffer.
|
|
* @param offset Offset of the next free byte in the buffer.
|
|
* @param data int16_t to be written into the buffer.
|
|
*
|
|
* @return Offset of next free byte in the buffer after writing the data.
|
|
*/
|
|
uint16_t sensirion_i2c_add_int16_t_to_buffer(uint8_t* buffer, uint16_t offset,
|
|
int16_t data);
|
|
|
|
/**
|
|
* sensirion_i2c_add_float_to_buffer() - Add a float to the buffer at offset.
|
|
* Adds 6 bytes to the buffer.
|
|
*
|
|
* @param buffer Pointer to buffer in which the write frame will be prepared.
|
|
* Caller needs to make sure that there is enough space after
|
|
* offset left to write the data into the buffer.
|
|
* @param offset Offset of the next free byte in the buffer.
|
|
* @param data float to be written into the buffer.
|
|
*
|
|
* @return Offset of next free byte in the buffer after writing the data.
|
|
*/
|
|
uint16_t sensirion_i2c_add_float_to_buffer(uint8_t* buffer, uint16_t offset,
|
|
float data);
|
|
|
|
/**
|
|
* sensirion_i2c_add_bytes_to_buffer() - Add a byte array to the buffer at
|
|
* offset.
|
|
*
|
|
* @param buffer Pointer to buffer in which the write frame will be
|
|
* prepared. Caller needs to make sure that there is
|
|
* enough space after offset left to write the data
|
|
* into the buffer.
|
|
* @param offset Offset of the next free byte in the buffer.
|
|
* @param data Pointer to data to be written into the buffer.
|
|
* @param data_length Number of bytes to be written into the buffer. Needs to
|
|
* be a multiple of SENSIRION_WORD_SIZE otherwise the
|
|
* function returns BYTE_NUM_ERROR.
|
|
*
|
|
* @return Offset of next free byte in the buffer after writing the
|
|
* data.
|
|
*/
|
|
uint16_t sensirion_i2c_add_bytes_to_buffer(uint8_t* buffer, uint16_t offset,
|
|
const uint8_t* data,
|
|
uint16_t data_length);
|
|
|
|
/**
|
|
* sensirion_i2c_write_data() - Writes data to the Sensor.
|
|
*
|
|
* @note This is just a wrapper for sensirion_i2c_hal_write() to
|
|
* not need to include the HAL in the drivers.
|
|
*
|
|
* @param address I2C address to write to.
|
|
* @param data Pointer to the buffer containing the data to write.
|
|
* @param data_length Number of bytes to send to the Sensor.
|
|
*
|
|
* @return NO_ERROR on success, error code otherwise
|
|
*/
|
|
int16_t sensirion_i2c_write_data(uint8_t address, const uint8_t* data,
|
|
uint16_t data_length);
|
|
|
|
/**
|
|
* sensirion_i2c_read_data_inplace() - Reads data from the Sensor.
|
|
*
|
|
* @param address Sensor I2C address
|
|
* @param buffer Allocated buffer to store data as bytes. Needs
|
|
* to be big enough to store the data including
|
|
* CRC. Twice the size of data should always
|
|
* suffice.
|
|
* @param expected_data_length Number of bytes to read (without CRC). Needs
|
|
* to be a multiple of SENSIRION_WORD_SIZE,
|
|
* otherwise the function returns BYTE_NUM_ERROR.
|
|
*
|
|
* @return NO_ERROR on success, an error code otherwise
|
|
*/
|
|
int16_t sensirion_i2c_read_data_inplace(uint8_t address, uint8_t* buffer,
|
|
uint16_t expected_data_length);
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* SENSIRION_I2C_H */
|