2013-01-12 23:44:42 +01:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* 3. Neither the name of the copyright holder nor the names of its
|
|
|
|
* contributors may be used to endorse or promote products derived
|
|
|
|
* from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
|
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
|
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
* \addtogroup cc2538
|
|
|
|
* @{
|
|
|
|
*
|
|
|
|
* \defgroup cc2538-gpio cc2538 General-Purpose I/O
|
|
|
|
*
|
|
|
|
* Driver for the cc2538 GPIO controller
|
|
|
|
* @{
|
|
|
|
*
|
|
|
|
* \file
|
|
|
|
* Header file with register and macro declarations for the cc2538 GPIO module
|
|
|
|
*/
|
|
|
|
#ifndef GPIO_H_
|
|
|
|
#define GPIO_H_
|
|
|
|
|
|
|
|
#include "reg.h"
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Type definition for callbacks invoked by the GPIO ISRs
|
|
|
|
* \param port The port that triggered the GPIO interrupt. \e port is passed
|
|
|
|
* by its numeric representation (Port A:0, B:1 etc). Defines for
|
|
|
|
* these numeric representations are GPIO_x_NUM
|
|
|
|
* \param pin The pin that triggered the interrupt, specified by number
|
|
|
|
* (0, 1, ..., 7)
|
|
|
|
*
|
|
|
|
* This is the prototype of a function pointer passed to
|
|
|
|
* gpio_register_callback(). These callbacks are registered on a port/pin
|
|
|
|
* basis. When a GPIO port generates an interrupt, if a callback has been
|
|
|
|
* registered for the port/pin combination, the ISR will invoke it. The ISR
|
|
|
|
* will pass the port/pin as arguments in that call, so that a developer can
|
|
|
|
* re-use the same callback for multiple port/pin combinations
|
|
|
|
*/
|
|
|
|
typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin);
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name Base addresses for the GPIO register instances
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_A_BASE 0x400D9000 /**< GPIO_A */
|
|
|
|
#define GPIO_B_BASE 0x400DA000 /**< GPIO_B */
|
|
|
|
#define GPIO_C_BASE 0x400DB000 /**< GPIO_C */
|
|
|
|
#define GPIO_D_BASE 0x400DC000 /**< GPIO_D */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name Numeric representation of the four GPIO ports
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_A_NUM 0 /**< GPIO_A: 0 */
|
|
|
|
#define GPIO_B_NUM 1 /**< GPIO_B: 1 */
|
|
|
|
#define GPIO_C_NUM 2 /**< GPIO_C: 2 */
|
|
|
|
#define GPIO_D_NUM 3 /**< GPIO_D: 3 */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
|
|
* \name GPIO Manipulation macros
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
/** \brief Set pins with PIN_MASK of port with PORT_BASE to input.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_SET_INPUT(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_DIR) &= ~(PIN_MASK); } while(0)
|
2013-01-12 23:44:42 +01:00
|
|
|
|
|
|
|
/** \brief Set pins with PIN_MASK of port with PORT_BASE to output.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_SET_OUTPUT(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_DIR) |= (PIN_MASK); } while(0)
|
2013-01-12 23:44:42 +01:00
|
|
|
|
2013-09-05 21:09:31 +02:00
|
|
|
/** \brief Set pins with PIN_MASK of port with PORT_BASE high.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_SET_PIN(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_DATA + ((PIN_MASK) << 2)) = 0xFF; } while(0)
|
2013-09-05 21:09:31 +02:00
|
|
|
|
|
|
|
/** \brief Set pins with PIN_MASK of port with PORT_BASE low.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_CLR_PIN(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_DATA + ((PIN_MASK) << 2)) = 0x00; } while(0)
|
2013-09-05 21:09:31 +02:00
|
|
|
|
2013-11-15 19:48:24 +01:00
|
|
|
/** \brief Set pins with PIN_MASK of port with PORT_BASE to value.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
2015-02-14 01:44:06 +01:00
|
|
|
* \param value The new value to write to the register. Only pins specified
|
|
|
|
* by PIN_MASK will be set.
|
|
|
|
*
|
|
|
|
* \note The outcome of this macro invocation will be to write to the register
|
|
|
|
* a new value for multiple pins. For that reason, the value argument cannot be
|
|
|
|
* a simple 0 or 1. Instead, it must be the value corresponding to the pins that
|
|
|
|
* you wish to set.
|
|
|
|
*
|
|
|
|
* Thus, if you only want to set a single pin (e.g. pin 2), do \e not pass 1,
|
|
|
|
* but you must pass 0x04 instead (1 << 2). This may seem counter-intuitive at
|
|
|
|
* first glance, but it allows a single invocation of this macro to set
|
|
|
|
* multiple pins in one go if so desired. For example, you can set pins 3 and 1
|
|
|
|
* and the same time clear pins 2 and 0. To do so, pass 0x0F as the PIN_MASK
|
|
|
|
* and then use 0x0A as the value ((1 << 3) | (1 << 1) for pins 3 and 1)
|
2013-11-15 19:48:24 +01:00
|
|
|
*/
|
|
|
|
#define GPIO_WRITE_PIN(PORT_BASE, PIN_MASK, value) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_DATA + ((PIN_MASK) << 2)) = (value); } while(0)
|
2013-11-15 19:48:24 +01:00
|
|
|
|
|
|
|
/** \brief Read pins with PIN_MASK of port with PORT_BASE.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
2015-02-14 01:44:06 +01:00
|
|
|
* \return The value of the pins specified by PIN_MASK
|
|
|
|
*
|
|
|
|
* This macro will \e not return 0 or 1. Instead, it will return the values of
|
|
|
|
* the pins specified by PIN_MASK ORd together. Thus, if you pass 0xC3
|
|
|
|
* (0x80 | 0x40 | 0x02 | 0x01) as the PIN_MASK and pins 7 and 0 are high,
|
|
|
|
* the macro will return 0x81.
|
2013-11-15 19:48:24 +01:00
|
|
|
*/
|
|
|
|
#define GPIO_READ_PIN(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
REG((PORT_BASE) + GPIO_DATA + ((PIN_MASK) << 2))
|
2013-11-15 19:48:24 +01:00
|
|
|
|
2013-01-12 23:44:42 +01:00
|
|
|
/** \brief Set pins with PIN_MASK of port with PORT_BASE to detect edge.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_DETECT_EDGE(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_IS) &= ~(PIN_MASK); } while(0)
|
2013-01-12 23:44:42 +01:00
|
|
|
|
|
|
|
/** \brief Set pins with PIN_MASK of port with PORT_BASE to detect level.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_DETECT_LEVEL(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_IS) |= (PIN_MASK); } while(0)
|
2013-01-12 23:44:42 +01:00
|
|
|
|
|
|
|
/** \brief Set pins with PIN_MASK of port with PORT_BASE to trigger an
|
|
|
|
* interrupt on both edges.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_TRIGGER_BOTH_EDGES(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_IBE) |= (PIN_MASK); } while(0)
|
2013-01-12 23:44:42 +01:00
|
|
|
|
|
|
|
/** \brief Set pins with PIN_MASK of port with PORT_BASE to trigger an
|
|
|
|
* interrupt on single edge (controlled by GPIO_IEV).
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_TRIGGER_SINGLE_EDGE(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_IBE) &= ~(PIN_MASK); } while(0)
|
2013-01-12 23:44:42 +01:00
|
|
|
|
|
|
|
/** \brief Set pins with PIN_MASK of port with PORT_BASE to trigger an
|
|
|
|
* interrupt on rising edge.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_DETECT_RISING(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_IEV) |= (PIN_MASK); } while(0)
|
2013-01-12 23:44:42 +01:00
|
|
|
|
|
|
|
/** \brief Set pins with PIN_MASK of port with PORT_BASE to trigger an
|
|
|
|
* interrupt on falling edge.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_DETECT_FALLING(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_IEV) &= ~(PIN_MASK); } while(0)
|
2013-01-12 23:44:42 +01:00
|
|
|
|
|
|
|
/** \brief Enable interrupt triggering for pins with PIN_MASK of port with
|
|
|
|
* PORT_BASE.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_ENABLE_INTERRUPT(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_IE) |= (PIN_MASK); } while(0)
|
2013-01-12 23:44:42 +01:00
|
|
|
|
|
|
|
/** \brief Disable interrupt triggering for pins with PIN_MASK of port with
|
|
|
|
* PORT_BASE.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_DISABLE_INTERRUPT(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_IE) &= ~(PIN_MASK); } while(0)
|
2013-01-12 23:44:42 +01:00
|
|
|
|
2015-04-08 22:49:50 +02:00
|
|
|
/** \brief Get raw interrupt status of port with PORT_BASE.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \return Bit-mask reflecting the raw interrupt status of all the port pins
|
|
|
|
*
|
|
|
|
* The bits set in the returned bit-mask reflect the status of the interrupts
|
|
|
|
* trigger conditions detected (raw, before interrupt masking), indicating that
|
|
|
|
* all the requirements are met, before they are finally allowed to trigger by
|
|
|
|
* the interrupt mask. The bits cleared indicate that corresponding input pins
|
|
|
|
* have not initiated an interrupt.
|
|
|
|
*/
|
|
|
|
#define GPIO_GET_RAW_INT_STATUS(PORT_BASE) \
|
|
|
|
REG((PORT_BASE) + GPIO_RIS)
|
|
|
|
|
|
|
|
/** \brief Get masked interrupt status of port with PORT_BASE.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \return Bit-mask reflecting the masked interrupt status of all the port pins
|
|
|
|
*
|
|
|
|
* The bits set in the returned bit-mask reflect the status of input lines
|
|
|
|
* triggering an interrupt. The bits cleared indicate that either no interrupt
|
|
|
|
* has been generated, or the interrupt is masked. This is the state of the
|
|
|
|
* interrupt after interrupt masking.
|
|
|
|
*/
|
|
|
|
#define GPIO_GET_MASKED_INT_STATUS(PORT_BASE) \
|
|
|
|
REG((PORT_BASE) + GPIO_MIS)
|
|
|
|
|
2013-11-15 19:48:24 +01:00
|
|
|
/** \brief Clear interrupt triggering for pins with PIN_MASK of port with
|
|
|
|
* PORT_BASE.
|
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_CLEAR_INTERRUPT(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_IC) = (PIN_MASK); } while(0)
|
2013-11-15 19:48:24 +01:00
|
|
|
|
2013-09-05 21:09:31 +02:00
|
|
|
/** \brief Configure the pin to be under peripheral control with PIN_MASK of
|
|
|
|
* port with PORT_BASE.
|
2013-01-12 23:44:42 +01:00
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_PERIPHERAL_CONTROL(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_AFSEL) |= (PIN_MASK); } while(0)
|
2013-01-12 23:44:42 +01:00
|
|
|
|
2013-09-05 21:09:31 +02:00
|
|
|
/** \brief Configure the pin to be software controlled with PIN_MASK of port
|
|
|
|
* with PORT_BASE.
|
2013-01-12 23:44:42 +01:00
|
|
|
* \param PORT_BASE GPIO Port register offset
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_SOFTWARE_CONTROL(PORT_BASE, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG((PORT_BASE) + GPIO_AFSEL) &= ~(PIN_MASK); } while(0)
|
2013-01-12 23:44:42 +01:00
|
|
|
|
2013-11-26 22:10:47 +01:00
|
|
|
/** \brief Set pins with PIN_MASK of port PORT to trigger a power-up interrupt
|
|
|
|
* on rising edge.
|
|
|
|
* \param PORT GPIO Port (not port base address)
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_POWER_UP_ON_RISING(PORT, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_P_EDGE_CTRL) &= \
|
2013-11-26 22:10:47 +01:00
|
|
|
~((PIN_MASK) << ((PORT) << 3)); } while(0)
|
|
|
|
|
|
|
|
/** \brief Set pins with PIN_MASK of port PORT to trigger a power-up interrupt
|
|
|
|
* on falling edge.
|
|
|
|
* \param PORT GPIO Port (not port base address)
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_POWER_UP_ON_FALLING(PORT, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_P_EDGE_CTRL) |= \
|
2013-11-26 22:10:47 +01:00
|
|
|
(PIN_MASK) << ((PORT) << 3); } while(0)
|
|
|
|
|
|
|
|
/** \brief Enable power-up interrupt triggering for pins with PIN_MASK of port
|
|
|
|
* PORT.
|
|
|
|
* \param PORT GPIO Port (not port base address)
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_ENABLE_POWER_UP_INTERRUPT(PORT, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_PI_IEN) |= \
|
2013-11-26 22:10:47 +01:00
|
|
|
(PIN_MASK) << ((PORT) << 3); } while(0)
|
|
|
|
|
|
|
|
/** \brief Disable power-up interrupt triggering for pins with PIN_MASK of port
|
|
|
|
* PORT.
|
|
|
|
* \param PORT GPIO Port (not port base address)
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_DISABLE_POWER_UP_INTERRUPT(PORT, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_PI_IEN) &= \
|
2013-11-26 22:10:47 +01:00
|
|
|
~((PIN_MASK) << ((PORT) << 3)); } while(0)
|
|
|
|
|
2015-04-08 22:49:50 +02:00
|
|
|
/** \brief Get power-up interrupt status of port PORT.
|
|
|
|
* \param PORT GPIO Port (not port base address)
|
|
|
|
* \return Bit-mask reflecting the power-up interrupt status of all the port
|
|
|
|
* pins
|
|
|
|
*/
|
|
|
|
#define GPIO_GET_POWER_UP_INT_STATUS(PORT) \
|
|
|
|
((REG(GPIO_PORT_TO_BASE(PORT) + GPIO_IRQ_DETECT_ACK) >> ((PORT) << 3)) & 0xFF)
|
|
|
|
|
2013-11-26 22:10:47 +01:00
|
|
|
/** \brief Clear power-up interrupt triggering for pins with PIN_MASK of port
|
|
|
|
* PORT.
|
|
|
|
* \param PORT GPIO Port (not port base address)
|
|
|
|
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
|
|
|
*/
|
|
|
|
#define GPIO_CLEAR_POWER_UP_INTERRUPT(PORT, PIN_MASK) \
|
Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:16:17 +01:00
|
|
|
do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_IRQ_DETECT_ACK) = \
|
2013-11-26 22:10:47 +01:00
|
|
|
(PIN_MASK) << ((PORT) << 3); } while(0)
|
|
|
|
|
2013-01-12 23:44:42 +01:00
|
|
|
/**
|
|
|
|
* \brief Converts a pin number to a pin mask
|
2015-02-14 01:44:06 +01:00
|
|
|
* \param PIN The pin number in the range [0..7]
|
2013-01-12 23:44:42 +01:00
|
|
|
* \return A pin mask which can be used as the PIN_MASK argument of the macros
|
|
|
|
* in this category
|
|
|
|
*/
|
2013-11-15 19:43:06 +01:00
|
|
|
#define GPIO_PIN_MASK(PIN) (1 << (PIN))
|
2013-09-05 20:59:56 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Converts a port number to the port base address
|
2015-02-14 01:44:06 +01:00
|
|
|
* \param PORT The port number in the range 0 - 3. Likely GPIO_X_NUM.
|
2013-09-05 20:59:56 +02:00
|
|
|
* \return The base address for the registers corresponding to that port
|
|
|
|
* number.
|
|
|
|
*/
|
2013-11-15 19:43:06 +01:00
|
|
|
#define GPIO_PORT_TO_BASE(PORT) (GPIO_A_BASE + ((PORT) << 12))
|
2013-01-12 23:44:42 +01:00
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO Register offset declarations
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_DATA 0x00000000 /**< Data register */
|
|
|
|
#define GPIO_DIR 0x00000400 /**< Data direction register */
|
|
|
|
#define GPIO_IS 0x00000404 /**< Interrupt sense */
|
|
|
|
#define GPIO_IBE 0x00000408 /**< Interrupt both edges */
|
|
|
|
#define GPIO_IEV 0x0000040C /**< Interrupt event */
|
|
|
|
#define GPIO_IE 0x00000410 /**< Interrupt mask */
|
|
|
|
#define GPIO_RIS 0x00000414 /**< Interrupt status - raw */
|
|
|
|
#define GPIO_MIS 0x00000418 /**< Interrupt status - masked */
|
|
|
|
#define GPIO_IC 0x0000041C /**< Interrupt clear */
|
|
|
|
#define GPIO_AFSEL 0x00000420 /**< Mode control select */
|
|
|
|
#define GPIO_GPIOLOCK 0x00000520 /**< GPIO commit unlock */
|
|
|
|
#define GPIO_GPIOCR 0x00000524 /**< GPIO commit */
|
|
|
|
#define GPIO_PMUX 0x00000700 /**< PMUX register */
|
|
|
|
#define GPIO_P_EDGE_CTRL 0x00000704 /**< Port edge control */
|
|
|
|
#define GPIO_USB_CTRL 0x00000708 /**< USB input power-up edge ctrl */
|
|
|
|
#define GPIO_PI_IEN 0x00000710 /**< Power-up interrupt enable */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK 0x00000718 /**< IRQ detect ACK - I/O ports */
|
|
|
|
#define GPIO_USB_IRQ_ACK 0x0000071C /**< IRQ detect ACK - USB */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK 0x00000720 /**< IRQ detect ACK - masked */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_DATA register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_DATA_DATA 0x000000FF /**< Input and output data */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_DIR register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_DIR_DIR 0x000000FF /**< Pin Input (0) / Output (1) */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_IS register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_IS_IS 0x000000FF /**< Detect Edge (0) / Level (1) */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_IBE register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_IBE_IBE 0x000000FF /**< Both Edges (1) / Single (0) */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_IEV register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_IEV_IEV 0x000000FF /**< Rising (1) / Falling (0) */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_IE register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_IE_IE 0x000000FF /**< Masked (0) / Not Masked (1) */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_RIS register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_RIS_RIS 0x000000FF /**< Raw interrupt status */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_MIS register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_MIS_MIS 0x000000FF /**< Masked interrupt status */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_IC register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_IC_IC 0x000000FF /**< Clear edge detection (1) */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_AFSEL register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_AFSEL_AFSEL 0x000000FF /**< Software (0) / Peripheral (1) */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_GPIOLOCK register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_GPIOLOCK_LOCK 0xFFFFFFFF /**< Locked (1) / Unlocked (0) */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_GPIOCR register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_GPIOCR_CR 0x000000FF /**< Allow alternate function (1) */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_PMUX register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_PMUX_CKOEN 0x00000080 /**< Clock out enable */
|
|
|
|
#define GPIO_PMUX_CKOPIN 0x00000010 /**< Decouple control pin select */
|
|
|
|
#define GPIO_PMUX_DCEN 0x00000008 /**< Decouple control enable */
|
|
|
|
#define GPIO_PMUX_DCPIN 0x00000001 /**< Decouple control pin select */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_P_EDGE_CTRL register bit masks.
|
|
|
|
* \brief Rising (0) / Falling (1)
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_P_EDGE_CTRL_PDIRC7 0x80000000 /**< Port D bit 7 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PDIRC6 0x40000000 /**< Port D bit 6 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PDIRC5 0x20000000 /**< Port D bit 5 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PDIRC4 0x10000000 /**< Port D bit 4 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PDIRC3 0x08000000 /**< Port D bit 3 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PDIRC2 0x04000000 /**< Port D bit 2 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PDIRC1 0x02000000 /**< Port D bit 1 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PDIRC0 0x01000000 /**< Port D bit 0 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PCIRC7 0x00800000 /**< Port C bit 7 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PCIRC6 0x00400000 /**< Port C bit 6 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PCIRC5 0x00200000 /**< Port C bit 5 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PCIRC4 0x00100000 /**< Port C bit 4 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PCIRC3 0x00080000 /**< Port C bit 3 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PCIRC2 0x00040000 /**< Port C bit 2 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PCIRC1 0x00020000 /**< Port C bit 1 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PCIRC0 0x00010000 /**< Port C bit 0 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PBIRC7 0x00008000 /**< Port B bit 7 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PBIRC6 0x00004000 /**< Port B bit 6 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PBIRC5 0x00002000 /**< Port B bit 5 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PBIRC4 0x00001000 /**< Port B bit 4 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PBIRC3 0x00000800 /**< Port B bit 3 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PBIRC2 0x00000400 /**< Port B bit 2 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PBIRC1 0x00000200 /**< Port B bit 1 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PBIRC0 0x00000100 /**< Port B bit 0 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PAIRC7 0x00000080 /**< Port A bit 7 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PAIRC6 0x00000040 /**< Port A bit 6 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PAIRC5 0x00000020 /**< Port A bit 5 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PAIRC4 0x00000010 /**< Port A bit 4 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PAIRC3 0x00000008 /**< Port A bit 3 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PAIRC2 0x00000004 /**< Port A bit 2 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PAIRC1 0x00000002 /**< Port A bit 1 */
|
|
|
|
#define GPIO_P_EDGE_CTRL_PAIRC0 0x00000001 /**< Port A bit 0 */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_USB_CTRL register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_USB_CTRL_USB_EDGE_CTL 0x00000001 /**< Rising (0) / Falling (1) */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_PI_IEN register bit masks.
|
|
|
|
* \brief Enabled (1) / Disabled (0)
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_PI_IEN_PDIEN7 0x80000000 /**< Port D bit 7 */
|
|
|
|
#define GPIO_PI_IEN_PDIEN6 0x40000000 /**< Port D bit 6 */
|
|
|
|
#define GPIO_PI_IEN_PDIEN5 0x20000000 /**< Port D bit 5 */
|
|
|
|
#define GPIO_PI_IEN_PDIEN4 0x10000000 /**< Port D bit 4 */
|
|
|
|
#define GPIO_PI_IEN_PDIEN3 0x08000000 /**< Port D bit 3 */
|
|
|
|
#define GPIO_PI_IEN_PDIEN2 0x04000000 /**< Port D bit 2 */
|
|
|
|
#define GPIO_PI_IEN_PDIEN1 0x02000000 /**< Port D bit 1 */
|
|
|
|
#define GPIO_PI_IEN_PDIEN0 0x01000000 /**< Port D bit 0 */
|
|
|
|
#define GPIO_PI_IEN_PCIEN7 0x00800000 /**< Port C bit 7 */
|
|
|
|
#define GPIO_PI_IEN_PCIEN6 0x00400000 /**< Port C bit 6 */
|
|
|
|
#define GPIO_PI_IEN_PCIEN5 0x00200000 /**< Port C bit 5 */
|
|
|
|
#define GPIO_PI_IEN_PCIEN4 0x00100000 /**< Port C bit 4 */
|
|
|
|
#define GPIO_PI_IEN_PCIEN3 0x00080000 /**< Port C bit 3 */
|
|
|
|
#define GPIO_PI_IEN_PCIEN2 0x00040000 /**< Port C bit 2 */
|
|
|
|
#define GPIO_PI_IEN_PCIEN1 0x00020000 /**< Port C bit 1 */
|
|
|
|
#define GPIO_PI_IEN_PCIEN0 0x00010000 /**< Port C bit 0 */
|
|
|
|
#define GPIO_PI_IEN_PBIEN7 0x00008000 /**< Port B bit 7 */
|
|
|
|
#define GPIO_PI_IEN_PBIEN6 0x00004000 /**< Port B bit 6 */
|
|
|
|
#define GPIO_PI_IEN_PBIEN5 0x00002000 /**< Port B bit 5 */
|
|
|
|
#define GPIO_PI_IEN_PBIEN4 0x00001000 /**< Port B bit 4 */
|
|
|
|
#define GPIO_PI_IEN_PBIEN3 0x00000800 /**< Port B bit 3 */
|
|
|
|
#define GPIO_PI_IEN_PBIEN2 0x00000400 /**< Port B bit 2 */
|
|
|
|
#define GPIO_PI_IEN_PBIEN1 0x00000200 /**< Port B bit 1 */
|
|
|
|
#define GPIO_PI_IEN_PBIEN0 0x00000100 /**< Port B bit 0 */
|
|
|
|
#define GPIO_PI_IEN_PAIEN7 0x00000080 /**< Port A bit 7 */
|
|
|
|
#define GPIO_PI_IEN_PAIEN6 0x00000040 /**< Port A bit 6 */
|
|
|
|
#define GPIO_PI_IEN_PAIEN5 0x00000020 /**< Port A bit 5 */
|
|
|
|
#define GPIO_PI_IEN_PAIEN4 0x00000010 /**< Port A bit 4 */
|
|
|
|
#define GPIO_PI_IEN_PAIEN3 0x00000008 /**< Port A bit 3 */
|
|
|
|
#define GPIO_PI_IEN_PAIEN2 0x00000004 /**< Port A bit 2 */
|
|
|
|
#define GPIO_PI_IEN_PAIEN1 0x00000002 /**< Port A bit 1 */
|
|
|
|
#define GPIO_PI_IEN_PAIEN0 0x00000001 /**< Port A bit 0 */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_IRQ_DETECT_ACK register bit masks
|
|
|
|
* \brief Detected (1) / Undetected (0)
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PDIACK7 0x80000000 /**< Port D bit 7 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PDIACK6 0x40000000 /**< Port D bit 6 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PDIACK5 0x20000000 /**< Port D bit 5 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PDIACK4 0x10000000 /**< Port D bit 4 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PDIACK3 0x08000000 /**< Port D bit 3 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PDIACK2 0x04000000 /**< Port D bit 2 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PDIACK1 0x02000000 /**< Port D bit 1 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PDIACK0 0x01000000 /**< Port D bit 0 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PCIACK7 0x00800000 /**< Port C bit 7 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PCIACK6 0x00400000 /**< Port C bit 6 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PCIACK5 0x00200000 /**< Port C bit 5 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PCIACK4 0x00100000 /**< Port C bit 4 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PCIACK3 0x00080000 /**< Port C bit 3 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PCIACK2 0x00040000 /**< Port C bit 2 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PCIACK1 0x00020000 /**< Port C bit 1 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PCIACK0 0x00010000 /**< Port C bit 0 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PBIACK7 0x00008000 /**< Port B bit 7 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PBIACK6 0x00004000 /**< Port B bit 6 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PBIACK5 0x00002000 /**< Port B bit 5 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PBIACK4 0x00001000 /**< Port B bit 4 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PBIACK3 0x00000800 /**< Port B bit 3 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PBIACK2 0x00000400 /**< Port B bit 2 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PBIACK1 0x00000200 /**< Port B bit 1 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PBIACK0 0x00000100 /**< Port B bit 0 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PAIACK7 0x00000080 /**< Port A bit 7 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PAIACK6 0x00000040 /**< Port A bit 6 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PAIACK5 0x00000020 /**< Port A bit 5 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PAIACK4 0x00000010 /**< Port A bit 4 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PAIACK3 0x00000008 /**< Port A bit 3 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PAIACK2 0x00000004 /**< Port A bit 2 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PAIACK1 0x00000002 /**< Port A bit 1 */
|
|
|
|
#define GPIO_IRQ_DETECT_ACK_PAIACK0 0x00000001 /**< Port A bit 0 */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_USB_IRQ_ACK register bit masks
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_USB_IRQ_ACK_USBACK 0x00000001 /**< Detected (1) / Not detected (0) */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \name GPIO_IRQ_DETECT_UNMASK register bit masks.
|
|
|
|
* \brief Detected (1) / Not detected (0)
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PDIACK7 0x80000000 /**< Port D bit 7 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PDIACK6 0x40000000 /**< Port D bit 6 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PDIACK5 0x20000000 /**< Port D bit 5 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PDIACK4 0x10000000 /**< Port D bit 4 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PDIACK3 0x08000000 /**< Port D bit 3 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PDIACK2 0x04000000 /**< Port D bit 2 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PDIACK1 0x02000000 /**< Port D bit 1 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PDIACK0 0x01000000 /**< Port D bit 0 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PCIACK7 0x00800000 /**< Port C bit 7 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PCIACK6 0x00400000 /**< Port C bit 6 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PCIACK5 0x00200000 /**< Port C bit 5 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PCIACK4 0x00100000 /**< Port C bit 4 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PCIACK3 0x00080000 /**< Port C bit 3 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PCIACK2 0x00040000 /**< Port C bit 2 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PCIACK1 0x00020000 /**< Port C bit 1 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PCIACK0 0x00010000 /**< Port C bit 0 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PBIACK7 0x00008000 /**< Port B bit 7 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PBIACK6 0x00004000 /**< Port B bit 6 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PBIACK5 0x00002000 /**< Port B bit 5 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PBIACK4 0x00001000 /**< Port B bit 4 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PBIACK3 0x00000800 /**< Port B bit 3 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PBIACK2 0x00000400 /**< Port B bit 2 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PBIACK1 0x00000200 /**< Port B bit 1 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PBIACK0 0x00000100 /**< Port B bit 0 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PAIACK7 0x00000080 /**< Port A bit 7 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PAIACK6 0x00000040 /**< Port A bit 6 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PAIACK5 0x00000020 /**< Port A bit 5 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PAIACK4 0x00000010 /**< Port A bit 4 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PAIACK3 0x00000008 /**< Port A bit 3 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PAIACK2 0x00000004 /**< Port A bit 2 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PAIACK1 0x00000002 /**< Port A bit 1 */
|
|
|
|
#define GPIO_IRQ_DETECT_UNMASK_PAIACK0 0x00000001 /**< Port A bit 0 */
|
|
|
|
/** @} */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \brief Initialise the GPIO module */
|
|
|
|
void gpio_init();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Register GPIO callback
|
|
|
|
* \param f Pointer to a function to be called when \a pin of \a port
|
|
|
|
* generates an interrupt
|
|
|
|
* \param port Associate \a f with this port. \e port must be specified with
|
|
|
|
* its numeric representation (Port A:0, B:1 etc). Defines for these
|
|
|
|
* numeric representations are GPIO_x_NUM
|
|
|
|
* \param pin Associate \a f with this pin, which is specified by number
|
|
|
|
* (0, 1, ..., 7)
|
|
|
|
*/
|
|
|
|
void gpio_register_callback(gpio_callback_t f, uint8_t port, uint8_t pin);
|
|
|
|
|
|
|
|
#endif /* GPIO_H_ */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
* @}
|
|
|
|
*/
|