-
Notifications
You must be signed in to change notification settings - Fork 0
Add new adapter layer #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: sensirion-common
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| # Copyright (c) 2025 Sensirion | ||
| # Copyright (c) 2026 Sensirion | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| /* | ||
| * Copyright (c) 2025 Sensirion | ||
| * Copyright (c) 2026 Sensirion | ||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
@@ -29,11 +29,11 @@ extern "C" { | |
| * conversions from byte arrays to basic data types. | ||
| * Since Zephyr does not provide a function for converting big-endian | ||
| * (MSB-first) byte arrays to floating-point values, the function | ||
| * sensirion_common_bytes_to_float() is | ||
| * sensirion_conversions_bytes_to_float() is | ||
| * provided for this purpose. | ||
| * To maintain a consistent naming scheme for all functions that convert byte | ||
| * arrays to basic types, the functions | ||
| * sensirion_common_bytes_to_<integer>() are also provided, | ||
| * sensirion_conversions_bytes_to_<integer>() are also provided, | ||
| * even in cases where Zephyr already provides equivalent functions for | ||
| * specific integer | ||
| * types. | ||
|
|
@@ -49,14 +49,14 @@ extern "C" { | |
| * @param bytes An array of at least four bytes (MSB first) | ||
| * @return The byte array represented as float | ||
| */ | ||
| float sensirion_common_bytes_to_float(const uint8_t *bytes); | ||
| float sensirion_conversions_bytes_to_float(const uint8_t *bytes); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could also be const uint8_t const* |
||
|
|
||
| #define sensirion_common_bytes_to_int16_t(bytes) ((int16_t)sys_get_be16(bytes)) | ||
| #define sensirion_common_bytes_to_uint16_t(bytes) ((uint16_t)sys_get_be16(bytes)) | ||
| #define sensirion_common_bytes_to_int32_t(bytes) ((int32_t)sys_get_be32(bytes)) | ||
| #define sensirion_common_bytes_to_uint32_t(bytes) ((uint32_t)sys_get_be32(bytes)) | ||
| #define sensirion_common_bytes_to_int64_t(bytes) ((int64_t)sys_get_be64(bytes)) | ||
| #define sensirion_common_bytes_to_uint64_t(bytes) ((uint64_t)sys_get_be64(bytes)) | ||
| #define sensirion_conversions_bytes_to_int16_t(bytes) ((int16_t)sys_get_be16(bytes)) | ||
| #define sensirion_conversions_bytes_to_uint16_t(bytes) ((uint16_t)sys_get_be16(bytes)) | ||
| #define sensirion_conversions_bytes_to_int32_t(bytes) ((int32_t)sys_get_be32(bytes)) | ||
| #define sensirion_conversions_bytes_to_uint32_t(bytes) ((uint32_t)sys_get_be32(bytes)) | ||
| #define sensirion_conversions_bytes_to_int64_t(bytes) ((int64_t)sys_get_be64(bytes)) | ||
| #define sensirion_conversions_bytes_to_uint64_t(bytes) ((uint64_t)sys_get_be64(bytes)) | ||
|
|
||
| /** @} */ | ||
|
|
||
|
|
@@ -77,8 +77,8 @@ float sensirion_common_bytes_to_float(const uint8_t *bytes); | |
| * @param destination_size Size of the destination integer in bytes. | ||
| * @param data_length Number of available bytes in source to copy. | ||
| */ | ||
| void sensirion_common_to_integer(const uint8_t *source, uint8_t *destination, | ||
| size_t destination_size, uint8_t data_length); | ||
| void sensirion_conversions_to_integer(const uint8_t *source, uint8_t *destination, | ||
| size_t destination_size, uint8_t data_length); | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| /* | ||
| * Copyright (c) 2025 Sensirion | ||
| * Copyright (c) 2026 Sensirion | ||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
@@ -10,140 +10,160 @@ | |
| #include <zephyr/drivers/i2c.h> | ||
| #include <zephyr/sys/crc.h> | ||
|
|
||
| #define SENSIRION_WORD_SIZE 2u | ||
| #define SENSIRION_CRC8_LEN 1u | ||
|
|
||
| #define SENSIRION_WORD_SIZE 2 | ||
| #define SENSIRION_CRC8_LEN 1 | ||
|
|
||
|
|
||
| uint8_t sensirion_i2c_packet_get_crc(const i2c_packet *packet, uint16_t index) | ||
| uint8_t sensirion_i2c_packet_get_crc(const i2c_packet_t *i2c_packet, uint16_t index) | ||
| { | ||
| return crc8(&packet->data[index], SENSIRION_WORD_SIZE, | ||
| packet->crc8_poly, packet->crc8_init, false); | ||
| return crc8(&i2c_packet->data[index], SENSIRION_WORD_SIZE, i2c_packet->crc8_poly, | ||
| i2c_packet->crc8_init, false); | ||
| } | ||
|
|
||
| bool sensirion_i2c_packet_check_crc(const i2c_packet *packet, uint16_t index) | ||
| bool sensirion_i2c_packet_check_crc(const i2c_packet_t *i2c_packet, uint16_t index) | ||
| { | ||
| if (sensirion_i2c_packet_get_crc(packet, index) != packet->data[index + SENSIRION_WORD_SIZE]) { | ||
| if (sensirion_i2c_packet_get_crc(i2c_packet, index) != | ||
| i2c_packet->data[index + SENSIRION_WORD_SIZE]) { | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
|
|
||
|
|
||
| uint16_t sensirion_i2c_packet_add_command16(i2c_packet *packet, uint16_t offset, uint16_t command) | ||
| uint16_t sensirion_i2c_packet_add_command16(i2c_packet_t *i2c_packet, uint16_t offset, | ||
| uint16_t command) | ||
| { | ||
| sys_put_be16(command, &packet->data[offset]); | ||
| sys_put_be16(command, &i2c_packet->data[offset]); | ||
| offset += 2; | ||
| return offset; | ||
| } | ||
|
|
||
| uint16_t sensirion_i2c_packet_add_command8(i2c_packet *packet, uint16_t offset, uint8_t command) | ||
| uint16_t sensirion_i2c_packet_add_command8(i2c_packet_t *i2c_packet, uint16_t offset, | ||
| uint8_t command) | ||
| { | ||
| packet->data[offset++] = command; | ||
| i2c_packet->data[offset++] = command; | ||
| return offset; | ||
| } | ||
|
|
||
| uint16_t sensirion_i2c_packet_add_uint64_t(i2c_packet *packet, uint16_t offset, uint64_t data) | ||
| uint16_t sensirion_i2c_packet_add_uint64_t(i2c_packet_t *i2c_packet, uint16_t offset, uint64_t data) | ||
| { | ||
| offset = sensirion_i2c_packet_add_uint32_t(packet, offset, data >> 32); | ||
| offset = sensirion_i2c_packet_add_uint32_t(packet, offset, data & 0xFFFFFFFF); | ||
| offset = sensirion_i2c_packet_add_uint32_t(i2c_packet, offset, data >> 32u); | ||
| offset = sensirion_i2c_packet_add_uint32_t(i2c_packet, offset, data & 0xFFFFFFFFu); | ||
| return offset; | ||
| } | ||
|
|
||
| uint16_t sensirion_i2c_packet_add_int64_t(i2c_packet *packet, uint16_t offset, int64_t data) | ||
| uint16_t sensirion_i2c_packet_add_int64_t(i2c_packet_t *i2c_packet, uint16_t offset, int64_t data) | ||
| { | ||
| return sensirion_i2c_packet_add_uint64_t(packet, offset, (uint64_t)data); | ||
| return sensirion_i2c_packet_add_uint64_t(i2c_packet, offset, (uint64_t)data); | ||
| } | ||
|
|
||
| uint16_t sensirion_i2c_packet_add_uint32_t(i2c_packet *packet, uint16_t offset, uint32_t data) | ||
| uint16_t sensirion_i2c_packet_add_uint32_t(i2c_packet_t *i2c_packet, uint16_t offset, uint32_t data) | ||
| { | ||
| offset = sensirion_i2c_packet_add_uint16_t(packet, offset, data >> 16); | ||
| offset = sensirion_i2c_packet_add_uint16_t(packet, offset, data & 0xFFFF); | ||
| offset = sensirion_i2c_packet_add_uint16_t(i2c_packet, offset, data >> 16u); | ||
| offset = sensirion_i2c_packet_add_uint16_t(i2c_packet, offset, data & 0xFFFFu); | ||
|
|
||
| return offset; | ||
| } | ||
|
|
||
| uint16_t sensirion_i2c_packet_add_int32_t(i2c_packet *packet, uint16_t offset, int32_t data) | ||
| uint16_t sensirion_i2c_packet_add_int32_t(i2c_packet_t *i2c_packet, uint16_t offset, int32_t data) | ||
| { | ||
| return sensirion_i2c_packet_add_uint32_t(packet, offset, (uint32_t)data); | ||
| return sensirion_i2c_packet_add_uint32_t(i2c_packet, offset, (uint32_t)data); | ||
| } | ||
|
|
||
| uint16_t sensirion_i2c_packet_add_uint16_t(i2c_packet *packet, uint16_t offset, uint16_t data) | ||
| uint16_t sensirion_i2c_packet_add_uint16_t(i2c_packet_t *i2c_packet, uint16_t offset, uint16_t data) | ||
| { | ||
| sys_put_be16(data, &packet->data[offset]); | ||
| sys_put_be16(data, &i2c_packet->data[offset]); | ||
| offset += 2; | ||
| if (packet->crc8_poly != 0) { | ||
| packet->data[offset] = sensirion_i2c_packet_get_crc(packet, offset - SENSIRION_WORD_SIZE); | ||
| if (i2c_packet->crc8_poly != 0) { | ||
| i2c_packet->data[offset] = | ||
| sensirion_i2c_packet_get_crc(i2c_packet, offset - SENSIRION_WORD_SIZE); | ||
| offset++; | ||
| } | ||
| return offset; | ||
| } | ||
|
|
||
| uint16_t sensirion_i2c_packet_add_int16_t(i2c_packet *packet, uint16_t offset, int16_t data) | ||
| uint16_t sensirion_i2c_packet_add_int16_t(i2c_packet_t *i2c_packet, uint16_t offset, int16_t data) | ||
| { | ||
| return sensirion_i2c_packet_add_uint16_t(packet, offset, (uint16_t)data); | ||
| return sensirion_i2c_packet_add_uint16_t(i2c_packet, offset, (uint16_t)data); | ||
| } | ||
|
|
||
| uint16_t sensirion_i2c_packet_add_float(i2c_packet *packet, uint16_t offset, float data) | ||
| uint16_t sensirion_i2c_packet_add_float(i2c_packet_t *i2c_packet, uint16_t offset, float data) | ||
| { | ||
| union { | ||
| uint32_t uint32_data; | ||
| float float_data; | ||
| } convert; | ||
|
|
||
| convert.float_data = data; | ||
| return sensirion_i2c_packet_add_uint32_t(packet, offset, convert.uint32_data); | ||
| return sensirion_i2c_packet_add_uint32_t(i2c_packet, offset, convert.uint32_data); | ||
| } | ||
|
|
||
| uint16_t sensirion_i2c_packet_add_bytes(i2c_packet *packet, uint16_t offset, const uint8_t *data, | ||
| uint16_t data_length) | ||
| uint16_t sensirion_i2c_packet_add_bytes(i2c_packet_t *i2c_packet, uint16_t offset, | ||
| const uint8_t *data, uint16_t data_length) | ||
| { | ||
| uint16_t i; | ||
|
|
||
| if (data_length % SENSIRION_WORD_SIZE != 0) { | ||
| if (data_length % SENSIRION_WORD_SIZE != 0u) { | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| for (i = 0; i < data_length; i += 2) { | ||
| packet->data[offset++] = data[i]; | ||
| packet->data[offset++] = data[i + 1]; | ||
| if (packet->crc8_poly != 0) { | ||
| packet->data[offset] = sensirion_i2c_packet_get_crc(packet, offset - SENSIRION_WORD_SIZE); | ||
| for (i = 0; i < data_length; i += 2u) { | ||
| i2c_packet->data[offset++] = data[i]; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how about of doing a memcpy? |
||
| i2c_packet->data[offset++] = data[i + 1u]; | ||
| if (i2c_packet->crc8_poly != 0u) { | ||
| i2c_packet->data[offset] = sensirion_i2c_packet_get_crc( | ||
| i2c_packet, offset - SENSIRION_WORD_SIZE); | ||
| offset++; | ||
| } | ||
| } | ||
| return offset; | ||
| } | ||
|
|
||
| int sensirion_i2c_packet_write(const struct i2c_dt_spec *i2c_spec, const i2c_packet_t *i2c_packet, | ||
| uint16_t data_length) | ||
| { | ||
| uint8_t has_8bit_command = (float)(data_length / 2.0f) != 0.0f; | ||
| uint16_t num_words = (data_length + has_8bit_command) / SENSIRION_WORD_SIZE; | ||
| uint8_t tx_buffer[SENSIRION_WORD_SIZE * num_words + SENSIRION_CRC8_LEN * num_words]; | ||
|
|
||
| /*skips the first word (command) because the command does not have a CRC*/ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we consistently use the i2c_packet_add_ there is no need to add a crc again. I also think the i2c_packet* should be the first arguement and the i2c_spec the last one! |
||
| for (uint16_t i = 1; i < num_words; i++) { | ||
| tx_buffer[i * (SENSIRION_WORD_SIZE + SENSIRION_CRC8_LEN)] = | ||
| i2c_packet->data[i * SENSIRION_WORD_SIZE]; | ||
| tx_buffer[i * (SENSIRION_WORD_SIZE + SENSIRION_CRC8_LEN) + 1] = | ||
| i2c_packet->data[i * SENSIRION_WORD_SIZE + 1]; | ||
| tx_buffer[i * (SENSIRION_WORD_SIZE + SENSIRION_CRC8_LEN) + 2] = | ||
| sensirion_i2c_packet_get_crc(i2c_packet, i * SENSIRION_WORD_SIZE); | ||
| } | ||
|
|
||
| return i2c_write_dt(i2c_spec, tx_buffer, sizeof(tx_buffer)); | ||
| } | ||
|
|
||
| int sensirion_i2c_packet_read(const struct i2c_dt_spec *i2c_spec, i2c_packet *packet, | ||
| uint16_t expected_data_length) | ||
| int sensirion_i2c_packet_read(const struct i2c_dt_spec *i2c_spec, i2c_packet_t *i2c_packet, | ||
| uint16_t expected_data_length) | ||
| { | ||
| int ret; | ||
| uint16_t i, j; | ||
| uint16_t crc_len = (packet->crc8_poly != 0) ? SENSIRION_CRC8_LEN : 0; | ||
| uint16_t size = (expected_data_length / SENSIRION_WORD_SIZE) * | ||
| (SENSIRION_WORD_SIZE + crc_len); | ||
| uint16_t crc_len = (i2c_packet->crc8_poly != 0) ? SENSIRION_CRC8_LEN : 0; | ||
| uint16_t size = | ||
| (expected_data_length / SENSIRION_WORD_SIZE) * (SENSIRION_WORD_SIZE + crc_len); | ||
|
|
||
| if (expected_data_length % SENSIRION_WORD_SIZE != 0) { | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| ret = i2c_read_dt(i2c_spec, packet->data, size); | ||
| ret = i2c_read_dt(i2c_spec, i2c_packet->data, size); | ||
| if (ret != 0) { | ||
| return ret; | ||
| } | ||
|
|
||
| for (i = 0, j = 0; i < size; i += SENSIRION_WORD_SIZE + crc_len) { | ||
|
|
||
| if (packet->crc8_poly != 0) { | ||
| if (!sensirion_i2c_packet_check_crc(packet, i)) { | ||
| if (i2c_packet->crc8_poly != 0) { | ||
| if (!sensirion_i2c_packet_check_crc(i2c_packet, i)) { | ||
| return -EIO; | ||
| } | ||
| } | ||
| packet->data[j++] = packet->data[i]; | ||
| packet->data[j++] = packet->data[i + 1]; | ||
| i2c_packet->data[j++] = i2c_packet->data[i]; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also here we may use a memcpy |
||
| i2c_packet->data[j++] = i2c_packet->data[i + 1]; | ||
| } | ||
|
|
||
| return 0; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we have to consider the byte order of the host. In case the host has the same byte order (BE) this code is wrong.
I'm aware that his is also the case for the code we have in sensirion_common :-(