EVE 1.0
io-expander-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) 2014, 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 
43 /**
44  * This driver supports the I2C-based IO expander type NXP PCAL9535A.
45  * The IO expander has 2 8-bits IO ports, 1 open drain interrupt output
46  * and 3 address lines. Both IO ports are operated as one common 16-bits
47  * port with PORT1 as MSByte and PORT0 as LSByte.
48  * The I2C address range is 0x20 - 0x27. Max baudrate is 400 kbit/s.
49  * The port bits could be set to inputs or outputs individually.
50  * Each input can be configured to have pullup or pulldown resistors.
51  *
52  * The selected I2C port must be initialized before using the driver.
53  */
54 
55 /***********************************************************************
56  * Global defines
57 ***********************************************************************/
58 /**
59  * io_expander_state_t structure holds run-time data for the IO expander instance.
60  *
61  */
63 {
64  uint16_t OutputValues; ///< Last values set for output to IO_EXPANDER_OUTPUT register
65  uint16_t InputValues; ///< Last read input values, copy of IO_EXPANDER_INPUT register
66  uint16_t InterruptStatus; ///< Pending interrupt status
67  uint16_t InterruptMask; ///< Internal interrupt bit mask (0 = disabled, 1 = enabled), inverted copy of IO_EXPANDER_INT_MASK register.
68  uint16_t Direction; ///< Current direction state, copy of IO_EXPANDER_DIRECTION register
69 };
70 
71 /**
72  * io_expander_t structure holds I2C port and slave address to be used,
73  * and the initial data for the ports.
74  *
75  */
76 
77 struct io_expander_t
78 {
79  const struct i2c_t *I2c; ///< I2C port I2C0 or I2C1
80  struct io_expander_state_t *State; ///< IO expander run-time state
81  uint8_t SlaveAddress; ///< I2C slave address 0x20 to 0x27
82  uint8_t Reserved; ///< Reserved and not used
83  uint16_t OutInit; ///< Initialize value for output port pins (0 = low output, 1 = high output)
84  uint16_t InInvert; ///< Invertion of inputs port pins (0 = no invert, 1 = invert)
85  uint16_t Direction; ///< Sets the direction of port pins (0 = output, 1 = input)
86  uint16_t PullEnable; ///< Enables pull resistors for port pins (0 = disable, 1 = enable)
87  uint16_t PullSelect; ///< Selects pullup or polldown resistors port pins (0 = 100k pulldown, 1 = 100k pullup)
88 };
89 
90 /**********************************************************************
91  * IO port expander commands
92  **********************************************************************/
93 #define IO_EXPANDER_INPUT 0x00
94 #define IO_EXPANDER_OUTPUT 0x02
95 #define IO_EXPANDER_INVERT 0x04
96 #define IO_EXPANDER_DIRECTION 0x06
97 #define IO_EXPANDER_DRIVE_PORT0 0x40
98 #define IO_EXPANDER_DRIVE_PORT1 0x42
99 #define IO_EXPANDER_INPUT_LATCH_ENABLE 0x44
100 #define IO_EXPANDER_PULL_ENABLE 0x46
101 #define IO_EXPANDER_PULL_SELECT 0x48
102 #define IO_EXPANDER_INT_MASK 0x4a
103 #define IO_EXPANDER_INT_STATUS 0x4c
104 #define IO_EXPANDER_OUTPUT_CONFIG 0x4f
105 
106 /**
107  * @name Functions called from application programs
108  * @{
109  */
110 
111 /**********************************************************************
112  * prototypes used by inline functions
113  **********************************************************************/
114 extern bool IoExpanderRead(const struct io_expander_t *IoExpander, const uint8_t Address, uint16_t *Data);
115 extern bool IoExpanderWrite(const struct io_expander_t *IoExpander, const uint8_t Address, const uint16_t Data);
116 
117 /**********************************************************************/
118 /**
119  * @brief Name: IoExpPortInit\n
120  * Initializes I2C-based IO expander type NXP PCAL9535A.
121  *
122  * @param IoExpander Parameters for the IO port expander to be used
123  * @return true if OK, else false
124  ***********************************************************************/
125 extern bool IoExpPortInit(const struct io_expander_t *IoExpander);
126 
127 /**********************************************************************/
128 /**
129  * @brief Name: IoExpPortRead\n
130  * Read 16-bits data from IO expander ports.
131  *
132  * @param IoExpander Parameters for the IO port expander to be used
133  * @param In Pointer to put data read from IO expander ports
134  * @return true if OK, else false
135  ***********************************************************************/
136 extern bool IoExpPortRead(const struct io_expander_t *IoExpander, uint16_t *In);
137 
138 /**********************************************************************/
139 /*
140  * @brief Name: IoExpPortWrite\n
141  * Write 16-bits data to IO expander ports.
142  *
143  * @param IoExpander Parameters for the IO port expander to be used
144  * @param Out Data to be written to IO expander ports
145  * @return true if OK, else false
146  ***********************************************************************/
147 extern bool IoExpPortWrite(const struct io_expander_t *IoExpander, const uint16_t Out, const uint16_t Mask);
148 
149 /**********************************************************************/
150 /**
151  * @brief Name: IoExpPortInterruptsRead\n
152  * Read and clear interrupt status from the IO expander.
153  *
154  * @param IoExpander Parameters for the IO port expander to be used
155  * @return bit mask with bits set for every unmasked pending interrupt
156  ***********************************************************************/
157 extern uint16_t IoExpPortInterruptsRead(const struct io_expander_t *IoExpander);
158 
159 /**********************************************************************/
160 /**
161  * @brief Name: IoExpPortInterruptsEnable\n
162  * Enable (unmask) interrupts for the selected set of pins.
163  *
164  * @param IoExpander Parameters for the IO port expander to be used
165  * @param Mask Pin bitmap
166  * @return true if OK, else false
167  ***********************************************************************/
168 extern bool IoExpPortInterruptsEnable(const struct io_expander_t *IoExpander, uint16_t Mask);
169 
170 /**********************************************************************/
171 /**
172  * @brief Name: IoExpPortInterruptsDisable\n
173  * Disable (mask) interrupts for the selected set of pins.
174  *
175  * @param IoExpander Parameters for the IO port expander to be used
176  * @param Mask Pin bitmap
177  * @return true if OK, else false
178  ***********************************************************************/
179 extern bool IoExpPortInterruptsDisable(const struct io_expander_t *IoExpander, uint16_t Mask);
180 
181 /**********************************************************************/
182 /**
183  * @brief Name: IoExpPortInterruptsDisable\n
184  * Clear (remove pending status) interrupts for the selected set of pins.
185  *
186  * @param IoExpander Parameters for the IO port expander to be used
187  * @param Mask Pin bitmap
188  * @return true if OK, else false
189  ***********************************************************************/
190 extern void IoExpPortInterruptsClear(const struct io_expander_t *IoExpander, uint16_t Mask);
191 
192 
193 /**********************************************************************/
194 /**
195  * @brief Name: IoExpPortSet\n
196  * Sets IO expander port bits.
197  *
198  * @param IoExpander Parameters for the IO port expander to be used
199  * @param SetBits Bits to be set at IO expander ports
200  * @return true if OK, else false
201  ***********************************************************************/
202 static inline bool IoExpPortSet(const struct io_expander_t *IoExpander, const uint16_t SetBits)
203 {
204  return IoExpPortWrite(IoExpander, SetBits, SetBits);
205 }
206 
207 /**********************************************************************/
208 /**
209  * @brief Name: IoExpPortClear\n
210  * Clears IO expander port bits.
211  *
212  * @param IoExpander Parameters for the IO port expander to be used
213  * @param ClearBits Bits to be cleared at IO expander ports
214  * @return true if OK, else false
215  ***********************************************************************/
216 static inline bool IoExpPortClear(const struct io_expander_t *IoExpander, const uint16_t ClearBits)
217 {
218  return IoExpPortWrite(IoExpander, ~ClearBits, ClearBits);
219 }
220 
221 /**********************************************************************/
222 /**
223  * @brief Name: IoExpPortDirection\n
224  * Set IO expander ports to input and output.
225  *
226  * @param IoExpander Parameters for the IO port expander to be used
227  * @param Direction 0 = output, 1 = input
228  * @return true if OK, else false
229  ***********************************************************************/
230 static inline bool IoExpPortDirection(const struct io_expander_t *IoExpander, const uint16_t Direction)
231 {
232  IoExpander->State->Direction = Direction;
233  return IoExpanderWrite(IoExpander, IO_EXPANDER_DIRECTION, Direction);
234 }
235 
236 /**********************************************************************/
237 /**
238  * @brief Name: IoExpPortDriveSet\n
239  * Set output drive strength for IO expander ports.
240  *
241  * @param IoExpander Parameters for the IO port expander to be used
242  * @param Drive Output drive strength data for the port bits
243  * 00 = 25%, 01 = 50%, 10 = 75%, 11 = 100% for each bit
244  * @return true if OK, else false
245  ***********************************************************************/
246 static inline bool IoExpPortDriveSet(const struct io_expander_t *IoExpander, const uint32_t Drive)
247 {
248  if (IoExpanderWrite(IoExpander, IO_EXPANDER_DRIVE_PORT0, (uint16_t)Drive) &&
249  IoExpanderWrite(IoExpander, IO_EXPANDER_DRIVE_PORT1, (uint16_t)(Drive >> 16)))
250  return true;
251  else
252  return false;
253 }
254 
255 /**********************************************************************/
256 /**
257  * @brief Name: IoExpPortPullResistorSet\n
258  * Disables/enables pullup/pulldown resistors for IO expander port pins.
259  *
260  * @param IoExpander Parameters for the IO port expander to be used
261  * @param PullEnable Enable pull resistors for port pins
262  * 0 = disable, 1 = enable
263  * @param PullSelect Sets pullup or polldown resistors for port pins
264  * 0 = 100k pulldown, 1 = 100k pullup
265  * @return true if OK, else false
266  ***********************************************************************/
267 static inline bool IoExpPortPullResistorSet(const struct io_expander_t *IoExpander, const uint16_t PullEnable, const uint16_t PullSelect)
268 {
269  if (IoExpanderWrite(IoExpander, IO_EXPANDER_PULL_SELECT, PullSelect) &&
270  IoExpanderWrite(IoExpander, IO_EXPANDER_PULL_ENABLE, PullEnable))
271  return true;
272  else
273  return false;
274 }
275 
276 /** @} */
277 #endif //DRIVER_IO_EXPANDER_PCAL9535A_H
bool IoExpPortWrite(const struct io_expander_t *IoExpander, const uint8_t Port0, const uint8_t Port1)
Name: IoExpPortWrite Write to IO expander PORT0 and PORT1.
bool IoExpPortInterruptsDisable(const struct io_expander_t *IoExpander, uint16_t Mask)
Name: IoExpPortInterruptsDisable Disable (mask) interrupts for the selected set of pins...
uint16_t IoExpPortInterruptsRead(const struct io_expander_t *IoExpander)
Name: IoExpPortInterruptsRead Read and clear interrupt status from the IO expander.
uint16_t PullSelect
Selects pullup or polldown resistors port pins (0 = 100k pulldown, 1 = 100k pullup) ...
void IoExpPortInterruptsClear(const struct io_expander_t *IoExpander, uint16_t Mask)
Name: IoExpPortInterruptsDisable Clear (remove pending status) interrupts for the selected set of pin...
uint16_t InInvert
Invertion of inputs port pins (0 = no invert, 1 = invert)
uint16_t OutputValues
Last values set for output to IO_EXPANDER_OUTPUT register.
static bool IoExpPortPullResistorSet(const struct io_expander_t *IoExpander, const uint16_t PullEnable, const uint16_t PullSelect)
Name: IoExpPortPullResistorSet Disables/enables pullup/pulldown resistors for IO expander port pins...
struct io_expander_state_t * State
IO expander run-time state.
uint8_t Reserved
Reserved and not used.
bool IoExpPortRead(const struct io_expander_t *IoExpander, uint16_t *In)
Name: IoExpPortRead Read 16-bits data from IO expander ports.
uint16_t InterruptStatus
Pending interrupt status.
uint16_t Direction
Sets the direction of port pins (0 = output, 1 = input)
bool IoExpPortInit(const struct io_expander_t *IoExpander)
Name: IoExpPortInit Initializes I2C-based IO expander type NXP PCAL9535A.
static bool IoExpPortSet(const struct io_expander_t *IoExpander, const uint16_t SetBits)
Name: IoExpPortSet Sets IO expander port bits.
uint16_t InputValues
Last read input values, copy of IO_EXPANDER_INPUT register.
bool IoExpPortInterruptsEnable(const struct io_expander_t *IoExpander, uint16_t Mask)
Name: IoExpPortInterruptsEnable Enable (unmask) interrupts for the selected set of pins...
uint16_t Direction
Current direction state, copy of IO_EXPANDER_DIRECTION register.
static bool IoExpPortDirection(const struct io_expander_t *IoExpander, const uint16_t Direction)
Name: IoExpPortDirection Set IO expander ports to input and output.
uint16_t InterruptMask
Internal interrupt bit mask (0 = disabled, 1 = enabled), inverted copy of IO_EXPANDER_INT_MASK regist...
static bool IoExpPortClear(const struct io_expander_t *IoExpander, const uint16_t ClearBits)
Name: IoExpPortClear Clears IO expander port bits.
uint16_t PullEnable
Enables pull resistors for port pins (0 = disable, 1 = enable)
static bool IoExpPortDriveSet(const struct io_expander_t *IoExpander, const uint32_t Drive)
Name: IoExpPortDriveSet Set output drive strength for IO expander ports.
uint16_t OutInit
Initialize value for output port pins (0 = low output, 1 = high output)