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