Penn Electric Racing / Mbed 2 deprecated SystemManagement

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

CANController/FanPump/FanPump.cpp

Committer:
martydd3
Date:
2014-11-07
Revision:
22:fc802e7715f8
Parent:
FanPump/FanPump.cpp@ 18:915a235bc099

File content as of revision 22:fc802e7715f8:

#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);
}