1 /* ----------------------------------------------------------------------------
\r
2 * ATMEL Microcontroller Software Support
\r
3 * ----------------------------------------------------------------------------
\r
4 * Copyright (c) 2008, Atmel Corporation
\r
6 * All rights reserved.
\r
8 * Redistribution and use in source and binary forms, with or without
\r
9 * modification, are permitted provided that the following conditions are met:
\r
11 * - Redistributions of source code must retain the above copyright notice,
\r
12 * this list of conditions and the disclaimer below.
\r
14 * Atmel's name may not be used to endorse or promote products derived from
\r
15 * this software without specific prior written permission.
\r
17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
\r
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
\r
20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
\r
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
\r
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
\r
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
\r
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\r
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
27 * ----------------------------------------------------------------------------
\r
30 //------------------------------------------------------------------------------
\r
32 //------------------------------------------------------------------------------
\r
37 //------------------------------------------------------------------------------
\r
38 // Internal definitions
\r
39 //------------------------------------------------------------------------------
\r
40 /// \internal Returns the current value of a register.
\r
41 #define READ(peripheral, register) (peripheral->register)
\r
42 /// \internal Modifies the current value of a register.
\r
43 #define WRITE(peripheral, register, value) (peripheral->register = value)
\r
45 //------------------------------------------------------------------------------
\r
46 // Internal functions
\r
47 //------------------------------------------------------------------------------
\r
48 //------------------------------------------------------------------------------
\r
49 /// Configures one or more pin(s) of a PIO controller as being controlled by
\r
50 /// peripheral A. Optionally, the corresponding internal pull-up(s) can be
\r
52 /// \param pio Pointer to a PIO controller.
\r
53 /// \param mask Bitmask of one or more pin(s) to configure.
\r
54 /// \param enablePullUp Indicates if the pin(s) internal pull-up shall be
\r
56 //------------------------------------------------------------------------------
\r
57 static void PIO_SetPeripheralA(AT91S_PIO *pio,
\r
59 unsigned char enablePullUp)
\r
61 // Disable interrupts on the pin(s)
\r
62 WRITE(pio, PIO_IDR, mask);
\r
64 // Enable the pull-up(s) if necessary
\r
67 WRITE(pio, PIO_PPUER, mask);
\r
71 WRITE(pio, PIO_PPUDR, mask);
\r
75 WRITE(pio, PIO_ASR, mask);
\r
76 WRITE(pio, PIO_PDR, mask);
\r
79 //------------------------------------------------------------------------------
\r
80 /// Configures one or more pin(s) of a PIO controller as being controlled by
\r
81 /// peripheral A. Optionally, the corresponding internal pull-up(s) can be
\r
83 /// \param pio Pointer to a PIO controller.
\r
84 /// \param mask Bitmask of one or more pin(s) to configure.
\r
85 /// \param enablePullUp Indicates if the pin(s) internal pull-up shall be
\r
87 //------------------------------------------------------------------------------
\r
88 static void PIO_SetPeripheralB(AT91S_PIO *pio,
\r
90 unsigned char enablePullUp)
\r
92 // Disable interrupts on the pin(s)
\r
93 WRITE(pio, PIO_IDR, mask);
\r
95 // Enable the pull-up(s) if necessary
\r
98 WRITE(pio, PIO_PPUER, mask);
\r
102 WRITE(pio, PIO_PPUDR, mask);
\r
106 WRITE(pio, PIO_BSR, mask);
\r
107 WRITE(pio, PIO_PDR, mask);
\r
110 //------------------------------------------------------------------------------
\r
111 /// Configures one or more pin(s) or a PIO controller as inputs. Optionally,
\r
112 /// the corresponding internal pull-up(s) and glitch filter(s) can be
\r
114 /// \param pio Pointer to a PIO controller.
\r
115 /// \param mask Bitmask indicating which pin(s) to configure as input(s).
\r
116 /// \param enablePullUp Indicates if the internal pull-up(s) must be enabled.
\r
117 /// \param enableFilter Indicates if the glitch filter(s) must be enabled.
\r
118 //------------------------------------------------------------------------------
\r
119 static void PIO_SetInput(AT91S_PIO *pio,
\r
121 unsigned char enablePullUp,
\r
122 unsigned char enableFilter)
\r
124 // Disable interrupts
\r
125 WRITE(pio, PIO_IDR, mask);
\r
127 // Enable pull-up(s) if necessary
\r
128 if (enablePullUp) {
\r
130 WRITE(pio, PIO_PPUER, mask);
\r
134 WRITE(pio, PIO_PPUDR, mask);
\r
137 // Enable filter(s) if necessary
\r
138 if (enableFilter) {
\r
140 WRITE(pio, PIO_IFER, mask);
\r
144 WRITE(pio, PIO_IFDR, mask);
\r
147 // Configure pin as input
\r
148 WRITE(pio, PIO_ODR, mask);
\r
149 WRITE(pio, PIO_PER, mask);
\r
152 //------------------------------------------------------------------------------
\r
153 /// Configures one or more pin(s) of a PIO controller as outputs, with the
\r
154 /// given default value. Optionally, the multi-drive feature can be enabled
\r
156 /// \param pio Pointer to a PIO controller.
\r
157 /// \param mask Bitmask indicating which pin(s) to configure.
\r
158 /// \param defaultValue Default level on the pin(s).
\r
159 /// \param enableMultiDrive Indicates if the pin(s) shall be configured as
\r
161 /// \param enablePullUp Indicates if the pin shall have its pull-up activated.
\r
162 //------------------------------------------------------------------------------
\r
163 static void PIO_SetOutput(AT91S_PIO *pio,
\r
165 unsigned char defaultValue,
\r
166 unsigned char enableMultiDrive,
\r
167 unsigned char enablePullUp)
\r
169 // Disable interrupts
\r
170 WRITE(pio, PIO_IDR, mask);
\r
172 // Enable pull-up(s) if necessary
\r
173 if (enablePullUp) {
\r
175 WRITE(pio, PIO_PPUER, mask);
\r
179 WRITE(pio, PIO_PPUDR, mask);
\r
182 // Enable multi-drive if necessary
\r
183 if (enableMultiDrive) {
\r
185 WRITE(pio, PIO_MDER, mask);
\r
189 WRITE(pio, PIO_MDDR, mask);
\r
192 // Set default value
\r
193 if (defaultValue) {
\r
195 WRITE(pio, PIO_SODR, mask);
\r
199 WRITE(pio, PIO_CODR, mask);
\r
202 // Configure pin(s) as output(s)
\r
203 WRITE(pio, PIO_OER, mask);
\r
204 WRITE(pio, PIO_PER, mask);
\r
207 //------------------------------------------------------------------------------
\r
208 // Exported functions
\r
209 //------------------------------------------------------------------------------
\r
210 //------------------------------------------------------------------------------
\r
211 /// Configures a list of Pin instances, which can either hold a single pin or a
\r
212 /// group of pins, depending on the mask value; all pins are configured by this
\r
214 /// Returns 1 if the configuration has been performed successfully; otherwise 0.
\r
215 /// \param list Pointer to a list of Pin instances.
\r
216 /// \param size Size of the Pin list (see <PIO_LISTSIZE>).
\r
217 //------------------------------------------------------------------------------
\r
218 unsigned char PIO_Configure(const Pin *list, unsigned int size)
\r
223 switch (list->type) {
\r
226 PIO_SetPeripheralA(list->pio,
\r
228 (list->attribute & PIO_PULLUP) ? 1 : 0);
\r
232 PIO_SetPeripheralB(list->pio,
\r
234 (list->attribute & PIO_PULLUP) ? 1 : 0);
\r
238 AT91C_BASE_PMC->PMC_PCER = 1 << list->id;
\r
239 PIO_SetInput(list->pio,
\r
241 (list->attribute & PIO_PULLUP) ? 1 : 0,
\r
242 (list->attribute & PIO_DEGLITCH)? 1 : 0);
\r
247 PIO_SetOutput(list->pio,
\r
249 (list->type == PIO_OUTPUT_1),
\r
250 (list->attribute & PIO_OPENDRAIN) ? 1 : 0,
\r
251 (list->attribute & PIO_PULLUP) ? 1 : 0);
\r
264 //------------------------------------------------------------------------------
\r
265 /// Sets a high output level on one or more pin(s) (if configured as output(s)).
\r
266 /// \param pin Pointer to a Pin instance describing one or more pins.
\r
267 //------------------------------------------------------------------------------
\r
268 void PIO_Set(const Pin *pin)
\r
270 WRITE(pin->pio, PIO_SODR, pin->mask);
\r
273 //------------------------------------------------------------------------------
\r
274 /// Sets a low output level on one or more pin(s) (if configured as output(s)).
\r
275 /// \param pin Pointer to a Pin instance describing one or more pins.
\r
276 //------------------------------------------------------------------------------
\r
277 void PIO_Clear(const Pin *pin)
\r
279 WRITE(pin->pio, PIO_CODR, pin->mask);
\r
282 //------------------------------------------------------------------------------
\r
283 /// Returns 1 if one or more PIO of the given Pin instance currently have a high
\r
284 /// level; otherwise returns 0.
\r
285 /// \param pin Pointer to a Pin instance describing one or more pins.
\r
286 //------------------------------------------------------------------------------
\r
287 unsigned char PIO_Get(const Pin *pin)
\r
290 if ((pin->type == PIO_OUTPUT_0) || (pin->type == PIO_OUTPUT_1)) {
\r
292 reg = READ(pin->pio, PIO_ODSR);
\r
296 reg = READ(pin->pio, PIO_PDSR);
\r
299 if ((reg & pin->mask) == 0) {
\r
310 //------------------------------------------------------------------------------
\r
311 /// Returns 1 if one or more PIO of the given Pin data to be driven on the I/O line
\r
312 /// level; otherwise returns 0.
\r
313 /// \param pin Pointer to a Pin instance describing one or more pins.
\r
314 //------------------------------------------------------------------------------
\r
315 unsigned char PIO_GetOutputDataStatus(const Pin *pin)
\r
317 if ((READ(pin->pio, PIO_ODSR) & pin->mask) == 0) {
\r
327 //------------------------------------------------------------------------------
\r
328 /// Returns the value of ISR for the PIO controller of the pin.
\r
329 /// Reading this register acknoledges all the ITs.
\r
330 /// \param pin Pointer to a Pin instance describing one or more pins.
\r
331 //------------------------------------------------------------------------------
\r
332 unsigned int PIO_GetISR(const Pin *pin)
\r
334 return (READ(pin->pio, PIO_ISR));
\r