User | Revision | Line number | New contents of line |
dewyatt |
0:4f712bd739d0
|
1
|
#include "mbed.h"
|
dewyatt |
0:4f712bd739d0
|
2
|
|
dewyatt |
0:4f712bd739d0
|
3
|
/** MCP23008 class
|
dewyatt |
0:4f712bd739d0
|
4
|
*
|
dewyatt |
0:4f712bd739d0
|
5
|
* Allow access to an I2C connected MCP23008 8-bit I/O extender chip
|
dewyatt |
0:4f712bd739d0
|
6
|
*
|
dewyatt |
0:4f712bd739d0
|
7
|
*/
|
dewyatt |
0:4f712bd739d0
|
8
|
class MCP23008 {
|
dewyatt |
0:4f712bd739d0
|
9
|
public:
|
dewyatt |
0:4f712bd739d0
|
10
|
enum Frequency {
|
dewyatt |
0:4f712bd739d0
|
11
|
Frequency_100KHz = 100000,
|
dewyatt |
0:4f712bd739d0
|
12
|
Frequency_400KHz = 400000,
|
dewyatt |
0:4f712bd739d0
|
13
|
/* Note: 1.7MHz probably won't work for mbed */
|
dewyatt |
0:4f712bd739d0
|
14
|
Frequency_1700KHz = 1700000
|
dewyatt |
0:4f712bd739d0
|
15
|
};
|
dewyatt |
0:4f712bd739d0
|
16
|
enum Pin {
|
dewyatt |
0:4f712bd739d0
|
17
|
Pin_GP0 = 0x01,
|
dewyatt |
0:4f712bd739d0
|
18
|
Pin_GP1 = 0x02,
|
dewyatt |
0:4f712bd739d0
|
19
|
Pin_GP2 = 0x04,
|
dewyatt |
0:4f712bd739d0
|
20
|
Pin_GP3 = 0x08,
|
dewyatt |
0:4f712bd739d0
|
21
|
Pin_GP4 = 0x10,
|
dewyatt |
0:4f712bd739d0
|
22
|
Pin_GP5 = 0x20,
|
dewyatt |
0:4f712bd739d0
|
23
|
Pin_GP6 = 0x40,
|
dewyatt |
0:4f712bd739d0
|
24
|
Pin_GP7 = 0x80,
|
dewyatt |
0:4f712bd739d0
|
25
|
Pin_All = 0xFF
|
dewyatt |
0:4f712bd739d0
|
26
|
};
|
dewyatt |
0:4f712bd739d0
|
27
|
/** Constructor
|
dewyatt |
0:4f712bd739d0
|
28
|
*
|
dewyatt |
0:4f712bd739d0
|
29
|
* @param sda I2C sda pin
|
dewyatt |
0:4f712bd739d0
|
30
|
* @param scl I2C scl pin
|
dewyatt |
0:4f712bd739d0
|
31
|
* @param address The hardware address of the MCP23008. This is the 3-bit
|
dewyatt |
0:4f712bd739d0
|
32
|
* value that is physically set via A0, A1, and A2.
|
dewyatt |
0:4f712bd739d0
|
33
|
* @param freq The I2C frequency. Should probably be 100KHz or 400KHz.
|
dewyatt |
0:4f712bd739d0
|
34
|
*/
|
dewyatt |
0:4f712bd739d0
|
35
|
MCP23008 ( PinName sda, PinName scl, uint8_t address, Frequency freq = Frequency_100KHz );
|
dewyatt |
0:4f712bd739d0
|
36
|
|
dewyatt |
0:4f712bd739d0
|
37
|
/** Set pins to input mode
|
dewyatt |
0:4f712bd739d0
|
38
|
*
|
dewyatt |
0:4f712bd739d0
|
39
|
* This function is used to set which pins are inputs (if any). Example:
|
dewyatt |
0:4f712bd739d0
|
40
|
* set_inputs ( Pin_GP0 | Pin_GP1 | Pin_GP2 );
|
dewyatt |
0:4f712bd739d0
|
41
|
* Note that these are set to input in addition to the previously set.
|
dewyatt |
0:4f712bd739d0
|
42
|
* In other words, the following:
|
dewyatt |
0:4f712bd739d0
|
43
|
* set_inputs ( Pin_GP1 );
|
dewyatt |
0:4f712bd739d0
|
44
|
* set_inputs ( Pin_GP2 );
|
dewyatt |
0:4f712bd739d0
|
45
|
* Results in at least two pins set to input.
|
dewyatt |
0:4f712bd739d0
|
46
|
*
|
dewyatt |
0:4f712bd739d0
|
47
|
* @param pins A bitmask of pins to set to input mode.
|
dewyatt |
0:4f712bd739d0
|
48
|
*/
|
dewyatt |
0:4f712bd739d0
|
49
|
void set_input_pins ( uint8_t pins );
|
dewyatt |
0:4f712bd739d0
|
50
|
/** Set pins to output mode
|
dewyatt |
0:4f712bd739d0
|
51
|
*
|
dewyatt |
0:4f712bd739d0
|
52
|
* This function is used to set which pins are outputs (if any). Example:
|
dewyatt |
0:4f712bd739d0
|
53
|
* set_outputs ( Pin_GP0 | Pin_GP1 | Pin_GP2 );
|
dewyatt |
0:4f712bd739d0
|
54
|
* Note that these are set to output in addition to the previously set.
|
dewyatt |
0:4f712bd739d0
|
55
|
* In other words, the following:
|
dewyatt |
0:4f712bd739d0
|
56
|
* set_outputs ( Pin_GP1 );
|
dewyatt |
0:4f712bd739d0
|
57
|
* set_outputs ( Pin_GP2 );
|
dewyatt |
0:4f712bd739d0
|
58
|
* Results in at least two pins set to output.
|
dewyatt |
0:4f712bd739d0
|
59
|
*
|
dewyatt |
0:4f712bd739d0
|
60
|
* @param pins A bitmask of pins to set to output mode.
|
dewyatt |
0:4f712bd739d0
|
61
|
*/
|
dewyatt |
0:4f712bd739d0
|
62
|
void set_output_pins ( uint8_t pins );
|
dewyatt |
0:4f712bd739d0
|
63
|
|
dewyatt |
0:4f712bd739d0
|
64
|
/** Write to the output pins.
|
dewyatt |
0:4f712bd739d0
|
65
|
*
|
dewyatt |
0:4f712bd739d0
|
66
|
* This function is used to set output pins on or off.
|
dewyatt |
0:4f712bd739d0
|
67
|
*
|
dewyatt |
0:4f712bd739d0
|
68
|
* @param values A bitmask indicating whether a pin should be on or off.
|
dewyatt |
0:4f712bd739d0
|
69
|
*/
|
dewyatt |
0:4f712bd739d0
|
70
|
void write_outputs ( uint8_t values );
|
dewyatt |
0:4f712bd739d0
|
71
|
/** Read back the outputs.
|
dewyatt |
0:4f712bd739d0
|
72
|
*
|
dewyatt |
0:4f712bd739d0
|
73
|
* This function is used to read the last values written to the output pins.
|
dewyatt |
0:4f712bd739d0
|
74
|
*
|
dewyatt |
0:4f712bd739d0
|
75
|
* @returns The value from the OLAT register.
|
dewyatt |
0:4f712bd739d0
|
76
|
*/
|
dewyatt |
0:4f712bd739d0
|
77
|
uint8_t read_outputs ();
|
dewyatt |
0:4f712bd739d0
|
78
|
|
dewyatt |
0:4f712bd739d0
|
79
|
/** Read from the input pins.
|
dewyatt |
0:4f712bd739d0
|
80
|
*
|
dewyatt |
0:4f712bd739d0
|
81
|
* This function is used to read the values from the input pins.
|
dewyatt |
0:4f712bd739d0
|
82
|
*
|
dewyatt |
0:4f712bd739d0
|
83
|
* @returns A bitmask of the current state of the input pins.
|
dewyatt |
0:4f712bd739d0
|
84
|
*/
|
dewyatt |
0:4f712bd739d0
|
85
|
uint8_t read_inputs ();
|
dewyatt |
0:4f712bd739d0
|
86
|
|
dewyatt |
0:4f712bd739d0
|
87
|
/** Set the input pin polarity.
|
dewyatt |
0:4f712bd739d0
|
88
|
*
|
dewyatt |
0:4f712bd739d0
|
89
|
* This function sets the polarity of the input pins.
|
dewyatt |
0:4f712bd739d0
|
90
|
* A 1 bit is inverted polarity, a 0 is normal.
|
dewyatt |
0:4f712bd739d0
|
91
|
*
|
dewyatt |
0:4f712bd739d0
|
92
|
* @param values A bitmask of the input polarity.
|
dewyatt |
0:4f712bd739d0
|
93
|
*/
|
dewyatt |
0:4f712bd739d0
|
94
|
void set_input_polarity ( uint8_t values );
|
dewyatt |
0:4f712bd739d0
|
95
|
/** Read back the current input pin polarity.
|
dewyatt |
0:4f712bd739d0
|
96
|
*
|
dewyatt |
0:4f712bd739d0
|
97
|
* This function reads the current state of the input pin polarity.
|
dewyatt |
0:4f712bd739d0
|
98
|
*
|
dewyatt |
0:4f712bd739d0
|
99
|
* @returns The value from the IPOL register.
|
dewyatt |
0:4f712bd739d0
|
100
|
*/
|
dewyatt |
0:4f712bd739d0
|
101
|
uint8_t get_input_polarity ();
|
dewyatt |
0:4f712bd739d0
|
102
|
|
dewyatt |
0:4f712bd739d0
|
103
|
/** Enable and disable the internal pull-up resistors for input pins.
|
dewyatt |
0:4f712bd739d0
|
104
|
*
|
dewyatt |
0:4f712bd739d0
|
105
|
* This function enables the internal 100 kΩ pull-up resistors.
|
dewyatt |
0:4f712bd739d0
|
106
|
* A 1 bit enables the pull-up resistor for the corresponding input pin.
|
dewyatt |
0:4f712bd739d0
|
107
|
*
|
dewyatt |
0:4f712bd739d0
|
108
|
* @param values A bitmask indicating which pull-up resistors should be enabled/disabled.
|
dewyatt |
0:4f712bd739d0
|
109
|
*/
|
dewyatt |
0:4f712bd739d0
|
110
|
void set_pullups ( uint8_t values );
|
dewyatt |
0:4f712bd739d0
|
111
|
/** Get the current state of the internal pull-up resistors.
|
dewyatt |
0:4f712bd739d0
|
112
|
*
|
dewyatt |
0:4f712bd739d0
|
113
|
* @returns The current state of the pull-up resistors.
|
dewyatt |
0:4f712bd739d0
|
114
|
*/
|
dewyatt |
0:4f712bd739d0
|
115
|
uint8_t get_pullups ();
|
dewyatt |
0:4f712bd739d0
|
116
|
|
dewyatt |
0:4f712bd739d0
|
117
|
/** Generate an interrupt when a pin changes.
|
dewyatt |
0:4f712bd739d0
|
118
|
*
|
dewyatt |
0:4f712bd739d0
|
119
|
* This function enables interrupt generation for the specified pins.
|
dewyatt |
0:4f712bd739d0
|
120
|
* The interrupt is active-low by default.
|
dewyatt |
0:4f712bd739d0
|
121
|
* The function acknowledge_interrupt must be called before another
|
dewyatt |
0:4f712bd739d0
|
122
|
* interrupt will be generated.
|
dewyatt |
0:4f712bd739d0
|
123
|
* Example:
|
dewyatt |
0:4f712bd739d0
|
124
|
* @code
|
dewyatt |
0:4f712bd739d0
|
125
|
* InterruptIn in ( p16 );
|
dewyatt |
0:4f712bd739d0
|
126
|
* MCP23008 mcp ( p9, p10, 0 );
|
dewyatt |
0:4f712bd739d0
|
127
|
* in.fall ( &interrupt );
|
dewyatt |
0:4f712bd739d0
|
128
|
* mcp.interrupt_on_changes ( MCP23008::Pin_GP0 );
|
dewyatt |
0:4f712bd739d0
|
129
|
* while ( 1 ) {
|
dewyatt |
0:4f712bd739d0
|
130
|
* wait ( 1 );
|
dewyatt |
0:4f712bd739d0
|
131
|
* }
|
dewyatt |
0:4f712bd739d0
|
132
|
* @endcode
|
dewyatt |
0:4f712bd739d0
|
133
|
*
|
dewyatt |
0:4f712bd739d0
|
134
|
* @param pins A bitmask of the pins that may generate an interrupt.
|
dewyatt |
0:4f712bd739d0
|
135
|
*/
|
dewyatt |
0:4f712bd739d0
|
136
|
void interrupt_on_changes ( uint8_t pins );
|
dewyatt |
0:4f712bd739d0
|
137
|
/** Disables interrupts for the specified pins.
|
dewyatt |
0:4f712bd739d0
|
138
|
*
|
dewyatt |
0:4f712bd739d0
|
139
|
* @param values A bitmask indicating which interrupts should be disabled.
|
dewyatt |
0:4f712bd739d0
|
140
|
*/
|
dewyatt |
0:4f712bd739d0
|
141
|
void disable_interrupts ( uint8_t pins );
|
dewyatt |
0:4f712bd739d0
|
142
|
|
dewyatt |
0:4f712bd739d0
|
143
|
/** Acknowledge a generated interrupt.
|
dewyatt |
0:4f712bd739d0
|
144
|
*
|
dewyatt |
0:4f712bd739d0
|
145
|
* This function must be called when an interrupt is generated to discover
|
dewyatt |
0:4f712bd739d0
|
146
|
* which pin caused the interrupt and to enable future interrupts.
|
dewyatt |
0:4f712bd739d0
|
147
|
*
|
dewyatt |
0:4f712bd739d0
|
148
|
* @param pin An output paramter that specifies which pin generated the interrupt.
|
dewyatt |
0:4f712bd739d0
|
149
|
* @param values The current state of the input pins.
|
dewyatt |
0:4f712bd739d0
|
150
|
*/
|
dewyatt |
0:4f712bd739d0
|
151
|
void acknowledge_interrupt ( uint8_t &pin, uint8_t &values );
|
dewyatt |
0:4f712bd739d0
|
152
|
|
dewyatt |
0:4f712bd739d0
|
153
|
private:
|
dewyatt |
0:4f712bd739d0
|
154
|
uint8_t read_register ( uint8_t reg );
|
dewyatt |
0:4f712bd739d0
|
155
|
void write_register ( uint8_t reg, uint8_t value );
|
dewyatt |
0:4f712bd739d0
|
156
|
void write_mask ( uint8_t reg, uint8_t mask, bool value );
|
dewyatt |
0:4f712bd739d0
|
157
|
|
dewyatt |
0:4f712bd739d0
|
158
|
void reset ();
|
dewyatt |
0:4f712bd739d0
|
159
|
|
dewyatt |
0:4f712bd739d0
|
160
|
I2C i2c;
|
dewyatt |
0:4f712bd739d0
|
161
|
uint8_t i2c_address;
|
dewyatt |
0:4f712bd739d0
|
162
|
};
|