diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2009-06-07 10:27:48 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2009-06-07 10:27:48 +0000 |
commit | 4fc5b696fad6b10620dcd49149bf64b829e38f77 (patch) | |
tree | 4e2509a8201057aa54fc2cb22eac8188c738c4e5 /src | |
parent | 9659a679baf31f9890d941c4e25617a7ca70756f (diff) | |
download | ChibiOS-4fc5b696fad6b10620dcd49149bf64b829e38f77.tar.gz ChibiOS-4fc5b696fad6b10620dcd49149bf64b829e38f77.tar.bz2 ChibiOS-4fc5b696fad6b10620dcd49149bf64b829e38f77.zip |
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1019 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/pal.c | 70 | ||||
-rw-r--r-- | src/lib/pal.h (renamed from src/include/ioports.h) | 216 |
2 files changed, 187 insertions, 99 deletions
diff --git a/src/lib/pal.c b/src/lib/pal.c new file mode 100644 index 000000000..045c35c20 --- /dev/null +++ b/src/lib/pal.c @@ -0,0 +1,70 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file pal.c
+ * @brief I/O Ports Abstraction Layer code
+ * @addtogroup PAL
+ * @{
+ */
+
+/**
+ * @brief Read from an I/O bus.
+ *
+ * @param[in] bus the I/O bus, pointer to a @p IOBus structure
+ * @return The bus logical states.
+ *
+ * @note The operation is not guaranteed to be atomic on all the architectures,
+ * for atomicity and/or portability reasons you may need to enclose port
+ * I/O operations between @p chSysLock() and @p chSysUnlock().
+ * @note The function internally uses the @p palReadGroup() macro. The use of
+ * this function is preferred when you value code size, readability and
+ * error checking over speed.
+ */
+ioportmask_t palReadBus(IOBus *bus) {
+
+ chDbgCheck((bus != NULL) &&
+ (bus->bus_offset > PAL_IOPORTS_WIDTH), "palReadBus");
+
+ return palReadGroup(bus->bus_port, bus->bus_mask, bus->bus_offset);
+}
+
+/**
+ * @brief Write to an I/O bus.
+ *
+ * @param[in] bus the I/O bus, pointer to a @p IOBus structure
+ * @param[in] bits the bits to be written on the I/O bus. Values exceeding
+ * the bus width are masked so most significant bits are lost.
+ *
+ * @note The operation is not guaranteed to be atomic on all the architectures,
+ * for atomicity and/or portability reasons you may need to enclose port
+ * I/O operations between @p chSysLock() and @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ */
+void palWriteBus(IOBus *bus, ioportmask_t bits) {
+
+ chDbgCheck((bus != NULL) &&
+ (bus->bus_offset > PAL_IOPORTS_WIDTH), "palWriteBus");
+
+ palWriteBus(bus->bus_port, bus->bus_mask, bus->bus_offset, bits);
+}
+
+/** @} */
diff --git a/src/include/ioports.h b/src/lib/pal.h index 8dd608fbe..11137c6cb 100644 --- a/src/include/ioports.h +++ b/src/lib/pal.h @@ -18,36 +18,37 @@ */
/**
- * @file ioports.h
- * @brief I/O ports
- * @addtogroup IOPorts
+ * @file pal.h
+ * @brief I/O Ports Abstraction Layer macros, types and structures
+ * @addtogroup PAL
* @{
*/
-#ifndef _IOPORTS_H_
-#define _IOPORTS_H_
+#ifndef _PAL_H_
+#define _PAL_H_
-#ifndef _IOPORTS_LLD_H_
-#include "ioports_lld.h"
+#ifndef _PAL_LLD_H_
+#include "pal_lld.h"
#endif
/**
* @brief Port bit helper macro.
- * @details This macro calculates the mask of a bit within a port. + * @details This macro calculates the mask of a bit within a port.
+ *
+ * @param[in] n the bit position within the port
+ * @return The bit mask. */
-#define IOPORT_BIT(n) ((ioportmask_t)(1 << (n)))
+#define PAL_PORT_BIT(n) ((ioportmask_t)(1 << (n)))
+
/**
- * @brief Port bus mask helper macro.
- * @details This macro calculates the proper bus mask starting from the width
- * and the offset.
+ * @brief Bits group mask helper.
+ * @details This macro calculates the mask of a bits group.
*
- * @param[in] width the width, in bits, of the I/O bus
- * @param[in] offset the offset, within the port, of the I/O bus. The offset
- * must be specified as offset from the least significant bit. + * @param[in] the group width + * @return The group mask.
*/
-#define IOPORT_BUS_MASK(width, offset) \
- ((ioportmask_t)(((1 << (width)) - 1) << (offset)))
+#define PAL_GROUP_MASK(width) ((ioportmask_t)(1 << (width)) - 1)
/**
* @brief I/O bus descriptor.
@@ -59,15 +60,20 @@ typedef struct {
/** Port identifier. */
ioportid_t bus_portid;
- /** Mask of the I/O lines that form the bus. The lines must be contiguous.
- * The mask must be pre-shifted and also defines the bus width. */
+ /** Bus mask aligned to port bit 0. The bus mask implicitly define the bus
+ * width. */
ioportmask_t bus_mask;
/** Offset, within the port, of the least significant bit of the bus. */
uint_fast8_t bus_offset;
} IOBus;
/**
- * @brief Reads an I/O port.
+ * @brief PAL subsystem initialization. + */
+#define palInit() pal_lld_init()
+
+/**
+ * @brief Reads the physical I/O port states.
*
* @param[in] port the port identifier
* @return The port logical states.
@@ -75,10 +81,27 @@ typedef struct { * @note The default implementation always return zero and computes the
* parameter eventual side effects.
*/
-#if !defined(ioport_read_lld) || defined(__DOXYGEN__)
-#define chPortRead(port) ((void)(port), 0)
+#if !defined(pal_lld_readport) || defined(__DOXYGEN__)
+#define palReadPort(port) ((void)(port), 0)
#else
-#define chPortRead(port) ioport_read_lld(port)
+#define palReadPort(port) pal_lld_readport(port)
+#endif
+
+/**
+ * @brief Reads the output latch.
+ * @details The purpose of this function is to read back the latched output
+ * value.
+ * + * @param[in] port the port identifier
+ * @return The latched logical states.
+ *
+ * @note The default implementation always return zero and computes the
+ * parameter eventual side effects.
+ */
+#if !defined(pal_lld_readlatch) || defined(__DOXYGEN__)
+#define palReadLatch(port) ((void)(port), 0)
+#else
+#define palReadLatch(port) pal_lld_readlatch(port)
#endif
/**
@@ -90,10 +113,10 @@ typedef struct { * @note The default implementation does nothing except computing the
* parameters eventual side effects.
*/
-#if !defined(ioport_write_lld) || defined(__DOXYGEN__)
-#define chPortWrite(port, bits) ((void)(port), (void)(bits))
+#if !defined(pal_lld_writeport) || defined(__DOXYGEN__)
+#define palWritePort(port, bits) ((void)(port), (void)(bits))
#else
-#define chPortWrite(port, bits) ioport_write_lld(port, bits)
+#define palWritePort(port, bits) pal_lld_writeport(port, bits)
#endif
/**
@@ -109,13 +132,12 @@ typedef struct { * optimal. Low level drivers may optimize the function by using
* specific hardware or coding.
*/
-#if !defined(ioport_set_lld) || defined(__DOXYGEN__)
-#define chPortSet(port, bits) { \
- ioport_t p = (port); \
- chPortWrite(p, chPortRead(p) | (bits)); \
+#if !defined(pal_lld_setport) || defined(__DOXYGEN__)
+#define palSetPort(port, bits) { \
+ palWritePort(port, palReadLatch(p) | (bits)); \
}
#else
-#define chPortSet(port, bits) ioport_set_lld(port, bits)
+#define palSetPort(port, bits) pal_lld_setport(port, bits)
#endif
/**
@@ -131,13 +153,12 @@ typedef struct { * optimal. Low level drivers may optimize the function by using
* specific hardware or coding.
*/
-#if !defined(ioport_clear_lld) || defined(__DOXYGEN__)
-#define chPortClear(port, bits) { \
- ioport_t p = (port); \
- chPortWrite(p, chPortRead(p) & ~(bits)); \
+#if !defined(pal_lld_clearport) || defined(__DOXYGEN__)
+#define palClearPort(port, bits) { \
+ palWritePort(port, palReadLatch(p) & ~(bits)); \
}
#else
-#define chPortClear(port, bits) ioport_clear_lld(port, bits)
+#define palClearPort(port, bits) pal_lld_clearport(port, bits)
#endif
/**
@@ -153,58 +174,47 @@ typedef struct { * optimal. Low level drivers may optimize the function by using
* specific hardware or coding.
*/
-#if !defined(ioport_toggle_lld) || defined(__DOXYGEN__)
-#define chPortToggle(port, bits) { \
- ioport_t p = (port); \
- chPortWrite(p, chPortRead(p) ^ (bits)); \
+#if !defined(pal_lld_toggleport) || defined(__DOXYGEN__)
+#define palTogglePort(port, bits) { \
+ palWritePort(port, palReadLatch(port) ^ (bits)); \
}
#else
-#define chPortToggle(port, bits) ioport_toggle_lld(port, bits)
+#define palTogglePort(port, bits) pal_lld_toggleport(port, bits)
#endif
/**
- * @brief Reads a value from an I/O bus.
- *
- * @param[in] bus the I/O bus, pointer to a @p IOBus structure
- * @return The bus logical states.
- *
- * @note The operation is not guaranteed to be atomic on all the architectures,
- * for atomicity and/or portability reasons you may need to enclose port
- * I/O operations between @p chSysLock() and @p chSysUnlock().
- * @note The default implementation not necessarily optimal. Low level drivers
- * may optimize the function by using specific hardware or coding.
- * @note The default implementation evaluates the parameter three times, be
- * careful with side effects.
+ * @brief Reads a group of bits.
+ * + * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] offset the group bit offset within the port
+ * @return The group logical states.
*/
-#if !defined(ioport_readbus_lld) || defined(__DOXYGEN__)
-#define chPortReadBus(bus) \
- ((chPortRead((bus)->bus_port) >> (bus)->bus_offset) & (bus)->bus_mask)
+#if !defined(pal_lld_readgroup) || defined(__DOXYGEN__)
+#define palReadGroup(port, mask, offset) \
+ ((palReadPort(port) >> (offset)) & (mask))
#else
-#define chPortReadBus(bus) ioport_readbus_lld(bus)
+#define palReadGroup(port, mask, offset) pal_lld_readgroup(port, mask, offset)
#endif
/**
- * @brief Writes a value on an I/O bus.
+ * @brief Writes a group of bits.
*
- * @param[in] bus the I/O bus, pointer to a @p IOBus structure
- * @param[in] bits the bits to be written on the I/O bus. Values exceeding
- * the bus width are masked so most significant bits are lost. - *
- * @note The operation is not guaranteed to be atomic on all the architectures,
- * for atomicity and/or portability reasons you may need to enclose port
- * I/O operations between @p chSysLock() and @p chSysUnlock().
- * @note The default implementation is non atomic and not necessarily
- * optimal. Low level drivers may optimize the function by using
- * specific hardware or coding.
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] offset the group bit offset within the port
+ * @param[in] bits the bits to be written. Values exceeding the group width
+ * are masked.
+ * @return The group logical states.
*/
-#if !defined(ioport_writebus_lld) || defined(__DOXYGEN__)
-#define chPortWriteBus(bus, bits) { \
- IOBus *b = (bus); \
- chPortWrite(b->bus_port, (chPortRead(b->bus_port) & ~b->bus_mask) | \
- (((bits) << b->bus_offset) & b->bus_mask)); \
+#if !defined(pal_lld_writegroup) || defined(__DOXYGEN__)
+#define palWriteGroup(port, mask, offset, bits) { \
+ palWritePort(port, (palReadLatch(port) & ~((mask) << (offset))) | \
+ (((bits) & (mask)) << (offset))); \
}
#else
-#define chPortWriteBus(bus, bits) ioport_writebus_lld(bus, bits)
+#define palWriteGroup(port, mask, offset, bits) \
+ pal_lld_writegroup(port, mask, offset, bits)
#endif
/**
@@ -218,12 +228,12 @@ typedef struct { *
* @note The default implementation not necessarily optimal. Low level drivers
* may optimize the function by using specific hardware or coding.
- * @note The default implementation internally uses the @p chPortRead().
+ * @note The default implementation internally uses the @p palReadPort().
*/
-#if !defined(ioport_readpad_lld) || defined(__DOXYGEN__)
-#define chPortReadPad(port, pad) ((chPortRead(port) >> (pad)) & 1)
+#if !defined(pal_lld_readpad) || defined(__DOXYGEN__)
+#define palReadPad(port, pad) ((palReadPort(port) >> (pad)) & 1)
#else
-#define chPortReadPad(port, pad) ioport_readpad_lld(port, pad)
+#define palReadPad(port, pad) pal_lld_readpad(port, pad)
#endif
/**
@@ -239,17 +249,16 @@ typedef struct { * @note The default implementation is non atomic and not necessarily
* optimal. Low level drivers may optimize the function by using
* specific hardware or coding.
- * @note The default implementation internally uses the @p chPortRead() and
- * @p chPortWrite().
+ * @note The default implementation internally uses the @p palReadLatch() and
+ * @p palWritePort().
*/
-#if !defined(ioport_writepad_lld) || defined(__DOXYGEN__)
-#define chPortWritePad(port, pad, value) {
- ioport_t p = (port); \
- chPortWrite(p, (chPortRead(p) & ~IOPORT_BIT(pad)) | \
- ((value & 1) << pad)); \
+#if !defined(pal_lld_writepad) || defined(__DOXYGEN__)
+#define palWritePad(port, pad, value) { \
+ palWritePort(port, (palReadLatch(port) & ~PAL_PORT_BIT(pad)) | \
+ (((value) & 1) << pad)); \
}
#else
-#define chPortWritePad(port, pad, value) ioport_writepad_lld(port, pad, value)
+#define palWritePad(port, pad, value) pal_lld_writepad(port, pad, value)
#endif
/**
@@ -264,12 +273,12 @@ typedef struct { * @note The default implementation is non atomic and not necessarily
* optimal. Low level drivers may optimize the function by using
* specific hardware or coding.
- * @note The default implementation internally uses the @p chPortSet().
+ * @note The default implementation internally uses the @p palSetPort().
*/
-#if !defined(ioport_setpad_lld) || defined(__DOXYGEN__)
-#define chPortSetPad(port, pad) chPortSet(port, IOPORT_BIT(pad))
+#if !defined(pal_lld_setpad) || defined(__DOXYGEN__)
+#define palSetPad(port, pad) palSetPort(port, PAL_PORT_BIT(pad))
#else
-#define chPortSetPad(port, pad) ioport_setpad_lld(port, pad)
+#define palSetPad(port, pad) pal_lld_setpad(port, pad)
#endif
/**
@@ -284,12 +293,12 @@ typedef struct { * @note The default implementation is non atomic and not necessarily
* optimal. Low level drivers may optimize the function by using
* specific hardware or coding.
- * @note The default implementation internally uses the @p chPortClear().
+ * @note The default implementation internally uses the @p palClearPort().
*/
-#if !defined(ioport_clearpad_lld) || defined(__DOXYGEN__)
-#define chPortClearPad(port, pad) chPortClear(port, IOPORT_BIT(pad))
+#if !defined(pal_lld_clearpad) || defined(__DOXYGEN__)
+#define palClearPad(port, pad) palClearPort(port, PAL_PORT_BIT(pad))
#else
-#define chPortClearPad(port, pad) ioport_clearpad_lld(port, pad)
+#define palClearPad(port, pad) pal_lld_clearpad(port, pad)
#endif
/**
@@ -304,14 +313,23 @@ typedef struct { * @note The default implementation is non atomic and not necessarily
* optimal. Low level drivers may optimize the function by using
* specific hardware or coding.
- * @note The default implementation internally uses the @p chPortToggle().
+ * @note The default implementation internally uses the @p palTogglePort().
*/
-#if !defined(ioport_togglepad_lld) || defined(__DOXYGEN__)
-#define chPortTogglePad(port, pad) ioport_toggle_lld(port, IOPORT_BIT(pad))
+#if !defined(pal_lld_togglepad) || defined(__DOXYGEN__)
+#define palTogglePad(port, pad) palTogglePort(port, PAL_PORT_BIT(pad))
#else
-#define chPortTogglePad(port, pad) ioport_togglepad_lld(port, pad)
+#define palTogglePad(port, pad) pal_lld_togglepad(port, pad)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ ioportmask_t palReadBus(IOBus *bus);
+ void palWriteBus(IOBus *bus, ioportmask_t bits);
+#ifdef __cplusplus
+}
#endif
-#endif /* _IOPORTS_H_ */
+#endif /* _PAL_H_ */
/** @} */
|