Penn Electric Racing / Mbed 2 deprecated SystemManagement

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

Revision:
17:c9ce210f6654
Parent:
13:fbd9b3f5a07c
Child:
18:915a235bc099
--- a/FanPump/FanPump.cpp	Fri Oct 24 22:38:20 2014 +0000
+++ b/FanPump/FanPump.cpp	Sat Oct 25 03:28:55 2014 +0000
@@ -1,56 +1,81 @@
 #include "FanPump.h"
 
-static FanPump* instance[6] = { NULL };
+static FanPump* instance[6] = { NULL };         // Access pwm object by channel#
+const int PCLK = 24e6;          // 24Mhz clock
 
 // 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) instance[i]->slew();   
+            if (instance[i] != NULL) {
+                items++;
+                sum += instance[i]->slew();
+            }
         }
     }
-    LPC_PWM1->IR = 0x73F;   // Clear interrupts
+    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
-void FanPump::slew() {
-    uint32_t currPulseT = *(&LPC_PWM1->MR0+pin);
-    uint32_t currPulse_us = currPulseT / 24;
-    uint32_t setPointT = setPoint_us * 24;      // Convert us into ticks
-    if (currPulseT == setPointT) return;        // Nothing to slew here, already at its setpoint
-
+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
+        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);
+        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;
-    
-    // Match the pin# to the PWM object for the interrupt
-    if (pin == p26 || pin == LED1) pin = 1;
-    if (pin == p25 || pin == LED2) pin = 2;
-    if (pin == p24 || pin == LED3) pin = 3;
-    if (pin == p23 || pin == LED4) pin = 4;
-    if (pin == p22)                pin = 5;
-    if (pin == p21)                pin = 6;
-    instance[pin-1] = this;
-    
-    LPC_PWM1->IR = 0x73F;   // Clear interrupts
+        
+    LPC_PWM1->IR = 0x73F;    // Clear interrupts
     NVIC_SetVector(PWM1_IRQn, (uint32_t)&pwmIRQ);
     NVIC_SetPriority(PWM1_IRQn, 0);
     NVIC_EnableIRQ(PWM1_IRQn);
-    LPC_PWM1->MR |= 1;  // Enable interrupt on MR0 (when the pwm period expires)
+    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