Revision e3287406

View differences:

Makefile
45 45
                $(AMIROLLD_SRCDIR)/alld_ltc4412.c \
46 46
                $(AMIROLLD_SRCDIR)/alld_mpr121.c \
47 47
                $(AMIROLLD_SRCDIR)/alld_pca9544a.c \
48
                $(AMIROLLD_SRCDIR)/alld_pcal6524.c \
48 49
                $(AMIROLLD_SRCDIR)/alld_pklcs1212e4001.c \
49 50
                $(AMIROLLD_SRCDIR)/alld_tlc5947.c \
50 51
                $(AMIROLLD_SRCDIR)/alld_tps2051bdbv.c \
include/alld_pcal6524.h
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
/** @} */
source/alld_pcal6524.c
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.c
21
 * @brief   GPIO extender function implementations.
22
 *
23
 * @addtogroup lld_gpioext
24
 * @{
25
 */
26

  
27
#include <alld_pcal6524.h>
28

  
29
#if defined(AMIROLLD_CFG_USE_PCAL6524) || defined(__DOXYGEN__)
30

  
31
#include <string.h>
32

  
33
/*============================================================================*/
34
/* local constants and functions                                              */
35
/*============================================================================*/
36

  
37
#define _MAXIMUM_GROUP_SIZE           6
38

  
39
/*============================================================================*/
40
/* helper functions                                                           */
41
/*============================================================================*/
42

  
43
/**
44
 * @brief   Returns the size of the group for a specified command.
45
 *
46
 * @param[in] cmd   Command to retrieve the group size for.
47
 *
48
 * @return    The size of the group in bytes.
49
 */
50
inline uint8_t pcal6524_lld_cmd_groupsize(const pcal6524_lld_cmd_t cmd)
51
{
52
  switch (cmd) {
53
    case PCAL6524_LLD_CMD_OUTPUTCONFIGURATION:
54
    case PCAL6524_LLD_CMD_SWITCHDEBOUNCECOUNT:
55
      return 1;
56
    case PCAL6524_LLD_CMD_SWITCHDEBOUNCEENABLE_P0:
57
    case PCAL6524_LLD_CMD_SWITCHDEBOUNCEENABLE_P1:
58
      return 2;
59
    case PCAL6524_LLD_CMD_INPUT_P0:
60
    case PCAL6524_LLD_CMD_INPUT_P1:
61
    case PCAL6524_LLD_CMD_INPUT_P2:
62
    case PCAL6524_LLD_CMD_OUTPUT_P0:
63
    case PCAL6524_LLD_CMD_OUTPUT_P1:
64
    case PCAL6524_LLD_CMD_OUTPUT_P2:
65
    case PCAL6524_LLD_CMD_POLARITYINVERSION_P0:
66
    case PCAL6524_LLD_CMD_POLARITYINVERSION_P1:
67
    case PCAL6524_LLD_CMD_POLARITYINVERSION_P2:
68
    case PCAL6524_LLD_CMD_CONFIGURATION_P0:
69
    case PCAL6524_LLD_CMD_CONFIGURATION_P1:
70
    case PCAL6524_LLD_CMD_CONFIGURATION_P2:
71
    case PCAL6524_LLD_CMD_INPUTLATCH_P0:
72
    case PCAL6524_LLD_CMD_INPUTLATCH_P1:
73
    case PCAL6524_LLD_CMD_INPUTLATCH_P2:
74
    case PCAL6524_LLD_CMD_PUPDENABLE_P0:
75
    case PCAL6524_LLD_CMD_PUPDENABLE_P1:
76
    case PCAL6524_LLD_CMD_PUPDENABLE_P2:
77
    case PCAL6524_LLD_CMD_PUPDSELECTION_P0:
78
    case PCAL6524_LLD_CMD_PUPDSELECTION_P1:
79
    case PCAL6524_LLD_CMD_PUPDSELECTION_P2:
80
    case PCAL6524_LLD_CMD_INTERRUPTMASK_P0:
81
    case PCAL6524_LLD_CMD_INTERRUPTMASK_P1:
82
    case PCAL6524_LLD_CMD_INTERRUPTMASK_P2:
83
    case PCAL6524_LLD_CMD_INTERRUPTSTATUS_P0:
84
    case PCAL6524_LLD_CMD_INTERRUPTSTATUS_P1:
85
    case PCAL6524_LLD_CMD_INTERRUPTSTATUS_P2:
86
    case PCAL6524_LLD_CMD_INTERRUPTCLEAR_P0:
87
    case PCAL6524_LLD_CMD_INTERRUPTCLEAR_P1:
88
    case PCAL6524_LLD_CMD_INTERRUPTCLEAR_P2:
89
    case PCAL6524_LLD_CMD_INPUTSTATUS_P0:
90
    case PCAL6524_LLD_CMD_INPUTSTATUS_P1:
91
    case PCAL6524_LLD_CMD_INPUTSTATUS_P2:
92
    case PCAL6524_LLD_CMD_INDIVIDUALPINOUTPUTCONFIGURATION_P0:
93
    case PCAL6524_LLD_CMD_INDIVIDUALPINOUTPUTCONFIGURATION_P1:
94
    case PCAL6524_LLD_CMD_INDIVIDUALPINOUTPUTCONFIGURATION_P2:
95
      return 3;
96
    case PCAL6524_LLD_CMD_OUTPUTDRIVESTRENGTH_P0A:
97
    case PCAL6524_LLD_CMD_OUTPUTDRIVESTRENGTH_P0B:
98
    case PCAL6524_LLD_CMD_OUTPUTDRIVESTRENGTH_P1A:
99
    case PCAL6524_LLD_CMD_OUTPUTDRIVESTRENGTH_P1B:
100
    case PCAL6524_LLD_CMD_OUTPUTDRIVESTRENGTH_P2A:
101
    case PCAL6524_LLD_CMD_OUTPUTDRIVESTRENGTH_P2B:
102
    case PCAL6524_LLD_CMD_INTERRUPTEDGE_P0A:
103
    case PCAL6524_LLD_CMD_INTERRUPTEDGE_P0B:
104
    case PCAL6524_LLD_CMD_INTERRUPTEDGE_P1A:
105
    case PCAL6524_LLD_CMD_INTERRUPTEDGE_P1B:
106
    case PCAL6524_LLD_CMD_INTERRUPTEDGE_P2A:
107
    case PCAL6524_LLD_CMD_INTERRUPTEDGE_P2B:
108
      return 6;
109
  }
110
  // must never occur
111
  apalDbgAssert(false);
112
  return 0;
113
}
114

  
115
/*============================================================================*/
116
/* general register access                                                    */
117
/*============================================================================*/
118

  
119
// Reading the ID is currently not supported, since the required I²C sequence can not trivially executed via periphAL and ChibiOS/HAL.
120
///**
121
// * @brief   Read device ID and manufacturer information.
122
// *
123
// * @param[in]   pcal6524d   The PCAL6524 driver to use.
124
// * @param[out]  info        Pointer where to store the information data.
125
// * @param[in]   timeout     Timeout for the function to return.
126
// *
127
// * @return    Indicator whether the function call was successful or a timeout occurred.
128
// */
129
//inline apalExitStatus_t
130
//pcal6524_lld_read_id(const PCAL6524Driver* const pcal6524d, pcal6524_lld_deviceid_t* const info, const apalTime_t timeout)
131
//{
132
//  apalDbgAssert(pcal6524d != NULL && pcal6524d->i2cd != NULL);
133
//  apalDbgAssert(info != NULL);
134
//
135
//  const uint8_t txbuf = (uint8_t)pcal6524d->addr;
136
//  return apalI2CMasterTransmit(pcal6524d->i2cd, PCAL6524_LLD_I2C_ADDR_DEVICEID, &txbuf, 1, info->raw, sizeof(info->raw), timeout);
137
//}
138

  
139
/**
140
 * @brief   Read 8bit data from any register.
141
 *
142
 * @param[in]   pcal6524d       The PCAL6524 driver to use.
143
 * @param[in]   reg             Command register to read.
144
 * @param[out]  data            Pointer to store the register data to.
145
 * @param[in]   timeout         Timeout for the function to return (in microseconds).
146
 *
147
 * @return    Indicator whether the function call was successful or a timeout occurred.
148
 */
149
inline apalExitStatus_t
150
pcal6524_lld_read_reg(const PCAL6524Driver* const pcal6524d, const pcal6524_lld_cmd_t reg, uint8_t* const data, const apalTime_t timeout)
151
{
152
  apalDbgAssert(pcal6524d != NULL && pcal6524d->i2cd != NULL);
153
  apalDbgAssert(data != NULL);
154

  
155
  const uint8_t txbuf = (uint8_t)reg;
156
  return apalI2CMasterTransmit(pcal6524d->i2cd, pcal6524d->addr, &txbuf, 1, data, 1, timeout);
157
}
158

  
159
/**
160
 * @brief   Write 8bit data to any (writable) register.
161
 *
162
 * @param[in]   pcal6524d       The PCAL6524 driver to use.
163
 * @param[in]   reg             Command register to write to.
164
 * @param[in]   data            Data to transmit.
165
 * @param[in]   timeout         Timout for the function to return (in microseconds).
166
 *
167
 * @return    Indicator whether the function call was successful or a timeout occurred.
168
 */
169
inline apalExitStatus_t
170
pcal6524_lld_write_reg(const PCAL6524Driver* const pcal6524d, const pcal6524_lld_cmd_t reg, const uint8_t data, const apalTime_t timeout)
171
{
172
  apalDbgAssert(pcal6524d != NULL && pcal6524d->i2cd != NULL);
173

  
174
  uint8_t txbuf[2] = { (uint8_t)reg, data };
175
  return apalI2CMasterTransmit(pcal6524d->i2cd, pcal6524d->addr, txbuf, 2, NULL, 0, timeout);
176
}
177

  
178
/**
179
 * @brief   Read register group starting with an arbitrary register.
180
 *
181
 * @param[in]   pcal6524d   The PCAL6524 driver to use.
182
 * @param[in]   reg         Command register to start at.
183
 * @param[out]  data        Pointer to store rhe group data to.
184
 *                          The reqired number of bytes depends on the group.
185
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
186
 *
187
 * @return    Indicator whether the function call was successful or a timeout occurred.
188
 */
189
inline apalExitStatus_t
190
pcal6524_lld_read_group(const PCAL6524Driver* const pcal6524d, const pcal6524_lld_cmd_t reg, uint8_t* const data, const apalTime_t timeout)
191
{
192
  apalDbgAssert(pcal6524d != NULL && pcal6524d->i2cd != NULL);
193
  apalDbgAssert(data != NULL);
194

  
195
  const uint8_t txbuf = (uint8_t)reg;
196
  return apalI2CMasterTransmit(pcal6524d->i2cd, pcal6524d->addr, &txbuf, 1, data, pcal6524_lld_cmd_groupsize(reg), timeout);
197
}
198

  
199
/**
200
 * @brief   Write register group data to any (writable) register.
201
 *
202
 * @param[in]   pcal6524d       The PCAL6524 driver to use.
203
 * @param[in]   reg             Command register to start at.
204
 * @param[in]   data            Data to transmit.
205
 *                              The reqired number of bytes depends on the group.
206
 * @param[in]   timeout         Timout for the function to return (in microseconds).
207
 *
208
 * @return    Indicator whether the function call was successful or a timeout occurred.
209
 */
210
inline apalExitStatus_t
211
pcal6524_lld_write_group(const PCAL6524Driver* const pcal6524d, const pcal6524_lld_cmd_t reg, const uint8_t* const data, const apalTime_t timeout)
212
{
213
  apalDbgAssert(pcal6524d != NULL && pcal6524d->i2cd != NULL);
214
  apalDbgAssert(data != NULL);
215

  
216
  uint8_t txbuf[_MAXIMUM_GROUP_SIZE + 1] = {(uint8_t)reg};
217
  memcpy(&txbuf[1], data, pcal6524_lld_cmd_groupsize(reg));
218
  return apalI2CMasterTransmit(pcal6524d->i2cd, pcal6524d->addr, txbuf, pcal6524_lld_cmd_groupsize(reg) + 1, NULL, 0, timeout);
219
}
220

  
221
/**
222
 * @brief   Read multiple registers continously, starting at an arbitrary one.
223
 *
224
 * @param[in]   pcal6524d   The PCAL6524 driver to use.
225
 * @param[in]   reg         Command register to start at.
226
 * @param[out]  data        Pointer to store the group data to.
227
 * @param[in]   length      Number of registers/bytes to read.
228
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
229
 *
230
 * @return    Indicator whether the function call was successful or a timeout occurred.
231
 */
232
inline apalExitStatus_t
233
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)
234
{
235
  apalDbgAssert(pcal6524d != NULL && pcal6524d->i2cd != NULL);
236
  apalDbgAssert(data != NULL);
237
  apalDbgAssert(length <= PCAL6524_LLD_NUM_REGISTERS);
238

  
239
  uint8_t txbuf = (uint8_t)reg | PCAL6524_LLD_CMD_AUTOINCREMENT;
240
  return apalI2CMasterTransmit(pcal6524d->i2cd, pcal6524d->addr, &txbuf, 1, data, length, timeout);
241
}
242

  
243
/**
244
 * @brief   Write multiple registers continously, starting at an arbitrary one.
245
 *
246
 * @param[in]   pcal6524d   The PCAL6524 driver to use.
247
 * @param[in]   reg         Command register to start at.
248
 * @param[in]   data        Pointer to the data to write.
249
 * @param[in]   length      Number of registers/bytes to write.
250
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
251
 *
252
 * @return    Indicator whether the function call was successful or a timeout occurred.
253
 */
254
inline apalExitStatus_t
255
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)
256
{
257
  apalDbgAssert(pcal6524d != NULL && pcal6524d->i2cd != NULL);
258
  apalDbgAssert(data != NULL);
259
  apalDbgAssert(length <= PCAL6524_LLD_NUM_REGISTERS);
260

  
261
  uint8_t txbuf[PCAL6524_LLD_NUM_REGISTERS + 1] = {(uint8_t)reg | PCAL6524_LLD_CMD_AUTOINCREMENT};
262
  memcpy(&txbuf[1], data, length);
263
  return apalI2CMasterTransmit(pcal6524d->i2cd, pcal6524d->addr, txbuf, length + 1, NULL, 0, timeout);
264
}
265

  
266
#endif /* defined(AMIROLLD_CFG_USE_PCAL6524) */
267

  
268
/** @} */

Also available in: Unified diff