aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/src
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-08-30 13:54:04 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-08-30 13:54:04 +0000
commite40ae9763814661fa99e2b546e4f2562fb48650b (patch)
treef3157c29964739ef5e7fcc46688861d63c5b9313 /os/hal/src
parenta2ee0679d1525a80cdaccc020413bfbb61d9b070 (diff)
downloadChibiOS-e40ae9763814661fa99e2b546e4f2562fb48650b.tar.gz
ChibiOS-e40ae9763814661fa99e2b546e4f2562fb48650b.tar.bz2
ChibiOS-e40ae9763814661fa99e2b546e4f2562fb48650b.zip
Enhanced PWM driver
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7208 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/src')
-rw-r--r--os/hal/src/pwm.c127
1 files changed, 119 insertions, 8 deletions
diff --git a/os/hal/src/pwm.c b/os/hal/src/pwm.c
index c10fda3ce..eb35e434e 100644
--- a/os/hal/src/pwm.c
+++ b/os/hal/src/pwm.c
@@ -73,6 +73,8 @@ void pwmObjectInit(PWMDriver *pwmp) {
pwmp->state = PWM_STOP;
pwmp->config = NULL;
+ pwmp->enabled = 0;
+ pwmp->channels = 0;
#if defined(PWM_DRIVER_EXT_INIT_HOOK)
PWM_DRIVER_EXT_INIT_HOOK(pwmp);
#endif
@@ -117,7 +119,8 @@ void pwmStop(PWMDriver *pwmp) {
osalDbgAssert((pwmp->state == PWM_STOP) || (pwmp->state == PWM_READY),
"invalid state");
pwm_lld_stop(pwmp);
- pwmp->state = PWM_STOP;
+ pwmp->enabled = 0;
+ pwmp->state = PWM_STOP;
osalSysUnlock();
}
@@ -155,7 +158,7 @@ void pwmChangePeriod(PWMDriver *pwmp, pwmcnt_t period) {
* or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
+ * @param[in] channel PWM channel identifier (0...channels-1)
* @param[in] width PWM pulse width as clock pulses number
*
* @api
@@ -164,16 +167,19 @@ void pwmEnableChannel(PWMDriver *pwmp,
pwmchannel_t channel,
pwmcnt_t width) {
- osalDbgCheck((pwmp != NULL) && (channel < PWM_CHANNELS));
+ osalDbgCheck((pwmp != NULL) && (channel < pwmp->channels));
osalSysLock();
+
osalDbgAssert(pwmp->state == PWM_READY, "not ready");
- pwm_lld_enable_channel(pwmp, channel, width);
+
+ pwmEnableChannelI(pwmp, channel, width);
+
osalSysUnlock();
}
/**
- * @brief Disables a PWM channel.
+ * @brief Disables a PWM channel and its notification.
* @pre The PWM unit must have been activated using @p pwmStart().
* @post The channel is disabled and its output line returned to the
* idle state.
@@ -182,17 +188,122 @@ void pwmEnableChannel(PWMDriver *pwmp,
* or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
+ * @param[in] channel PWM channel identifier (0...channels-1)
*
* @api
*/
void pwmDisableChannel(PWMDriver *pwmp, pwmchannel_t channel) {
- osalDbgCheck((pwmp != NULL) && (channel < PWM_CHANNELS));
+ osalDbgCheck((pwmp != NULL) && (channel < pwmp->channels));
+
+ osalSysLock();
+
+ osalDbgAssert(pwmp->state == PWM_READY, "not ready");
+
+ pwmDisableChannelI(pwmp, channel);
+
+ osalSysUnlock();
+}
+
+/**
+ * @brief Enables the periodic activation edge notification.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @note If the notification is already enabled then the call has no effect.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ *
+ * @api
+ */
+void pwmEnablePeriodicNotification(PWMDriver *pwmp) {
+
+ osalDbgCheck(pwmp != NULL);
+
+ osalSysLock();
+
+ osalDbgAssert(pwmp->state == PWM_READY, "not ready");
+ osalDbgAssert(pwmp->config->callback != NULL, "undefined periodic callback");
+
+ pwm_lld_enable_periodic_notification(pwmp);
+
+ osalSysUnlock();
+}
+
+/**
+ * @brief Disables the periodic activation edge notification.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @note If the notification is already disabled then the call has no effect.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ *
+ * @api
+ */
+void pwmDisablePeriodicNotification(PWMDriver *pwmp) {
+
+ osalDbgCheck(pwmp != NULL);
+
+ osalSysLock();
+
+ osalDbgAssert(pwmp->state == PWM_READY, "not ready");
+ osalDbgAssert(pwmp->config->callback != NULL, "undefined periodic callback");
+
+ pwm_lld_disable_periodic_notification(pwmp);
+
+ osalSysUnlock();
+}
+
+/**
+ * @brief Enables a channel de-activation edge notification.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @pre The channel must have been activated using @p pwmEnableChannel().
+ * @note If the notification is already enabled then the call has no effect.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] channel PWM channel identifier (0...channels-1)
+ *
+ * @api
+ */
+void pwmEnableChannelNotification(PWMDriver *pwmp, pwmchannel_t channel) {
+
+ osalDbgCheck((pwmp != NULL) && (channel < pwmp->channels));
+
+ osalSysLock();
+
+ osalDbgAssert(pwmp->state == PWM_READY, "not ready");
+ osalDbgAssert((pwmp->enabled & (1 << channel)) != 0,
+ "channel not enabled");
+ osalDbgAssert(pwmp->config->channels[channel].callback != NULL,
+ "undefined channel callback");
+
+ pwm_lld_enable_channel_notification(pwmp, channel);
+
+ osalSysUnlock();
+}
+
+/**
+ * @brief Disables a channel de-activation edge notification.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @pre The channel must have been activated using @p pwmEnableChannel().
+ * @note If the notification is already disabled then the call has no effect.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] channel PWM channel identifier (0...channels-1)
+ *
+ * @api
+ */
+void pwmDisableChannelNotification(PWMDriver *pwmp, pwmchannel_t channel) {
+
+ osalDbgCheck((pwmp != NULL) && (channel < pwmp->channels));
osalSysLock();
+
osalDbgAssert(pwmp->state == PWM_READY, "not ready");
- pwm_lld_disable_channel(pwmp, channel);
+ osalDbgAssert((pwmp->enabled & (1 << channel)) != 0,
+ "channel not enabled");
+ osalDbgAssert(pwmp->config->channels[channel].callback != NULL,
+ "undefined channel callback");
+
+ pwm_lld_disable_channel_notification(pwmp, channel);
+
osalSysUnlock();
}