Penn Electric Racing / Mbed 2 deprecated SystemManagement

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

Revision:
13:fbd9b3f5a07c
Parent:
12:e0adb697fcdb
Child:
17:c9ce210f6654
--- a/FanPump/FanPump.cpp	Tue Oct 21 23:44:15 2014 +0000
+++ b/FanPump/FanPump.cpp	Fri Oct 24 22:09:04 2014 +0000
@@ -1,110 +1,56 @@
-#include "mbed.h"
 #include "FanPump.h"
 
-PwmOut pwmPins[PIN_NUM] = { 
-    PwmOut(P2_0),         // pump 1
-    PwmOut(P2_1),         // pump 2
-    PwmOut(P2_2),         // fan 1
-    PwmOut(P2_3),         // fan 2
-};
-
-PinStatus pin_status[PIN_NUM];
-CANBuffer *tx_Fan_Buffer;
+static FanPump* instance[6] = { NULL };
 
-FanPump::FanPump(CANBuffer *can){
-    for(int i = 0; i < PIN_NUM; i++){
-        pin_status[i].cur_duty = 0.0;
-        pin_status[i].new_duty = 0.0;
-        
-        pin_status[i].pin = &pwmPins[i];
-        pin_status[i].pin->period_ms(10);
-        pin_status[i].pin->write(0.0);
-        
-        pin_threads[i] = NULL;
-    }  
-
-    tx_Fan_Buffer = can;
+// Interrupt handler, must be called from static context, calls all the slew functions
+void pwmIRQ() {
+    if (LPC_PWM1->IR & 1) {
+        for (int i = 0; i < 6; i++) {
+            if (instance[i] != NULL) instance[i]->slew();   
+        }
+    }
+    LPC_PWM1->IR = 0x73F;   // Clear interrupts
 }
 
-// this is not a member function. For some reason, thread does weird things
-// with functions in classes. Apparently pointers get messed up when pointing to
-// a function in a class
-void ramp_pin(void const *arg)
-{
-    PinStatus *pin_stat = (PinStatus *)arg;
-    float *cur_duty = &(pin_stat->cur_duty);
-    float *new_duty = &(pin_stat->new_duty);
-    
-    while(*cur_duty != *new_duty)
-    {
-        if(*new_duty > *cur_duty){
-            *cur_duty += 1.0;
-            
-            if(*cur_duty > *new_duty)
-                *cur_duty = *new_duty;   
-        } else if(*new_duty < *cur_duty){
-            *cur_duty -= 1.0;
-            
-            if(*cur_duty < *new_duty)
-                *cur_duty = *new_duty;   
-        }
-        
-        pin_stat->pin->write((*cur_duty));
-        
-        Thread::wait(5);    //1% duty cycle per 0.005 s
+// 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
+
+    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);
+        else pwm.pulsewidth_us(currPulse_us - maxChange_us);
     }
 }
 
-void FanPump::set_fan_pump(FanPumpSelect fan_pump, float duty){
-    if((int)fan_pump >= PIN_NUM || duty > 100.0)
-        return;
+FanPump::FanPump(PinName pin, float period, float slew) : pwm(pin) {
+    setPoint_us = 0;
+    period_us = period / 1.0e6;
+    pwm.period_us(period_us);
+    maxChange_us = (period / slew) * period_us;
     
-    free_pin(fan_pump);
-
-    pin_status[fan_pump].new_duty = duty;
-    pin_threads[fan_pump] = new Thread(ramp_pin, &pin_status[fan_pump]);
-}
-
-void FanPump::shutdown(FanPumpSelect fan_pump){
-    free_pin(fan_pump);
+    // 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;
     
-    pin_status[fan_pump].cur_duty = 0;
-    pin_status[fan_pump].new_duty = 0;
-    pin_status[fan_pump].pin->write(0);
-}
-
-void FanPump::shutdown_all(){
-    for(int i = 0; i < PIN_NUM; i++)
-        FanPump::shutdown((FanPumpSelect)i);    
+    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)
 }
-
-void FanPump::free_pin(FanPumpSelect fan_pump){
-    if(pin_threads[fan_pump] != NULL){
-        pin_threads[fan_pump]->terminate();
-        free(pin_threads[fan_pump]);    
-    }    
-}
-
-void update_fans_pumps(void const *arg){
-    char data[8] = {0};
-    while(1){
-        memcpy(&pin_status[0].cur_duty, data, sizeof(float));
-        memcpy(&pin_status[1].cur_duty, data+4, sizeof(float));
-        
-        CANMessage txPumpMessage(TX_PUMP_ID, data, 8);
-        tx_Fan_Buffer->txWrite(txPumpMessage);
-        
-        memcpy(&pin_status[2].cur_duty, data, sizeof(float));
-        memcpy(&pin_status[3].cur_duty, data+4, sizeof(float));
-        
-        CANMessage txFanMessage(TX_FAN_ID, data, 8);
-        tx_Fan_Buffer->txWrite(txFanMessage);
-        
-        Thread::wait(100);  // 10 Hz update    
-    }    
-}
-
-void FanPump::start_update()
-{
-    Thread update_thread(update_fans_pumps);
+void FanPump::write(float duty) {
+    if (duty < 0) duty = 0;
+    if (duty > 1) duty = 1;
+    setPoint_us = duty * period_us;
 }
\ No newline at end of file