ChibiOS/RT Architecture - Reference Manual - Guides |
00001 /* 00002 ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. 00003 00004 This file is part of ChibiOS/RT. 00005 00006 ChibiOS/RT is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 ChibiOS/RT is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 00019 --- 00020 00021 A special exception to the GPL can be applied should you wish to distribute 00022 a combined work that includes ChibiOS/RT, without being obliged to provide 00023 the source code for any proprietary components. See the file exception.txt 00024 for full details of how and when the exception can be applied. 00025 */ 00026 00027 /** 00028 * @file pal.h 00029 * @brief I/O Ports Abstraction Layer macros, types and structures. 00030 * 00031 * @addtogroup PAL 00032 * @{ 00033 */ 00034 00035 #ifndef _PAL_H_ 00036 #define _PAL_H_ 00037 00038 #if CH_HAL_USE_PAL || defined(__DOXYGEN__) 00039 00040 /*===========================================================================*/ 00041 /* Driver constants. */ 00042 /*===========================================================================*/ 00043 00044 /** 00045 * @brief Bits in a mode word dedicated as mode selector. 00046 * @details The other bits are not defined and may be used as device-specific 00047 * option bits. 00048 */ 00049 #define PAL_MODE_MASK 0xF 00050 00051 /** 00052 * @brief After reset state. 00053 * @details The state itself is not specified and is architecture dependent, 00054 * it is guaranteed to be equal to the after-reset state. It is 00055 * usually an input state. 00056 */ 00057 #define PAL_MODE_RESET 0 00058 00059 /** 00060 * @brief Safe state for <b>unconnected</b> pads. 00061 * @details The state itself is not specified and is architecture dependent, 00062 * it may be mapped on @p PAL_MODE_INPUT_PULLUP, 00063 * @p PAL_MODE_INPUT_PULLDOWN or @p PAL_MODE_OUTPUT_PUSHPULL as 00064 * example. 00065 */ 00066 #define PAL_MODE_UNCONNECTED 1 00067 00068 /** 00069 * @brief Regular input high-Z pad. 00070 */ 00071 #define PAL_MODE_INPUT 2 00072 00073 /** 00074 * @brief Input pad with weak pull up resistor. 00075 */ 00076 #define PAL_MODE_INPUT_PULLUP 3 00077 00078 /** 00079 * @brief Input pad with weak pull down resistor. 00080 */ 00081 #define PAL_MODE_INPUT_PULLDOWN 4 00082 00083 /** 00084 * @brief Analog input mode. 00085 */ 00086 #define PAL_MODE_INPUT_ANALOG 5 00087 00088 /** 00089 * @brief Push-pull output pad. 00090 */ 00091 #define PAL_MODE_OUTPUT_PUSHPULL 6 00092 00093 /** 00094 * @brief Open-drain output pad. 00095 */ 00096 #define PAL_MODE_OUTPUT_OPENDRAIN 7 00097 00098 /** 00099 * @brief Logical low state. 00100 */ 00101 #define PAL_LOW 0 00102 00103 /** 00104 * @brief Logical high state. 00105 */ 00106 #define PAL_HIGH 1 00107 00108 /*===========================================================================*/ 00109 /* Driver pre-compile time settings. */ 00110 /*===========================================================================*/ 00111 00112 /*===========================================================================*/ 00113 /* Derived constants and error checks. */ 00114 /*===========================================================================*/ 00115 00116 /*===========================================================================*/ 00117 /* Driver data structures and types. */ 00118 /*===========================================================================*/ 00119 00120 #include "pal_lld.h" 00121 00122 /** 00123 * @brief I/O bus descriptor. 00124 * @details This structure describes a group of contiguous digital I/O lines 00125 * that have to be handled as bus. 00126 * @note I/O operations on a bus do not affect I/O lines on the same port but 00127 * not belonging to the bus. 00128 */ 00129 typedef struct { 00130 /** 00131 * @brief Port identifier. 00132 */ 00133 ioportid_t bus_portid; 00134 /** 00135 * @brief Bus mask aligned to port bit 0. 00136 * @note The bus mask implicitly define the bus width. A logical AND is 00137 * performed on the bus data. 00138 */ 00139 ioportmask_t bus_mask; 00140 /** 00141 * @brief Offset, within the port, of the least significant bit of the bus. 00142 */ 00143 uint_fast8_t bus_offset; 00144 } IOBus; 00145 00146 /*===========================================================================*/ 00147 /* Driver macros. */ 00148 /*===========================================================================*/ 00149 00150 /** 00151 * @brief Port bit helper macro. 00152 * @details This macro calculates the mask of a bit within a port. 00153 * 00154 * @param[in] n bit position within the port 00155 * @return The bit mask. 00156 */ 00157 #define PAL_PORT_BIT(n) ((ioportmask_t)(1 << (n))) 00158 00159 00160 /** 00161 * @brief Bits group mask helper. 00162 * @details This macro calculates the mask of a bits group. 00163 * 00164 * @param[in] width group width 00165 * @return The group mask. 00166 */ 00167 #define PAL_GROUP_MASK(width) ((ioportmask_t)(1 << (width)) - 1) 00168 00169 /** 00170 * @brief Data part of a static I/O bus initializer. 00171 * @details This macro should be used when statically initializing an I/O bus 00172 * that is part of a bigger structure. 00173 * 00174 * @param[in] name name of the IOBus variable 00175 * @param[in] port I/O port descriptor 00176 * @param[in] width bus width in bits 00177 * @param[in] offset bus bit offset within the port 00178 */ 00179 #define _IOBUS_DATA(name, port, width, offset) \ 00180 {port, PAL_GROUP_MASK(width), offset} 00181 00182 /** 00183 * @brief Static I/O bus initializer. 00184 * 00185 * @param[in] name name of the IOBus variable 00186 * @param[in] port I/O port descriptor 00187 * @param[in] width bus width in bits 00188 * @param[in] offset bus bit offset within the port 00189 */ 00190 #define IOBUS_DECL(name, port, width, offset) \ 00191 IOBus name = _IOBUS_DATA(name, port, width, offset) 00192 00193 /** 00194 * @brief PAL subsystem initialization. 00195 * 00196 * @param[in] config pointer to an architecture specific configuration 00197 * structure. This structure is defined in the low level driver 00198 * header. 00199 */ 00200 #define palInit(config) pal_lld_init(config) 00201 00202 /** 00203 * @brief Reads the physical I/O port states. 00204 * @note The default implementation always return zero and computes the 00205 * parameter eventual side effects. 00206 * 00207 * @param[in] port port identifier 00208 * @return The port logical states. 00209 */ 00210 #if !defined(pal_lld_readport) || defined(__DOXYGEN__) 00211 #define palReadPort(port) ((void)(port), 0) 00212 #else 00213 #define palReadPort(port) pal_lld_readport(port) 00214 #endif 00215 00216 /** 00217 * @brief Reads the output latch. 00218 * @details The purpose of this function is to read back the latched output 00219 * value. 00220 * @note The default implementation always return zero and computes the 00221 * parameter eventual side effects. 00222 * 00223 * @param[in] port port identifier 00224 * @return The latched logical states. 00225 */ 00226 #if !defined(pal_lld_readlatch) || defined(__DOXYGEN__) 00227 #define palReadLatch(port) ((void)(port), 0) 00228 #else 00229 #define palReadLatch(port) pal_lld_readlatch(port) 00230 #endif 00231 00232 /** 00233 * @brief Writes a bits mask on a I/O port. 00234 * @note The default implementation does nothing except computing the 00235 * parameters eventual side effects. 00236 * 00237 * @param[in] port port identifier 00238 * @param[in] bits bits to be written on the specified port 00239 */ 00240 #if !defined(pal_lld_writeport) || defined(__DOXYGEN__) 00241 #define palWritePort(port, bits) ((void)(port), (void)(bits)) 00242 #else 00243 #define palWritePort(port, bits) pal_lld_writeport(port, bits) 00244 #endif 00245 00246 /** 00247 * @brief Sets a bits mask on a I/O port. 00248 * @note The operation is not guaranteed to be atomic on all the 00249 * architectures, for atomicity and/or portability reasons you may 00250 * need to enclose port I/O operations between @p chSysLock() and 00251 * @p chSysUnlock(). 00252 * @note The default implementation is non atomic and not necessarily 00253 * optimal. Low level drivers may optimize the function by using 00254 * specific hardware or coding. 00255 * 00256 * @param[in] port port identifier 00257 * @param[in] bits bits to be ORed on the specified port 00258 */ 00259 #if !defined(pal_lld_setport) || defined(__DOXYGEN__) 00260 #define palSetPort(port, bits) { \ 00261 palWritePort(port, palReadLatch(port) | (bits)); \ 00262 } 00263 #else 00264 #define palSetPort(port, bits) pal_lld_setport(port, bits) 00265 #endif 00266 00267 /** 00268 * @brief Clears a bits mask on a I/O port. 00269 * @note The operation is not guaranteed to be atomic on all the 00270 * architectures, for atomicity and/or portability reasons you may 00271 * need to enclose port I/O operations between @p chSysLock() and 00272 * @p chSysUnlock(). 00273 * @note The default implementation is non atomic and not necessarily 00274 * optimal. Low level drivers may optimize the function by using 00275 * specific hardware or coding. 00276 * 00277 * @param[in] port port identifier 00278 * @param[in] bits bits to be cleared on the specified port 00279 * 00280 */ 00281 #if !defined(pal_lld_clearport) || defined(__DOXYGEN__) 00282 #define palClearPort(port, bits) { \ 00283 palWritePort(port, palReadLatch(port) & ~(bits)); \ 00284 } 00285 #else 00286 #define palClearPort(port, bits) pal_lld_clearport(port, bits) 00287 #endif 00288 00289 /** 00290 * @brief Toggles a bits mask on a I/O port. 00291 * @note The operation is not guaranteed to be atomic on all the 00292 * architectures, for atomicity and/or portability reasons you may 00293 * need to enclose port I/O operations between @p chSysLock() and 00294 * @p chSysUnlock(). 00295 * @note The default implementation is non atomic and not necessarily 00296 * optimal. Low level drivers may optimize the function by using 00297 * specific hardware or coding. 00298 * 00299 * @param[in] port port identifier 00300 * @param[in] bits bits to be XORed on the specified port 00301 */ 00302 #if !defined(pal_lld_toggleport) || defined(__DOXYGEN__) 00303 #define palTogglePort(port, bits) { \ 00304 palWritePort(port, palReadLatch(port) ^ (bits)); \ 00305 } 00306 #else 00307 #define palTogglePort(port, bits) pal_lld_toggleport(port, bits) 00308 #endif 00309 00310 /** 00311 * @brief Reads a group of bits. 00312 * 00313 * @param[in] port port identifier 00314 * @param[in] mask group mask, a logical AND is performed on the input 00315 * data 00316 * @param[in] offset group bit offset within the port 00317 * @return The group logical states. 00318 */ 00319 #if !defined(pal_lld_readgroup) || defined(__DOXYGEN__) 00320 #define palReadGroup(port, mask, offset) \ 00321 ((palReadPort(port) >> (offset)) & (mask)) 00322 #else 00323 #define palReadGroup(port, mask, offset) pal_lld_readgroup(port, mask, offset) 00324 #endif 00325 00326 /** 00327 * @brief Writes a group of bits. 00328 * 00329 * @param[in] port port identifier 00330 * @param[in] mask group mask, a logical AND is performed on the 00331 * output data 00332 * @param[in] offset group bit offset within the port 00333 * @param[in] bits bits to be written. Values exceeding the group 00334 * width are masked. 00335 */ 00336 #if !defined(pal_lld_writegroup) || defined(__DOXYGEN__) 00337 #define palWriteGroup(port, mask, offset, bits) { \ 00338 palWritePort(port, (palReadLatch(port) & ~((mask) << (offset))) | \ 00339 (((bits) & (mask)) << (offset))); \ 00340 } 00341 #else 00342 #define palWriteGroup(port, mask, offset, bits) \ 00343 pal_lld_writegroup(port, mask, offset, bits) 00344 #endif 00345 00346 00347 /** 00348 * @brief Pads group mode setup. 00349 * @details This function programs a pads group belonging to the same port 00350 * with the specified mode. 00351 * @note Programming an unknown or unsupported mode is silently ignored. 00352 * 00353 * @param[in] port port identifier 00354 * @param[in] mask group mask 00355 * @param[in] mode group mode 00356 * 00357 */ 00358 #if !defined(pal_lld_setgroupmode) || defined(__DOXYGEN__) 00359 #define palSetGroupMode(port, mask, mode) 00360 #else 00361 #define palSetGroupMode(port, mask, mode) pal_lld_setgroupmode(port, mask, mode) 00362 #endif 00363 00364 /** 00365 * @brief Reads an input pad logical state. 00366 * @note The default implementation not necessarily optimal. Low level 00367 * drivers may optimize the function by using specific hardware 00368 * or coding. 00369 * @note The default implementation internally uses the @p palReadPort(). 00370 * 00371 * @param[in] port port identifier 00372 * @param[in] pad pad number within the port 00373 * @return The logical state. 00374 * @retval PAL_LOW low logical state. 00375 * @retval PAL_HIGH high logical state. 00376 * 00377 */ 00378 #if !defined(pal_lld_readpad) || defined(__DOXYGEN__) 00379 #define palReadPad(port, pad) ((palReadPort(port) >> (pad)) & 1) 00380 #else 00381 #define palReadPad(port, pad) pal_lld_readpad(port, pad) 00382 #endif 00383 00384 /** 00385 * @brief Writes a logical state on an output pad. 00386 * @note The operation is not guaranteed to be atomic on all the 00387 * architectures, for atomicity and/or portability reasons you may 00388 * need to enclose port I/O operations between @p chSysLock() and 00389 * @p chSysUnlock(). 00390 * @note The default implementation is non atomic and not necessarily 00391 * optimal. Low level drivers may optimize the function by using 00392 * specific hardware or coding. 00393 * @note The default implementation internally uses the @p palReadLatch() 00394 * and @p palWritePort(). 00395 * 00396 * @param[in] port port identifier 00397 * @param[in] pad pad number within the port 00398 * @param[in] bit logical value, the value must be @p PAL_LOW or 00399 * @p PAL_HIGH 00400 */ 00401 #if !defined(pal_lld_writepad) || defined(__DOXYGEN__) 00402 #define palWritePad(port, pad, bit) { \ 00403 palWritePort(port, (palReadLatch(port) & ~PAL_PORT_BIT(pad)) | \ 00404 (((bit) & 1) << pad)); \ 00405 } 00406 #else 00407 #define palWritePad(port, pad, bit) pal_lld_writepad(port, pad, bit) 00408 #endif 00409 00410 /** 00411 * @brief Sets a pad logical state to @p PAL_HIGH. 00412 * @note The operation is not guaranteed to be atomic on all the 00413 * architectures, for atomicity and/or portability reasons you may 00414 * need to enclose port I/O operations between @p chSysLock() and 00415 * @p chSysUnlock(). 00416 * @note The default implementation is non atomic and not necessarily 00417 * optimal. Low level drivers may optimize the function by using 00418 * specific hardware or coding. 00419 * @note The default implementation internally uses the @p palSetPort(). 00420 * 00421 * @param[in] port port identifier 00422 * @param[in] pad pad number within the port 00423 */ 00424 #if !defined(pal_lld_setpad) || defined(__DOXYGEN__) 00425 #define palSetPad(port, pad) palSetPort(port, PAL_PORT_BIT(pad)) 00426 #else 00427 #define palSetPad(port, pad) pal_lld_setpad(port, pad) 00428 #endif 00429 00430 /** 00431 * @brief Clears a pad logical state to @p PAL_LOW. 00432 * @note The operation is not guaranteed to be atomic on all the 00433 * architectures, for atomicity and/or portability reasons you may 00434 * need to enclose port I/O operations between @p chSysLock() and 00435 * @p chSysUnlock(). 00436 * @note The default implementation is non atomic and not necessarily 00437 * optimal. Low level drivers may optimize the function by using 00438 * specific hardware or coding. 00439 * @note The default implementation internally uses the @p palClearPort(). 00440 * 00441 * @param[in] port port identifier 00442 * @param[in] pad pad number within the port 00443 */ 00444 #if !defined(pal_lld_clearpad) || defined(__DOXYGEN__) 00445 #define palClearPad(port, pad) palClearPort(port, PAL_PORT_BIT(pad)) 00446 #else 00447 #define palClearPad(port, pad) pal_lld_clearpad(port, pad) 00448 #endif 00449 00450 /** 00451 * @brief Toggles a pad logical state. 00452 * @note The operation is not guaranteed to be atomic on all the 00453 * architectures, for atomicity and/or portability reasons you may 00454 * need to enclose port I/O operations between @p chSysLock() and 00455 * @p chSysUnlock(). 00456 * @note The default implementation is non atomic and not necessarily 00457 * optimal. Low level drivers may optimize the function by using 00458 * specific hardware or coding. 00459 * @note The default implementation internally uses the @p palTogglePort(). 00460 * 00461 * @param[in] port port identifier 00462 * @param[in] pad pad number within the port 00463 */ 00464 #if !defined(pal_lld_togglepad) || defined(__DOXYGEN__) 00465 #define palTogglePad(port, pad) palTogglePort(port, PAL_PORT_BIT(pad)) 00466 #else 00467 #define palTogglePad(port, pad) pal_lld_togglepad(port, pad) 00468 #endif 00469 00470 00471 /** 00472 * @brief Pad mode setup. 00473 * @details This function programs a pad with the specified mode. 00474 * @note The default implementation not necessarily optimal. Low level 00475 * drivers may optimize the function by using specific hardware 00476 * or coding. 00477 * @note Programming an unknown or unsupported mode is silently ignored. 00478 * 00479 * @param[in] port port identifier 00480 * @param[in] pad pad number within the port 00481 * @param[in] mode pad mode 00482 */ 00483 #if !defined(pal_lld_setpadmode) || defined(__DOXYGEN__) 00484 #define palSetPadMode(port, pad, mode) \ 00485 palSetGroupMode(port, PAL_PORT_BIT(pad), mode) 00486 #else 00487 #define palSetPadMode(port, pad, mode) pal_lld_setpadmode(port, pad, mode) 00488 #endif 00489 00490 /*===========================================================================*/ 00491 /* External declarations. */ 00492 /*===========================================================================*/ 00493 00494 #ifdef __cplusplus 00495 extern "C" { 00496 #endif 00497 ioportmask_t palReadBus(IOBus *bus); 00498 void palWriteBus(IOBus *bus, ioportmask_t bits); 00499 void palSetBusMode(IOBus *bus, uint_fast8_t mode); 00500 #ifdef __cplusplus 00501 } 00502 #endif 00503 00504 #endif /* _PAL_H_ */ 00505 00506 #endif /* CH_HAL_USE_PAL */ 00507 00508 /** @} */