mirror of https://github.com/rusefi/ChibiOS.git
PAL callbacks implementation for STM32, not complete yet.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10507 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
ab5f8476e1
commit
92fe1a3524
|
@ -126,6 +126,14 @@
|
|||
*/
|
||||
typedef void (*palcallback_t)(void *arg);
|
||||
|
||||
/**
|
||||
* @brief Type of a PAL event record.
|
||||
*/
|
||||
typedef struct {
|
||||
palcallback_t cb;
|
||||
void *arg;
|
||||
} palevent_t;
|
||||
|
||||
#include "hal_pal_lld.h"
|
||||
|
||||
/**
|
||||
|
@ -202,6 +210,52 @@ typedef struct {
|
|||
#define IOBUS_DECL(name, port, width, offset) \
|
||||
IOBus name = _IOBUS_DATA(name, port, width, offset)
|
||||
|
||||
/**
|
||||
* @name Low level driver helper macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Common ISR code.
|
||||
* @note This macro is meant to be used in the low level drivers
|
||||
* implementation only.
|
||||
*
|
||||
* @param[in] e event index
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _pal_isr_code(e) _pal_events[e].cb(_pal_events[e].arg)
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
#define _pal_set_event(e, c, a) { \
|
||||
_pal_events[e].cb = c; \
|
||||
_pal_events[e].arg = a; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
#define _pal_clear_event(e) { \
|
||||
_pal_events[e].cb = NULL; \
|
||||
_pal_events[e].arg = NULL; \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
|
|
|
@ -38,10 +38,24 @@
|
|||
#error "missing or unsupported platform for GPIOv3 PAL driver"
|
||||
#endif
|
||||
|
||||
/* Handling a difference in ST headers.*/
|
||||
#if defined(STM32L4XX)
|
||||
#define EMR EMR1
|
||||
#define IMR IMR1
|
||||
#define PR PR1
|
||||
#define RTSR RTSR1
|
||||
#define FTSR FTSR1
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Event records for the 16 GPIO EXTI channels.
|
||||
*/
|
||||
palevent_t _pal_events[16];
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
@ -194,6 +208,117 @@ void _pal_lld_setgroupmode(ioportid_t port,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _pal_lld_enablepadevent(ioportid_t port,
|
||||
iopadid_t pad,
|
||||
ioeventmode_t mode,
|
||||
palcallback_t callback,
|
||||
void *arg) {
|
||||
|
||||
uint32_t padmask, cridx, crmask, portidx;
|
||||
|
||||
/* Mask of the pad.*/
|
||||
padmask = 1U << (uint32_t)pad;
|
||||
|
||||
/* Multiple channel setting of the same channel not allowed, first disable
|
||||
it. This is done because on STM32 the same channel cannot be mapped on
|
||||
multiple ports.*/
|
||||
osalDbgAssert(((EXTI->RTSR & padmask) == 0U) &&
|
||||
((EXTI->FTSR & padmask) == 0U), "channel already in use");
|
||||
|
||||
/* Index and mask of the SYSCFG CR register to be used.*/
|
||||
cridx = (uint32_t)pad >> 2U;
|
||||
crmask = ~(0xFU << (((uint32_t)pad & 3U) * 4U));
|
||||
|
||||
/* Port index is obtained assuming that GPIO ports are placed at regular
|
||||
0x400 intervalis in memory space. So far this is true for all devices.*/
|
||||
portidx = (uint32_t)port >> 10U;
|
||||
|
||||
/* Port selection in SYSCFG.*/
|
||||
SYSCFG->EXTICR[cridx] = (SYSCFG->EXTICR[cridx] & crmask) | portidx;
|
||||
|
||||
/* Programming edge registers.*/
|
||||
if (mode & PAL_EVENT_MODE_RISING_EDGE)
|
||||
EXTI->RTSR |= padmask;
|
||||
else
|
||||
EXTI->RTSR &= ~padmask;
|
||||
if (mode & PAL_EVENT_MODE_FALLING_EDGE)
|
||||
EXTI->FTSR |= padmask;
|
||||
else
|
||||
EXTI->FTSR &= ~padmask;
|
||||
|
||||
/* Programming interrupt and event registers.*/
|
||||
if (callback != NULL) {
|
||||
EXTI->IMR |= padmask;
|
||||
EXTI->EMR &= ~padmask;
|
||||
}
|
||||
else {
|
||||
EXTI->EMR |= padmask;
|
||||
EXTI->IMR &= ~padmask;
|
||||
}
|
||||
|
||||
/* Setting up callback and argument for this event.*/
|
||||
_pal_set_event(pad, callback, arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
uint32_t padmask, rtsr1, ftsr1;
|
||||
|
||||
rtsr1 = EXTI->RTSR1;
|
||||
ftsr1 = EXTI->FTSR1;
|
||||
|
||||
/* Mask of the pad.*/
|
||||
padmask = 1U << (uint32_t)pad;
|
||||
|
||||
/* If either RTRS1 or FTSR1 is enabled then the channel is in use.*/
|
||||
if (((rtsr1 | ftsr1) & padmask) != 0U) {
|
||||
uint32_t cridx, croff, crport, portidx;
|
||||
|
||||
/* Index and mask of the SYSCFG CR register to be used.*/
|
||||
cridx = (uint32_t)pad >> 2U;
|
||||
croff = ((uint32_t)pad & 3U) * 4U;
|
||||
|
||||
/* Port index is obtained assuming that GPIO ports are placed at regular
|
||||
0x400 intervalis in memory space. So far this is true for all devices.*/
|
||||
portidx = (uint32_t)port >> 10U;
|
||||
|
||||
crport = (SYSCFG->EXTICR[cridx] >> croff) & 0xFU;
|
||||
|
||||
osalDbgAssert(crport == portidx, "channel mapped on different port");
|
||||
|
||||
/* Disabling channel.*/
|
||||
EXTI->IMR &= ~padmask;
|
||||
EXTI->EMR &= ~padmask;
|
||||
EXTI->RTSR = rtsr1 & ~padmask;
|
||||
EXTI->FTSR = ftsr1 & ~padmask;
|
||||
EXTI->PR = padmask;
|
||||
|
||||
/* Clearing callback and argument for this event.*/
|
||||
_pal_clear_event(pad);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_PAL */
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -341,13 +341,23 @@ typedef uint32_t iomode_t;
|
|||
typedef uint32_t ioline_t;
|
||||
|
||||
/**
|
||||
* @brief Port Identifier.
|
||||
* @brief Type of an event mode.
|
||||
*/
|
||||
typedef uint32_t ioeventmode_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a port Identifier.
|
||||
* @details This type can be a scalar or some kind of pointer, do not make
|
||||
* any assumption about it, use the provided macros when populating
|
||||
* variables of this type.
|
||||
*/
|
||||
typedef stm32_gpio_t * ioportid_t;
|
||||
|
||||
/**
|
||||
* @brief Type of an pad identifier.
|
||||
*/
|
||||
typedef uint32_t iopadid_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I/O Ports Identifiers. */
|
||||
/* The low level driver wraps the definitions already present in the STM32 */
|
||||
|
@ -551,7 +561,38 @@ typedef stm32_gpio_t * ioportid_t;
|
|||
*/
|
||||
#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit)
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_enablepadevent(port, pad, mode, callback, arg) \
|
||||
_pal_lld_enablepadevent(port, pad, mode, callback, arg)
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
#define pal_lld_disablepadevent(port, pad) \
|
||||
_pal_lld_disablepadevent(port, pad)
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern const PALConfig pal_default_config;
|
||||
extern palevent_t _pal_events[16];
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -560,6 +601,12 @@ extern "C" {
|
|||
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,
|
||||
palcallback_t callback,
|
||||
void *arg);
|
||||
void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue