From 16e2a55bf42f532404cddd8ddbc7cbee38c39572 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 2 Sep 2017 16:35:10 +0000 Subject: Made PAL callback and wait APIs independent from each other. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10543 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/hal_pal.h | 338 +++++++++++++++++++++++++++++------------------ 1 file changed, 207 insertions(+), 131 deletions(-) (limited to 'os/hal/include/hal_pal.h') diff --git a/os/hal/include/hal_pal.h b/os/hal/include/hal_pal.h index a0ef91b37..3514b7ffe 100644 --- a/os/hal/include/hal_pal.h +++ b/os/hal/include/hal_pal.h @@ -117,6 +117,14 @@ * @name PAL configuration options * @{ */ +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__) +#define PAL_USE_CALLBACKS TRUE +#endif + /** * @brief Enables synchronous APIs. * @note Disabling this option saves both code and data space. @@ -149,6 +157,7 @@ typedef struct { */ threads_queue_t threads; #endif +#if PAL_USE_CALLBACKS || defined(__DOXYGEN__) /** * @brief Event callback. */ @@ -157,6 +166,7 @@ typedef struct { * @brief Event callback argument. */ void *arg; +#endif } palevent_t; #include "hal_pal_lld.h" @@ -235,10 +245,73 @@ typedef struct { #define IOBUS_DECL(name, port, width, offset) \ IOBus name = _IOBUS_DATA(name, port, width, offset) +#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__) /** * @name Low level driver helper macros * @{ */ +#if (PAL_USE_CALLBACKS && PAL_USE_WAIT) || defined(__DOXYGEN__) +/** + * @brief Initializes a PAL event object. + * + * @param[in] e event index + * + * @notapi + */ +#define _pal_init_event(e) \ + do { \ + osalThreadQueueObjectInit(&_pal_events[e].threads); \ + _pal_events[e].cb = NULL; \ + _pal_events[e].arg = NULL; \ + } while (false) +#endif /* PAL_USE_CALLBACKS && PAL_USE_WAIT */ + +#if PAL_USE_CALLBACKS && !PAL_USE_WAIT +#define _pal_init_event(e) \ + do { \ + _pal_events[e].cb = NULL; \ + _pal_events[e].arg = NULL; \ + } while (false) +#endif /* PAL_USE_CALLBACKS && !PAL_USE_WAIT */ + +#if !PAL_USE_CALLBACKS && PAL_USE_WAIT +#define _pal_init_event(e) \ + do { \ + osalThreadQueueObjectInit(&_pal_events[e].threads); \ + } while (false) +#endif /* !PAL_USE_CALLBACKS && PAL_USE_WAIT */ + +#if (PAL_USE_CALLBACKS && PAL_USE_WAIT) || defined(__DOXYGEN__) +/** + * @brief Clears a PAL event object. + * + * @param[in] e event index + * + * @notapi + */ +#define _pal_clear_event(e) \ + do { \ + osalThreadDequeueAllI(&_pal_events[pad].threads, MSG_RESET); \ + _pal_events[e].cb = NULL; \ + _pal_events[e].arg = NULL; \ + } while (false) +#endif /* PAL_USE_CALLBACKS && PAL_USE_WAIT */ + +#if PAL_USE_CALLBACKS && !PAL_USE_WAIT +#define _pal_clear_event(e) \ + do { \ + _pal_events[e].cb = NULL; \ + _pal_events[e].arg = NULL; \ + } while (false) +#endif /* PAL_USE_CALLBACKS && !PAL_USE_WAIT */ + +#if !PAL_USE_CALLBACKS && PAL_USE_WAIT +#define _pal_clear_event(e) \ + do { \ + osalThreadDequeueAllI(&_pal_events[pad].threads, MSG_RESET); \ + } while (false) +#endif /* !PAL_USE_CALLBACKS && PAL_USE_WAIT */ + /** * @brief Common ISR code. * @note This macro is meant to be used in the low level drivers @@ -248,7 +321,7 @@ typedef struct { * * @notapi */ -#if PAL_USE_WAIT || defined(__DOXYGEN__) +#if (PAL_USE_CALLBACKS && PAL_USE_WAIT) || defined(__DOXYGEN__) #define _pal_isr_code(e) do { \ if (_pal_events[e].cb != NULL) { \ _pal_events[e].cb(_pal_events[e].arg); \ @@ -257,60 +330,26 @@ typedef struct { osalThreadDequeueAllI(&_pal_events[e].threads, MSG_OK); \ osalSysUnlockFromISR(); \ } while (false) -#else +#endif /* PAL_USE_CALLBACKS && PAL_USE_WAIT */ + +#if PAL_USE_CALLBACKS && !PAL_USE_WAIT #define _pal_isr_code(e) do { \ if (_pal_events[e].cb != NULL) { \ _pal_events[e].cb(_pal_events[e].arg); \ } \ } while (false) -#endif +#endif /* PAL_USE_CALLBACKS && !PAL_USE_WAIT */ -/** - * @brief PAL event setup. - * @note This macro is meant to be used in the low level drivers - * implementation only. - * - * @param[in] e event index - * @param[in] c callback pointer - * @param[in] a callback argument - * - * @notapi - */ -#if PAL_USE_WAIT || defined(__DOXYGEN__) -#define _pal_set_event(e, c, a) { \ - osalThreadQueueObjectInit(&_pal_events[e].threads); \ - _pal_events[e].cb = c; \ - _pal_events[e].arg = a; \ -} -#else -#define _pal_set_event(e, c, a) { \ - _pal_events[e].cb = c; \ - _pal_events[e].arg = a; \ -} -#endif +#if (!PAL_USE_CALLBACKS && PAL_USE_WAIT) || defined(__DOXYGEN__) +#define _pal_isr_code(e) do { \ + osalSysLockFromISR(); \ + osalThreadDequeueAllI(&_pal_events[e].threads, MSG_OK); \ + osalSysUnlockFromISR(); \ +} while (false) +#endif /* !PAL_USE_CALLBACKS && PAL_USE_WAIT */ -/** - * @brief PAL event clear. - * @note This macro is meant to be used in the low level drivers - * implementation only. - * - * @param[in] e event index - * - * @notapi - */ -#if PAL_USE_WAIT || defined(__DOXYGEN__) -#define _pal_clear_event(e) { \ - osalThreadDequeueAllI(&_pal_events[e].threads, MSG_RESET); \ - _pal_events[e].cb = NULL; \ - _pal_events[e].arg = NULL; \ -} -#else -#define _pal_clear_event(e) { \ - _pal_events[e].cb = NULL; \ - _pal_events[e].arg = NULL; \ -} -#endif /** @} */ +#endif /* PAL_USE_CALLBACKS || PAL_USE_WAIT */ /** * @name Macro Functions @@ -627,78 +666,6 @@ typedef struct { #define palSetPadMode(port, pad, mode) pal_lld_setpadmode(port, pad, mode) #endif -/** - * @brief Pad event enable. - * @details This function programs an event callback in the specified mode. - * @note Programming an unknown or unsupported mode is silently ignored. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * @param[in] mode pad event mode - * @param[in] callback event callback function - * @param[in] arg callback argument - * - * @iclass - */ -#if !defined(pal_lld_enablepadevent) || defined(__DOXYGEN__) -#define palEnablePadEventI(port, pad, mode, callback, arg) -#else -#define palEnablePadEventI(port, pad, mode, callback, arg) \ - pal_lld_enablepadevent(port, pad, mode, callback, arg) -#endif - -/** - * @brief Pad event disable. - * @details This function disables previously programmed event callbacks. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * - * @iclass - */ -#if !defined(pal_lld_disablepadevent) || defined(__DOXYGEN__) -#define palDisablePadEventI(port, pad) -#else -#define PadDisablepalEventI(port, pad) \ - pal_lld_disablepadevent(port, pad) -#endif - -/** - * @brief Pad event enable. - * @details This function programs an event callback in the specified mode. - * @note Programming an unknown or unsupported mode is silently ignored. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * @param[in] mode pad event mode - * @param[in] callback event callback function - * @param[in] arg callback argument - * - * @api - */ -#define palEnablePadEvent(port, pad, mode, callback, arg) \ - do { \ - osalSysLock(); \ - palEnablePadEventI(port, pad, mode, callback, arg); \ - osalSysUnlock(); \ - } while (false) - -/** - * @brief Pad event disable. - * @details This function disables previously programmed event callbacks. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * - * @api - */ -#define palDisablePadEvent(port, pad) \ - do { \ - osalSysLock(); \ - palisablePadDEventI(port, pad); \ - osalSysUnlock(); \ - } while (false) - /** * @brief Reads an input line logic state. * @note The function can be called from any context. @@ -810,26 +777,93 @@ typedef struct { #define palSetLineMode(line, mode) pal_lld_setlinemode(line, mode) #endif +#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__) +/** + * @brief Pad event enable. + * @note Programming an unknown or unsupported mode is silently ignored. + * + * @param[in] port port identifier + * @param[in] pad pad number within the port + * @param[in] mode pad event mode + * + * @iclass + */ +#if !defined(pal_lld_enablepadevent) || defined(__DOXYGEN__) +#define palEnablePadEventI(port, pad, mode) +#else +#define palEnablePadEventI(port, pad, mode) \ + pal_lld_enablepadevent(port, pad, mode) +#endif + +/** + * @brief Pad event disable. + * @details This function also disables previously programmed event callbacks. + * + * @param[in] port port identifier + * @param[in] pad pad number within the port + * + * @iclass + */ +#if !defined(pal_lld_disablepadevent) || defined(__DOXYGEN__) +#define palDisablePadEventI(port, pad) +#else +#define PadDisablepalEventI(port, pad) \ + pal_lld_disablepadevent(port, pad) +#endif + +/** + * @brief Pad event enable. + * @note Programming an unknown or unsupported mode is silently ignored. + * + * @param[in] port port identifier + * @param[in] pad pad number within the port + * @param[in] mode pad event mode + * + * @api + */ +#define palEnablePadEvent(port, pad, mode) \ + do { \ + osalSysLock(); \ + palEnablePadEventI(port, pad, mode); \ + osalSysUnlock(); \ + } while (false) + +/** + * @brief Pad event disable. + * @details This function also disables previously programmed event callbacks. + * + * @param[in] port port identifier + * @param[in] pad pad number within the port + * + * @api + */ +#define palDisablePadEvent(port, pad) \ + do { \ + osalSysLock(); \ + palisablePadDEventI(port, pad); \ + osalSysUnlock(); \ + } while (false) + /** * @brief Line event enable. + * @note Programming an unknown or unsupported mode is silently ignored. * * @param[in] line line identifier * @param[in] mode line event mode - * @param[in] callback event callback function - * @param[in] arg callback argument * * @iclass */ #if !defined(pal_lld_enablelineevent) || defined(__DOXYGEN__) -#define palEnableLineEventI(line, mode, callback, arg) \ - palEnablePadEventI(PAL_PORT(line), PAL_PAD(line), mode, callback, arg) +#define palEnableLineEventI(line, mode) \ + palEnablePadEventI(PAL_PORT(line), PAL_PAD(line), mode) #else -#define palEnableLineEventI(line, mode, callback, arg) \ - pal_lld_enablelineevent(line, mode, callback, arg) +#define palEnableLineEventI(line, mode) \ + pal_lld_enablelineevent(line, mode) #endif /** * @brief Line event disable. + * @details This function also disables previously programmed event callbacks. * * @param[in] line line identifier * @@ -844,35 +878,73 @@ typedef struct { /** * @brief Line event enable. + * @note Programming an unknown or unsupported mode is silently ignored. * * @param[in] line line identifier * @param[in] mode line event mode - * @param[in] callback event callback function - * @param[in] arg callback argument * * @api */ -#define palEnableLineEvent(line, mode, callback, arg) \ +#define palEnableLineEvent(line, mode) \ do { \ osalSysLock(); \ - palEnableLineEventI(line, mode, callback, arg); \ + palEnableLineEventI(line, mode); \ osalSysUnlock(); \ } while (false) /** * @brief Line event disable. + * @details This function also disables previously programmed event callbacks. * * @param[in] line line identifier * * @api */ -#define paDisableLineEvent(line) \ +#define palDisableLineEvent(line) \ do { \ osalSysLock(); \ palDisableLineEventI(line); \ osalSysUnlock(); \ } while (false) +#endif /* PAL_USE_CALLBACKS || PAL_USE_WAIT */ + +#if PAL_USE_CALLBACKS || defined(__DOXYGEN__) +/** + * @brief Associates a callback to a pad. + * + * @param[in] port port identifier + * @param[in] pad pad number within the port + * @param[in] mode pad event mode + * @param[in] callback event callback function + * @param[in] arg callback argument + * + * @api + */ +#define palSetPadCallback(port, pad, cb, arg) \ + do { \ + osalSysLock(); \ + palSetPadCallbackI(port, pad, cb, arg); \ + osalSysUnlock(); \ + } while (false) + +/** + * @brief Associates a callback to a line. + * + * @param[in] line line identifier + * @param[in] callback event callback function + * @param[in] arg callback argument + * + * @iclass + */ +#define palSetLineCallback(line, cb, arg) \ + do { \ + osalSysLock(); \ + palSetLineCallbackI(line, cb, arg); \ + osalSysUnlock(); \ + } while (false) +#endif /* PAL_USE_CALLBACKS */ + #if PAL_USE_WAIT || defined(__DOXYGEN__) /** * @brief Waits for an edge on the specified port/pad. @@ -914,7 +986,6 @@ typedef struct { palWaitLineTimeoutS(line, timeout); \ osalSysUnlock(); \ } while (false) - #endif /* PAL_USE_WAIT */ /** @} */ @@ -929,6 +1000,11 @@ extern "C" { ioportmask_t palReadBus(IOBus *bus); void palWriteBus(IOBus *bus, ioportmask_t bits); void palSetBusMode(IOBus *bus, iomode_t mode); +#if PAL_USE_CALLBACKS || defined(__DOXYGEN__) + void palSetPadCallbackI(ioportid_t port, iopadid_t pad, + palcallback_t cb, void *arg); + void palSetLineCallbackI(ioline_t line, palcallback_t cb, void *arg); +#endif /* PAL_USE_CALLBACKS */ #if PAL_USE_WAIT || defined(__DOXYGEN__) msg_t palWaitPadTimeoutS(ioportid_t port, iopadid_t pad, systime_t timeout); msg_t palWaitLineTimeoutS(ioline_t line, systime_t timeout); -- cgit v1.2.3