aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/include/hal_pal.h149
-rw-r--r--os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.c10
-rw-r--r--os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.h21
-rw-r--r--os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.c10
-rw-r--r--os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.h21
-rw-r--r--os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.c10
-rw-r--r--os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.h21
-rw-r--r--os/hal/src/hal_pal.c40
8 files changed, 236 insertions, 46 deletions
diff --git a/os/hal/include/hal_pal.h b/os/hal/include/hal_pal.h
index ede48c470..f19c8396f 100644
--- a/os/hal/include/hal_pal.h
+++ b/os/hal/include/hal_pal.h
@@ -113,6 +113,19 @@
/* Driver pre-compile time settings. */
/*===========================================================================*/
+/**
+ * @name PAL configuration options
+ * @{
+ */
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__)
+#define PAL_USE_WAIT TRUE
+#endif
+/** @} */
+
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
@@ -130,7 +143,19 @@ typedef void (*palcallback_t)(void *arg);
* @brief Type of a PAL event record.
*/
typedef struct {
+#if defined(PAL_USE_WAIT) || defined(__DOXYGEN__)
+ /**
+ * @brief Threads queued for an event.
+ */
+ threads_queue_t threads;
+#endif
+ /**
+ * @brief Event callback.
+ */
palcallback_t cb;
+ /**
+ * @brief Event callback argument.
+ */
void *arg;
} palevent_t;
@@ -223,7 +248,22 @@ typedef struct {
*
* @notapi
*/
-#define _pal_isr_code(e) _pal_events[e].cb(_pal_events[e].arg)
+#if defined(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); \
+ } \
+ osalSysLockFromISR(); \
+ osalThreadDequeueAllI(&_pal_events[e].threads, MSG_OK); \
+ osalSysUnlockFromISR(); \
+} while (false)
+#else
+#define _pal_isr_code(e) do { \
+ if (_pal_events[e].cb != NULL) { \
+ _pal_events[e].cb(_pal_events[e].arg); \
+ } \
+} while (false)
+#endif
/**
* @brief PAL event setup.
@@ -236,10 +276,18 @@ typedef struct {
*
* @notapi
*/
+#if defined(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
/**
* @brief PAL event clear.
@@ -250,10 +298,18 @@ typedef struct {
*
* @notapi
*/
+#if defined(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
/** @} */
/**
@@ -585,9 +641,9 @@ typedef struct {
* @iclass
*/
#if !defined(pal_lld_enablepadevent) || defined(__DOXYGEN__)
-#define palPadEnableEventI(port, pad, mode, callback, arg)
+#define palEnablePadEventI(port, pad, mode, callback, arg)
#else
-#define palPadEnableEventI(port, pad, mode, callback, arg) \
+#define palEnablePadEventI(port, pad, mode, callback, arg) \
pal_lld_enablepadevent(port, pad, mode, callback, arg)
#endif
@@ -601,9 +657,9 @@ typedef struct {
* @iclass
*/
#if !defined(pal_lld_disablepadevent) || defined(__DOXYGEN__)
-#define palPadDisableEventI(port, pad)
+#define palDisablePadEventI(port, pad)
#else
-#define palPadDisableEventI(port, pad) \
+#define PadDisablepalEventI(port, pad) \
pal_lld_disablepadevent(port, pad)
#endif
@@ -620,10 +676,10 @@ typedef struct {
*
* @api
*/
-#define palPadEnableEvent(port, pad, mode, callback, arg) \
+#define palEnablePadEvent(port, pad, mode, callback, arg) \
do { \
osalSysLock(); \
- palPadEnableEventI(port, pad, mode, callback, arg); \
+ palEnablePadEventI(port, pad, mode, callback, arg); \
osalSysUnlock(); \
} while (false)
@@ -636,10 +692,10 @@ typedef struct {
*
* @api
*/
-#define palPadDisableEvent(port, pad) \
+#define palDisablePadEvent(port, pad) \
do { \
osalSysLock(); \
- palPadDisableEventI(port, pad); \
+ palisablePadDEventI(port, pad); \
osalSysUnlock(); \
} while (false)
@@ -764,12 +820,12 @@ typedef struct {
*
* @iclass
*/
-#if !defined(pal_lld_lineenableevent) || defined(__DOXYGEN__)
-#define palLineEnableEventI(line, mode, callback, arg) \
- palPadEnableEventI(PAL_PORT(line), PAL_PAD(line), mode, callback, arg)
+#if !defined(pal_lld_enablelineevent) || defined(__DOXYGEN__)
+#define palEnableLineEventI(line, mode, callback, arg) \
+ palEnablePadEventI(PAL_PORT(line), PAL_PAD(line), mode, callback, arg)
#else
-#define palLineEnableEventI(line, mode, callback, arg) \
- pal_lld_lineenableevent(line, mode, callback, arg)
+#define palEnableLineEventI(line, mode, callback, arg) \
+ pal_lld_enablelineevent(line, mode, callback, arg)
#endif
/**
@@ -779,11 +835,11 @@ typedef struct {
*
* @iclass
*/
-#if !defined(pal_lld_linedisableevent) || defined(__DOXYGEN__)
-#define palLineDisableEventI(line) \
- palPadDisableEventI(PAL_PORT(line), PAL_PAD(line))
+#if !defined(pal_lld_disablelineevent) || defined(__DOXYGEN__)
+#define palDisableLineEventI(line) \
+ palDisablePadEventI(PAL_PORT(line), PAL_PAD(line))
#else
-#define palLineDisableEventI(line) pal_lld_linedisableevent(line)
+#define palDisableLineEventI(line) pal_lld_disablelineevent(line)
#endif
/**
@@ -796,10 +852,10 @@ typedef struct {
*
* @api
*/
-#define palLineEnableEvent(line, mode, callback, arg) \
+#define palEnableLineEvent(line, mode, callback, arg) \
do { \
osalSysLock(); \
- palLineEnableEventI(line, mode, callback, arg); \
+ palEnableLineEventI(line, mode, callback, arg); \
osalSysUnlock(); \
} while (false)
@@ -810,12 +866,57 @@ typedef struct {
*
* @api
*/
-#define palLineDisableEvent(line) \
+#define paDisableLineEvent(line) \
+ do { \
+ osalSysLock(); \
+ palDisableLineEventI(line); \
+ osalSysUnlock(); \
+ } while (false)
+
+#if defined(PAL_USE_WAIT) || defined(__DOXYGEN__)
+/**
+ * @brief Waits for an edge on the specified port/pad.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @returns The operation state.
+ * @retval MSG_OK if an edge has been detected.
+ * @retval MSG_TIMEOUT if a timeout occurred before an edge cound be detected.
+ * @retval MSG_RESET if the event has been disabled while the thread was
+ * waiting for an edge.
+ *
+ * @api
+ */
+#define palWaitPadTimeout(port, pad, timeout) \
do { \
osalSysLock(); \
- palLineDisableEventI(line); \
+ palWaitPadTimeoutS(port, pad, timeout); \
osalSysUnlock(); \
} while (false)
+
+
+/**
+ * @brief Waits for an edge on the specified line.
+ *
+ * @param[in] line line identifier
+ * @param[in] timeout operation timeout
+ * @returns The operation state.
+ * @retval MSG_OK if an edge has been detected.
+ * @retval MSG_TIMEOUT if a timeout occurred before an edge cound be detected.
+ * @retval MSG_RESET if the event has been disabled while the thread was
+ * waiting for an edge.
+ *
+ * @api
+ */
+#define palWaitLineTimeout(line, timeout) \
+ do { \
+ osalSysLock(); \
+ palWaitLineTimeoutS(line, timeout); \
+ osalSysUnlock(); \
+ } while (false)
+
+#endif /* defined(PAL_USE_WAIT) */
+
/** @} */
/*===========================================================================*/
@@ -828,6 +929,10 @@ extern "C" {
ioportmask_t palReadBus(IOBus *bus);
void palWriteBus(IOBus *bus, ioportmask_t bits);
void palSetBusMode(IOBus *bus, iomode_t mode);
+#if defined(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);
+#endif /* defined(PAL_USE_WAIT) */
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.c b/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.c
index b432fa6ee..be8f7e829 100644
--- a/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.c
+++ b/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.c
@@ -235,14 +235,8 @@ void _pal_lld_enablepadevent(ioportid_t port,
EXTI->FTSR &= ~padmask;
/* Programming interrupt and event registers.*/
- if (callback != NULL) {
- EXTI->IMR |= padmask;
- EXTI->EMR &= ~padmask;
- }
- else {
- EXTI->EMR |= padmask;
- EXTI->IMR &= ~padmask;
- }
+ EXTI->IMR |= padmask;
+ EXTI->EMR &= ~padmask;
/* Setting up callback and argument for this event.*/
_pal_set_event(pad, callback, arg);
diff --git a/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.h b/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.h
index a80597d64..a20cea930 100644
--- a/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.h
+++ b/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.h
@@ -394,6 +394,27 @@ typedef uint32_t iopadid_t;
#define pal_lld_disablepadevent(port, pad) \
_pal_lld_disablepadevent(port, pad)
+/**
+ * @brief Returns a PAL event structure associated to a pad.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @notapi
+ */
+#define pal_lld_get_pad_event(port, pad) \
+ &_pal_events[pad]; (void)(port)
+
+/**
+ * @brief Returns a PAL event structure associated to a line.
+ *
+ * @param[in] line line identifier
+ *
+ * @notapi
+ */
+#define pal_lld_get_line_event(line) \
+ &_pal_events[PAL_PAD(line)]
+
#if !defined(__DOXYGEN__)
extern const PALConfig pal_default_config;
extern palevent_t _pal_events[16];
diff --git a/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.c b/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.c
index 6a23eff29..70f769f02 100644
--- a/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.c
+++ b/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.c
@@ -264,14 +264,8 @@ void _pal_lld_enablepadevent(ioportid_t port,
EXTI->FTSR &= ~padmask;
/* Programming interrupt and event registers.*/
- if (callback != NULL) {
- EXTI->IMR |= padmask;
- EXTI->EMR &= ~padmask;
- }
- else {
- EXTI->EMR |= padmask;
- EXTI->IMR &= ~padmask;
- }
+ EXTI->IMR |= padmask;
+ EXTI->EMR &= ~padmask;
/* Setting up callback and argument for this event.*/
_pal_set_event(pad, callback, arg);
diff --git a/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.h b/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.h
index ba90ccafd..4a30a61a5 100644
--- a/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.h
+++ b/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.h
@@ -577,6 +577,27 @@ typedef uint32_t iopadid_t;
#define pal_lld_disablepadevent(port, pad) \
_pal_lld_disablepadevent(port, pad)
+/**
+ * @brief Returns a PAL event structure associated to a pad.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @notapi
+ */
+#define pal_lld_get_pad_event(port, pad) \
+ &_pal_events[pad]; (void)(port)
+
+/**
+ * @brief Returns a PAL event structure associated to a line.
+ *
+ * @param[in] line line identifier
+ *
+ * @notapi
+ */
+#define pal_lld_get_line_event(line) \
+ &_pal_events[PAL_PAD(line)]
+
#if !defined(__DOXYGEN__)
extern const PALConfig pal_default_config;
extern palevent_t _pal_events[16];
diff --git a/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.c b/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.c
index a20e39c9a..6c8a1ec2e 100644
--- a/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.c
+++ b/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.c
@@ -260,14 +260,8 @@ void _pal_lld_enablepadevent(ioportid_t port,
EXTI->FTSR &= ~padmask;
/* Programming interrupt and event registers.*/
- if (callback != NULL) {
- EXTI->IMR |= padmask;
- EXTI->EMR &= ~padmask;
- }
- else {
- EXTI->EMR |= padmask;
- EXTI->IMR &= ~padmask;
- }
+ EXTI->IMR |= padmask;
+ EXTI->EMR &= ~padmask;
/* Setting up callback and argument for this event.*/
_pal_set_event(pad, callback, arg);
diff --git a/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.h b/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.h
index b1f5694b6..7b423807e 100644
--- a/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.h
+++ b/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.h
@@ -589,6 +589,27 @@ typedef uint32_t iopadid_t;
#define pal_lld_disablepadevent(port, pad) \
_pal_lld_disablepadevent(port, pad)
+/**
+ * @brief Returns a PAL event structure associated to a pad.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @notapi
+ */
+#define pal_lld_get_pad_event(port, pad) \
+ &_pal_events[pad]; (void)(port)
+
+/**
+ * @brief Returns a PAL event structure associated to a line.
+ *
+ * @param[in] line line identifier
+ *
+ * @notapi
+ */
+#define pal_lld_get_line_event(line) \
+ &_pal_events[PAL_PAD(line)]
+
#if !defined(__DOXYGEN__)
extern const PALConfig pal_default_config;
extern palevent_t _pal_events[16];
diff --git a/os/hal/src/hal_pal.c b/os/hal/src/hal_pal.c
index 0be77ad70..850c3506b 100644
--- a/os/hal/src/hal_pal.c
+++ b/os/hal/src/hal_pal.c
@@ -117,6 +117,46 @@ void palSetBusMode(IOBus *bus, iomode_t mode) {
palSetGroupMode(bus->portid, bus->mask, bus->offset, mode);
}
+#if defined(PAL_USE_WAIT) || defined(__DOXYGEN__)
+/**
+ * @brief Waits for an edge on the specified port/pad.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @returns The operation state.
+ * @retval MSG_OK if an edge has been detected.
+ * @retval MSG_TIMEOUT if a timeout occurred before an edge cound be detected.
+ * @retval MSG_RESET if the event has been disabled while the thread was
+ * waiting for an edge.
+ *
+ * @sclass
+ */
+msg_t palWaitPadTimeoutS(ioportid_t port, iopadid_t pad, systime_t timeout) {
+
+ palevent_t *pep = pal_lld_get_pad_event(port, pad);
+ return osalThreadEnqueueTimeoutS(&pep->threads, timeout);
+}
+
+/**
+ * @brief Waits for an edge on the specified line.
+ *
+ * @param[in] line line identifier
+ * @param[in] timeout operation timeout
+ * @returns The operation state.
+ * @retval MSG_OK if an edge has been detected.
+ * @retval MSG_TIMEOUT if a timeout occurred before an edge cound be detected.
+ * @retval MSG_RESET if the event has been disabled while the thread was
+ * waiting for an edge.
+ *
+ * @sclass
+ */
+msg_t palWaitLineTimeoutS(ioline_t line, systime_t timeout) {
+
+ palevent_t *pep = pal_lld_get_line_event(line);
+ return osalThreadEnqueueTimeoutS(&pep->threads, timeout);
+}
+#endif /* defined(PAL_USE_WAIT) */
+
#endif /* HAL_USE_PAL == TRUE */
/** @} */