pca9505.c
3699 bytes
1// Copyright 2022 nirim000
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "i2c_master.h"
5#include "pca9505.h"
6
7#include "debug.h"
8
9#define SLAVE_TO_ADDR(n) (n << 1)
10#define TIMEOUT 100
11
12enum {
13 CMD_INPUT_0 = 0,
14 CMD_INPUT_1,
15 CMD_INPUT_2,
16 CMD_INPUT_3,
17 CMD_INPUT_4,
18 CMD_OUTPUT_0 = 8,
19 CMD_OUTPUT_1,
20 CMD_OUTPUT_2,
21 CMD_OUTPUT_3,
22 CMD_OUTPUT_4,
23 CMD_INVERSION_0 = 16,
24 CMD_INVERSION_1,
25 CMD_INVERSION_2,
26 CMD_INVERSION_3,
27 CMD_INVERSION_4,
28 CMD_CONFIG_0 = 24,
29 CMD_CONFIG_1,
30 CMD_CONFIG_2,
31 CMD_CONFIG_3,
32 CMD_CONFIG_4,
33};
34
35void pca9505_init(uint8_t slave_addr) {
36 static uint8_t s_init = 0;
37 if (!s_init) {
38 i2c_init();
39
40 s_init = 1;
41 }
42
43 // TODO: could check device connected
44}
45
46bool pca9505_set_config(uint8_t slave_addr, pca9505_port_t port, uint8_t conf) {
47 uint8_t addr = SLAVE_TO_ADDR(slave_addr);
48 uint8_t cmd = 0;
49 switch (port) {
50 case 0:
51 cmd = CMD_CONFIG_0;
52 break;
53 case 1:
54 cmd = CMD_CONFIG_1;
55 break;
56 case 2:
57 cmd = CMD_CONFIG_2;
58 break;
59 case 3:
60 cmd = CMD_CONFIG_3;
61 break;
62 case 4:
63 cmd = CMD_CONFIG_4;
64 break;
65 }
66
67 i2c_status_t ret = i2c_write_register(addr, cmd, &conf, sizeof(conf), TIMEOUT);
68 if (ret != I2C_STATUS_SUCCESS) {
69 print("pca9505_set_config::FAILED\n");
70 return false;
71 }
72
73 return true;
74}
75
76bool pca9505_set_polarity(uint8_t slave_addr, pca9505_port_t port, uint8_t conf) {
77 uint8_t addr = SLAVE_TO_ADDR(slave_addr);
78 uint8_t cmd = 0;
79 switch (port) {
80 case 0:
81 cmd = CMD_INVERSION_0;
82 break;
83 case 1:
84 cmd = CMD_INVERSION_1;
85 break;
86 case 2:
87 cmd = CMD_INVERSION_2;
88 break;
89 case 3:
90 cmd = CMD_INVERSION_3;
91 break;
92 case 4:
93 cmd = CMD_INVERSION_4;
94 break;
95 }
96
97 i2c_status_t ret = i2c_write_register(addr, cmd, &conf, sizeof(conf), TIMEOUT);
98 if (ret != I2C_STATUS_SUCCESS) {
99 print("pca9505_set_polarity::FAILED\n");
100 return false;
101 }
102
103 return true;
104}
105
106bool pca9505_set_output(uint8_t slave_addr, pca9505_port_t port, uint8_t conf) {
107 uint8_t addr = SLAVE_TO_ADDR(slave_addr);
108 uint8_t cmd = 0;
109 switch (port) {
110 case 0:
111 cmd = CMD_OUTPUT_0;
112 break;
113 case 1:
114 cmd = CMD_OUTPUT_1;
115 break;
116 case 2:
117 cmd = CMD_OUTPUT_2;
118 break;
119 case 3:
120 cmd = CMD_OUTPUT_3;
121 break;
122 case 4:
123 cmd = CMD_OUTPUT_4;
124 break;
125 }
126
127 i2c_status_t ret = i2c_write_register(addr, cmd, &conf, sizeof(conf), TIMEOUT);
128 if (ret != I2C_STATUS_SUCCESS) {
129 print("pca9505_set_output::FAILED\n");
130 return false;
131 }
132
133 return true;
134}
135
136bool pca9505_read_pins(uint8_t slave_addr, pca9505_port_t port, uint8_t* out) {
137 uint8_t addr = SLAVE_TO_ADDR(slave_addr);
138 uint8_t cmd = 0;
139 switch (port) {
140 case 0:
141 cmd = CMD_INPUT_0;
142 break;
143 case 1:
144 cmd = CMD_INPUT_1;
145 break;
146 case 2:
147 cmd = CMD_INPUT_2;
148 break;
149 case 3:
150 cmd = CMD_INPUT_3;
151 break;
152 case 4:
153 cmd = CMD_INPUT_4;
154 break;
155 }
156
157 i2c_status_t ret = i2c_read_register(addr, cmd, out, sizeof(uint8_t), TIMEOUT);
158 if (ret != I2C_STATUS_SUCCESS) {
159 print("pca9505_read_pins::FAILED\n");
160 return false;
161 }
162
163 return true;
164}