-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathNCA9595.h
300 lines (259 loc) · 11.9 KB
/
NCA9595.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
/*!\file NCA9595.h
** \author SMFSW
** \copyright MIT (c) 2017-2024, SMFSW
** \brief NCA9595 Driver
** \details NCA9595: Low-voltage 16-bit I²C and SMBus I/O expander
**/
/****************************************************************/
#ifndef __NCA9595_H__
#define __NCA9595_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "sarmfsw.h"
#include "I2C_component.h"
#include "I2C_peripheral.h"
#if defined(HAL_I2C_MODULE_ENABLED)
/****************************************************************/
#ifndef I2C_NCA9595_NB
//! \note Define I2C_NCA9595_NB to enable multiple peripherals of this type
#define I2C_NCA9595_NB 1 //!< Number of NCA9595 peripherals
#endif
// *****************************************************************************
// Section: Constants
// *****************************************************************************
#define NCA9595_ADDR 0x20 //!< NCA9595 address
#ifndef NCA9595_BASE_ADDR
//! \note Define NCA9595_BASE_ADDR to change default device base address
#define NCA9595_BASE_ADDR NCA9595_ADDR //!< NCA9595 Base address
#endif
// *****************************************************************************
// Section: Types
// *****************************************************************************
/*!\enum NCA9595_reg_map
** \brief Register map enum of NCA9595
** \note Shouldn't be used directly (use \ref NCA9595_wreg_map instead)
**/
typedef enum PACK__ NCA9595_reg_map {
NCA9595__InputPort0 = 0, //!< Input port 0
NCA9595__InputPort1, //!< Input port 1
NCA9595__OutputPort0, //!< Output port 0
NCA9595__OutputPort1, //!< Output port 1
NCA9595__PolarityPort0, //!< Polarity inversion port 0
NCA9595__PolarityPort1, //!< Polarity inversion port 1
NCA9595__ConfigPort0, //!< Configuration port 0
NCA9595__ConfigPort1, //!< Configuration port 1
NCA9595__PullUpConfigPort0, //!< Configuration pull-up port 0
NCA9595__PullUpConfigPort1, //!< Configuration pull-up port 1
} NCA9595_reg;
/*!\enum NCA9595_wreg_map
** \brief Register map enum of NCA9595
**/
typedef enum PACK__ NCA9595_wreg_map {
// WORDs map
#if defined(__BIG_ENDIAN__)
NCA9595__InputPorts = NCA9595__InputPort1, //!< Input ports
NCA9595__OutputPorts = NCA9595__OutputPort1, //!< Output ports
NCA9595__PolarityPorts = NCA9595__PolarityPort1, //!< Polarity inversion ports
NCA9595__ConfigPorts = NCA9595__ConfigPort1, //!< Configuration ports
NCA9595__PullUpConfigPorts = NCA9595__PullUpConfigPort1 //!< Configuration pull-up port 0
#else
NCA9595__InputPorts = NCA9595__InputPort0, //!< Input ports
NCA9595__OutputPorts = NCA9595__OutputPort0, //!< Output ports
NCA9595__PolarityPorts = NCA9595__PolarityPort0, //!< Polarity inversion ports
NCA9595__ConfigPorts = NCA9595__ConfigPort0, //!< Configuration ports
NCA9595__PullUpConfigPorts = NCA9595__PullUpConfigPort0 //!< Configuration pull-up port 0
#endif
} NCA9595_wreg;
/*!\enum NCA9595_Cfg
** \brief Configuration register values for NCA9595
**/
typedef enum PACK__ NCA9595_Cfg {
NCA9595__Cfg_Output = 0, //!< corresponding port pin is enabled as an output
NCA9595__Cfg_Input, //!< corresponding port pin is enabled as a high-impedance input
} NCA9595_Config;
/*!\enum NCA9595_Polarity
** \brief Polarity inversion register values for NCA9595
**/
typedef enum PACK__ NCA9595_Polarity {
NCA9595__Pol_Direct = 0, //!< corresponding port pin’s polarity is retained
NCA9595__Pol_Invert, //!< corresponding port pin’s polarity is inverted in the Input register
} NCA9595_Polarity;
/*!\enum NCA9595_PullUp
** \brief Pull-Up configuration register values for NCA9595
**/
typedef enum PACK__ NCA9595_PullUp {
NCA9595__PUp_Disable = 0, //!< corresponding port pull-up resistors are disabled
NCA9595__PUp_Enable, //!< corresponding port pull-up resistors are enabled
} NCA9595_PullUp;
/*!\union uNCA9595_REG__IN
** \brief Union for Input register pair of NCA9595
**/
typedef union uNCA9595_REG__IN {
uint16_t Word;
struct PACK__ {
// Less significant bit first
uint16_t I0_0 :1; //!< Input bit for Port 0 Channel 0
uint16_t I0_1 :1; //!< Input bit for Port 0 Channel 1
uint16_t I0_2 :1; //!< Input bit for Port 0 Channel 2
uint16_t I0_3 :1; //!< Input bit for Port 0 Channel 3
uint16_t I0_4 :1; //!< Input bit for Port 0 Channel 4
uint16_t I0_5 :1; //!< Input bit for Port 0 Channel 5
uint16_t I0_6 :1; //!< Input bit for Port 0 Channel 6
uint16_t I0_7 :1; //!< Input bit for Port 0 Channel 7
uint16_t I1_0 :1; //!< Input bit for Port 1 Channel 0
uint16_t I1_1 :1; //!< Input bit for Port 1 Channel 1
uint16_t I1_2 :1; //!< Input bit for Port 1 Channel 2
uint16_t I1_3 :1; //!< Input bit for Port 1 Channel 3
uint16_t I1_4 :1; //!< Input bit for Port 1 Channel 4
uint16_t I1_5 :1; //!< Input bit for Port 1 Channel 5
uint16_t I1_6 :1; //!< Input bit for Port 1 Channel 6
uint16_t I1_7 :1; //!< Input bit for Port 1 Channel 7
} Bits;
} uNCA9595_REG__IN;
/*!\union uNCA9595_REG__OUT
** \brief Union for Output register pair of NCA9595
**/
typedef union uNCA9595_REG__OUT {
uint16_t Word;
struct PACK__ {
// Less significant bit first
uint16_t O0_0 :1; //!< Output bit for Port 0 Channel 0
uint16_t O0_1 :1; //!< Output bit for Port 0 Channel 1
uint16_t O0_2 :1; //!< Output bit for Port 0 Channel 2
uint16_t O0_3 :1; //!< Output bit for Port 0 Channel 3
uint16_t O0_4 :1; //!< Output bit for Port 0 Channel 4
uint16_t O0_5 :1; //!< Output bit for Port 0 Channel 5
uint16_t O0_6 :1; //!< Output bit for Port 0 Channel 6
uint16_t O0_7 :1; //!< Output bit for Port 0 Channel 7
uint16_t O1_0 :1; //!< Output bit for Port 1 Channel 0
uint16_t O1_1 :1; //!< Output bit for Port 1 Channel 1
uint16_t O1_2 :1; //!< Output bit for Port 1 Channel 2
uint16_t O1_3 :1; //!< Output bit for Port 1 Channel 3
uint16_t O1_4 :1; //!< Output bit for Port 1 Channel 4
uint16_t O1_5 :1; //!< Output bit for Port 1 Channel 5
uint16_t O1_6 :1; //!< Output bit for Port 1 Channel 6
uint16_t O1_7 :1; //!< Output bit for Port 1 Channel 7
} Bits;
} uNCA9595_REG__OUT;
/*!\union uNCA9595_REG__CFG
** \brief Union for Config register pair of NCA9595
**/
typedef union uNCA9595_REG__CFG {
uint16_t Word;
struct PACK__ {
// Less significant bit first
NCA9595_Config C0_0 :1; //!< Configuration bit for Port 0 Channel 0
NCA9595_Config C0_1 :1; //!< Configuration bit for Port 0 Channel 1
NCA9595_Config C0_2 :1; //!< Configuration bit for Port 0 Channel 2
NCA9595_Config C0_3 :1; //!< Configuration bit for Port 0 Channel 3
NCA9595_Config C0_4 :1; //!< Configuration bit for Port 0 Channel 4
NCA9595_Config C0_5 :1; //!< Configuration bit for Port 0 Channel 5
NCA9595_Config C0_6 :1; //!< Configuration bit for Port 0 Channel 6
NCA9595_Config C0_7 :1; //!< Configuration bit for Port 0 Channel 7
NCA9595_Config C1_0 :1; //!< Configuration bit for Port 1 Channel 0
NCA9595_Config C1_1 :1; //!< Configuration bit for Port 1 Channel 1
NCA9595_Config C1_2 :1; //!< Configuration bit for Port 1 Channel 2
NCA9595_Config C1_3 :1; //!< Configuration bit for Port 1 Channel 3
NCA9595_Config C1_4 :1; //!< Configuration bit for Port 1 Channel 4
NCA9595_Config C1_5 :1; //!< Configuration bit for Port 1 Channel 5
NCA9595_Config C1_6 :1; //!< Configuration bit for Port 1 Channel 6
NCA9595_Config C1_7 :1; //!< Configuration bit for Port 1 Channel 7
} Bits;
} uNCA9595_REG__CFG;
/*!\union uNCA9595_REG__POL
** \brief Union for Polarity inversion register pair of NCA9595
**/
typedef union uNCA9595_REG__POL {
uint16_t Word;
struct PACK__ {
// Less significant bit first
NCA9595_Polarity N0_0 :1; //!< Polarity inversion bit for Port 0 Channel 0
NCA9595_Polarity N0_1 :1; //!< Polarity inversion bit for Port 0 Channel 1
NCA9595_Polarity N0_2 :1; //!< Polarity inversion bit for Port 0 Channel 2
NCA9595_Polarity N0_3 :1; //!< Polarity inversion bit for Port 0 Channel 3
NCA9595_Polarity N0_4 :1; //!< Polarity inversion bit for Port 0 Channel 4
NCA9595_Polarity N0_5 :1; //!< Polarity inversion bit for Port 0 Channel 5
NCA9595_Polarity N0_6 :1; //!< Polarity inversion bit for Port 0 Channel 6
NCA9595_Polarity N0_7 :1; //!< Polarity inversion bit for Port 0 Channel 7
NCA9595_Polarity N1_0 :1; //!< Polarity inversion bit for Port 1 Channel 0
NCA9595_Polarity N1_1 :1; //!< Polarity inversion bit for Port 1 Channel 1
NCA9595_Polarity N1_2 :1; //!< Polarity inversion bit for Port 1 Channel 2
NCA9595_Polarity N1_3 :1; //!< Polarity inversion bit for Port 1 Channel 3
NCA9595_Polarity N1_4 :1; //!< Polarity inversion bit for Port 1 Channel 4
NCA9595_Polarity N1_5 :1; //!< Polarity inversion bit for Port 1 Channel 5
NCA9595_Polarity N1_6 :1; //!< Polarity inversion bit for Port 1 Channel 6
NCA9595_Polarity N1_7 :1; //!< Polarity inversion bit for Port 1 Channel 7
} Bits;
} uNCA9595_REG__POL;
/*!\union uNCA9595_REG__PUP
** \brief Union for PullUp register pair of NCA9595
**/
typedef union uNCA9595_REG__PUP {
uint16_t Word;
struct PACK__ {
// Less significant bit first
NCA9595_PullUp R0_0 :1; //!< PullUp bit for Port 0 Channel 0
NCA9595_PullUp R0_1 :1; //!< PullUp bit for Port 0 Channel 1
NCA9595_PullUp R0_2 :1; //!< PullUp bit for Port 0 Channel 2
NCA9595_PullUp R0_3 :1; //!< PullUp bit for Port 0 Channel 3
NCA9595_PullUp R0_4 :1; //!< PullUp bit for Port 0 Channel 4
NCA9595_PullUp R0_5 :1; //!< PullUp bit for Port 0 Channel 5
NCA9595_PullUp R0_6 :1; //!< PullUp bit for Port 0 Channel 6
NCA9595_PullUp R0_7 :1; //!< PullUp bit for Port 0 Channel 7
NCA9595_PullUp R1_0 :1; //!< PullUp bit for Port 1 Channel 0
NCA9595_PullUp R1_1 :1; //!< PullUp bit for Port 1 Channel 1
NCA9595_PullUp R1_2 :1; //!< PullUp bit for Port 1 Channel 2
NCA9595_PullUp R1_3 :1; //!< PullUp bit for Port 1 Channel 3
NCA9595_PullUp R1_4 :1; //!< PullUp bit for Port 1 Channel 4
NCA9595_PullUp R1_5 :1; //!< PullUp bit for Port 1 Channel 5
NCA9595_PullUp R1_6 :1; //!< PullUp bit for Port 1 Channel 6
NCA9595_PullUp R1_7 :1; //!< PullUp bit for Port 1 Channel 7
} Bits;
} uNCA9595_REG__PUP;
// *****************************************************************************
// Section: Interface Routines
// *****************************************************************************
/******************/
/*** Slave init ***/
/******************/
/*!\brief Initialization for NCA9595 peripheral
** \param[in] idx - NCA9595 index
** \param[in] hi2c - pointer to NCA9595 I2C instance
** \param[in] devAddress - NCA9595 device address
** \return FctERR - error code
**/
FctERR NONNULL__ NCA9595_Init(const uint8_t idx, I2C_HandleTypeDef * const hi2c, const uint16_t devAddress);
/*!\brief Initialization for NCA9595 peripheral
** \warning In case multiple devices (defined by I2C_NCA9595_NB > 1), you shall use NCA9595_Init instead
** \return FctERR - error code
**/
FctERR NCA9595_Init_Single(void);
/************************/
/*** Low level access ***/
/************************/
/*!\brief I2C Write function for NCA9595
** \note Writes 8bits register pair (address shall be even for little endian / odd for big endian)
** \param[in,out] pSlave - Pointer to I2C slave instance
** \param[in] data - pointer to write from
** \param[in] addr - Address to write to
** \return FctERR - error code
**/
FctERR NONNULL__ NCA9595_Write_Word(I2C_slave_t * const pSlave, const uint16_t * data, const uint16_t addr);
/*!\brief I2C Read function for NCA9595
** \note Reads 8bits register pair (address shall be even for little endian / odd for big endian)
** \param[in,out] pSlave - Pointer to I2C slave instance
** \param[in,out] data - pointer to read to
** \param[in] addr - Address to read from
** \return FctERR - error code
**/
FctERR NONNULL__ NCA9595_Read_Word(I2C_slave_t * const pSlave, uint16_t * data, const uint16_t addr);
/****************************************************************/
#include "NCA9595_proc.h" // Include procedures
#include "NCA9595_ex.h" // Include extensions
#endif
#ifdef __cplusplus
}
#endif
#endif /* __NCA9595_H__ */
/****************************************************************/