Subversion Repositories idreammicro-avr

Rev

Rev 31 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
30 jlesech 1
/**************************************************************************//**
2
 * \brief MCP23008 library
3
 * \author Copyright (C) 2012  Julien Le Sech - www.idreammicro.com
4
 * \version 1.0
5
 * \date 201201025
6
 *
7
 * This file is part of the iDreamMicro library.
8
 *
9
 * This library is free software: you can redistribute it and/or modify it under
10
 * the terms of the GNU Lesser General Public License as published by the Free
11
 * Software Foundation, either version 3 of the License, or (at your option) any
12
 * later version.
13
 *
14
 * This library is distributed in the hope that it will be useful, but WITHOUT
15
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17
 * details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program. If not, see http://www.gnu.org/licenses/
21
 ******************************************************************************/
22
 
23
/**************************************************************************//**
24
 * \file mcp23008.c
25
 ******************************************************************************/
26
 
27
/******************************************************************************
28
 * Header file inclusions.
29
 ******************************************************************************/
30
 
31
#include <mcp23008/mcp23008.h>
32
 
33
#include <twi/twi.h>
34
#include <useful/bits.h>
35
 
36
#include <assert.h>
37
#include <stdint.h>
38
#include <stdlib.h>
39
 
40
/******************************************************************************
41
 * Private macros.
42
 ******************************************************************************/
43
 
44
#define MCP23008__ADDRESS               0x20
45
 
46
#define MCP23008__REG_IODIR             0x00
47
#define MCP23008__REG_IPOL              0x01
48
#define MCP23008__REG_GPINTEN   0x02
49
#define MCP23008__REG_DEFVAL    0x03
50
#define MCP23008__REG_INTCON    0x04
51
#define MCP23008__REG_IOCON             0x05
52
#define MCP23008__REG_GPPU              0x06
53
#define MCP23008__REG_INTF              0x07
54
#define MCP23008__REG_INTCAP    0x08
55
#define MCP23008__REG_GPIO              0x09
56
#define MCP23008__REG_OLAT              0x0A
57
 
58
#define MCP23008__CLOCK_RATE    400000
59
 
60
/******************************************************************************
61
 * Private function prototypes.
62
 ******************************************************************************/
63
 
64
/**************************************************************************//**
65
 *
66
 ******************************************************************************/
67
static
68
uint8_t
69
mcp23008__read_register
70
(
71
    uint8_t address
72
);
73
 
74
/**************************************************************************//**
75
 *
76
 ******************************************************************************/
77
static
78
void
79
mcp23008__write_register
80
(
81
    uint8_t     address,
82
    uint8_t     value
83
);
84
 
85
/******************************************************************************
86
 * Private variable declarations.
87
 ******************************************************************************/
88
 
89
static uint8_t mcp23008__twi_address = 0;
90
 
91
/******************************************************************************
92
 * Public function definitions.
93
 ******************************************************************************/
94
 
95
/**************************************************************************//**
96
 * \fn void mcp23008__initialize(uint8_t hardware_address)
97
 *
98
 * \brief Initialize MCP23008.
99
 *
100
 * \param hardware_address      Hardware address defined by pins A0 to A2.
101
 ******************************************************************************/
102
void
103
mcp23008__initialize
104
(
105
    uint8_t hardware_address
106
){
107
    // Initialize TWI.
108
    twi__initialize(MCP23008__CLOCK_RATE);
109
 
110
    // Compute MCP23008 TWI address.
111
    mcp23008__twi_address = (MCP23008__ADDRESS | hardware_address) << 1;
112
 
113
    twi__start();
114
    twi__send_slaw(mcp23008__twi_address);
115
    twi__send_data(MCP23008__REG_IODIR);
116
    twi__send_data(0xFF);
117
    twi__send_data(0x00);
118
    twi__send_data(0x00);
119
    twi__send_data(0x00);
120
    twi__send_data(0x00);
121
    twi__send_data(0x00);
122
    twi__send_data(0x00);
123
    twi__send_data(0x00);
124
    twi__send_data(0x00);
125
    twi__send_data(0x00);
126
    twi__stop();
127
}
128
 
129
/**************************************************************************//**
130
 *
131
 ******************************************************************************/
132
void
133
mcp23008__configure_pin
134
(
135
 
136
    mcp23008__gpio_t            pin,
137
    mcp23008__direction_t       direction
138
){
139
    uint8_t port_configuration = mcp23008__read_register(MCP23008__REG_IODIR);
140
 
141
    if (MCP23008__DIRECTION__INPUT == direction)
142
    {
143
        BIT__SET(port_configuration, pin);
144
    }
145
    else
146
    {
147
        BIT__RST(port_configuration, pin);
148
    }
149
 
150
    mcp23008__write_register(MCP23008__REG_IODIR, port_configuration);
151
}
152
 
153
/**************************************************************************//**
154
 *
155
 ******************************************************************************/
156
void
157
mcp23008__configure_port
158
(
159
    mcp23008__direction_t direction
160
){
161
    mcp23008__write_register(MCP23008__REG_IODIR, direction);
162
}
163
 
164
/**************************************************************************//**
165
 *
166
 ******************************************************************************/
167
mcp23008__level_t
168
mcp23008__get_pin_level
169
(
170
    mcp23008__gpio_t pin
171
){
172
    uint8_t port_value = mcp23008__read_register(MCP23008__REG_GPIO);
173
 
174
    mcp23008__level_t level = BIT__TST(port_value, pin);
175
 
176
    return level;
177
}
178
 
179
/**************************************************************************//**
180
 *
181
 ******************************************************************************/
182
void
183
mcp23008__set_pin_level
184
(
185
    mcp23008__gpio_t    pin,
186
    mcp23008__level_t   level
187
){
188
    uint8_t port_value = mcp23008__read_register(MCP23008__REG_GPIO);
189
 
190
    if (MCP23008__LEVEL__HIGH == level)
191
    {
192
        BIT__SET(port_value, pin);
193
    }
194
    else
195
    {
196
        BIT__RST(port_value, pin);
197
    }
198
 
199
    mcp23008__write_register(MCP23008__REG_GPIO, port_value);
200
}
201
 
202
/**************************************************************************//**
203
 *
204
 ******************************************************************************/
205
uint8_t
206
mcp23008__get_port_value
207
(
208
    void
209
){
210
    uint8_t value = mcp23008__read_register(MCP23008__REG_GPIO);
211
 
212
    return value;
213
}
214
 
215
/**************************************************************************//**
216
 *
217
 ******************************************************************************/
218
void
219
mcp23008__set_port_value
220
(
221
    uint8_t value
222
){
223
    mcp23008__write_register(MCP23008__REG_GPIO, value);
224
}
225
 
226
/******************************************************************************
227
 * Private function definitions.
228
 ******************************************************************************/
229
 
230
/**************************************************************************//**
231
 *
232
 ******************************************************************************/
233
static
234
uint8_t
235
mcp23008__read_register
236
(
237
    uint8_t address
238
){
239
    uint8_t value = 0;
240
 
241
    twi__start();
242
    twi__send_slaw(mcp23008__twi_address);
243
    twi__send_data(address);
244
    twi__stop();
245
 
246
    twi__start();
247
    twi__send_slar(mcp23008__twi_address);
248
    twi__receive_data_nack(&value);
249
    twi__stop();
250
 
251
    return value;
252
}
253
 
254
/**************************************************************************//**
255
 *
256
 ******************************************************************************/
257
static
258
void
259
mcp23008__write_register
260
(
261
    uint8_t     address,
262
    uint8_t     value
263
){
264
    twi__start();
265
    twi__send_slaw(mcp23008__twi_address);
266
    twi__send_data(address);
267
    twi__send_data(value);
268
    twi__stop();
269
}