Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
Diff: CANController/FanPump/FanPump.cpp
- Revision:
- 22:fc802e7715f8
- Parent:
- 18:915a235bc099
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CANController/FanPump/FanPump.cpp Fri Nov 07 21:09:50 2014 +0000
@@ -0,0 +1,82 @@
+#include "FanPump.h"
+
+static FanPump* instance[6] = { NULL }; // Access pwm object by channel#
+const int PCLK = 24e6; // 24Mhz clock
+uint32_t FanPump::period_us = 0.0;
+
+// Interrupt handler, must be called from static context, calls all the slew functions
+void pwmIRQ() {
+ int sum = 0;
+ int items = 0;
+ if (LPC_PWM1->IR & 1) {
+ for (int i = 0; i < 6; i++) {
+ if (instance[i] != NULL) {
+ items++;
+ sum += instance[i]->slew();
+ }
+ }
+ }
+ LPC_PWM1->IR = 0x73F; // Clear interrupts
+ if (items == sum) LPC_PWM1->MCR = 0; // Detach all the interrupts, every pin is already where it needs to be
+}
+
+// Called on each timer expire for each pwm object
+int FanPump::slew() {
+ uint32_t currPulseT = *((uint32_t*)(&LPC_PWM1->MR0)+chan); // Get the current pulsewidth ticks
+ uint32_t setPointT = setPoint_us * (PCLK/1e6); // Convert us into ticks
+ if (currPulseT == setPointT) return 1; // Nothing to slew here, already at its setpoint
+
+ uint32_t currPulse_us = currPulseT / (PCLK/1e6); // Convert to us
+ if (currPulseT < setPointT) {
+ if (setPoint_us - currPulse_us <= maxChange_us) pwm.pulsewidth_us(setPoint_us); // Close to the setpoint, write it directly
+ else pwm.pulsewidth_us(currPulse_us + maxChange_us);
+ } else {
+ if (currPulse_us - setPoint_us <= maxChange_us) pwm.pulsewidth_us(setPoint_us); // Close to the setpoint, write it directly
+ else pwm.pulsewidth_us(currPulse_us - maxChange_us);
+ }
+ return 0;
+}
+
+FanPump::FanPump(PinName pin, float period, float slew) : pwm(pin) {
+
+ // Match the pin# to the PWM object for the interrupt
+ int chan=0;
+ if (pin == p26 || pin == LED1) chan = 1;
+ if (pin == p25 || pin == LED2) chan = 2;
+ if (pin == p24 || pin == LED3) chan = 3;
+ if (pin == p23 || pin == LED4) chan = 4;
+ if (pin == p22) chan = 5;
+ if (pin == p21) chan = 6;
+ if (chan == 0) return; // Invalid pin
+ instance[chan-1] = this;
+
+ setPoint_us = 0;
+ period_us = period / 1.0e6;
+ pwm.period_us(period_us);
+ maxChange_us = (period / slew) * period_us;
+
+ LPC_PWM1->IR = 0x73F; // Clear interrupts
+ NVIC_SetVector(PWM1_IRQn, (uint32_t)&pwmIRQ);
+ NVIC_SetPriority(PWM1_IRQn, 0);
+ NVIC_EnableIRQ(PWM1_IRQn);
+ LPC_PWM1->MCR = 1; // Enable interrupt on MR0 (when the pwm period expires)
+}
+void FanPump::write(float duty) {
+ if (duty < 0) duty = 0;
+ if (duty > 1) duty = 1;
+ setPoint_us = duty * period_us;
+ LPC_PWM1->MCR = 1; // Enable interrupt on MR0 (when the pwm period expires)
+}
+void FanPump::directOff() {
+ __disable_irq();
+ pwm.pulsewidth_us(0);
+ setPoint_us = 0;
+ __enable_irq();
+}
+float FanPump::read() {
+ return (float)(setPoint_us)/(float)(period_us);
+}
+float FanPump::readRaw() {
+ uint32_t currPulseT = *((uint32_t*)(&LPC_PWM1->MR0)+chan); // Get the current pulsewidth ticks
+ return ((float)(currPulseT) / (float)(PCLK/1e6)) / (float)(period_us);
+}
\ No newline at end of file
