forked from espressif/esp-bsp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request espressif#141 from espressif2022/feature/add_io_ex…
…pander_ht8574 io_expander: Added io_expander of HT8574. (BSP-280)
- Loading branch information
Showing
7 changed files
with
456 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
idf_component_register(SRCS "esp_io_expander_ht8574.c" INCLUDE_DIRS "include" REQUIRES "driver") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# ESP IO Expander Chip HT8574 | ||
|
||
Implementation of the HT8574 io expander chip with esp_io_expander component. | ||
|
||
| Chip | Communication interface | Component name | Link to datasheet | | ||
| :--------------: | :---------------------: | :------------: | :---------------: | | ||
| HT8574 | I2C | esp_io_expander_ht8574 | [datasheet](https://datasheet.lcsc.com/lcsc/2109081930_HTCSEMI-HT8574ARTZ_C2895056.pdf) | | ||
|
||
## Add to project | ||
|
||
Packages from this repository are uploaded to [Espressif's component service](https://components.espressif.com/). | ||
You can add them to your project via `idf.py add-dependency`, e.g. | ||
``` | ||
idf.py add-dependency esp_io_expander_ht8574==1.0.0 | ||
``` | ||
|
||
Alternatively, you can create `idf_component.yml`. More is in [Espressif's documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html). | ||
|
||
## Example use | ||
|
||
Creation of the component. | ||
|
||
``` | ||
esp_io_expander_handle_t io_expander = NULL; | ||
esp_io_expander_new_i2c_ht8574(1, ESP_IO_EXPANDER_I2C_HT8574_ADDRESS_000, &io_expander); | ||
``` | ||
|
||
Set pin 0 and pin 1 with output dircetion and low level: | ||
|
||
``` | ||
esp_io_expander_set_dir(io_expander, IO_EXPANDER_PIN_NUM_0 | IO_EXPANDER_PIN_NUM_1, IO_EXPANDER_OUTPUT); | ||
esp_io_expander_set_level(io_expander, IO_EXPANDER_PIN_NUM_0 | IO_EXPANDER_PIN_NUM_1, 0); | ||
``` | ||
|
||
Print all pins's status to the log: | ||
|
||
``` | ||
esp_io_expander_print_state(io_expander); | ||
``` |
146 changes: 146 additions & 0 deletions
146
components/io_expander/esp_io_expander_ht8574/esp_io_expander_ht8574.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <inttypes.h> | ||
#include <string.h> | ||
#include <stdlib.h> | ||
|
||
#include "driver/i2c.h" | ||
#include "esp_bit_defs.h" | ||
#include "esp_check.h" | ||
#include "esp_log.h" | ||
|
||
#include "esp_io_expander.h" | ||
#include "esp_io_expander_ht8574.h" | ||
|
||
/* Timeout of each I2C communication */ | ||
#define I2C_TIMEOUT_MS (10) | ||
|
||
#define IO_COUNT (8) | ||
|
||
/* Default register value on power-up */ | ||
#define DIR_REG_DEFAULT_VAL (0xff) | ||
#define OUT_REG_DEFAULT_VAL (0xff) | ||
|
||
/** | ||
* @brief Device Structure Type | ||
* | ||
*/ | ||
typedef struct { | ||
esp_io_expander_t base; | ||
i2c_port_t i2c_num; | ||
uint32_t i2c_address; | ||
struct { | ||
uint8_t direction; | ||
uint8_t output; | ||
} regs; | ||
} esp_io_expander_ht8574_t; | ||
|
||
static char *TAG = "ht8574"; | ||
|
||
static esp_err_t read_input_reg(esp_io_expander_handle_t handle, uint32_t *value); | ||
static esp_err_t write_output_reg(esp_io_expander_handle_t handle, uint32_t value); | ||
static esp_err_t read_output_reg(esp_io_expander_handle_t handle, uint32_t *value); | ||
static esp_err_t write_direction_reg(esp_io_expander_handle_t handle, uint32_t value); | ||
static esp_err_t read_direction_reg(esp_io_expander_handle_t handle, uint32_t *value); | ||
static esp_err_t reset(esp_io_expander_t *handle); | ||
static esp_err_t del(esp_io_expander_t *handle); | ||
|
||
esp_err_t esp_io_expander_new_i2c_ht8574(i2c_port_t i2c_num, uint32_t i2c_address, esp_io_expander_handle_t *handle) | ||
{ | ||
ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX, ESP_ERR_INVALID_ARG, TAG, "Invalid i2c num"); | ||
ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "Invalid handle"); | ||
|
||
esp_io_expander_ht8574_t *ht8574 = (esp_io_expander_ht8574_t *)calloc(1, sizeof(esp_io_expander_ht8574_t)); | ||
ESP_RETURN_ON_FALSE(ht8574, ESP_ERR_NO_MEM, TAG, "Malloc failed"); | ||
|
||
ht8574->base.config.io_count = IO_COUNT; | ||
ht8574->base.config.flags.dir_out_bit_zero = 1; | ||
ht8574->i2c_num = i2c_num; | ||
ht8574->i2c_address = i2c_address; | ||
ht8574->base.read_input_reg = read_input_reg; | ||
ht8574->base.write_output_reg = write_output_reg; | ||
ht8574->base.read_output_reg = read_output_reg; | ||
ht8574->base.write_direction_reg = write_direction_reg; | ||
ht8574->base.read_direction_reg = read_direction_reg; | ||
ht8574->base.del = del; | ||
ht8574->base.reset = reset; | ||
|
||
esp_err_t ret = ESP_OK; | ||
/* Reset configuration and register status */ | ||
ESP_GOTO_ON_ERROR(reset(&ht8574->base), err, TAG, "Reset failed"); | ||
|
||
*handle = &ht8574->base; | ||
return ESP_OK; | ||
err: | ||
free(ht8574); | ||
return ret; | ||
} | ||
|
||
static esp_err_t read_input_reg(esp_io_expander_handle_t handle, uint32_t *value) | ||
{ | ||
esp_io_expander_ht8574_t *ht8574 = (esp_io_expander_ht8574_t *)__containerof(handle, esp_io_expander_ht8574_t, base); | ||
|
||
uint8_t temp = 0; | ||
// *INDENT-OFF* | ||
ESP_RETURN_ON_ERROR( | ||
i2c_master_read_from_device(ht8574->i2c_num, ht8574->i2c_address, &temp, 1, pdMS_TO_TICKS(I2C_TIMEOUT_MS)), | ||
TAG, "Read input reg failed"); | ||
// *INDENT-ON* | ||
*value = temp; | ||
return ESP_OK; | ||
} | ||
|
||
static esp_err_t write_output_reg(esp_io_expander_handle_t handle, uint32_t value) | ||
{ | ||
esp_io_expander_ht8574_t *ht8574 = (esp_io_expander_ht8574_t *)__containerof(handle, esp_io_expander_ht8574_t, base); | ||
value &= 0xff; | ||
|
||
uint8_t data = (uint8_t)value; | ||
ESP_RETURN_ON_ERROR( | ||
i2c_master_write_to_device(ht8574->i2c_num, ht8574->i2c_address, &data, 1, pdMS_TO_TICKS(I2C_TIMEOUT_MS)), | ||
TAG, "Write output reg failed"); | ||
ht8574->regs.output = value; | ||
return ESP_OK; | ||
} | ||
|
||
static esp_err_t read_output_reg(esp_io_expander_handle_t handle, uint32_t *value) | ||
{ | ||
esp_io_expander_ht8574_t *ht8574 = (esp_io_expander_ht8574_t *)__containerof(handle, esp_io_expander_ht8574_t, base); | ||
|
||
*value = ht8574->regs.output; | ||
return ESP_OK; | ||
} | ||
|
||
static esp_err_t write_direction_reg(esp_io_expander_handle_t handle, uint32_t value) | ||
{ | ||
esp_io_expander_ht8574_t *ht8574 = (esp_io_expander_ht8574_t *)__containerof(handle, esp_io_expander_ht8574_t, base); | ||
value &= 0xff; | ||
ht8574->regs.direction = value; | ||
return ESP_OK; | ||
} | ||
|
||
static esp_err_t read_direction_reg(esp_io_expander_handle_t handle, uint32_t *value) | ||
{ | ||
esp_io_expander_ht8574_t *ht8574 = (esp_io_expander_ht8574_t *)__containerof(handle, esp_io_expander_ht8574_t, base); | ||
|
||
*value = ht8574->regs.direction; | ||
return ESP_OK; | ||
} | ||
|
||
static esp_err_t reset(esp_io_expander_t *handle) | ||
{ | ||
ESP_RETURN_ON_ERROR(write_output_reg(handle, OUT_REG_DEFAULT_VAL), TAG, "Write output reg failed"); | ||
return ESP_OK; | ||
} | ||
|
||
static esp_err_t del(esp_io_expander_t *handle) | ||
{ | ||
esp_io_expander_ht8574_t *ht8574 = (esp_io_expander_ht8574_t *)__containerof(handle, esp_io_expander_ht8574_t, base); | ||
|
||
free(ht8574); | ||
return ESP_OK; | ||
} |
7 changes: 7 additions & 0 deletions
7
components/io_expander/esp_io_expander_ht8574/idf_component.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
dependencies: | ||
esp_io_expander: | ||
version: ^1.0.1 | ||
idf: '>=4.4.2' | ||
description: ESP IO Expander - HT8574 | ||
url: https://github.com/espressif/esp-bsp/tree/master/components/io_expander/esp_io_expander_ht8574 | ||
version: 1.0.0 |
60 changes: 60 additions & 0 deletions
60
components/io_expander/esp_io_expander_ht8574/include/esp_io_expander_ht8574.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <stdint.h> | ||
|
||
#include "driver/i2c.h" | ||
#include "esp_err.h" | ||
|
||
#include "esp_io_expander.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @brief Create a new ht8574 IO expander driver | ||
* | ||
* @note The I2C communication should be initialized before use this function | ||
* | ||
* @param i2c_num: I2C port num | ||
* @param i2c_address: I2C address of chip | ||
* @param handle: IO expander handle | ||
* | ||
* @return | ||
* - ESP_OK: Success, otherwise returns ESP_ERR_xxx | ||
*/ | ||
esp_err_t esp_io_expander_new_i2c_ht8574(i2c_port_t i2c_num, uint32_t i2c_address, esp_io_expander_handle_t *handle); | ||
|
||
/** | ||
* @brief I2C address of the ht8574 | ||
* | ||
* The 8-bit address format is as follows: | ||
* | ||
* (Slave Address) | ||
* ┌─────────────────┷─────────────────┐ | ||
* ┌─────┐─────┐─────┐─────┐─────┐─────┐─────┐─────┐ | ||
* | 0 | 1 | 1 | 1 | A2 | A1 | A0 | R/W | | ||
* └─────┘─────┘─────┘─────┘─────┘─────┘─────┘─────┘ | ||
* └────────┯────────┘ └─────┯──────┘ | ||
* (Fixed) (Hareware Selectable) | ||
* | ||
* And the 7-bit slave address is the most important data for users. | ||
* For example, if a chip's A0,A1,A2 are connected to GND, it's 7-bit slave address is 0111000b(0x38). | ||
* Then users can use `ESP_IO_EXPANDER_I2C_HT8574_ADDRESS_000` to init it. | ||
*/ | ||
#define ESP_IO_EXPANDER_I2C_HT8574_ADDRESS_000 (0x38) | ||
#define ESP_IO_EXPANDER_I2C_HT8574_ADDRESS_001 (0x29) | ||
#define ESP_IO_EXPANDER_I2C_HT8574_ADDRESS_010 (0x2A) | ||
#define ESP_IO_EXPANDER_I2C_HT8574_ADDRESS_011 (0x2B) | ||
#define ESP_IO_EXPANDER_I2C_HT8574_ADDRESS_100 (0x2C) | ||
|
||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
Oops, something went wrong.