EVE 1.0
gpio-ext-pcal9535a.h
Go to the documentation of this file.
1 #ifndef DRIVER_IO_EXPANDER_PCAL9535A_H
2 #define DRIVER_IO_EXPANDER_PCAL9535A_H
3 /**********************************************************************/
4 /*
5  * Copyright (c) 2015, Jetro AS
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without modification,
9  * are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  * derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONRIBUTORS ``AS IS'' AND ANY EXPRESS
20  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
22  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
28  * OF SUCH DAMAGE.
29  *
30  * This file is part of the EVE platform.
31  */
32 
33 /**
34  * \file
35  * @brief Driver for I2C-based IO expander type NXP PCAL9535A.
36  *
37  * @author KLO, Jetro AS
38  */ /******************************************************************/
39 
40 #include <stdbool.h>
41 #include <string.h>
42 #include "gpio-ext.h"
43 
44 /**
45  * \defgroup gpio_ext_pcal9535a PCAL9535a GPIO driver
46  * \ingroup gpio_ext
47  * \ingroup extdrv
48  * \{
49  *
50  * This driver supports the I2C-based IO expander type NXP PCAL9535A.
51  * The IO expander has 2 8-bits IO ports, 1 open drain interrupt output
52  * and 3 address lines. Both IO ports are operated as one common 16-bits
53  * port with PORT1 as MSByte and PORT0 as LSByte.
54  * The I2C address range is 0x20 - 0x27. Max baudrate is 400 kbit/s.
55  * The port bits could be set to inputs or outputs individually.
56  * Each input can be configured to have pullup or pulldown resistors.
57  *
58  * The selected I2C port must be initialized before using the driver.
59  */
60 
61 /**
62  * io_expander_state_t structure holds run-time data for the IO expander instance.
63  *
64  */
66 {
67  uint16_t OutputValues; ///< Last values set for output to IO_EXPANDER_OUTPUT register
68  uint16_t InputValues; ///< Last read input values, copy of IO_EXPANDER_INPUT register
69  uint16_t InterruptStatus; ///< Pending interrupt status
70  uint16_t InterruptMask; ///< Internal interrupt bit mask (0 = disabled, 1 = enabled), inverted copy of IO_EXPANDER_INT_MASK register.
71  uint16_t Direction; ///< Current direction state, copy of IO_EXPANDER_DIRECTION register
72 };
73 
74 /**
75  * io_expander_t structure holds I2C port and slave address to be used,
76  * and the initial data for the ports.
77  *
78  */
79 
81 {
82  const struct i2c_t* I2c; ///< I2C port I2C0 or I2C1
83  struct gpio_ext_pcal_state_t* State; ///< IO expander run-time state
84  uint8_t SlaveAddress; ///< I2C slave address 0x20 to 0x27
85  uint8_t Reserved; ///< Reserved and not used
86  uint16_t OutInit; ///< Initialize value for output port pins (0 = low output, 1 = high output)
87  uint16_t InInvert; ///< Invertion of inputs port pins (0 = no invert, 1 = invert)
88  uint16_t Direction; ///< Sets the direction of port pins (0 = output, 1 = input)
89  uint16_t PullEnable; ///< Enables pull resistors for port pins (0 = disable, 1 = enable)
90  uint16_t PullSelect; ///< Selects pullup or polldown resistors port pins (0 = 100k pulldown, 1 = 100k pullup)
91 };
92 
93 /**********************************************************************
94  * IO port expander commands
95  **********************************************************************/
96 #define IO_EXPANDER_INPUT 0x00
97 #define IO_EXPANDER_OUTPUT 0x02
98 #define IO_EXPANDER_INVERT 0x04
99 #define IO_EXPANDER_DIRECTION 0x06
100 #define IO_EXPANDER_DRIVE_PORT0 0x40
101 #define IO_EXPANDER_DRIVE_PORT1 0x42
102 #define IO_EXPANDER_INPUT_LATCH_ENABLE 0x44
103 #define IO_EXPANDER_PULL_ENABLE 0x46
104 #define IO_EXPANDER_PULL_SELECT 0x48
105 #define IO_EXPANDER_INT_MASK 0x4a
106 #define IO_EXPANDER_INT_STATUS 0x4c
107 #define IO_EXPANDER_OUTPUT_CONFIG 0x4f
108 
109 /**
110  * Pointer to GpioPcalFunc structure uses to initialize the array of GPIO
111  * virtual functions .Func in struct ext_gpio_t GPIO descriptor.
112  */
113 extern const struct gpio_ext_api_t GpioPcalFunc;
114 
115 /**
116  * @name Functions called from application programs
117  * @{
118  */
119 
120 /**********************************************************************
121  * prototypes used by inline functions
122  **********************************************************************/
123 extern uint16_t ReadPcal(const struct gpio_ext_t* GpioExt, uint8_t Address);
124 extern void WritePcal(const struct gpio_ext_t* GpioExt, uint8_t Address, uint16_t Data);
125 
126 /**
127  * @brief Initialize I2C-based IO expander type NXP PCAL9535A.
128  *
129  * @param GpioExt Parameters for the IO port expander to be used
130  */
131 static inline void GpioExtInitPcal(const struct gpio_ext_t *GpioExt)
132 {
133  // nothing to do
134 }
135 
136 /**
137  * @brief De-initialize I2C-based IO expander type NXP PCAL9535A.
138  *
139  * @param GpioExt Parameters for the IO port expander to be used
140  * @return true if OK, else false
141  */
142 static inline void GpioExtDisablePcal(const struct gpio_ext_t *GpioExt)
143 {
144  // nothing to do
145 }
146 
147 /**
148  * @brief Name: GpioExtInPortPcal\n
149  * Read 16-bits data from GPIO port.
150  *
151  * @param GpioExt Parameters for the IO port expander to be used
152  * @return Data read
153  */
154 static inline uint16_t GpioExtInPortPcal(const struct gpio_ext_t *GpioExt)
155 {
156  return ReadPcal(GpioExt, IO_EXPANDER_INPUT);
157 }
158 
159 /**
160  * @brief Name: GpioExtOutPortPcal\n
161  * Write 16-bits data to GPIO port.
162  *
163  * @param GpioExt Parameters for the IO port expander to be used
164  * @param Data Data to be written to IO expander ports
165  */
166 static inline void GpioExtOutPortPcal(const struct gpio_ext_t *GpioExt, uint16_t Data)
167 {
168  WritePcal(GpioExt, IO_EXPANDER_OUTPUT, Data);
169 }
170 
171 /**
172  * @brief Set pins direction to GPIO port.
173  *
174  * @param GpioExt Parameters for the IO port expander to be used
175  * @param Direction New direction to be settled
176  */
177 static inline void GpioExtSetDirectionPcal(const struct gpio_ext_t* GpioExt,
178  uint16_t Direction)
179 {
180  // NB: register contains an inverted value
181  WritePcal(GpioExt, IO_EXPANDER_DIRECTION, ~Direction);
182 }
183 
184 /**
185  * @brief Select pullup or pulldown for GPIO port.
186  *
187  * @param GpioExt Parameters for the IO port expander to be used
188  * @param PullSelect 0 - pulldown, 1 - pullup
189  */
190 static inline void GpioExtSetPullSelectPcal(const struct gpio_ext_t* GpioExt,
191  uint16_t PullSelect)
192 {
193  WritePcal(GpioExt, IO_EXPANDER_PULL_SELECT, PullSelect);
194 }
195 
196 /**
197  * @brief Enable pullup/pulldown to GPIO port.
198  *
199  * @param GpioExt Parameters for the IO port expander to be used
200  * @param PullEnable 0 - disable, 1 - enable
201  */
202 static inline void GpioExtSetPullEnablePcal(const struct gpio_ext_t* GpioExt,
203  uint16_t PullEnable)
204 {
205  WritePcal(GpioExt, IO_EXPANDER_PULL_ENABLE, PullEnable);
206 }
207 
208 static inline void GpioExtSetInterruptsPcal(const struct gpio_ext_t *GpioExt,
209  uint16_t Mask)
210 {
211  GpioExt->State->InterruptMask = Mask;
212  // NB: register contains an inverted value
213  WritePcal(GpioExt, IO_EXPANDER_INT_MASK, ~Mask);
214 }
215 
216 static inline void GpioExtSetLatchPcal(const struct gpio_ext_t *GpioExt,
217  uint16_t Mask)
218 {
219  WritePcal(GpioExt, IO_EXPANDER_INPUT_LATCH_ENABLE, Mask);
220 }
221 
222 extern void GpioExtSetDrivePcal(const struct gpio_ext_t *GpioExt, uint8_t Values[]);
223 
224 /** \} */
225 
226 /** \} gpio_ext_pcal9535a */
227 
228 #endif //DRIVER_IO_EXPANDER_PCAL9535A_H
uint16_t InterruptMask
Internal interrupt bit mask (0 = disabled, 1 = enabled)
Definition: gpio-ext.h:112
uint16_t Direction
Current direction state, copy of IO_EXPANDER_DIRECTION register.
uint16_t OutInit
Initialize value for output port pins (0 = low output, 1 = high output)
uint16_t PullSelect
Selects pullup or polldown resistors port pins (0 = 100k pulldown, 1 = 100k pullup) ...
static void GpioExtSetDirectionPcal(const struct gpio_ext_t *GpioExt, uint16_t Direction)
Set pins direction to GPIO port.
uint8_t SlaveAddress
I2C slave address 0x20 to 0x27.
static void GpioExtSetPullSelectPcal(const struct gpio_ext_t *GpioExt, uint16_t PullSelect)
Select pullup or pulldown for GPIO port.
const struct i2c_t * I2c
I2C port I2C0 or I2C1.
static void GpioExtOutPortPcal(const struct gpio_ext_t *GpioExt, uint16_t Data)
Name: GpioExtOutPortPcal Write 16-bits data to GPIO port.
static void GpioExtInitPcal(const struct gpio_ext_t *GpioExt)
Initialize I2C-based IO expander type NXP PCAL9535A.
Abstract IO extender driver.
uint16_t InputValues
Last read input values, copy of IO_EXPANDER_INPUT register.
uint16_t PullEnable
Enables pull resistors for port pins (0 = disable, 1 = enable)
static void GpioExtSetPullEnablePcal(const struct gpio_ext_t *GpioExt, uint16_t PullEnable)
Enable pullup/pulldown to GPIO port.
uint16_t Direction
Sets the direction of port pins (0 = output, 1 = input)
uint16_t InInvert
Invertion of inputs port pins (0 = no invert, 1 = invert)
uint16_t InterruptMask
Internal interrupt bit mask (0 = disabled, 1 = enabled), inverted copy of IO_EXPANDER_INT_MASK regist...
struct gpio_ext_state_t * State
Address to struct with RAM variables used by the driver.
Definition: gpio-ext.h:176
uint16_t OutputValues
Last values set for output to IO_EXPANDER_OUTPUT register.
uint8_t Reserved
Reserved and not used.
struct gpio_ext_pcal_state_t * State
IO expander run-time state.
uint16_t InterruptStatus
Pending interrupt status.
const struct gpio_ext_api_t GpioPcalFunc
static void GpioExtDisablePcal(const struct gpio_ext_t *GpioExt)
De-initialize I2C-based IO expander type NXP PCAL9535A.
static uint16_t GpioExtInPortPcal(const struct gpio_ext_t *GpioExt)
Name: GpioExtInPortPcal Read 16-bits data from GPIO port.