summaryrefslogtreecommitdiffstats
path: root/libopencm3/include/libopencm3/lm4f/gpio.h
blob: 5f90ad375712fa10c1a780424d2e77872b8e7f6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
/** @defgroup gpio_defines General Purpose I/O Defines
 *
 * @brief <b>Defined Constants and Types for the LM4F General Purpose I/O</b>
 *
 * @ingroup LM4Fxx_defines
 *
 * @version 1.0.0
 *
 * @author @htmlonly &copy; @endhtmlonly 2011
 * Gareth McMullin <gareth@blacksphere.co.nz>
 * @author @htmlonly &copy; @endhtmlonly 2013
 * Alexandru Gagniuc <mr.nuke.me@gmail.com>
 *
 * @date 16 March 2013
 *
 * LGPL License Terms @ref lgpl_license
 */

/*
 * This file is part of the libopencm3 project.
 *
 * Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz>
 * Copyright (C) 2013 Alexandru Gagniuc <mr.nuke.me@gmail.com>
 *
 * This library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef LM4F_GPIO_H
#define LM4F_GPIO_H

/**@{*/

#include <libopencm3/cm3/common.h>
#include <libopencm3/lm4f/memorymap.h>

/* =============================================================================
 * Convenience macros
 * ---------------------------------------------------------------------------*/
/** @defgroup gpio_reg_base GPIO register base addresses
 * @{*/
#define GPIOA				GPIOA_BASE
#define GPIOB				GPIOB_BASE
#define GPIOC				GPIOC_BASE
#define GPIOD				GPIOD_BASE
#define GPIOE				GPIOE_BASE
#define GPIOF				GPIOF_BASE
#define GPIOG				GPIOG_BASE
#define GPIOH				GPIOH_BASE
#define GPIOJ				GPIOJ_BASE
#define GPIOK				GPIOK_BASE
#define GPIOL				GPIOL_BASE
#define GPIOM				GPIOM_BASE
#define GPION				GPION_BASE
#define GPIOP				GPIOP_BASE
#define GPIOQ				GPIOQ_BASE
/** @} */

/* =============================================================================
 * GPIO number definitions (for convenience)
 *
 * These are usable across all GPIO registers,
 * except GPIO_LOCK and GPIO_PCTL
 * ---------------------------------------------------------------------------*/
/** @defgroup gpio_pin_id GPIO pin identifiers
 * @{*/
#define GPIO0				(1 << 0)
#define GPIO1				(1 << 1)
#define GPIO2				(1 << 2)
#define GPIO3				(1 << 3)
#define GPIO4				(1 << 4)
#define GPIO5				(1 << 5)
#define GPIO6				(1 << 6)
#define GPIO7				(1 << 7)
#define GPIO_ALL			0xff
/** @} */

/* =============================================================================
 * GPIO registers
 * ---------------------------------------------------------------------------*/

/* GPIO Data */
#define GPIO_DATA(port)			(&MMIO32(port + 0x000))

/* GPIO Direction */
#define GPIO_DIR(port)			MMIO32(port + 0x400)

/* GPIO Interrupt Sense */
#define GPIO_IS(port)			MMIO32(port + 0x404)

/* GPIO Interrupt Both Edges */
#define GPIO_IBE(port)			MMIO32(port + 0x408)

/* GPIO Interrupt Event */
#define GPIO_IEV(port)			MMIO32(port + 0x40c)

/* GPIO Interrupt Mask */
#define GPIO_IM(port)			MMIO32(port + 0x410)

/* GPIO Raw Interrupt Status */
#define GPIO_RIS(port)			MMIO32(port + 0x414)

/* GPIO Masked Interrupt Status */
#define GPIO_MIS(port)			MMIO32(port + 0x418)

/* GPIO Interrupt Clear */
#define GPIO_ICR(port)			MMIO32(port + 0x41c)

/* GPIO Alternate Function Select */
#define GPIO_AFSEL(port)		MMIO32(port + 0x420)

/* GPIO 2-mA Drive Select */
#define GPIO_DR2R(port)			MMIO32(port + 0x500)

/* GPIO 4-mA Drive Select */
#define GPIO_DR4R(port)			MMIO32(port + 0x504)

/* GPIO 8-mA Drive Select */
#define GPIO_DR8R(port)			MMIO32(port + 0x508)

/* GPIO Open Drain Select */
#define GPIO_ODR(port)			MMIO32(port + 0x50c)

/* GPIO Pull-Up Select */
#define GPIO_PUR(port)			MMIO32(port + 0x510)

/* GPIO Pull-Down Select */
#define GPIO_PDR(port)			MMIO32(port + 0x514)

/* GPIO Slew Rate Control Select */
#define GPIO_SLR(port)			MMIO32(port + 0x518)

/* GPIO Digital Enable */
#define GPIO_DEN(port)			MMIO32(port + 0x51c)

/* GPIO Lock */
#define GPIO_LOCK(port)			MMIO32(port + 0x520)

/* GPIO Commit */
#define GPIO_CR(port)			MMIO32(port + 0x524)

/* GPIO Analog Mode Select */
#define GPIO_AMSEL(port)		MMIO32(port + 0x528)

/* GPIO Port Control */
#define GPIO_PCTL(port)			MMIO32(port + 0x52C)

/* GPIO ADC Control */
#define GPIO_ADCCTL(port)		MMIO32(port + 0x530)

/* GPIO DMA Control */
#define GPIO_DMACTL(port)		MMIO32(port + 0x534)

/* GPIO Peripheral Identification */
#define GPIO_PERIPH_ID4(port)		MMIO32(port + 0xFD0)
#define GPIO_PERIPH_ID5(port)		MMIO32(port + 0xFD4)
#define GPIO_PERIPH_ID6(port)		MMIO32(port + 0xFD8)
#define GPIO_PERIPH_ID7(port)		MMIO32(port + 0xFDC)
#define GPIO_PERIPH_ID0(port)		MMIO32(port + 0xFE0)
#define GPIO_PERIPH_ID1(port)		MMIO32(port + 0xFE4)
#define GPIO_PERIPH_ID2(port)		MMIO32(port + 0xFE8)
#define GPIO_PERIPH_ID3(port)		MMIO32(port + 0xFEC)

/* GPIO PrimeCell Identification */
#define GPIO_PCELL_ID0(port)		MMIO32(port + 0xFF0)
#define GPIO_PCELL_ID1(port)		MMIO32(port + 0xFF4)
#define GPIO_PCELL_ID2(port)		MMIO32(port + 0xFF8)
#define GPIO_PCELL_ID3(port)		MMIO32(port + 0xFFC)

/* =============================================================================
 * Convenience enums
 * ---------------------------------------------------------------------------*/
enum gpio_mode {
	GPIO_MODE_OUTPUT,	/**< Configure pin as output */
	GPIO_MODE_INPUT,	/**< Configure pin as input */
	GPIO_MODE_ANALOG,	/**< Configure pin as analog function */
};

enum gpio_pullup {
	GPIO_PUPD_NONE,		/**< Do not pull the pin high or low */
	GPIO_PUPD_PULLUP,	/**< Pull the pin high */
	GPIO_PUPD_PULLDOWN,	/**< Pull the pin low */
};

enum gpio_output_type {
	GPIO_OTYPE_PP,		/**< Push-pull configuration */
	GPIO_OTYPE_OD,		/**< Open drain configuration */
};

enum gpio_drive_strength {
	GPIO_DRIVE_2MA,		/**< 2mA drive */
	GPIO_DRIVE_4MA,		/**< 4mA drive */
	GPIO_DRIVE_8MA,		/**< 8mA drive */
	GPIO_DRIVE_8MA_SLEW_CTL,/**< 8mA drive with slew rate control */
};

enum gpio_trigger {
	GPIO_TRIG_LVL_LOW,	/**< Level trigger, signal low */
	GPIO_TRIG_LVL_HIGH,	/**< Level trigger, signal high */
	GPIO_TRIG_EDGE_FALL,	/**< Falling edge trigger */
	GPIO_TRIG_EDGE_RISE,	/**< Rising edge trigger*/
	GPIO_TRIG_EDGE_BOTH,	/**< Falling and Rising edges trigger*/
};
/* =============================================================================
 * Function prototypes
 * ---------------------------------------------------------------------------*/
BEGIN_DECLS

void gpio_enable_ahb_aperture(void);
void gpio_mode_setup(uint32_t gpioport, enum gpio_mode mode,
		     enum gpio_pullup pullup, uint8_t gpios);
void gpio_set_output_config(uint32_t gpioport, enum gpio_output_type otype,
			    enum gpio_drive_strength drive, uint8_t gpios);
void gpio_set_af(uint32_t gpioport, uint8_t alt_func_num, uint8_t gpios);

void gpio_toggle(uint32_t gpioport, uint8_t gpios);
void gpio_unlock_commit(uint32_t gpioport, uint8_t gpios);

/* Let's keep these ones inlined. GPIO control should be fast */
/** @ingroup gpio_control
 * @{ */

/**
 * \brief Get status of a Group of Pins (atomic)
 *
 * Reads the level of the given pins. Bit 0 of the returned data corresponds to
 * GPIO0 level, bit 1 to GPIO1 level. and so on. Bits corresponding to masked
 * pins (corresponding bit of gpios parameter set to zero) are returned as 0.
 *
 * This is an atomic operation.
 *
 * @param[in] gpioport GPIO block register address base @ref gpio_reg_base
 * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified
 *		    by OR'ing then together.
 *
 * @return The level of the GPIO port. The pins not specified in gpios are
 *	   masked to zero.
 */
static inline uint8_t gpio_read(uint32_t gpioport, uint8_t gpios)
{
	return GPIO_DATA(gpioport)[gpios];
}

/**
 * \brief Set level of a Group of Pins (atomic)
 *
 * Sets the level of the given pins. Bit 0 of the data parameter corresponds to
 * GPIO0, bit 1 to GPIO1. and so on. Maskedpins (corresponding bit of gpios
 * parameter set to zero) are returned not affected.
 *
 * This is an atomic operation.
 *
 * @param[in] gpioport GPIO block register address base @ref gpio_reg_base
 * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified
 *		    by OR'ing then together.
 * @param[in] data Level to set pin to. Bit 0 of data corresponds to GPIO0, bit
 *		   1 to GPIO1. and so on.
 */
static inline void gpio_write(uint32_t gpioport, uint8_t gpios, uint8_t data)
{
	/* ipaddr[9:2] mask the bits to be set, hence the array index */
	GPIO_DATA(gpioport)[gpios] = data;
}

/**
 * \brief Set a Group of Pins (atomic)
 *
 * Set one or more pins of the given GPIO port. This is an atomic operation.
 *
 * @param[in] gpioport GPIO block register address base @ref gpio_reg_base
 * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified
 *		    by OR'ing then together.
 */
static inline void gpio_set(uint32_t gpioport, uint8_t gpios)
{
	gpio_write(gpioport, gpios, 0xff);
}

/**
 * \brief Clear a Group of Pins (atomic)
 *
 * Clear one or more pins of the given GPIO port. This is an atomic operation.
 *
 * @param[in] gpioport GPIO block register address base @ref gpio_reg_base
 * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified
 *		    by OR'ing then together.
 */
static inline void gpio_clear(uint32_t gpioport, uint8_t gpios)
{
	gpio_write(gpioport, gpios, 0);
}

/**
 * \brief Read level of all pins from a port (atomic)
 *
 * Read the current value of the given GPIO port. This is an atomic operation.
 *
 * This is functionally identical to @ref gpio_read (gpioport, GPIO_ALL).
 *
 * @param[in] gpioport GPIO block register address base @ref gpio_reg_base
 *
 * @return The level of all the pins on the GPIO port.
 */
static inline uint8_t gpio_port_read(uint32_t gpioport)
{
	return gpio_read(gpioport, GPIO_ALL);
}

/**
 * \brief Set level of of all pins from a port (atomic)
 *
 * Set the level of all pins on the given GPIO port. This is an atomic
 * operation.
 *
 * This is functionally identical to @ref gpio_write (gpioport, GPIO_ALL, data).
 *
 * @param[in] gpioport GPIO block register address base @ref gpio_reg_base
 * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified
 *		    by OR'ing then together.
 * @param[in] data Level to set pin to. Bit 0 of data corresponds to GPIO0, bit
 *		   1 to GPIO1. and so on.
 */
static inline void gpio_port_write(uint32_t gpioport, uint8_t data)
{
	gpio_write(gpioport, GPIO_ALL, data);
}
/** @} */

void gpio_configure_trigger(uint32_t gpioport, enum gpio_trigger trigger,
			    uint8_t gpios);
void gpio_enable_interrupts(uint32_t gpioport, uint8_t gpios);
void gpio_disable_interrupts(uint32_t gpioport, uint8_t gpios);


/* Let's keep these ones inlined. GPIO. They are designed to be used in ISRs */
/** @ingroup gpio_irq
 * @{ */
/** \brief Determine if interrupt is generated by the given pin
 *
 * @param[in] gpioport GPIO block register address base @ref gpio_reg_base
 * @param[in] srcpins source pin or group of pins to check.
 */
static inline bool gpio_is_interrupt_source(uint32_t gpioport, uint8_t srcpins)
{
	return GPIO_MIS(gpioport) & srcpins;
}

/**
 * \brief Mark interrupt as serviced
 *
 * After an interrupt is services, its flag must be cleared. If the flag is not
 * cleared, then execution will jump back to the start of the ISR after the ISR
 * returns.
 *
 * @param[in] gpioport GPIO block register address base @ref gpio_reg_base
 * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified
 *		    by OR'ing then together.
 */
static inline void gpio_clear_interrupt_flag(uint32_t gpioport, uint8_t gpios)
{
	GPIO_ICR(gpioport) |= gpios;
}

/** @} */
END_DECLS

#endif

/**@}*/