hal_pal.h 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023
  1. /*
  2. ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. /**
  14. * @file hal_pal.h
  15. * @brief I/O Ports Abstraction Layer macros, types and structures.
  16. *
  17. * @addtogroup PAL
  18. * @{
  19. */
  20. #ifndef HAL_PAL_H
  21. #define HAL_PAL_H
  22. #if (HAL_USE_PAL == TRUE) || defined(__DOXYGEN__)
  23. /*===========================================================================*/
  24. /* Driver constants. */
  25. /*===========================================================================*/
  26. /**
  27. * @name Pads mode constants
  28. * @{
  29. */
  30. /**
  31. * @brief After reset state.
  32. * @details The state itself is not specified and is architecture dependent,
  33. * it is guaranteed to be equal to the after-reset state. It is
  34. * usually an input state.
  35. */
  36. #define PAL_MODE_RESET 0U
  37. /**
  38. * @brief Safe state for <b>unconnected</b> pads.
  39. * @details The state itself is not specified and is architecture dependent,
  40. * it may be mapped on @p PAL_MODE_INPUT_PULLUP,
  41. * @p PAL_MODE_INPUT_PULLDOWN or @p PAL_MODE_OUTPUT_PUSHPULL for
  42. * example.
  43. */
  44. #define PAL_MODE_UNCONNECTED 1U
  45. /**
  46. * @brief Regular input high-Z pad.
  47. */
  48. #define PAL_MODE_INPUT 2U
  49. /**
  50. * @brief Input pad with weak pull up resistor.
  51. */
  52. #define PAL_MODE_INPUT_PULLUP 3U
  53. /**
  54. * @brief Input pad with weak pull down resistor.
  55. */
  56. #define PAL_MODE_INPUT_PULLDOWN 4U
  57. /**
  58. * @brief Analog input mode.
  59. */
  60. #define PAL_MODE_INPUT_ANALOG 5U
  61. /**
  62. * @brief Push-pull output pad.
  63. */
  64. #define PAL_MODE_OUTPUT_PUSHPULL 6U
  65. /**
  66. * @brief Open-drain output pad.
  67. */
  68. #define PAL_MODE_OUTPUT_OPENDRAIN 7U
  69. /** @} */
  70. /**
  71. * @name Logic level constants
  72. * @{
  73. */
  74. /**
  75. * @brief Logical low state.
  76. */
  77. #define PAL_LOW 0U
  78. /**
  79. * @brief Logical high state.
  80. */
  81. #define PAL_HIGH 1U
  82. /** @} */
  83. /**
  84. * @name PAL event modes
  85. * @{
  86. */
  87. #define PAL_EVENT_MODE_EDGES_MASK 3U /**< @brief Mask of edges field. */
  88. #define PAL_EVENT_MODE_DISABLED 0U /**< @brief Channel disabled. */
  89. #define PAL_EVENT_MODE_RISING_EDGE 1U /**< @brief Rising edge callback. */
  90. #define PAL_EVENT_MODE_FALLING_EDGE 2U /**< @brief Falling edge callback. */
  91. #define PAL_EVENT_MODE_BOTH_EDGES 3U /**< @brief Both edges callback. */
  92. /** @} */
  93. /*===========================================================================*/
  94. /* Driver pre-compile time settings. */
  95. /*===========================================================================*/
  96. /**
  97. * @name PAL configuration options
  98. * @{
  99. */
  100. /**
  101. * @brief Enables synchronous APIs.
  102. * @note Disabling this option saves both code and data space.
  103. */
  104. #if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__)
  105. #define PAL_USE_CALLBACKS TRUE
  106. #endif
  107. /**
  108. * @brief Enables synchronous APIs.
  109. * @note Disabling this option saves both code and data space.
  110. */
  111. #if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__)
  112. #define PAL_USE_WAIT TRUE
  113. #endif
  114. /** @} */
  115. /*===========================================================================*/
  116. /* Derived constants and error checks. */
  117. /*===========================================================================*/
  118. /*===========================================================================*/
  119. /* Driver data structures and types. */
  120. /*===========================================================================*/
  121. /**
  122. * @brief Type of a PAL event callback.
  123. */
  124. typedef void (*palcallback_t)(void *arg);
  125. #if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
  126. /**
  127. * @brief Type of a PAL event record.
  128. */
  129. typedef struct {
  130. #if (PAL_USE_WAIT == TRUE) || defined(__DOXYGEN__)
  131. /**
  132. * @brief Threads queued for an event.
  133. */
  134. threads_queue_t threads;
  135. #endif
  136. #if (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
  137. /**
  138. * @brief Event callback.
  139. */
  140. palcallback_t cb;
  141. /**
  142. * @brief Event callback argument.
  143. */
  144. void *arg;
  145. #endif
  146. } palevent_t;
  147. #endif
  148. #include "hal_pal_lld.h"
  149. /**
  150. * @brief I/O bus descriptor.
  151. * @details This structure describes a group of contiguous digital I/O lines
  152. * that have to be handled as bus.
  153. * @note I/O operations on a bus do not affect I/O lines on the same port but
  154. * not belonging to the bus.
  155. */
  156. typedef struct {
  157. /**
  158. * @brief Port identifier.
  159. */
  160. ioportid_t portid;
  161. /**
  162. * @brief Bus mask aligned to port bit 0.
  163. * @note The bus mask implicitly define the bus width. A logic AND is
  164. * performed on the bus data.
  165. */
  166. ioportmask_t mask;
  167. /**
  168. * @brief Offset, within the port, of the least significant bit of the bus.
  169. */
  170. uint_fast8_t offset;
  171. } IOBus;
  172. /*===========================================================================*/
  173. /* Driver macros. */
  174. /*===========================================================================*/
  175. /**
  176. * @brief Port bit helper macro.
  177. * @details This macro calculates the mask of a bit within a port.
  178. *
  179. * @param[in] n bit position within the port
  180. * @return The bit mask.
  181. */
  182. #if !defined(PAL_PORT_BIT) || defined(__DOXYGEN__)
  183. #define PAL_PORT_BIT(n) ((ioportmask_t)(1U << (n)))
  184. #endif
  185. /**
  186. * @brief Bits group mask helper.
  187. * @details This macro calculates the mask of a bits group.
  188. *
  189. * @param[in] width group width
  190. * @return The group mask.
  191. */
  192. #if !defined(PAL_GROUP_MASK) || defined(__DOXYGEN__)
  193. #define PAL_GROUP_MASK(width) ((ioportmask_t)(1U << (width)) - 1U)
  194. #endif
  195. /**
  196. * @brief Data part of a static I/O bus initializer.
  197. * @details This macro should be used when statically initializing an I/O bus
  198. * that is part of a bigger structure.
  199. *
  200. * @param[in] name name of the IOBus variable
  201. * @param[in] port I/O port descriptor
  202. * @param[in] width bus width in bits
  203. * @param[in] offset bus bit offset within the port
  204. */
  205. #define _IOBUS_DATA(name, port, width, offset) \
  206. {port, PAL_GROUP_MASK(width), offset}
  207. /**
  208. * @brief Static I/O bus initializer.
  209. *
  210. * @param[in] name name of the IOBus variable
  211. * @param[in] port I/O port descriptor
  212. * @param[in] width bus width in bits
  213. * @param[in] offset bus bit offset within the port
  214. */
  215. #define IOBUS_DECL(name, port, width, offset) \
  216. IOBus name = _IOBUS_DATA(name, port, width, offset)
  217. #if (PAL_USE_CALLBACKS == TRUE) || (PAL_USE_WAIT == TRUE) || \
  218. defined(__DOXYGEN__)
  219. /**
  220. * @name Low level driver helper macros
  221. * @{
  222. */
  223. #if ((PAL_USE_CALLBACKS == TRUE) && (PAL_USE_WAIT == TRUE)) || \
  224. defined(__DOXYGEN__)
  225. /**
  226. * @brief Initializes a PAL event object.
  227. *
  228. * @param[in] e event index
  229. *
  230. * @notapi
  231. */
  232. #define _pal_init_event(e) \
  233. do { \
  234. osalThreadQueueObjectInit(&_pal_events[e].threads); \
  235. _pal_events[e].cb = NULL; \
  236. _pal_events[e].arg = NULL; \
  237. } while (false)
  238. #endif /* (PAL_USE_CALLBACKS == TRUE) && (PAL_USE_WAIT == TRUE) */
  239. #if (PAL_USE_CALLBACKS == TRUE) && (PAL_USE_WAIT == FALSE)
  240. #define _pal_init_event(e) \
  241. do { \
  242. _pal_events[e].cb = NULL; \
  243. _pal_events[e].arg = NULL; \
  244. } while (false)
  245. #endif /* (PAL_USE_CALLBACKS == TRUE) && (PAL_USE_WAIT == FALSE) */
  246. #if (PAL_USE_CALLBACKS == FALSE) && (PAL_USE_WAIT == TRUE)
  247. #define _pal_init_event(e) \
  248. do { \
  249. osalThreadQueueObjectInit(&_pal_events[e].threads); \
  250. } while (false)
  251. #endif /* (PAL_USE_CALLBACKS == FALSE) && (PAL_USE_WAIT == TRUE) */
  252. #if ((PAL_USE_CALLBACKS == TRUE) && (PAL_USE_WAIT == TRUE)) || defined(__DOXYGEN__)
  253. /**
  254. * @brief Clears a PAL event object.
  255. *
  256. * @param[in] e event index
  257. *
  258. * @notapi
  259. */
  260. #define _pal_clear_event(e) \
  261. do { \
  262. osalThreadDequeueAllI(&_pal_events[pad].threads, MSG_RESET); \
  263. _pal_events[e].cb = NULL; \
  264. _pal_events[e].arg = NULL; \
  265. } while (false)
  266. #endif /* (PAL_USE_CALLBACKS == TRUE) && (PAL_USE_WAIT == TRUE) */
  267. #if (PAL_USE_CALLBACKS == TRUE) && (PAL_USE_WAIT == FALSE)
  268. #define _pal_clear_event(e) \
  269. do { \
  270. _pal_events[e].cb = NULL; \
  271. _pal_events[e].arg = NULL; \
  272. } while (false)
  273. #endif /* (PAL_USE_CALLBACKS == TRUE) && (PAL_USE_WAIT == FALSE) */
  274. #if (PAL_USE_CALLBACKS == FALSE) && (PAL_USE_WAIT == TRUE)
  275. #define _pal_clear_event(e) \
  276. do { \
  277. osalThreadDequeueAllI(&_pal_events[pad].threads, MSG_RESET); \
  278. } while (false)
  279. #endif /* (PAL_USE_CALLBACKS == FALSE) && (PAL_USE_WAIT == TRUE) */
  280. /**
  281. * @brief Common ISR code.
  282. * @note This macro is meant to be used in the low level drivers
  283. * implementation only.
  284. *
  285. * @param[in] e event index
  286. *
  287. * @notapi
  288. */
  289. #if ((PAL_USE_CALLBACKS == TRUE) && (PAL_USE_WAIT == TRUE)) || \
  290. defined(__DOXYGEN__)
  291. #define _pal_isr_code(e) do { \
  292. if (_pal_events[e].cb != NULL) { \
  293. _pal_events[e].cb(_pal_events[e].arg); \
  294. } \
  295. osalSysLockFromISR(); \
  296. osalThreadDequeueAllI(&_pal_events[e].threads, MSG_OK); \
  297. osalSysUnlockFromISR(); \
  298. } while (false)
  299. #endif /* (PAL_USE_CALLBACKS == TRUE) && (PAL_USE_WAIT == TRUE) */
  300. #if (PAL_USE_CALLBACKS == TRUE) && (PAL_USE_WAIT == FALSE)
  301. #define _pal_isr_code(e) do { \
  302. if (_pal_events[e].cb != NULL) { \
  303. _pal_events[e].cb(_pal_events[e].arg); \
  304. } \
  305. } while (false)
  306. #endif /* (PAL_USE_CALLBACKS == TRUE) && (PAL_USE_WAIT == FALSE) */
  307. #if ((PAL_USE_CALLBACKS == FALSE) && (PAL_USE_WAIT == TRUE)) || \
  308. defined(__DOXYGEN__)
  309. #define _pal_isr_code(e) do { \
  310. osalSysLockFromISR(); \
  311. osalThreadDequeueAllI(&_pal_events[e].threads, MSG_OK); \
  312. osalSysUnlockFromISR(); \
  313. } while (false)
  314. #endif /* (PAL_USE_CALLBACKS == FALSE) && (PAL_USE_WAIT == TRUE) */
  315. /** @} */
  316. #endif /* (PAL_USE_CALLBACKS == TRUE) || (PAL_USE_WAIT == TRUE) */
  317. /**
  318. * @name Macro Functions
  319. * @{
  320. */
  321. /**
  322. * @brief PAL subsystem initialization.
  323. * @note This function is implicitly invoked by @p halInit(), there is
  324. * no need to explicitly initialize the driver.
  325. *
  326. * @init
  327. */
  328. #if defined(PAL_NEW_INIT) || defined(__DOXYGEN__)
  329. #define palInit() pal_lld_init()
  330. #else
  331. #define palInit(config) pal_lld_init(config)
  332. #endif
  333. /**
  334. * @brief Reads the physical I/O port states.
  335. * @note The function can be called from any context.
  336. *
  337. * @param[in] port port identifier
  338. * @return The port logic states.
  339. *
  340. * @special
  341. */
  342. #if !defined(pal_lld_readport) || defined(__DOXYGEN__)
  343. #define palReadPort(port) ((void)(port), 0U)
  344. #else
  345. #define palReadPort(port) pal_lld_readport(port)
  346. #endif
  347. /**
  348. * @brief Reads the output latch.
  349. * @details The purpose of this function is to read back the latched output
  350. * value.
  351. * @note The function can be called from any context.
  352. *
  353. * @param[in] port port identifier
  354. * @return The latched logic states.
  355. *
  356. * @special
  357. */
  358. #if !defined(pal_lld_readlatch) || defined(__DOXYGEN__)
  359. #define palReadLatch(port) ((void)(port), 0U)
  360. #else
  361. #define palReadLatch(port) pal_lld_readlatch(port)
  362. #endif
  363. /**
  364. * @brief Writes a bits mask on a I/O port.
  365. * @note The function can be called from any context.
  366. *
  367. * @param[in] port port identifier
  368. * @param[in] bits bits to be written on the specified port
  369. *
  370. * @special
  371. */
  372. #if !defined(pal_lld_writeport) || defined(__DOXYGEN__)
  373. #define palWritePort(port, bits) ((void)(port), (void)(bits))
  374. #else
  375. #define palWritePort(port, bits) pal_lld_writeport(port, bits)
  376. #endif
  377. /**
  378. * @brief Sets a bits mask on a I/O port.
  379. * @note The operation is not guaranteed to be atomic on all the
  380. * architectures, for atomicity and/or portability reasons you may
  381. * need to enclose port I/O operations between @p osalSysLock() and
  382. * @p osalSysUnlock().
  383. * @note The function can be called from any context.
  384. *
  385. * @param[in] port port identifier
  386. * @param[in] bits bits to be ORed on the specified port
  387. *
  388. * @special
  389. */
  390. #if !defined(pal_lld_setport) || defined(__DOXYGEN__)
  391. #define palSetPort(port, bits) \
  392. palWritePort(port, palReadLatch(port) | (bits))
  393. #else
  394. #define palSetPort(port, bits) pal_lld_setport(port, bits)
  395. #endif
  396. /**
  397. * @brief Clears a bits mask on a I/O port.
  398. * @note The operation is not guaranteed to be atomic on all the
  399. * architectures, for atomicity and/or portability reasons you may
  400. * need to enclose port I/O operations between @p osalSysLock() and
  401. * @p osalSysUnlock().
  402. * @note The function can be called from any context.
  403. *
  404. * @param[in] port port identifier
  405. * @param[in] bits bits to be cleared on the specified port
  406. *
  407. * @special
  408. */
  409. #if !defined(pal_lld_clearport) || defined(__DOXYGEN__)
  410. #define palClearPort(port, bits) \
  411. palWritePort(port, palReadLatch(port) & ~(bits))
  412. #else
  413. #define palClearPort(port, bits) pal_lld_clearport(port, bits)
  414. #endif
  415. /**
  416. * @brief Toggles a bits mask on a I/O port.
  417. * @note The operation is not guaranteed to be atomic on all the
  418. * architectures, for atomicity and/or portability reasons you may
  419. * need to enclose port I/O operations between @p osalSysLock() and
  420. * @p osalSysUnlock().
  421. * @note The function can be called from any context.
  422. *
  423. * @param[in] port port identifier
  424. * @param[in] bits bits to be XORed on the specified port
  425. *
  426. * @special
  427. */
  428. #if !defined(pal_lld_toggleport) || defined(__DOXYGEN__)
  429. #define palTogglePort(port, bits) \
  430. palWritePort(port, palReadLatch(port) ^ (bits))
  431. #else
  432. #define palTogglePort(port, bits) pal_lld_toggleport(port, bits)
  433. #endif
  434. /**
  435. * @brief Reads a group of bits.
  436. * @note The function can be called from any context.
  437. *
  438. * @param[in] port port identifier
  439. * @param[in] mask group mask, a logic AND is performed on the input
  440. * data
  441. * @param[in] offset group bit offset within the port
  442. * @return The group logic states.
  443. *
  444. * @special
  445. */
  446. #if !defined(pal_lld_readgroup) || defined(__DOXYGEN__)
  447. #define palReadGroup(port, mask, offset) \
  448. ((palReadPort(port) >> (offset)) & (mask))
  449. #else
  450. #define palReadGroup(port, mask, offset) pal_lld_readgroup(port, mask, offset)
  451. #endif
  452. /**
  453. * @brief Writes a group of bits.
  454. * @note The operation is not guaranteed to be atomic on all the
  455. * architectures, for atomicity and/or portability reasons you may
  456. * need to enclose port I/O operations between @p osalSysLock() and
  457. * @p osalSysUnlock().
  458. * @note The function can be called from any context.
  459. *
  460. * @param[in] port port identifier
  461. * @param[in] mask group mask, a logic AND is performed on the
  462. * output data
  463. * @param[in] offset group bit offset within the port
  464. * @param[in] bits bits to be written. Values exceeding the group
  465. * width are masked.
  466. *
  467. * @special
  468. */
  469. #if !defined(pal_lld_writegroup) || defined(__DOXYGEN__)
  470. #define palWriteGroup(port, mask, offset, bits) \
  471. palWritePort(port, (palReadLatch(port) & ~((mask) << (offset))) | \
  472. (((bits) & (mask)) << (offset)))
  473. #else
  474. #define palWriteGroup(port, mask, offset, bits) \
  475. pal_lld_writegroup(port, mask, offset, bits)
  476. #endif
  477. /**
  478. * @brief Pads group mode setup.
  479. * @details This function programs a pads group belonging to the same port
  480. * with the specified mode.
  481. * @note The operation is not guaranteed to be atomic on all the
  482. * architectures, for atomicity and/or portability reasons you may
  483. * need to enclose port I/O operations between @p osalSysLock() and
  484. * @p osalSysUnlock().
  485. * @note Programming an unknown or unsupported mode is silently ignored.
  486. * @note The function can be called from any context.
  487. *
  488. * @param[in] port port identifier
  489. * @param[in] mask group mask
  490. * @param[in] offset group bit offset within the port
  491. * @param[in] mode group mode
  492. *
  493. * @special
  494. */
  495. #if !defined(pal_lld_setgroupmode) || defined(__DOXYGEN__)
  496. #define palSetGroupMode(port, mask, offset, mode)
  497. #else
  498. #define palSetGroupMode(port, mask, offset, mode) \
  499. pal_lld_setgroupmode(port, mask, offset, mode)
  500. #endif
  501. /**
  502. * @brief Reads an input pad logic state.
  503. * @note The function can be called from any context.
  504. *
  505. * @param[in] port port identifier
  506. * @param[in] pad pad number within the port
  507. * @return The logic state.
  508. * @retval PAL_LOW low logic state.
  509. * @retval PAL_HIGH high logic state.
  510. *
  511. * @special
  512. */
  513. #if !defined(pal_lld_readpad) || defined(__DOXYGEN__)
  514. #define palReadPad(port, pad) ((palReadPort(port) >> (pad)) & 1U)
  515. #else
  516. #define palReadPad(port, pad) pal_lld_readpad(port, pad)
  517. #endif
  518. /**
  519. * @brief Writes a logic state on an output pad.
  520. * @note The operation is not guaranteed to be atomic on all the
  521. * architectures, for atomicity and/or portability reasons you may
  522. * need to enclose port I/O operations between @p osalSysLock() and
  523. * @p osalSysUnlock().
  524. * @note The function can be called from any context.
  525. *
  526. * @param[in] port port identifier
  527. * @param[in] pad pad number within the port
  528. * @param[in] bit logic value, the value must be @p PAL_LOW or
  529. * @p PAL_HIGH
  530. *
  531. * @special
  532. */
  533. #if !defined(pal_lld_writepad) || defined(__DOXYGEN__)
  534. #define palWritePad(port, pad, bit) \
  535. palWritePort(port, (palReadLatch(port) & ~PAL_PORT_BIT(pad)) | \
  536. (((bit) & 1U) << pad))
  537. #else
  538. #define palWritePad(port, pad, bit) pal_lld_writepad(port, pad, bit)
  539. #endif
  540. /**
  541. * @brief Sets a pad logic state to @p PAL_HIGH.
  542. * @note The operation is not guaranteed to be atomic on all the
  543. * architectures, for atomicity and/or portability reasons you may
  544. * need to enclose port I/O operations between @p osalSysLock() and
  545. * @p osalSysUnlock().
  546. * @note The function can be called from any context.
  547. *
  548. * @param[in] port port identifier
  549. * @param[in] pad pad number within the port
  550. *
  551. * @special
  552. */
  553. #if !defined(pal_lld_setpad) || defined(__DOXYGEN__)
  554. #define palSetPad(port, pad) palSetPort(port, PAL_PORT_BIT(pad))
  555. #else
  556. #define palSetPad(port, pad) pal_lld_setpad(port, pad)
  557. #endif
  558. /**
  559. * @brief Clears a pad logic state to @p PAL_LOW.
  560. * @note The operation is not guaranteed to be atomic on all the
  561. * architectures, for atomicity and/or portability reasons you may
  562. * need to enclose port I/O operations between @p osalSysLock() and
  563. * @p osalSysUnlock().
  564. * @note The function can be called from any context.
  565. *
  566. * @param[in] port port identifier
  567. * @param[in] pad pad number within the port
  568. *
  569. * @special
  570. */
  571. #if !defined(pal_lld_clearpad) || defined(__DOXYGEN__)
  572. #define palClearPad(port, pad) palClearPort(port, PAL_PORT_BIT(pad))
  573. #else
  574. #define palClearPad(port, pad) pal_lld_clearpad(port, pad)
  575. #endif
  576. /**
  577. * @brief Toggles a pad logic state.
  578. * @note The operation is not guaranteed to be atomic on all the
  579. * architectures, for atomicity and/or portability reasons you may
  580. * need to enclose port I/O operations between @p osalSysLock() and
  581. * @p osalSysUnlock().
  582. * @note The function can be called from any context.
  583. *
  584. * @param[in] port port identifier
  585. * @param[in] pad pad number within the port
  586. *
  587. * @special
  588. */
  589. #if !defined(pal_lld_togglepad) || defined(__DOXYGEN__)
  590. #define palTogglePad(port, pad) palTogglePort(port, PAL_PORT_BIT(pad))
  591. #else
  592. #define palTogglePad(port, pad) pal_lld_togglepad(port, pad)
  593. #endif
  594. /**
  595. * @brief Pad mode setup.
  596. * @details This function programs a pad with the specified mode.
  597. * @note The operation is not guaranteed to be atomic on all the
  598. * architectures, for atomicity and/or portability reasons you may
  599. * need to enclose port I/O operations between @p osalSysLock() and
  600. * @p osalSysUnlock().
  601. * @note Programming an unknown or unsupported mode is silently ignored.
  602. * @note The function can be called from any context.
  603. *
  604. * @param[in] port port identifier
  605. * @param[in] pad pad number within the port
  606. * @param[in] mode pad mode
  607. *
  608. * @special
  609. */
  610. #if !defined(pal_lld_setpadmode) || defined(__DOXYGEN__)
  611. #define palSetPadMode(port, pad, mode) \
  612. palSetGroupMode(port, PAL_PORT_BIT(pad), 0U, mode)
  613. #else
  614. #define palSetPadMode(port, pad, mode) pal_lld_setpadmode(port, pad, mode)
  615. #endif
  616. /**
  617. * @brief Reads an input line logic state.
  618. * @note The function can be called from any context.
  619. *
  620. * @param[in] line line identifier
  621. * @return The logic state.
  622. * @retval PAL_LOW low logic state.
  623. * @retval PAL_HIGH high logic state.
  624. *
  625. * @special
  626. */
  627. #if !defined(pal_lld_readline) || defined(__DOXYGEN__)
  628. #define palReadLine(line) palReadPad(PAL_PORT(line), PAL_PAD(line))
  629. #else
  630. #define palReadLine(line) pal_lld_readline(line)
  631. #endif
  632. /**
  633. * @brief Writes a logic state on an output line.
  634. * @note The operation is not guaranteed to be atomic on all the
  635. * architectures, for atomicity and/or portability reasons you may
  636. * need to enclose port I/O operations between @p osalSysLock() and
  637. * @p osalSysUnlock().
  638. * @note The function can be called from any context.
  639. *
  640. * @param[in] line line identifier
  641. * @param[in] bit logic value, the value must be @p PAL_LOW or
  642. * @p PAL_HIGH
  643. *
  644. * @special
  645. */
  646. #if !defined(pal_lld_writeline) || defined(__DOXYGEN__)
  647. #define palWriteLine(line, bit) palWritePad(PAL_PORT(line), PAL_PAD(line), bit)
  648. #else
  649. #define palWriteLine(line, bit) pal_lld_writeline(line, bit)
  650. #endif
  651. /**
  652. * @brief Sets a line logic state to @p PAL_HIGH.
  653. * @note The operation is not guaranteed to be atomic on all the
  654. * architectures, for atomicity and/or portability reasons you may
  655. * need to enclose port I/O operations between @p osalSysLock() and
  656. * @p osalSysUnlock().
  657. * @note The function can be called from any context.
  658. *
  659. * @param[in] line line identifier
  660. *
  661. * @special
  662. */
  663. #if !defined(pal_lld_setline) || defined(__DOXYGEN__)
  664. #define palSetLine(line) palSetPad(PAL_PORT(line), PAL_PAD(line))
  665. #else
  666. #define palSetLine(line) pal_lld_setline(line)
  667. #endif
  668. /**
  669. * @brief Clears a line logic state to @p PAL_LOW.
  670. * @note The operation is not guaranteed to be atomic on all the
  671. * architectures, for atomicity and/or portability reasons you may
  672. * need to enclose port I/O operations between @p osalSysLock() and
  673. * @p osalSysUnlock().
  674. * @note The function can be called from any context.
  675. *
  676. * @param[in] line line identifier
  677. *
  678. * @special
  679. */
  680. #if !defined(pal_lld_clearline) || defined(__DOXYGEN__)
  681. #define palClearLine(line) palClearPad(PAL_PORT(line), PAL_PAD(line))
  682. #else
  683. #define palClearLine(line) pal_lld_clearline(line)
  684. #endif
  685. /**
  686. * @brief Toggles a line logic state.
  687. * @note The operation is not guaranteed to be atomic on all the
  688. * architectures, for atomicity and/or portability reasons you may
  689. * need to enclose port I/O operations between @p osalSysLock() and
  690. * @p osalSysUnlock().
  691. * @note The function can be called from any context.
  692. *
  693. * @param[in] line line identifier
  694. *
  695. * @special
  696. */
  697. #if !defined(pal_lld_toggleline) || defined(__DOXYGEN__)
  698. #define palToggleLine(line) palTogglePad(PAL_PORT(line), PAL_PAD(line))
  699. #else
  700. #define palToggleLine(line) pal_lld_toggleline(line)
  701. #endif
  702. /**
  703. * @brief Line mode setup.
  704. * @note The operation is not guaranteed to be atomic on all the
  705. * architectures, for atomicity and/or portability reasons you may
  706. * need to enclose port I/O operations between @p osalSysLock() and
  707. * @p osalSysUnlock().
  708. * @note The function can be called from any context.
  709. *
  710. * @param[in] line line identifier
  711. * @param[in] mode pad mode
  712. *
  713. * @special
  714. */
  715. #if !defined(pal_lld_setlinemode) || defined(__DOXYGEN__)
  716. #define palSetLineMode(line, mode) \
  717. palSetPadMode(PAL_PORT(line), PAL_PAD(line), mode)
  718. #else
  719. #define palSetLineMode(line, mode) pal_lld_setlinemode(line, mode)
  720. #endif
  721. #if (PAL_USE_CALLBACKS == TRUE) || (PAL_USE_WAIT == TRUE) || \
  722. defined(__DOXYGEN__)
  723. /**
  724. * @brief Pad event enable.
  725. * @note Programming an unknown or unsupported mode is silently ignored.
  726. *
  727. * @param[in] port port identifier
  728. * @param[in] pad pad number within the port
  729. * @param[in] mode pad event mode
  730. *
  731. * @iclass
  732. */
  733. #if !defined(pal_lld_enablepadevent) || defined(__DOXYGEN__)
  734. #define palEnablePadEventI(port, pad, mode)
  735. #else
  736. #define palEnablePadEventI(port, pad, mode) \
  737. pal_lld_enablepadevent(port, pad, mode)
  738. #endif
  739. /**
  740. * @brief Pad event disable.
  741. * @details This function also disables previously programmed event callbacks.
  742. *
  743. * @param[in] port port identifier
  744. * @param[in] pad pad number within the port
  745. *
  746. * @iclass
  747. */
  748. #if !defined(pal_lld_disablepadevent) || defined(__DOXYGEN__)
  749. #define palDisablePadEventI(port, pad)
  750. #else
  751. #define palDisablePadEventI(port, pad) \
  752. pal_lld_disablepadevent(port, pad)
  753. #endif
  754. /**
  755. * @brief Pad event enable.
  756. * @note Programming an unknown or unsupported mode is silently ignored.
  757. *
  758. * @param[in] port port identifier
  759. * @param[in] pad pad number within the port
  760. * @param[in] mode pad event mode
  761. *
  762. * @api
  763. */
  764. #define palEnablePadEvent(port, pad, mode) \
  765. do { \
  766. osalSysLock(); \
  767. palEnablePadEventI(port, pad, mode); \
  768. osalSysUnlock(); \
  769. } while (false)
  770. /**
  771. * @brief Pad event disable.
  772. * @details This function also disables previously programmed event callbacks.
  773. *
  774. * @param[in] port port identifier
  775. * @param[in] pad pad number within the port
  776. *
  777. * @api
  778. */
  779. #define palDisablePadEvent(port, pad) \
  780. do { \
  781. osalSysLock(); \
  782. palDisablePadEventI(port, pad); \
  783. osalSysUnlock(); \
  784. } while (false)
  785. /**
  786. * @brief Line event enable.
  787. * @note Programming an unknown or unsupported mode is silently ignored.
  788. *
  789. * @param[in] line line identifier
  790. * @param[in] mode line event mode
  791. *
  792. * @iclass
  793. */
  794. #if !defined(pal_lld_enablelineevent) || defined(__DOXYGEN__)
  795. #define palEnableLineEventI(line, mode) \
  796. palEnablePadEventI(PAL_PORT(line), PAL_PAD(line), mode)
  797. #else
  798. #define palEnableLineEventI(line, mode) \
  799. pal_lld_enablelineevent(line, mode)
  800. #endif
  801. /**
  802. * @brief Line event disable.
  803. * @details This function also disables previously programmed event callbacks.
  804. *
  805. * @param[in] line line identifier
  806. *
  807. * @iclass
  808. */
  809. #if !defined(pal_lld_disablelineevent) || defined(__DOXYGEN__)
  810. #define palDisableLineEventI(line) \
  811. palDisablePadEventI(PAL_PORT(line), PAL_PAD(line))
  812. #else
  813. #define palDisableLineEventI(line) pal_lld_disablelineevent(line)
  814. #endif
  815. /**
  816. * @brief Line event enable.
  817. * @note Programming an unknown or unsupported mode is silently ignored.
  818. *
  819. * @param[in] line line identifier
  820. * @param[in] mode line event mode
  821. *
  822. * @api
  823. */
  824. #define palEnableLineEvent(line, mode) \
  825. do { \
  826. osalSysLock(); \
  827. palEnableLineEventI(line, mode); \
  828. osalSysUnlock(); \
  829. } while (false)
  830. /**
  831. * @brief Line event disable.
  832. * @details This function also disables previously programmed event callbacks.
  833. *
  834. * @param[in] line line identifier
  835. *
  836. * @api
  837. */
  838. #define palDisableLineEvent(line) \
  839. do { \
  840. osalSysLock(); \
  841. palDisableLineEventI(line); \
  842. osalSysUnlock(); \
  843. } while (false)
  844. /**
  845. * @brief Pad event enable check.
  846. *
  847. * @param[in] port port identifier
  848. * @param[in] pad pad number within the port
  849. * @return Pad event status.
  850. * @retval false if the pad event is disabled.
  851. * @retval true if the pad event is enabled.
  852. *
  853. * @xclass
  854. */
  855. #if !defined(pal_lld_ispadeventenabled) || defined(__DOXYGEN__)
  856. #define palIsPadEventEnabledX(port, pad) false
  857. #else
  858. #define palIsPadEventEnabledX(port, pad) \
  859. pal_lld_ispadeventenabled(port, pad)
  860. #endif
  861. /**
  862. * @brief Line event enable check.
  863. *
  864. * @param[in] line line identifier
  865. * @return Line event status.
  866. * @retval false if the line event is disabled.
  867. * @retval true if the line event is enabled.
  868. *
  869. * @xclass
  870. */
  871. #if !defined(pal_lld_islineeventenabled) || defined(__DOXYGEN__)
  872. #define palIsLineEventEnabledX(line) \
  873. pal_lld_ispadeventenabled(PAL_PORT(line), PAL_PAD(line))
  874. #else
  875. #define palIsLineEventEnabledX(line) \
  876. pal_lld_islineeventenabled(line)
  877. #endif
  878. #endif /* PAL_USE_CALLBACKS || PAL_USE_WAIT */
  879. #if (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
  880. /**
  881. * @brief Associates a callback to a pad.
  882. *
  883. * @param[in] port port identifier
  884. * @param[in] pad pad number within the port
  885. * @param[in] cb event callback function
  886. * @param[in] arg callback argument
  887. *
  888. * @api
  889. */
  890. #define palSetPadCallback(port, pad, cb, arg) \
  891. do { \
  892. osalSysLock(); \
  893. palSetPadCallbackI(port, pad, cb, arg); \
  894. osalSysUnlock(); \
  895. } while (false)
  896. /**
  897. * @brief Associates a callback to a line.
  898. *
  899. * @param[in] line line identifier
  900. * @param[in] cb event callback function
  901. * @param[in] arg callback argument
  902. *
  903. * @api
  904. */
  905. #define palSetLineCallback(line, cb, arg) \
  906. do { \
  907. osalSysLock(); \
  908. palSetLineCallbackI(line, cb, arg); \
  909. osalSysUnlock(); \
  910. } while (false)
  911. #endif /* PAL_USE_CALLBACKS == TRUE */
  912. /** @} */
  913. /*===========================================================================*/
  914. /* External declarations. */
  915. /*===========================================================================*/
  916. #ifdef __cplusplus
  917. extern "C" {
  918. #endif
  919. ioportmask_t palReadBus(const IOBus *bus);
  920. void palWriteBus(const IOBus *bus, ioportmask_t bits);
  921. void palSetBusMode(const IOBus *bus, iomode_t mode);
  922. #if (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
  923. void palSetPadCallbackI(ioportid_t port, iopadid_t pad,
  924. palcallback_t cb, void *arg);
  925. void palSetLineCallbackI(ioline_t line, palcallback_t cb, void *arg);
  926. #endif /* PAL_USE_CALLBACKS == TRUE */
  927. #if (PAL_USE_WAIT == TRUE) || defined(__DOXYGEN__)
  928. msg_t palWaitPadTimeoutS(ioportid_t port, iopadid_t pad,
  929. sysinterval_t timeout);
  930. msg_t palWaitPadTimeout(ioportid_t port, iopadid_t pad,
  931. sysinterval_t timeout);
  932. msg_t palWaitLineTimeoutS(ioline_t line, sysinterval_t timeout);
  933. msg_t palWaitLineTimeout(ioline_t line, sysinterval_t timeout);
  934. #endif /* PAL_USE_WAIT == TRUE */
  935. #ifdef __cplusplus
  936. }
  937. #endif
  938. #endif /* HAL_PAL_H */
  939. #endif /* HAL_USE_PAL == TRUE */
  940. /** @} */