RCM — ESP32 Room Controller
WT32-ETH01 firmware
Loading...
Searching...
No Matches
pca9535.c
Go to the documentation of this file.
1
9#include "pca9535.h"
10
11#include "driver/i2c_master.h"
12#include "esp_check.h"
13#include "esp_log.h"
14#include "freertos/FreeRTOS.h"
15#include "freertos/task.h"
16
17static const char *TAG = "pca9535";
18
19#define I2C_PORT I2C_NUM_0
20#define I2C_SCL_GPIO 14
21#define I2C_SDA_GPIO 15
22#define I2C_FREQ_HZ 400000
23#define I2C_TIMEOUT_MS 1000
24
25#define PCA9535_I2C_ADDR 0x20
26
27#define PCA9535_REG_INPUT0 0x00
28#define PCA9535_REG_INPUT1 0x01
29#define PCA9535_REG_OUTPUT0 0x02
30#define PCA9535_REG_OUTPUT1 0x03
31#define PCA9535_REG_INVERT0 0x04
32#define PCA9535_REG_INVERT1 0x05
33#define PCA9535_REG_CONFIG0 0x06
34#define PCA9535_REG_CONFIG1 0x07
35
37#define LED_P03_BIT (1U << 3)
38#define LED_P04_BIT (1U << 4)
39#define LED_MASK (LED_P03_BIT | LED_P04_BIT)
40
42#define PORT0_CONFIG_LEDS 0xE7
43
44#define TEST_BLINK_MS 400
45
46static i2c_master_bus_handle_t s_i2c_bus;
47static i2c_master_dev_handle_t s_pca9535_dev;
48static uint8_t s_output0;
49static bool s_initialized;
50
51static esp_err_t pca9535_write_reg(uint8_t reg, uint8_t value)
52{
53 uint8_t buf[2] = {reg, value};
54 return i2c_master_transmit(s_pca9535_dev, buf, sizeof(buf), I2C_TIMEOUT_MS);
55}
56
57static esp_err_t pca9535_read_reg(uint8_t reg, uint8_t *value)
58{
59 return i2c_master_transmit_receive(s_pca9535_dev, &reg, 1, value, 1, I2C_TIMEOUT_MS);
60}
61
62static esp_err_t pca9535_set_port0(uint8_t value)
63{
64 ESP_RETURN_ON_ERROR(pca9535_write_reg(PCA9535_REG_OUTPUT0, value), TAG, "write output0 failed");
65 s_output0 = value;
66 return ESP_OK;
67}
68
69esp_err_t pca9535_init(void)
70{
71 if (s_initialized) {
72 return ESP_OK;
73 }
74
75 i2c_master_bus_config_t bus_cfg = {
76 .i2c_port = I2C_PORT,
77 .sda_io_num = I2C_SDA_GPIO,
78 .scl_io_num = I2C_SCL_GPIO,
79 .clk_source = I2C_CLK_SRC_DEFAULT,
80 .glitch_ignore_cnt = 7,
81 .flags.enable_internal_pullup = true,
82 };
83 ESP_RETURN_ON_ERROR(i2c_new_master_bus(&bus_cfg, &s_i2c_bus), TAG, "i2c bus init failed");
84
85 i2c_device_config_t dev_cfg = {
86 .dev_addr_length = I2C_ADDR_BIT_LEN_7,
87 .device_address = PCA9535_I2C_ADDR,
88 .scl_speed_hz = I2C_FREQ_HZ,
89 };
90 ESP_RETURN_ON_ERROR(i2c_master_bus_add_device(s_i2c_bus, &dev_cfg, &s_pca9535_dev),
91 TAG, "i2c device add failed");
92
93 ESP_RETURN_ON_ERROR(pca9535_write_reg(PCA9535_REG_INVERT0, 0x00), TAG, "invert0 failed");
94 ESP_RETURN_ON_ERROR(pca9535_write_reg(PCA9535_REG_INVERT1, 0x00), TAG, "invert1 failed");
96 TAG, "config0 failed");
97 ESP_RETURN_ON_ERROR(pca9535_write_reg(PCA9535_REG_CONFIG1, 0xFF), TAG, "config1 failed");
98 ESP_RETURN_ON_ERROR(pca9535_set_port0(0x00), TAG, "output0 failed");
99
100 uint8_t config0 = 0;
101 ESP_RETURN_ON_ERROR(pca9535_read_reg(PCA9535_REG_CONFIG0, &config0), TAG, "read config0 failed");
102
103 s_initialized = true;
104 ESP_LOGI(TAG, "PCA9535 at 0x%02X, %u Hz, SCL=GPIO%d SDA=GPIO%d, config0=0x%02X",
106 return ESP_OK;
107}
108
112static void pca9535_test_task(void *arg)
113{
114 const uint8_t patterns[] = {LED_P03_BIT, LED_P04_BIT};
115 size_t idx = 0;
116
117 while (true) {
118 uint8_t port = patterns[idx];
119 if (pca9535_set_port0(port) == ESP_OK) {
120 ESP_LOGI(TAG, "Test LED port0=0x%02X", port);
121 }
122
123 idx = (idx + 1) % (sizeof(patterns) / sizeof(patterns[0]));
124 vTaskDelay(pdMS_TO_TICKS(TEST_BLINK_MS));
125 }
126}
127
128esp_err_t pca9535_test_start(void)
129{
130 static bool started = false;
131
132 ESP_RETURN_ON_FALSE(s_initialized, ESP_ERR_INVALID_STATE, TAG, "not initialized");
133
134 if (started) {
135 return ESP_OK;
136 }
137
138 BaseType_t created = xTaskCreate(pca9535_test_task, "pca9535_test", 2048, NULL, 5, NULL);
139 ESP_RETURN_ON_FALSE(created == pdPASS, ESP_ERR_NO_MEM, TAG, "test task create failed");
140
141 started = true;
142 ESP_LOGI(TAG, "Test task started: LEDs on P0.3 and P0.4");
143 return ESP_OK;
144}
esp_err_t pca9535_test_start(void)
Запускает тестовую задачу: поочерённое мигание светодиодов P0.3 и P0.4.
Definition pca9535.c:128
#define PCA9535_I2C_ADDR
Definition pca9535.c:25
static void pca9535_test_task(void *arg)
Тест: поочерённое включение P0.3 и P0.4.
Definition pca9535.c:112
#define PCA9535_REG_OUTPUT0
Definition pca9535.c:29
#define I2C_FREQ_HZ
Definition pca9535.c:22
#define PCA9535_REG_INVERT1
Definition pca9535.c:32
#define LED_P03_BIT
Светодиоды на порту 0, пины 3 и 4.
Definition pca9535.c:37
static esp_err_t pca9535_set_port0(uint8_t value)
Definition pca9535.c:62
#define PORT0_CONFIG_LEDS
Конфигурация: P0.3 и P0.4 — выходы, остальные — входы
Definition pca9535.c:42
#define PCA9535_REG_CONFIG0
Definition pca9535.c:33
static i2c_master_bus_handle_t s_i2c_bus
Definition pca9535.c:46
#define I2C_SDA_GPIO
Definition pca9535.c:21
static const char * TAG
Definition pca9535.c:17
static uint8_t s_output0
Definition pca9535.c:48
#define PCA9535_REG_INVERT0
Definition pca9535.c:31
esp_err_t pca9535_init(void)
Инициализирует шину I2C и PCA9535.
Definition pca9535.c:69
#define I2C_SCL_GPIO
Definition pca9535.c:20
static bool s_initialized
Definition pca9535.c:49
static i2c_master_dev_handle_t s_pca9535_dev
Definition pca9535.c:47
#define TEST_BLINK_MS
Definition pca9535.c:44
#define PCA9535_REG_CONFIG1
Definition pca9535.c:34
static esp_err_t pca9535_read_reg(uint8_t reg, uint8_t *value)
Definition pca9535.c:57
#define I2C_TIMEOUT_MS
Definition pca9535.c:23
#define LED_P04_BIT
Definition pca9535.c:38
#define I2C_PORT
Definition pca9535.c:19
static esp_err_t pca9535_write_reg(uint8_t reg, uint8_t value)
Definition pca9535.c:51
Драйвер I2C-расширителя портов PCA9535.