From 921fd4234a69e3ca8a8ebf42b55593fdeed93af6 Mon Sep 17 00:00:00 2001 From: kbracher Date: Sat, 29 Jun 2024 17:52:44 +0200 Subject: [PATCH] add support for multiple DS2482 devices --- DS2482_HAL.c | 88 ++++++++++++++++++++++++++++++---------------------- DS2482_HAL.h | 62 ++++++++++++++++++++++++++++-------- README.md | 31 ++++++++++++++---- 3 files changed, 125 insertions(+), 56 deletions(-) diff --git a/DS2482_HAL.c b/DS2482_HAL.c index 9dd98c6..daa4aca 100644 --- a/DS2482_HAL.c +++ b/DS2482_HAL.c @@ -29,17 +29,35 @@ typedef struct { uint8_t DIR : 1; } DS2482_Status; -static I2C_HandleTypeDef* hi2c; +#if MULTIPLE_DEVICES +#define hi2c ds2482->hi2c +#define DS2482_I2C_ADDR ds2482->address +#define DEV_ARG ds2482, +#define DEV_ARG_DEF const ds2482_t *const ds2482, +#define DEV_ARG_ONE ds2482 +#define DEV_ARG_ONE_DEF const ds2482_t* const ds2482 +#else +#define DEV_ARG +#define DEV_ARG_DEF +#define DEV_ARG_ONE +#define DEV_ARG_ONE_DEF +static I2C_HandleTypeDef* hi2c; +#endif + +#if MULTIPLE_DEVICES +HAL_StatusTypeDef ds2482_init(DEV_ARG_ONE_DEF) { +#else HAL_StatusTypeDef ds2482_init(I2C_HandleTypeDef* handle) { hi2c = handle; +#endif - HAL_StatusTypeDef status = ds2482_reset(); + HAL_StatusTypeDef status = ds2482_reset(DEV_ARG_ONE); if (status != HAL_OK) { return status; } - status = ds2482_write_config(DS2482_CONFIG_APU); + status = ds2482_write_config(DEV_ARG DS2482_CONFIG_APU); if (status != HAL_OK) { return status; } @@ -55,22 +73,22 @@ HAL_StatusTypeDef ds2482_init(I2C_HandleTypeDef* handle) { return HAL_OK; } -HAL_StatusTypeDef ds2482_reset() { +HAL_StatusTypeDef ds2482_reset(DEV_ARG_ONE_DEF) { uint8_t data[1] = {DS2482_CMD_RESET}; return HAL_I2C_Master_Transmit(hi2c, DS2482_I2C_ADDR, data, sizeof(data), DS2482_TIMEOUT_I2C); } -HAL_StatusTypeDef ds2482_write_config(uint8_t config) { +HAL_StatusTypeDef ds2482_write_config(DEV_ARG_DEF uint8_t config) { uint8_t data[2] = {DS2482_CMD_WRITE_CONFIG, config | (~config << 4)}; return HAL_I2C_Master_Transmit(hi2c, DS2482_I2C_ADDR, data, sizeof(data), DS2482_TIMEOUT_I2C); } -HAL_StatusTypeDef ds2482_set_read_ptr(uint8_t read_ptr) { +HAL_StatusTypeDef ds2482_set_read_ptr(DEV_ARG_DEF uint8_t read_ptr) { uint8_t data[2] = {DS2482_CMD_SET_READ_PTR, read_ptr}; return HAL_I2C_Master_Transmit(hi2c, DS2482_I2C_ADDR, data, sizeof(data), DS2482_TIMEOUT_I2C); } -HAL_StatusTypeDef ds2482_1w_reset(bool* presence) { +HAL_StatusTypeDef ds2482_1w_reset(DEV_ARG_DEF bool* presence) { uint8_t data[1] = {DS2482_CMD_1W_RESET}; HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hi2c, DS2482_I2C_ADDR, data, sizeof(data), DS2482_TIMEOUT_I2C); if (status != HAL_OK) { @@ -97,7 +115,7 @@ HAL_StatusTypeDef ds2482_1w_reset(bool* presence) { return HAL_OK; } -HAL_StatusTypeDef ds2482_1w_write_byte(uint8_t byte) { +HAL_StatusTypeDef ds2482_1w_write_byte(DEV_ARG_DEF uint8_t byte) { uint8_t data[2] = {DS2482_CMD_1W_WRITE_BYTE, byte}; HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hi2c, DS2482_I2C_ADDR, data, sizeof(data), DS2482_TIMEOUT_I2C); if (status != HAL_OK) { @@ -119,7 +137,7 @@ HAL_StatusTypeDef ds2482_1w_write_byte(uint8_t byte) { return HAL_OK; } -HAL_StatusTypeDef ds2482_1w_read_byte(uint8_t* byte) { +HAL_StatusTypeDef ds2482_1w_read_byte(DEV_ARG_DEF uint8_t* byte) { uint8_t data[1] = {DS2482_CMD_1W_READ_BYTE}; HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hi2c, DS2482_I2C_ADDR, data, sizeof(data), DS2482_TIMEOUT_I2C); if (status != HAL_OK) { @@ -138,7 +156,7 @@ HAL_StatusTypeDef ds2482_1w_read_byte(uint8_t* byte) { } } while (status_reg.BUSY); - status = ds2482_set_read_ptr(DS2482_READ_DATA); + status = ds2482_set_read_ptr(DEV_ARG DS2482_READ_DATA); if (status != HAL_OK) { return status; } @@ -146,12 +164,12 @@ HAL_StatusTypeDef ds2482_1w_read_byte(uint8_t* byte) { return HAL_I2C_Master_Receive(hi2c, DS2482_I2C_ADDR, byte, 1, DS2482_TIMEOUT_I2C); } -HAL_StatusTypeDef ds2482_1w_triplet(uint8_t dir) { +HAL_StatusTypeDef ds2482_1w_triplet(DEV_ARG_DEF uint8_t dir) { uint8_t data[2] = {DS2482_CMD_1W_TRIPLET, dir ? 0xFF : 0x00}; return HAL_I2C_Master_Transmit(hi2c, DS2482_I2C_ADDR, data, sizeof(data), DS2482_TIMEOUT_I2C); } -static HAL_StatusTypeDef ds2482_1w_write_bit(bool bit) { +HAL_StatusTypeDef ds2482_1w_write_bit(DEV_ARG_DEF bool bit) { uint8_t data[2] = {DS2482_CMD_1W_SINGLE_BIT, bit ? 0xFF : 0x00}; HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hi2c, DS2482_I2C_ADDR, data, sizeof(data), DS2482_TIMEOUT_I2C); if (status != HAL_OK) { @@ -173,7 +191,7 @@ static HAL_StatusTypeDef ds2482_1w_write_bit(bool bit) { return HAL_OK; } -static HAL_StatusTypeDef ds2482_1w_read_bit(bool* bit) { +HAL_StatusTypeDef ds2482_1w_read_bit(DEV_ARG_DEF bool* bit) { uint8_t data[2] = {DS2482_CMD_1W_SINGLE_BIT, 0xFF}; HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hi2c, DS2482_I2C_ADDR, data, sizeof(data), DS2482_TIMEOUT_I2C); if (status != HAL_OK) { @@ -250,30 +268,30 @@ static uint8_t crc8; // Return true : device present // false : no device present // -static bool OWReset() { +static bool OWReset(DEV_ARG_ONE_DEF) { bool presence; - (void)ds2482_1w_reset(&presence); + (void)ds2482_1w_reset(DEV_ARG &presence); return presence; } //-------------------------------------------------------------------------- // Send 8 bits of data to the 1-Wire bus // -static inline void OWWriteByte(uint8_t byte_value) { (void)ds2482_1w_write_byte(byte_value); } +static inline void OWWriteByte(DEV_ARG_DEF uint8_t byte_value) { (void)ds2482_1w_write_byte(DEV_ARG byte_value); } //-------------------------------------------------------------------------- // Send 1 bit of data to teh 1-Wire bus // -static inline void OWWriteBit(uint8_t bit_value) { ds2482_1w_write_bit(bit_value); } +static inline void OWWriteBit(DEV_ARG_DEF uint8_t bit_value) { (void)ds2482_1w_write_bit(DEV_ARG bit_value); } //-------------------------------------------------------------------------- // Read 1 bit of data from the 1-Wire bus // Return 1 : bit read is 1 // 0 : bit read is 0 // -static inline uint8_t OWReadBit() { +static inline uint8_t OWReadBit(DEV_ARG_ONE_DEF) { bool bit; - ds2482_1w_read_bit(&bit); + (void)ds2482_1w_read_bit(DEV_ARG &bit); return bit; } @@ -308,7 +326,7 @@ static uint8_t docrc8(uint8_t value) { // Return true : device found, ROM number in ROM_NO buffer // false : device not found, end of search // -static bool OWSearch() { +static bool OWSearch(DEV_ARG_ONE_DEF) { int id_bit_number; int last_zero, rom_byte_number, search_result; int id_bit, cmp_id_bit; @@ -325,7 +343,7 @@ static bool OWSearch() { // if the last call was not the last one if (!LastDeviceFlag) { // 1-Wire reset - if (!OWReset()) { + if (!OWReset(DEV_ARG_ONE)) { // reset the search LastDiscrepancy = 0; LastDeviceFlag = false; @@ -334,13 +352,13 @@ static bool OWSearch() { } // issue the search command - OWWriteByte(0xF0); + OWWriteByte(DEV_ARG 0xF0); // loop to do the search do { // read a bit and its complement - id_bit = OWReadBit(); - cmp_id_bit = OWReadBit(); + id_bit = OWReadBit(DEV_ARG_ONE); + cmp_id_bit = OWReadBit(DEV_ARG_ONE); // check for no devices on 1-wire if ((id_bit == 1) && (cmp_id_bit == 1)) @@ -376,7 +394,7 @@ static bool OWSearch() { ROM_NO[rom_byte_number] &= ~rom_byte_mask; // serial number search direction write bit - OWWriteBit(search_direction); + OWWriteBit(DEV_ARG search_direction); // increment the byte counter id_bit_number // and shift the mask rom_byte_mask @@ -421,13 +439,13 @@ static bool OWSearch() { // Return true : device found, ROM number in ROM_NO buffer // false : no device present // -static bool OWFirst() { +static bool OWFirst(DEV_ARG_ONE_DEF) { // reset the search state LastDiscrepancy = 0; LastDeviceFlag = false; LastFamilyDiscrepancy = 0; - return OWSearch(); + return OWSearch(DEV_ARG_ONE); } //-------------------------------------------------------------------------- @@ -435,14 +453,10 @@ static bool OWFirst() { // Return true : device found, ROM number in ROM_NO buffer // false : device not found, end of search // -static inline bool OWNext() { - // leave the search state alone - return OWSearch(); -} - +static inline bool OWNext(DEV_ARG_ONE_DEF) { return OWSearch(DEV_ARG_ONE); } // Verify the device with the ROM number in ROM_NO buffer is present. -HAL_StatusTypeDef ds2482_1w_verify_device(uint64_t device, bool* present) { +HAL_StatusTypeDef ds2482_1w_verify_device(DEV_ARG_DEF uint64_t device, bool* present) { uint8_t rom_backup[8]; int i, rslt; @@ -455,7 +469,7 @@ HAL_StatusTypeDef ds2482_1w_verify_device(uint64_t device, bool* present) { LastDiscrepancy = 64; LastDeviceFlag = false; - if (OWSearch()) { + if (OWSearch(DEV_ARG_ONE)) { // check if same device found rslt = true; for (i = 0; i < 8; i++) { @@ -473,8 +487,8 @@ HAL_StatusTypeDef ds2482_1w_verify_device(uint64_t device, bool* present) { -HAL_StatusTypeDef ds2482_1w_search(uint16_t max_devices, uint64_t devices[static max_devices]) { - OWFirst(); +HAL_StatusTypeDef ds2482_1w_search(DEV_ARG_DEF uint16_t max_devices, uint64_t devices[static max_devices]) { + OWFirst(DEV_ARG_ONE); uint16_t count = 0; do { uint64_t device = 0; @@ -482,7 +496,7 @@ HAL_StatusTypeDef ds2482_1w_search(uint16_t max_devices, uint64_t devices[static device |= (uint64_t)ROM_NO[i] << (i * 8); } devices[count++] = device; - } while (OWNext() && count < max_devices); + } while (OWNext(DEV_ARG_ONE) && count < max_devices); return HAL_OK; } diff --git a/DS2482_HAL.h b/DS2482_HAL.h index 52eaa5a..75d8d10 100644 --- a/DS2482_HAL.h +++ b/DS2482_HAL.h @@ -1,5 +1,6 @@ #pragma once +#include #ifndef DS2482_HAL_H #define DS2482_HAL_H @@ -13,24 +14,59 @@ #error "No target defined" #endif -#define DS2482_I2C_ADDR 0x30 // TODO: change to actual address -#define DS2482_TIMEOUT_1W 100 -#define DS2482_TIMEOUT_I2C 100 +#define MULTIPLE_DEVICES false //set to true if multiple DS2482 devices are connected + +#if !MULTIPLE_DEVICES + #define DS2482_I2C_ADDR 0x00 //set to I2C address of the DS2482 device (if in single device mode) +#endif +#define DS2482_TIMEOUT_1W 100 //timeout in ms for 1-wire operations +#define DS2482_TIMEOUT_I2C 100 //timeout in ms for I2C operations +#if !MULTIPLE_DEVICES + static_assert(DS2482_I2C_ADDR != 0x00, "DS2482_I2C_ADDR must be set in single device mode!"); +#endif + +static_assert (DS2482_TIMEOUT_1W < UINT16_MAX, "DS2482_TIMEOUT_1W must be less than 65535"); +static_assert (DS2482_TIMEOUT_I2C < UINT32_MAX, "DS2482_TIMEOUT_I2C must be less than 4294967295"); +static_assert (DS2482_TIMEOUT_1W > 0, "DS2482_TIMEOUT_1W cannot be negative"); +static_assert (DS2482_TIMEOUT_I2C > 0, "DS2482_TIMEOUT_I2C cannot be negative"); + #define nag_attr [[nodiscard("Check status for errors!")]] -nag_attr HAL_StatusTypeDef ds2482_init(I2C_HandleTypeDef* handle); -nag_attr HAL_StatusTypeDef ds2482_reset(); -nag_attr HAL_StatusTypeDef ds2482_write_config(uint8_t config); -nag_attr HAL_StatusTypeDef ds2482_set_read_ptr(uint8_t read_ptr); -nag_attr HAL_StatusTypeDef ds2482_1w_reset(bool* presence); -nag_attr HAL_StatusTypeDef ds2482_1w_write_byte(uint8_t byte); -nag_attr HAL_StatusTypeDef ds2482_1w_read_byte(uint8_t* byte); -nag_attr HAL_StatusTypeDef ds2482_1w_triplet(uint8_t dir); +#if MULTIPLE_DEVICES + typedef struct { + I2C_HandleTypeDef* hi2c; + uint16_t address; + } ds2482_t; -nag_attr HAL_StatusTypeDef ds2482_1w_search(uint16_t max_devices, uint64_t devices[static max_devices]); -nag_attr HAL_StatusTypeDef ds2482_1w_verify_device(uint64_t device, bool* present); + static inline ds2482_t ds2482_create(I2C_HandleTypeDef* hi2c, uint16_t address) { + return (ds2482_t){.hi2c = hi2c, .address = address}; + } + + #define DEV_ARG const ds2482_t * const ds2482, + nag_attr HAL_StatusTypeDef ds2482_init(const ds2482_t * const ds2482); + nag_attr HAL_StatusTypeDef ds2482_reset(const ds2482_t * const ds2482); +#else + nag_attr HAL_StatusTypeDef ds2482_init(I2C_HandleTypeDef* hi2c); + nag_attr HAL_StatusTypeDef ds2482_reset(); + #define DEV_ARG +#endif + +nag_attr HAL_StatusTypeDef ds2482_write_config(DEV_ARG uint8_t config); +nag_attr HAL_StatusTypeDef ds2482_set_read_ptr(DEV_ARG uint8_t read_ptr); +nag_attr HAL_StatusTypeDef ds2482_1w_reset(DEV_ARG bool* presence); +nag_attr HAL_StatusTypeDef ds2482_1w_write_byte(DEV_ARG uint8_t byte); +nag_attr HAL_StatusTypeDef ds2482_1w_read_byte(DEV_ARG uint8_t* byte); +nag_attr HAL_StatusTypeDef ds2482_1w_read_bit(DEV_ARG bool* bit); +nag_attr HAL_StatusTypeDef ds2482_1w_write_bit(DEV_ARG bool bit); +nag_attr HAL_StatusTypeDef ds2482_1w_triplet(DEV_ARG uint8_t dir); + +nag_attr HAL_StatusTypeDef ds2482_1w_search(DEV_ARG uint16_t max_devices, uint64_t devices[static max_devices]); +nag_attr HAL_StatusTypeDef ds2482_1w_verify_device(DEV_ARG uint64_t device, bool* present); + +#undef nag_attr +#undef DEV_ARG #endif // DS2482_HAL_H \ No newline at end of file diff --git a/README.md b/README.md index d4685cd..8fec44c 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ A DS2482-100 HAL for the STM32F3/F4/H7 series ## Usage -Be sure to have the target chip defined: +Define the target chip, and set the compiler to C23+: -`gcc [...] -DSTM32[F3/F4/H7]` +`gcc [...] --std=gnu2x -DSTM32[F3/F4/H7]` or ```yaml @@ -15,18 +15,37 @@ or cDefinitions: - STM32[F3/F4/H7] - USE_HAL_DRIVER + +# ... + +# Compiler flags +cFlags: + - --std=gnu2x ``` Then, configure the HAL: ```c // (in DS2482_HAL.h) -#define DS2482_I2C_ADDR 0x30 //change to desired values -#define DS2482_TIMEOUT_1W 100 //how long we wait for 1-Wire operations to complete -#define DS2482_TIMEOUT_I2C 100 +#define MULTIPLE_DEVICES false //set to true if multiple DS2482 devices are connected + +#if !MULTIPLE_DEVICES + #define DS2482_I2C_ADDR 0x00 //set to I2C address of the DS2482 device (if in single device mode) +#endif +#define DS2482_TIMEOUT_1W 100 //timeout in ms for 1-wire operations +#define DS2482_TIMEOUT_I2C 100 //timeout in ms for I2C operations ``` -Call `ds2482_init()` with the I2C handle, and the HAL is ready. +For multiple DS2482 devices on one chip: + - Set `MULTIPLE_DEVICES` to `true` + - Call `ds2482_create()` with the I2C handle and address + - Call `ds2482_init()` with the handle + - The HAL is ready + +For just one DS2482: + - Set `DS2482_I2C_ADDR` to the I2C address + - Call `ds2482_init()` with the I2C handle + - The HAL is ready Be sure to check the return values for error handling.