Statistics
| Branch: | Tag: | Revision:

amiro-lld / include / alld_pcal6524.h @ 8c47f14b

History | View | Annotate | Download (14.903 KB)

1
/*
2
AMiRo-LLD is a compilation of low-level hardware drivers for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4

5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU Lesser General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU Lesser General Public License for more details.
14

15
You should have received a copy of the GNU Lesser General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18

    
19
/**
20
 * @file    alld_pcal6524.h
21
 * @brief   GPIO extender macros and structures.
22
 *
23
 * @addtogroup lld_gpioext
24
 * @{
25
 */
26

    
27
#ifndef AMIROLLD_PCAL6524_H
28
#define AMIROLLD_PCAL6524_H
29

    
30
#include <amiro-lld.h>
31

    
32
#if defined(AMIROLLD_CFG_USE_PCAL6524) || defined(__DOXYGEN__)
33

    
34
/**
35
 * @brief   Maximum I2C frequency.
36
 */
37
#define PCAL6524_LLD_I2C_MAXFREQUENCY           1000000
38

    
39
/**
40
 * @brief   A falling edge indicats an interrupt.
41
 */
42
#define PCAL6524_LLD_INT_EDGE                   APAL_GPIO_EDGE_FALLING
43

    
44
/**
45
 * @brief   The PCAL6524Driver sruct.
46
 */
47
typedef struct {
48
  apalI2CDriver_t* i2cd;
49
  apalI2Caddr_t addr;
50
} PCAL6524Driver;
51

    
52
/**
53
 * @brief   Possible I2C address configurations.
54
 */
55
enum {
56
  PCAL6524_LLD_I2C_ADDR_FIXED     = 0x0020u,  /**< Fixed part of the I2C address. */
57
  PCAL6524_LLD_I2C_ADDR_SCL       = 0x0020u,  /**< ADDR pin connected to SCL. */
58
  PCAL6524_LLD_I2C_ADDR_SDA       = 0x0021u,  /**< ADDR pin connected to SDA. */
59
  PCAL6524_LLD_I2C_ADDR_VSS       = 0x0022u,  /**< ADDR pin connected to VSS. */
60
  PCAL6524_LLD_I2C_ADDR_VDD       = 0x0023u,  /**< ADDR pin connected to VDD. */
61
  PCAL6524_LLD_I2C_ADDR_DEVICEID  = 0x007Cu,  /**< Special address to read device ID information. */
62
};
63

    
64
/**
65
 * @brief   Command bit to enable auto-incrementation of command value.
66
 * @details Can be added (ORed) to any command value.
67
 */
68
#define PCAL6524_LLD_CMD_AUTOINCREMENT          0x80u
69

    
70
/**
71
 * @brief   The total number of registers that can be accessed.
72
 * @note    This is the maximum number of bytes that may be read or written continuously.
73
 */
74
#define PCAL6524_LLD_NUM_REGISTERS              52
75

    
76
typedef union {
77
  uint8_t raw[3];
78
  struct {
79
    uint16_t name : 12;
80
    uint16_t part : 9;
81
    uint8_t revision : 3;
82
  };
83
} pcal6524_lld_deviceid_t;
84

    
85
/**
86
 * @brief   Control commands for the PCAL6524.
87
 */
88
typedef enum {
89
  PCAL6524_LLD_CMD_INPUT_P0                             = 0x00u,  /**<  read only */
90
  PCAL6524_LLD_CMD_INPUT_P1                             = 0x01u,  /**<  read only */
91
  PCAL6524_LLD_CMD_INPUT_P2                             = 0x02u,  /**<  read only */
92
  PCAL6524_LLD_CMD_OUTPUT_P0                            = 0x04u,  /**< read/write */
93
  PCAL6524_LLD_CMD_OUTPUT_P1                            = 0x05u,  /**< read/write */
94
  PCAL6524_LLD_CMD_OUTPUT_P2                            = 0x06u,  /**< read/write */
95
  PCAL6524_LLD_CMD_POLARITYINVERSION_P0                 = 0x08u,  /**< read/write */
96
  PCAL6524_LLD_CMD_POLARITYINVERSION_P1                 = 0x09u,  /**< read/write */
97
  PCAL6524_LLD_CMD_POLARITYINVERSION_P2                 = 0x0Au,  /**< read/write */
98
  PCAL6524_LLD_CMD_CONFIGURATION_P0                     = 0x0Cu,  /**< read/write */
99
  PCAL6524_LLD_CMD_CONFIGURATION_P1                     = 0x0Du,  /**< read/write */
100
  PCAL6524_LLD_CMD_CONFIGURATION_P2                     = 0x0Eu,  /**< read/write */
101
  PCAL6524_LLD_CMD_OUTPUTDRIVESTRENGTH_P0A              = 0x40u,  /**< read/write */
102
  PCAL6524_LLD_CMD_OUTPUTDRIVESTRENGTH_P0B              = 0x41u,  /**< read/write */
103
  PCAL6524_LLD_CMD_OUTPUTDRIVESTRENGTH_P1A              = 0x42u,  /**< read/write */
104
  PCAL6524_LLD_CMD_OUTPUTDRIVESTRENGTH_P1B              = 0x43u,  /**< read/write */
105
  PCAL6524_LLD_CMD_OUTPUTDRIVESTRENGTH_P2A              = 0x44u,  /**< read/write */
106
  PCAL6524_LLD_CMD_OUTPUTDRIVESTRENGTH_P2B              = 0x45u,  /**< read/write */
107
  PCAL6524_LLD_CMD_INPUTLATCH_P0                        = 0x48u,  /**< read/write */
108
  PCAL6524_LLD_CMD_INPUTLATCH_P1                        = 0x49u,  /**< read/write */
109
  PCAL6524_LLD_CMD_INPUTLATCH_P2                        = 0x4Au,  /**< read/write */
110
  PCAL6524_LLD_CMD_PUPDENABLE_P0                        = 0x4Cu,  /**< read/write */
111
  PCAL6524_LLD_CMD_PUPDENABLE_P1                        = 0x4Du,  /**< read/write */
112
  PCAL6524_LLD_CMD_PUPDENABLE_P2                        = 0x4Eu,  /**< read/write */
113
  PCAL6524_LLD_CMD_PUPDSELECTION_P0                     = 0x50u,  /**< read/write */
114
  PCAL6524_LLD_CMD_PUPDSELECTION_P1                     = 0x51u,  /**< read/write */
115
  PCAL6524_LLD_CMD_PUPDSELECTION_P2                     = 0x52u,  /**< read/write */
116
  PCAL6524_LLD_CMD_INTERRUPTMASK_P0                     = 0x54u,  /**< read/write */
117
  PCAL6524_LLD_CMD_INTERRUPTMASK_P1                     = 0x55u,  /**< read/write */
118
  PCAL6524_LLD_CMD_INTERRUPTMASK_P2                     = 0x56u,  /**< read/write */
119
  PCAL6524_LLD_CMD_INTERRUPTSTATUS_P0                   = 0x58u,  /**<  read only */
120
  PCAL6524_LLD_CMD_INTERRUPTSTATUS_P1                   = 0x59u,  /**<  read only */
121
  PCAL6524_LLD_CMD_INTERRUPTSTATUS_P2                   = 0x5Au,  /**<  read only */
122
  PCAL6524_LLD_CMD_OUTPUTCONFIGURATION                  = 0x5Cu,  /**< read/write */
123
  PCAL6524_LLD_CMD_INTERRUPTEDGE_P0A                    = 0x60u,  /**< read/write */
124
  PCAL6524_LLD_CMD_INTERRUPTEDGE_P0B                    = 0x61u,  /**< read/write */
125
  PCAL6524_LLD_CMD_INTERRUPTEDGE_P1A                    = 0x62u,  /**< read/write */
126
  PCAL6524_LLD_CMD_INTERRUPTEDGE_P1B                    = 0x63u,  /**< read/write */
127
  PCAL6524_LLD_CMD_INTERRUPTEDGE_P2A                    = 0x64u,  /**< read/write */
128
  PCAL6524_LLD_CMD_INTERRUPTEDGE_P2B                    = 0x65u,  /**< read/write */
129
  PCAL6524_LLD_CMD_INTERRUPTCLEAR_P0                    = 0x68u,  /**< write only */
130
  PCAL6524_LLD_CMD_INTERRUPTCLEAR_P1                    = 0x69u,  /**< write only */
131
  PCAL6524_LLD_CMD_INTERRUPTCLEAR_P2                    = 0x6Au,  /**< write only */
132
  PCAL6524_LLD_CMD_INPUTSTATUS_P0                       = 0x6Cu,  /**<  read only */
133
  PCAL6524_LLD_CMD_INPUTSTATUS_P1                       = 0x6Du,  /**<  read only */
134
  PCAL6524_LLD_CMD_INPUTSTATUS_P2                       = 0x6Eu,  /**<  read only */
135
  PCAL6524_LLD_CMD_INDIVIDUALPINOUTPUTCONFIGURATION_P0  = 0x70u,  /**< read/write */
136
  PCAL6524_LLD_CMD_INDIVIDUALPINOUTPUTCONFIGURATION_P1  = 0x71u,  /**< read/write */
137
  PCAL6524_LLD_CMD_INDIVIDUALPINOUTPUTCONFIGURATION_P2  = 0x72u,  /**< read/write */
138
  PCAL6524_LLD_CMD_SWITCHDEBOUNCEENABLE_P0              = 0x74u,  /**< read/write */
139
  PCAL6524_LLD_CMD_SWITCHDEBOUNCEENABLE_P1              = 0x75u,  /**< read/write */
140
  PCAL6524_LLD_CMD_SWITCHDEBOUNCECOUNT                  = 0x76u,  /**< read/write */
141
} pcal6524_lld_cmd_t;
142

    
143
/**
144
 * @brief   Input register bit values.
145
 * @details The bits in the input register reflect the incoming logic levels per pin.
146
 *          If a pin is configured as ouput, the bit reflects th set value or is forced to 0 in case the outpus is configured as open-drain.
147
 *          If a pin is configured as input with latched interrupts, reading the according port will reset the input value and clear the interrupt.
148
 */
149
typedef enum {
150
  PCAL6524_LLD_INPUT_LOW  = 0b0,
151
  PCAL6524_LLD_INPUT_HIGH = 0b1,
152
} pcal6524_lld_input_t;
153

    
154
/**
155
 * @brief   Output register bit values.
156
 * @details Defines the logic level to be driven by output pins.
157
 *          The default value (after reset) is 0b1 (high),
158
 */
159
typedef enum {
160
  PCAL6524_LLD_OUTPUT_LOW     = 0b0,
161
  PCAL6524_LLD_OUTPUT_HIGH    = 0b1,
162
} pcal6524_lld_output_t;
163

    
164
/**
165
 * @brief   Polarity inversion register values.
166
 * @details Allows to inverse the logic values written to the input register.
167
 *          The default value (after reset) is 0b0 (disabled).
168
 */
169
typedef enum {
170
  PCAL6524_LLD_POLARITYINVERSION_DISABLED = 0b0,
171
  PCAL6524_LLD_POLARITYINVERSION_ENABLED  = 0b1,
172
} pcal6524_lld_polarityinversion_t;
173

    
174
/**
175
 * @brief   Configuration regsiter bit values.
176
 * @details Configures the direction of the I/O pins to either high-impedance input or output.
177
 *          The default value (after reset) is 0b1 (input).
178
 */
179
typedef enum {
180
  PCAL6524_LLD_CONFIGURATION_INPUT    = 0b1,
181
  PCAL6524_LLD_CONFIGURATION_OUTPUT   = 0b0,
182
} pcal6524_lld_configuration_t;
183

    
184
/**
185
 * @brief   Output drive strength register mask values.
186
 * @details Configures maximum current of output pins can be defined via a 2 bit mask per pin.
187
 *          Toggling multiple output pins simultaneously a peak current may induce noise to supply voltage and ground.
188
 *          By lowering the maximum current per pin. this effect can be minimized.
189
 *          The default value (after reset) is 0b11 (factor 1x)
190
 */
191
typedef enum {
192
  PCAL6524_LL_OUTPUTDRIVESTRENGTH_0_25    = 0b00,
193
  PCAL6524_LL_OUTPUTDRIVESTRENGTH_0_5     = 0b01,
194
  PCAL6524_LL_OUTPUTDRIVESTRENGTH_0_75    = 0b10,
195
  PCAL6524_LL_OUTPUTDRIVESTRENGTH_1       = 0b11,
196
} pcal6524_lld_outputdrivestrength_t;
197

    
198
/**
199
 * @brief   Input latch register bit values.
200
 * @details Allows to latch interrupt and input states per pin, if an interrupt occurred.
201
 *          The default value (after reset) is 0b0 (disabled).
202
 */
203
typedef enum {
204
  PCAL6524_LLD_INPUTLATCH_ENABLED   = 0b1,
205
  PCAL6524_LLD_INPUTLATCH_DISABLED  = 0b0,
206
} pcal6524_lld_inputlatch_t;
207

    
208
/**
209
 * @brief   Pull-up/Pull-down enable register bis values.
210
 * @details Configures per pin whether the pull-up/pull-down resistors shall be enabled.
211
 *          If a pin is configured as open-drain output, the setting in this register are overridden and the resistors are disconnected.
212
 *          The default value (after reset) is 0b0 (disabled).
213
 */
214
typedef enum {
215
  PCAL6524_LLD_PUPD_ENABLED   = 0b1,
216
  PCAL6524_LLD_PUPD_DISABLED  = 0b0,
217
} pcal6524_lld_pupdenable_t;
218

    
219
/**
220
 * @brief   Pull-up/Pull-dpwn selection register bit values.
221
 * @details Selects between pull-up and pull-down resistor (100 kΩ) per pin.
222
 *          Has no effect if the according bit is the pull-up/pull-down enable register is disabled.
223
 *          The default value (after reset) is 0b1 (pull-up).
224
 */
225
typedef enum {
226
  PCAL6524_LLD_PUPDSELECTION_PULLUP   = 0b1,
227
  PCAL6524_LLD_PUPDSELECTION_PULLDOWN = 0b0,
228
} pcal6524_lld_pupdselection_t;
229

    
230
/**
231
 * @brief   Interrupt mask register bit values.
232
 * @details Allows to enable (value 0) or disable (value 1) interrupts per pin.
233
 *          The default value (after reset) is 0b1 (interrupt disabled).
234
 */
235
typedef enum {
236
  PCAL6524_LLD_INTERRUPTMASK_ENABLED  = 0b0,
237
  PCAL6524_LLD_INTERRUPTMASK_DSIABLED = 0b1,
238
} pcal6524_lld_interruptmask_t;
239

    
240
/**
241
 * @brief   Interrupt status register bit value.
242
 * @details Indicates whether an interrupt occurred per pin.
243
 *          After reset the register is initialized with 0b0 (no interrupt occurred yet).
244
 */
245
typedef enum {
246
  PCAL6524_LLD_INTERRUPTSTATUS_ACTIVE   = 0b1,
247
  PCAL6524_LLD_INTERRUPTSTATUS_INACTIVE = 0b0,
248
} pcal6542_lld_interruptstatus_t;
249

    
250
/**
251
 * @brief   Output port configuration register mask of valid bits.
252
 */
253
#define PCAL6524_LLD_OUTPUTCONFIGURATION_MASK       0x07u
254

    
255
/**
256
 * @brief   Output port configuration register mask for I/O port 0.
257
 */
258
#define PCAL6524_LLD_OUTPUTCONFIGURATION_MASK_PORT0 0x01u
259

    
260
/**
261
 * @brief   Output port configuration register mask for I/O port 1.
262
 */
263
#define PCAL6524_LLD_OUTPUTCONFIGURATION_MASK_PORT1 0x02u
264

    
265
/**
266
 * @brief   Output port configuration register mask for I/O port 2.
267
 */
268
#define PCAL6524_LLD_OUTPUTCONFIGURATION_MASK_PORT2 0x04u
269

    
270
/**
271
 * @brief   Output port configuration register bit values.
272
 * @details Configures all ouput pins per port to be push-pull or open-drain.
273
 *          The default value (after reset) is 0b0 (push-pull).
274
 */
275
typedef enum {
276
  PCAL6524_LLD_OUTPUTCONFIGURATION_PUSHPULL   = 0b0,
277
  PCAL6524_LLD_OUTPUTCONFIGURATION_OPENDRAIN  = 0b1,
278
} pcal6524_lld_outputconfiguration_t;
279

    
280
/**
281
 * @brief   Interrupt edge register mask values.
282
 * @details Configures the type of event that would cause an interrupt per pin.
283
 *          The default value (after reset) is 0b00 (level triggered).
284
 */
285
typedef enum {
286
  PCAL6524_LLD_INTERRUPTEDGE_LEVELTRIGGERED = 0b00,
287
  PCAL6524_LLD_INTERRUPTEDGE_RISINGEDGE     = 0b01,
288
  PCAL6524_LLD_INTERRUPTEDGE_FALLINGEDGE    = 0b10,
289
  PCAL6524_LLD_INTERRUPTEDGE_ANYEDGE        = 0b11,
290
} pcal6524_lld_interruptedge_t;
291

    
292
/**
293
 * @brief   Input status register bit values.
294
 * @details Reflects the current logic level per pin similar to the input register.
295
 *          However, values are not latched and reading the register will not reset interrupts.
296
 */
297
typedef enum {
298
  PCAL6524_LLD_INPUTSTATUS_LOW  = 0b0,
299
  PCAL6524_LLD_INPUTSTATUS_HIGH = 0b1,
300
} pcal6524_lld_inputstatus_t;
301

    
302
/**
303
 * @brief   Individual pin output configuration register bit values.
304
 * @details Can be used to invert the port-wide push-pull/open-drain configuration via the ouput port configuration register per pin.
305
 *          the default value (after reset) is 0b0 (not inverted).
306
 */
307
typedef enum {
308
  PCAL6524_LLD_INDIVIDUALPINOUTPUTCONFIGURATION_PORT      = 0b0,
309
  PCAL6524_LLD_INDIVIDUALPINOUTPUTCONFIGURATION_INVERTED  = 0b1,
310
} pcal6524_lld_individualpinoutputconfiguration_t;
311

    
312
/**
313
 * @brief   Switch debounce enable register bit values.
314
 * @details Allows to enable debounce functionality for I/O ports 0 and 1.
315
 *          In order to use the debounce feature, an oscillator signal must be applied to pin 0 of port 0.
316
 *          The default value (after reset) is 0b0 (disabled).
317
 */
318
typedef enum {
319
  PCAL6524_LLD_SWITCHDEBOUNCE_ENABLED   = 0b1,
320
  PCAL6524_LLD_SWITCHDEBOUNCE_DISABLED  = 0b0,
321
} pcal6524_lld_switchdebounceenable_t;
322

    
323
#ifdef __cplusplus
324
extern "C" {
325
#endif
326
  uint8_t pcal6524_lld_cmd_groupsize(const pcal6524_lld_cmd_t cmd);
327

    
328
//  apalExitStatus_t pcal6524_lld_read_id(const PCAL6524Driver* const pcal6524d, uint8_t* const data, const apalTime_t timeout);
329
  apalExitStatus_t pcal6524_lld_read_reg(const PCAL6524Driver* const pcal6524d, const pcal6524_lld_cmd_t reg, uint8_t* const data, const apalTime_t timeout);
330
  apalExitStatus_t pcal6524_lld_write_reg(const PCAL6524Driver* const pcal6524d, const pcal6524_lld_cmd_t reg, const uint8_t data, const apalTime_t timeout);
331
  apalExitStatus_t pcal6524_lld_read_group(const PCAL6524Driver* const pcal6524d, const pcal6524_lld_cmd_t reg, uint8_t* const data, const apalTime_t timeout);
332
  apalExitStatus_t pcal6524_lld_write_group(const PCAL6524Driver* const pcal6524d, const pcal6524_lld_cmd_t reg, const uint8_t* const data, const apalTime_t timeout);
333
  apalExitStatus_t pcal6524_lld_read_continuous(const PCAL6524Driver* const pcal6524d, const pcal6524_lld_cmd_t reg, uint8_t* const data, const uint8_t length, const apalTime_t timeout);
334
  apalExitStatus_t pcal6524_lld_write_continuous(const PCAL6524Driver* const pcal6524d, const pcal6524_lld_cmd_t reg, const uint8_t* const data, const uint8_t length, const apalTime_t timeout);
335
#ifdef __cplusplus
336
}
337
#endif
338

    
339
#endif /* defined(AMIROLLD_CFG_USE_PCAL6524) */
340

    
341
#endif /* AMIROLLD_PCAL6524_H */
342

    
343
/** @} */