aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports/SAMA/LLD/PIOv1
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal/ports/SAMA/LLD/PIOv1')
-rw-r--r--os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.c301
-rw-r--r--os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.h49
2 files changed, 332 insertions, 18 deletions
diff --git a/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.c b/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.c
index 81f8d6cd0..dbf5c36a4 100644
--- a/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.c
+++ b/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.c
@@ -29,10 +29,36 @@
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
+#define __PIOA ((Pio *)0xFC038000U)
+#define EVENTS_NUMBER (4 * 32)
+
+/**
+ * @brief PIOA interrupt priority level setting.
+ */
+#define SAMA_PIOA_IRQ_PRIORITY 2
+
+/**
+ * @brief PIOB interrupt priority level setting.
+ */
+#define SAMA_PIOB_IRQ_PRIORITY 2
+
+/**
+ * @brief PIOC interrupt priority level setting.
+ */
+#define SAMA_PIOC_IRQ_PRIORITY 2
+
+/**
+ * @brief PIOD interrupt priority level setting.
+ */
+#define SAMA_PIOD_IRQ_PRIORITY 2
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
+/**
+ * @brief Event records for the GPIO interrupts.
+ */
+palevent_t _pal_events[EVENTS_NUMBER];
/*===========================================================================*/
/* Driver local variables and types. */
@@ -45,10 +71,167 @@
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
+/**
+ * @brief PIOA interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(SAMA_PIOA_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ uint32_t sr, imr, is;
+ uint8_t i, j;
+
+ sr = pal_lld_read_status(PIOA);
+ imr = pal_lld_read_int_mask(PIOA);
+
+ is = sr & imr;
+ for (j = 0, i = 0; i < 32; i++, j++) {
+ if (!(is & (0x1 << j))) {
+ continue;
+ }
+#if (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
+ if (_pal_events[i].cb != NULL) {
+ _pal_events[i].cb(&is);
+ }
+#endif
+ }
+ aicAckInt();
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief PIOB interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(SAMA_PIOB_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ uint32_t sr, imr, is;
+ uint8_t i, j;
+
+ sr = pal_lld_read_status(PIOB);
+ imr = pal_lld_read_int_mask(PIOB);
+
+ is = sr & imr;
+ for (j = 0, i = 32; i < 64; i++, j++) {
+ if (!(is & (0x1 << j))) {
+ continue;
+ }
+#if (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
+ if (_pal_events[i].cb != NULL) {
+ _pal_events[i].cb(&is);
+ }
+#endif
+ }
+ aicAckInt();
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief PIOC interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(SAMA_PIOC_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ uint32_t sr, imr, is;
+ uint8_t i, j;
+
+ sr = pal_lld_read_status(PIOC);
+ imr = pal_lld_read_int_mask(PIOC);
+
+ is = sr & imr;
+ for (j = 0, i = 64; i < 96; i++, j++) {
+ if (!(is & (0x1 << j))) {
+ continue;
+ }
+#if (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
+ if (_pal_events[i].cb != NULL) {
+ _pal_events[i].cb(&is);
+ }
+#endif
+ }
+ aicAckInt();
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief PIOD interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(SAMA_PIOD_HANDLER) {
+ OSAL_IRQ_PROLOGUE();
+
+ uint32_t sr, imr, is;
+ uint8_t i, j;
+
+ sr = pal_lld_read_status(PIOD);
+ imr = pal_lld_read_int_mask(PIOD);
+
+ is = sr & imr;
+ for (j = 0, i = 96; i < 128; i++, j++) {
+ if (!(is & (0x1 << j))) {
+ continue;
+ }
+#if (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
+ if (_pal_events[i].cb != NULL) {
+ _pal_events[i].cb(&is);
+ }
+#endif
+ }
+ aicAckInt();
+ OSAL_IRQ_EPILOGUE();
+}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
+/**
+ * @brief PAL driver initialization.
+ *
+ * @notapi
+ */
+void _pal_lld_init(void) {
+
+#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
+ unsigned i;
+
+ for (i = 0; i < EVENTS_NUMBER; i++) {
+ _pal_init_event(i);
+ }
+
+ /*
+ * Clears status register
+ */
+ pal_lld_read_status(PIOA);
+ pal_lld_read_status(PIOB);
+ pal_lld_read_status(PIOC);
+ pal_lld_read_status(PIOD);
+
+ aicSetSourcePriority(ID_PIOA, SAMA_PIOA_IRQ_PRIORITY);
+ aicSetSourceHandler(ID_PIOA, SAMA_PIOA_HANDLER);
+ aicEnableInt(ID_PIOA);
+
+ aicSetSourcePriority(ID_PIOB, SAMA_PIOB_IRQ_PRIORITY);
+ aicSetSourceHandler(ID_PIOB, SAMA_PIOB_HANDLER);
+ aicEnableInt(ID_PIOB);
+
+ aicSetSourcePriority(ID_PIOC, SAMA_PIOC_IRQ_PRIORITY);
+ aicSetSourceHandler(ID_PIOC, SAMA_PIOC_HANDLER);
+ aicEnableInt(ID_PIOC);
+
+ aicSetSourcePriority(ID_PIOD, SAMA_PIOD_IRQ_PRIORITY);
+ aicSetSourceHandler(ID_PIOD, SAMA_PIOD_HANDLER);
+ aicEnableInt(ID_PIOD);
+#endif /* #if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__) */
+}
/**
* @brief Pads mode setup.
@@ -82,5 +265,123 @@ void _pal_lld_setgroupmode(ioportid_t port,
port->CFGR = cfgr;
}
+#if SAMA_HAL_IS_SECURE
+/**
+ * @brief Configures debouncing time for pads.
+ *
+ * @param[in] db_time debouncing time
+ *
+ * @api
+ */
+void pal_lld_cfg_debouncing_time(uint32_t db_time) {
+
+ /*
+ * Debouncing time configuration only in SECURE STATE
+ */
+ __PIOA->S_PIO_SCDR = db_time & 0x3FFF;
+}
+#endif
+
+/**
+ * @brief Reads/Clears Interrupt Status Register.
+ *
+ * @param[in] port port identifier
+ *
+ * @api
+ */
+uint32_t pal_lld_read_status(ioportid_t port) {
+ return port->ISR;
+}
+
+/**
+ * @brief Reads Interrupt Mask Register.
+ *
+ * @param[in] port port identifier
+ *
+ * @api
+ */
+uint32_t pal_lld_read_int_mask(ioportid_t port) {
+ return port->IMR;
+}
+
+/**
+ * @brief Reads Configuration Register.
+ *
+ * @param[in] port port identifier
+ *
+ * @api
+ */
+uint32_t pal_lld_read_cfgr(ioportid_t port) {
+ return port->CFGR;
+}
+
+#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
+ *
+ * @notapi
+ */
+void _pal_lld_enablepadevent(ioportid_t port,
+ iopadid_t pad,
+ ioeventmode_t mode) {
+
+ port->MSKR = pad;
+ port->CFGR |= mode;
+ port->IER = 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
+ */
+palevent_t* pal_lld_get_pad_event(ioportid_t port, iopadid_t pad) {
+
+ palevent_t* palevt = NULL;
+
+ if (port == PIOA) {
+ palevt = &_pal_events[pad];
+ }
+ else if (port == PIOB) {
+ palevt = &_pal_events[32 + pad];
+ }
+ else if (port == PIOC) {
+ palevt = &_pal_events[64 + pad];
+ }
+ else {
+ palevt = &_pal_events[96 + pad];
+ }
+
+ return palevt;
+}
+
+/**
+ * @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
+ *
+ * @notapi
+ */
+void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad) {
+
+ port->IDR |= pad;
+
+#if PAL_USE_CALLBACKS || PAL_USE_WAIT
+ /* Callback cleared and/or thread reset.*/
+ _pal_clear_event(pad);
+#endif
+}
+#endif /* PAL_USE_CALLBACKS || PAL_USE_WAIT */
+
#endif /* HAL_USE_PAL */
/** @} */
diff --git a/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.h b/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.h
index e2ede7c52..53386ba5b 100644
--- a/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.h
+++ b/os/hal/ports/SAMA/LLD/PIOv1/hal_pal_lld.h
@@ -30,6 +30,9 @@
/*===========================================================================*/
/* Unsupported modes and specific modes */
/*===========================================================================*/
+/* Specifies palInit() without parameter, required until all platforms will
+ be updated to the new style.*/
+#define PAL_NEW_INIT
#undef PAL_MODE_RESET
#undef PAL_MODE_UNCONNECTED
@@ -102,7 +105,8 @@
PAL_SAMA_IFSCEN_MASK | \
PAL_SAMA_OPD_MASK | \
PAL_SAMA_SCHMITT_MASK | \
- PAL_SAMA_DRVSTR_MASK
+ PAL_SAMA_DRVSTR_MASK | \
+ PAL_SAMA_EVTSEL_MASK
#if SAMA_HAL_IS_SECURE
#define PAL_SAMA_SECURE_MASK (1U << 31U)
@@ -146,7 +150,7 @@
*/
#define PAL_MODE_INPUT_PULLDOWN (PAL_SAMA_DIR_INPUT | \
PAL_SAMA_SCHMITT | \
- PAL_SAMA_PUEN_PULLDOWN)
+ PAL_SAMA_PDEN_PULLDOWN)
/**
* @brief Analog input mode.
@@ -365,13 +369,12 @@ typedef uint32_t iopadid_t;
/* Implementation, some of the following macros could be implemented as */
/* functions, if so please put them in pal_lld.c. */
/*===========================================================================*/
-
/**
- * @brief PIO ports subsystem initialization.
+ * @brief GPIO ports subsystem initialization.
*
* @notapi
*/
-#define pal_lld_init(config)
+#define pal_lld_init() _pal_lld_init()
/**
* @brief Reads an I/O port.
@@ -497,7 +500,8 @@ typedef uint32_t iopadid_t;
*
* @notapi
*/
-#define pal_lld_enablepadevent(port, pad, mode)
+#define pal_lld_enablepadevent(port, pad, mode) \
+ _pal_lld_enablepadevent(port, pad, mode)
/**
* @brief Pad event disable.
@@ -508,17 +512,8 @@ typedef uint32_t iopadid_t;
*
* @notapi
*/
-#define 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)
+#define pal_lld_disablepadevent(port, pad) \
+ _pal_lld_disablepadevent(port, pad)
/**
* @brief Returns a PAL event structure associated to a line.
@@ -527,14 +522,32 @@ typedef uint32_t iopadid_t;
*
* @notapi
*/
-#define pal_lld_get_line_event(line)
+#define pal_lld_get_line_event(line) \
+ &_pal_events[PAL_PAD(line)]
+
+#if !defined(__DOXYGEN__)
+extern palevent_t _pal_events[4 * 32];
+#endif
#ifdef __cplusplus
extern "C" {
#endif
+ void _pal_lld_init(void);
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
iomode_t mode);
+ void _pal_lld_enablepadevent(ioportid_t port,
+ iopadid_t pad,
+ ioeventmode_t mode);
+ void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad);
+ palevent_t* pal_lld_get_pad_event(ioportid_t port, iopadid_t pad);
+ /* LLD only functions */
+#if SAMA_HAL_IS_SECURE
+ void pal_lld_cfg_debouncing_time(uint32_t db_time);
+#endif
+ uint32_t pal_lld_read_status(ioportid_t port);
+ uint32_t pal_lld_read_int_mask(ioportid_t port);
+ uint32_t pal_lld_read_cfgr(ioportid_t port);
#ifdef __cplusplus
}
#endif