Subversion Repositories idreammicro-avr

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 jlesech 1
/**************************************************************************//**
2
 * \brief Digital I/O library - Implementation
3
 * \author Copyright (C) 2009  Julien Le Sech - www.idreammicro.com
4
 * \version 1.0
5
 * \date 20090314
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 digital_io.c
25
 ******************************************************************************/
26
 
27
/******************************************************************************
28
 * Header file inclusions.
29
 ******************************************************************************/
30
 
31
#include <digital_io/digital_io.h>
64 jlesech 32
 
2 jlesech 33
#include <useful/bits.h>
34
 
35
#include <avr/io.h>
36
 
37
#include <stdint.h>
38
 
39
/******************************************************************************
40
 * Private macro definitions.
41
 ******************************************************************************/
42
 
43
/**************************************************************************//**
64 jlesech 44
 * \def     DIGITAL_IO__PORT_DIRECTION__INPUT
2 jlesech 45
 * \brief
46
 ******************************************************************************/
47
#define DIGITAL_IO__PORT_DIRECTION__INPUT   0x00
48
 
49
/**************************************************************************//**
64 jlesech 50
 * \def     DIGITAL_IO__PORT_DIRECTION__OUTPUT
2 jlesech 51
 * \brief
52
 ******************************************************************************/
53
#define DIGITAL_IO__PORT_DIRECTION__OUTPUT  0xFF
54
 
55
/**************************************************************************//**
64 jlesech 56
 * \def     digital_io__get_index(port)
2 jlesech 57
 * \brief
58
 ******************************************************************************/
59
#define digital_io__get_index(port)         ((port) >> 4)
60
 
61
/******************************************************************************
62
 * Private types.
63
 ******************************************************************************/
64
 
65
/**************************************************************************//**
64 jlesech 66
 * \struct  digital_io__register
67
 * \brief   Digital I/O register.
68
 *
2 jlesech 69
 * \typedef digital_io__register_t
64 jlesech 70
 * \brief   Digital IO register.
2 jlesech 71
 ******************************************************************************/
72
typedef struct digital_io__register
73
{
74
    const uint8_t volatile * const  p_input;
75
    uint8_t volatile * const        p_output;
76
    uint8_t volatile * const        p_direction;
77
} digital_io__register_t;
78
 
79
/******************************************************************************
80
 * Private variable definitions.
81
 ******************************************************************************/
82
 
83
static const digital_io__register_t ports[] =
84
{
85
    #ifdef PORTA
86
    [digital_io__get_index(DIGITAL_IO__PORT_A)]
87
    { // PORT A.
88
        .p_input                = &PINA,
89
        .p_output               = &PORTA,
90
        .p_direction    = &DDRA
91
    },
92
    #endif
93
    #ifdef PORTB
94
    [digital_io__get_index(DIGITAL_IO__PORT_B)]
95
    { // PORT B.
96
        .p_input                = &PINB,
97
        .p_output               = &PORTB,
98
        .p_direction    = &DDRB
99
    },
100
    #endif
101
    #ifdef PORTC
102
    [digital_io__get_index(DIGITAL_IO__PORT_C)]
103
    { // PORT C.
104
        .p_input                = &PINC,
105
        .p_output               = &PORTC,
106
        .p_direction    = &DDRC
107
    },
108
    #endif
109
    #ifdef PORTD
110
    [digital_io__get_index(DIGITAL_IO__PORT_D)]
111
    { // PORT D.
112
        .p_input                = &PIND,
113
        .p_output               = &PORTD,
114
        .p_direction    = &DDRD
115
    },
116
    #endif
117
    #ifdef PORTE
118
    [digital_io__get_index(DIGITAL_IO__PORT_E)]
119
    { // PORT E.
120
        .p_input                = &PINE,
121
        .p_output               = &PORTE,
122
        .p_direction    = &DDRE
123
    },
124
    #endif
125
    #ifdef PORTF
126
    [digital_io__get_index(DIGITAL_IO__PORT_F)]
127
    { // PORT F.
128
        .p_input                = &PINF,
129
        .p_output               = &PORTF,
130
        .p_direction    = &DDRF
131
    },
132
    #endif
133
    #ifdef PORTG
134
    [digital_io__get_index(DIGITAL_IO__PORT_G)]
135
    { // PORT G.
136
        .p_input                = &PING,
137
        .p_output               = &PORTG,
138
        .p_direction    = &DDRG
139
    },
140
    #endif
141
    #ifdef PORTH
142
    [digital_io__get_index(DIGITAL_IO__PORT_H)]
143
    { // PORT H.
144
        .p_input                = &PINH,
145
        .p_output               = &PORTH,
146
        .p_direction    = &DDRH
147
    },
148
    #endif
149
    #ifdef PORTJ
150
    [digital_io__get_index(DIGITAL_IO__PORT_J)]
151
    { // PORT J.
152
        .p_input                = &PINJ,
153
        .p_output               = &PORTJ,
154
        .p_direction    = &DDRJ
155
    },
156
    #endif
157
    #ifdef PORTK
158
    [digital_io__get_index(DIGITAL_IO__PORT_K)] =
159
    { // PORT K.
160
        .p_input                = &PINK,
161
        .p_output               = &PORTK,
162
        .p_direction    = &DDRK
163
    },
164
    #endif
165
    #ifdef PORTL
166
    [digital_io__get_index(DIGITAL_IO__PORT_L)]
167
    { // PORT L.
168
        .p_input                = &PINL,
169
        .p_output               = &PORTL,
170
        .p_direction    = &DDRL
171
    }
172
    #endif
173
};
174
 
175
/******************************************************************************
176
 * Public function definitions.
177
 ******************************************************************************/
178
 
179
/**************************************************************************//**
180
 * \fn void digital_io__configure_pin(
181
 * digital_io__pin_position_t   pin_position,
182
 * digital_io__direction_t      direction)
183
 *
184
 * \brief Configure a pin.
185
 *
186
 * \param[in]   pin_position    pin position to configure
187
 * \param       direction       pin direction
188
 ******************************************************************************/
189
void
190
digital_io__configure_pin
191
(
192
        digital_io__pin_position_t  pin_position,
193
        digital_io__direction_t     direction
194
){
195
        // Alias.
196
        digital_io__register_t const* p_register =
197
        &(ports[digital_io__get_port(pin_position)]);
198
 
199
        if (DIGITAL_IO__DIRECTION__INPUT == direction)
200
        {
201
        BIT__RST(*(p_register->p_direction), digital_io__get_pin(pin_position));
202
        }
203
        else
204
        {
205
        BIT__SET(*(p_register->p_direction), digital_io__get_pin(pin_position));
206
        }
207
}
208
 
209
/**************************************************************************//**
210
 * \fn digital_io__level_t digital_io__get_pin_level(
211
 * digital_io__pin_position_t pin_position)
212
 *
213
 * \brief Get the level of a pin.
214
 *
215
 * \param   pin_position    pin position to get level
216
 *
217
 * \return digital io level
218
 ******************************************************************************/
219
digital_io__level_t
220
digital_io__get_pin_level
221
(
222
        digital_io__pin_position_t  pin_position
223
){
224
        // Alias.
225
        digital_io__register_t const* p_register =
226
        &(ports[digital_io__get_port(pin_position)]);
227
 
228
        digital_io__level_t level =
229
        BIT__TST(*(p_register->p_input), digital_io__get_pin(pin_position)) ?
230
                DIGITAL_IO__LEVEL__HIGH : DIGITAL_IO__LEVEL__LOW;
231
 
232
        return level;
233
}
234
 
235
/**************************************************************************//**
236
 * \fn void digital_io__set_pin_level(
237
 * digital_io__pin_position_t   pin_position,
238
 * digital_io__level_t          level)
239
 *
240
 * \brief Set the level of a pin.
241
 *
242
 * \param[in]   pin_position    pin position to set level
243
 * \param       level           level to set
244
 ******************************************************************************/
245
void
246
digital_io__set_pin_level
247
(
248
        digital_io__pin_position_t  pin_position,
249
        digital_io__level_t         level
250
){
251
        // Alias.
252
        digital_io__register_t const* p_register =
253
        &(ports[digital_io__get_port(pin_position)]);
254
 
255
        if (DIGITAL_IO__LEVEL__LOW == level)
256
        {
257
        BIT__RST(*(p_register->p_output), digital_io__get_pin(pin_position));
258
        }
259
        else
260
        {
261
        BIT__SET(*(p_register->p_output), digital_io__get_pin(pin_position));
262
        }
263
}
264
 
265
/**************************************************************************//**
266
 * \fn void digital_io__toggle_pin_level(
267
 * digital_io__pin_position_t pin_position)
268
 *
269
 * \brief Toggle the level of a pin.
270
 *
271
 * \param   pin_position    pin position to toggle level
272
 ******************************************************************************/
273
void
274
digital_io__toggle_pin_level
275
(
276
        digital_io__pin_position_t  pin_position
277
){
278
    // Alias.
279
    digital_io__register_t const* p_register =
280
        &(ports[digital_io__get_port(pin_position)]);
281
 
282
    BIT__TGL(*(p_register->p_output), digital_io__get_pin(pin_position));
283
}
284
 
285
/**************************************************************************//**
286
 * \fn void digital_io__configure_port(
287
 * digital_io__port_t       port,
288
 * digital_io__direction_t  direction)
289
 *
290
 * \brief Configure a port.
291
 *
292
 * \param   port        port to configure
293
 * \param   direction   port direction to configure
294
 ******************************************************************************/
295
void
296
digital_io__configure_port
297
(
298
    digital_io__port_t      port,
299
    digital_io__direction_t direction
300
){
301
        // Alias.
302
        digital_io__register_t const* p_register =
303
        &(ports[digital_io__get_port(port)]);
304
 
305
        if (DIGITAL_IO__DIRECTION__INPUT == direction)
306
        {
307
                *(p_register->p_direction) = DIGITAL_IO__PORT_DIRECTION__INPUT;
308
        }
309
        else
310
        {
311
                *(p_register->p_direction) = DIGITAL_IO__PORT_DIRECTION__OUTPUT;
312
        }
313
}
314
 
315
/**************************************************************************//**
316
 * \fn uint8_t digital_io__get_port_value(digital_io__port_t port)
317
 *
318
 * \brief Get the value of a port.
319
 *
320
 * \param   port    port to get value
321
 *
322
 * \return port value
323
 ******************************************************************************/
324
digital_io__port_value_t
325
digital_io__get_port_value
326
(
327
    digital_io__port_t  port
328
){
329
        // Alias.
330
        digital_io__register_t const* p_register =
331
        &(ports[digital_io__get_port(port)]);
332
 
333
        uint8_t value = *(p_register->p_input);
334
 
335
        return value;
336
}
337
 
338
/**************************************************************************//**
339
 * \fn void digital_io__set_port_value(
340
 * digital_io__port_t       port,
341
 * digital_io__port_value_t value)
342
 *
343
 * \brief Set the value of a port.
344
 *
345
 * \param   port  port to set value
346
 * \param   value port value to set
347
 ******************************************************************************/
348
void
349
digital_io__set_port_value
350
(
351
    digital_io__port_t          port,
352
    digital_io__port_value_t    value
353
){
354
        // Alias.
355
        digital_io__register_t const* p_register =
356
        &(ports[digital_io__get_port(port)]);
357
 
358
        *(p_register->p_output) = value;
359
}