Name
Hardware Configuration Support on IMX Processors — Details
Synopsis
#include <cyg/hal/hal_io.h>
cyg_uint32 desc = CYGHWR_HAL_IMX_PAD(
pad
,
mode
)
;
cyg_uint32 desc = CYGHWR_HAL_IMX_SNVS_PAD(
pad
,
mode
)
;
CYGHWR_HAL_IMX_PAD_SET
(
desc
)
;
cyg_uint32 desc = CYGHWR_HAL_IMX_DAISY(
reg
,
value
)
;
CYGHWR_HAL_IMX_DAISY_SET
(
desc
)
;
cyg_uint32 desc = CYGHWR_HAL_IMX_CLOCK_GATE(
reg
,
gate
)
;
CYGHWR_HAL_IMX_CLOCK_ENABLE
(
desc
)
;
CYGHWR_HAL_IMX_CLOCK_DISABLE
(
desc
)
;
cyg_uint32 desc = CYGHWR_HAL_IMX_GPIO(
ctlr
,
pin
,
mode
)
;
CYGHWR_HAL_IMX_GPIO_SET
(
desc
)
;
CYGHWR_HAL_IMX_GPIO_OUT
(
desc
,
val
)
;
CYGHWR_HAL_IMX_GPIO_IN
(
desc
,
val
)
;
CYGHWR_HAL_IMX_GPIO_INTSTAT
(
desc
,
status
)
;
CYGHWR_HAL_IMX_GPIO_INTMASK
(
desc
,
enable
)
;
CYGHWR_HAL_IMX_GPIO_INTCLR
(
desc
)
;
Description
The IMX HAL provides a number of macros to support the encoding of various hardware configuration options into a 32-bit descriptor. This is useful to drivers and other packages that need to configure the hardware.
PAD Multiplexing
Many of the IO pads on the chip can be connected to a
variety of different devices and have a variety of
properties that need to be configured. A standard pad
descriptor is created by the
CYGHWR_HAL_IMX_PAD()
macro. For the
SNVS
pads connected to
GPIO5
the
CYGHWR_HAL_IMX_SNVS_PAD()
is used
instead. The pad
argument defines the pad
to be configured, and follows the hardware naming
convention, for example AD_B0(12)
or
SD_B1(3)
. The mode
argument is the terminal part of a
CYGHWR_HAL_IMX_PAD_MODE_XXXX
macro; this
may be one supplied in the HAL, or one constructed by the
driver or application. This macro is defined as a
combination of the
CYGHWR_HAL_IMX_PAD_MODE_
definitions in
cyg/hal/var_io.h
, which correspond to
the definitions in the hardware pad MUX and CTL registers.
The macro CYGHWR_HAL_IMX_PAD_SET()
is
used to configure a pad according to the descriptor.
The following example shows how the LPUART pads are configured.
#define CYGHWR_HAL_IMX_PAD_MODE_LPUART_PAD(__alt) \ CYGHWR_HAL_IMX_PAD_MODE_MUX(__alt) | \ CYGHWR_HAL_IMX_PAD_MODE_PUE | \ CYGHWR_HAL_IMX_PAD_MODE_PKE | \ CYGHWR_HAL_IMX_PAD_MODE_PUS_47K_PU | \ CYGHWR_HAL_IMX_PAD_MODE_DSE(6) | \ CYGHWR_HAL_IMX_PAD_MODE_SPEED_MED2 #define CYGHWR_HAL_IMX_LPUART1_TX CYGHWR_HAL_IMX_PAD( AD_B0(12), LPUART_PAD(2) ) #define CYGHWR_HAL_IMX_LPUART1_RX CYGHWR_HAL_IMX_PAD( AD_B0(13), LPUART_PAD(2) )
PAD Daisy Chaining
Some device IO lines can connect to multiple pads, the daisy
chain registers select which pad is to be used for the
device. A daisy chain descriptor is created by the
CYGHWR_HAL_IMX_DAISY
macro. The
reg
argument selects which daisy chain
device line is to be programmed, and the
val
argument defines the pad
selection. Both of these arguments are fragments of macros
defined in cyg/hal/var_io.h
. Only
registers and values currently used are defined there, new
ones can be added there or defined in the driver or
application.
The CYGHWR_HAL_IMX_DAISY_SET
macro is
called to program the configuration from a descriptor into
the hardware.
The following example shows some daisy chain descriptor definitions.
# define CYGHWR_HAL_NXP_LPUART3_TXD_DAISY CYGHWR_HAL_IMX_DAISY(LPUART3_TX, AD_B1_06_ALT2) # define CYGHWR_HAL_NXP_LPUART3_RXD_DAISY CYGHWR_HAL_IMX_DAISY(LPUART3_RX, AD_B1_07_ALT2) # define CYGHWR_HAL_NXP_LPUART3_CTS_DAISY CYGHWR_HAL_IMX_DAISY(LPUART3_CTS_B, AD_B1_04_ALT2) # define CYGHWR_HAL_NXP_LPUART3_RTS_DAISY CYGHWR_HAL_IMX_DAISY_NONE
Clock Gating Control
Most device clocks are controlled by a gate that needs to be
switched on or off. The HAL provides macros which may be
used to enable or disable peripheral clocks. Effectively
this indicates whether the peripheral is powered on
(enabled) or powered down (disabled), and so may be used to
ensure unused peripherals are turned off to save power. The
macro CYGHWR_HAL_IMX_CLOCK_GATE()
defines
a clock gate descriptor. The reg
argument
gives the CCGR
register to be used and
the gate
argument selects the clock gate
bit in that register. Clock gate descriptors are defined in
cyg/hal/var_io.h
and new values will be
added there as needed.
The macros CYGHWR_HAL_IMX_CLOCK_ENABLE()
and CYGHWR_HAL_IMX_CLOCK_DISABLE()
enable
and disable the clock described by the descriptor. At
present clocks are either fully on or fully off, the option
to switch clocks off in WAIT mode is not implemented.
It is important to remember that before a peripheral can be used, it must be enabled. It is safe to re-enable a peripheral that is already enabled, although usually a device driver will only do so once in its initialization. eCos will automatically initialize some peripheral blocks where it needs to use the associated peripherals, and in eCos-supplied device drivers which are included in the eCos configuration. However this should not be relied on - it is always safest to enable the peripheral clocks anyway just in case.
GPIO
A descriptor is created by the
CYGHWR_HAL_IMX_GPIO()
macro. The
ctlr
argument selects the GPIO controller
while the pin
argument selects the GPIO
pin in the controller. The mode
argument
configures the pin within the GPIO controller.
For basic I/O the supplied mode
is either
IN
or OUT
. For input
pins an interrupt configuration mode
can
us used instead (with IN
implied). At
present the options LOW_LEVEL
,
HIGH_LEVEL
,
RISING_EDGE
,
FALLING_EDGE
and
BOTH_EDGES
are available to define which
input transitions/states will generate an interrupt event.
For example, the descriptor for GPIO output control of GPIO1 pin 9 could be declared as follows:
#define OUTPUT_EXAMPLE CYGHWR_HAL_IMX_GPIO(1, 9, OUT)
Correspondingly, a descriptor for polled input of GPIO5 pin
0 can simply be declared using IN
for the
mode
field:
#define INPUT_EXAMPLE CYGHWR_HAL_IMX_GPIO(5, 0, IN)
For polled or interrupt
driven input the relevant interrupt detection can be
specifiued as the mode
field. e,g:
#define INPUT_EXAMPLE CYGHWR_HAL_IMX_GPIO(5, 0, BOTH_EDGES)
In addition to GPIO configuration, the matching pad will need to be configured using a PAD descriptor as detailed above in PAD Multiplexing.
Prior to a pin being accessed for GPIO then the pin
and its corresponding pad
will need to be configured at run-time. With appropriate
descriptor values defined this is done via the
SET
calls. For example, using the
manifests from above:
// One-time initialisation of output pin: CYGHWR_HAL_IMX_PAD_SET(OUTPUT_PAD); CYGHWR_HAL_IMX_GPIO_SET(OUTPUT_EXAMPLE); // One-time initialisation of input pin: CYGHWR_HAL_IMX_PAD_SET(INPUT_PAD) CYGHWR_HAL_IMX_GPIO_SET(INPUT_EXAMPLE);
Subsequent to the setting of the I/O configuration the GPIO pin can then be accessed as configured.
If a GPIO pin has been configured as an output then its value
may be set using
CYGHWR_HAL_IMX_GPIO_OUT()
. For example:
CYGHWR_HAL_IMX_GPIO_OUT(OUTPUT_EXAMPLE, 0); // set LOW some_app_processing(); CYGHWR_HAL_IMX_GPIO_OUT(OUTPUT_EXAMPLE, 1); // set HIGH
Similarly the current value of an input pin can be read
using CYGHWR_HAL_IMX_GPIO_IN()
. For
example:
int bstat; CYGHWR_HAL_IMX_GPIO_IN(INPUT_EXAMPLE, &bstat);
Note | |
---|---|
Normally the variant HAL will manage the masking
and acknowledgment of interrupts via the standard kernel
interrupt support API, and so the application level code
does not normally need to access the low-level
For completeness the low-level helpers exposed to the standard interrupt support are documented here. |
The CYGHWR_HAL_IMX_GPIO_INTMASK()
parameter enable
controls the
masking/unmasking of the interrupt associated with the pin
descriptor. A non-zero value will enable the source, with
0
disabling the source.
If required, the current active “interrupt
asserted” state of a pin can be interrogated using
CYGHWR_HAL_IMX_GPIO_INTSTAT()
.
The CYGHWR_HAL_IMX_GPIO_INTCLR
function
can be used to acknowledge an active interrupt.
Since most of the individual GPIO pin interrupt sources are
multiplexed through the Cortex-M NVIC
the
variant HAL provides support for demultiplexing the combined
GPIO interrupts to individual logical vectors. The CDL
option
CYGSEM_HAL_CORTEXM_IMX_GPIO_INT_DEMUX
controls whether the demux feature is implemented. It is
enabled by default when the CYGPKG_KERNEL
is configured. This feature avoids application code having to
manage their own demux support when interrupt support is
required for multiple pins on a specific GPIO controller.
For example, the physical GPIO2
pin
5
is actually multiplexed via the
hardware
CYGNUM_HAL_INTERRUPT_GPIO2_COMBO_0_15
interrupt vector. If the HAL demux support is enabled then
that specific pin source can be supported individually via
the
CYGNUM_HAL_INTERRUPT_GPIO2_INT5
logical
vector manifest, with the other 15 sources multiplexed onto
the underlying NVIC
interrupt also
available via their own logical vector numbers.
2024-03-18 | eCosPro Non-Commercial Public License |