Penn Electric Racing / Mbed 2 deprecated SystemManagement

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

Committer:
pspatel321
Date:
Thu Jan 22 07:59:48 2015 +0000
Revision:
37:2207b58b9a7f
Tested in car with other systems.  Most features working.  Xbees need work. DC-DC protection features are glitchy due to spurious current readings.  Thresholds may need adjustment.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pspatel321 37:2207b58b9a7f 1 #include "FanPump.h"
pspatel321 37:2207b58b9a7f 2
pspatel321 37:2207b58b9a7f 3 #define S_ATOMIC __disable_irq();
pspatel321 37:2207b58b9a7f 4 #define E_ATOMIC __enable_irq();
pspatel321 37:2207b58b9a7f 5
pspatel321 37:2207b58b9a7f 6 static FanPump* instance[6] = { NULL }; // Access pwm object by channel#
pspatel321 37:2207b58b9a7f 7 const int PCLK = 24e6; // 24Mhz default clock to PWM module
pspatel321 37:2207b58b9a7f 8
pspatel321 37:2207b58b9a7f 9 // Interrupt handler, must be called from static context, calls all the slew functions
pspatel321 37:2207b58b9a7f 10 void pwmIRQ()
pspatel321 37:2207b58b9a7f 11 {
pspatel321 37:2207b58b9a7f 12 int sum = 0, items = 0;
pspatel321 37:2207b58b9a7f 13 if (LPC_PWM1->IR & 1) { // Interrupt pending
pspatel321 37:2207b58b9a7f 14 for (int i = 0; i < 6; i++) { // Check every channel
pspatel321 37:2207b58b9a7f 15 if (instance[i] != NULL) { // Make sure it exists
pspatel321 37:2207b58b9a7f 16 items++; // Count each number serviced
pspatel321 37:2207b58b9a7f 17 sum += instance[i]->slew(); // Add the return values (1 if nothing was done in function)
pspatel321 37:2207b58b9a7f 18 }
pspatel321 37:2207b58b9a7f 19 }
pspatel321 37:2207b58b9a7f 20 }
pspatel321 37:2207b58b9a7f 21 LPC_PWM1->IR = 0x73F; // Clear interrupt
pspatel321 37:2207b58b9a7f 22 if (items == sum) {
pspatel321 37:2207b58b9a7f 23 LPC_PWM1->MCR = 0; // Disable the interrupts, every duty is already where it needs to be
pspatel321 37:2207b58b9a7f 24 }
pspatel321 37:2207b58b9a7f 25 }
pspatel321 37:2207b58b9a7f 26
pspatel321 37:2207b58b9a7f 27 // Called on each timer expire for each pwm object
pspatel321 37:2207b58b9a7f 28 int FanPump::slew()
pspatel321 37:2207b58b9a7f 29 {
pspatel321 37:2207b58b9a7f 30 uint32_t currPulseT = *MR_base; // Get the current pulsewidth ticks
pspatel321 37:2207b58b9a7f 31 uint32_t setPointT = setPoint_us * (PCLK/1e6); // Convert us into ticks
pspatel321 37:2207b58b9a7f 32 if (currPulseT == setPointT) return 1; // Nothing to slew here, already at its setpoint
pspatel321 37:2207b58b9a7f 33
pspatel321 37:2207b58b9a7f 34 uint32_t currPulse_us = currPulseT / (PCLK/1e6); // Convert to us
pspatel321 37:2207b58b9a7f 35 if (currPulseT < setPointT) {
pspatel321 37:2207b58b9a7f 36 if (setPoint_us - currPulse_us <= maxChange_us) pwm.pulsewidth_us(setPoint_us); // Close to the setpoint, write it directly
pspatel321 37:2207b58b9a7f 37 else pwm.pulsewidth_us(currPulse_us + maxChange_us);
pspatel321 37:2207b58b9a7f 38 } else {
pspatel321 37:2207b58b9a7f 39 if (currPulse_us - setPoint_us <= maxChange_us) pwm.pulsewidth_us(setPoint_us); // Close to the setpoint, write it directly
pspatel321 37:2207b58b9a7f 40 else pwm.pulsewidth_us(currPulse_us - maxChange_us);
pspatel321 37:2207b58b9a7f 41 }
pspatel321 37:2207b58b9a7f 42 return 0;
pspatel321 37:2207b58b9a7f 43 }
pspatel321 37:2207b58b9a7f 44
pspatel321 37:2207b58b9a7f 45 FanPump::FanPump(PinName pin, float period, float slew) : pwm(pin)
pspatel321 37:2207b58b9a7f 46 {
pspatel321 37:2207b58b9a7f 47
pspatel321 37:2207b58b9a7f 48 // Match the pin# to the PWM object for the interrupt
pspatel321 37:2207b58b9a7f 49 int channel = 0;
pspatel321 37:2207b58b9a7f 50 if (pin == p26 || pin == LED1) channel = 1;
pspatel321 37:2207b58b9a7f 51 if (pin == p25 || pin == LED2) channel = 2;
pspatel321 37:2207b58b9a7f 52 if (pin == p24 || pin == LED3) channel = 3;
pspatel321 37:2207b58b9a7f 53 if (pin == p23 || pin == LED4) channel = 4;
pspatel321 37:2207b58b9a7f 54 if (pin == p22) channel = 5;
pspatel321 37:2207b58b9a7f 55 if (pin == p21) channel = 6;
pspatel321 37:2207b58b9a7f 56 if (channel == 0) return; // Invalid pin
pspatel321 37:2207b58b9a7f 57 instance[channel-1] = this; // Attach this object to an instance pointer to access from interrupt
pspatel321 37:2207b58b9a7f 58
pspatel321 37:2207b58b9a7f 59 // Set the match register address
pspatel321 37:2207b58b9a7f 60 if (channel == 1) MR_base = &LPC_PWM1->MR1;
pspatel321 37:2207b58b9a7f 61 if (channel == 2) MR_base = &LPC_PWM1->MR2;
pspatel321 37:2207b58b9a7f 62 if (channel == 3) MR_base = &LPC_PWM1->MR3;
pspatel321 37:2207b58b9a7f 63 if (channel == 4) MR_base = &LPC_PWM1->MR4;
pspatel321 37:2207b58b9a7f 64 if (channel == 5) MR_base = &LPC_PWM1->MR5;
pspatel321 37:2207b58b9a7f 65 if (channel == 6) MR_base = &LPC_PWM1->MR6;
pspatel321 37:2207b58b9a7f 66
pspatel321 37:2207b58b9a7f 67 setPoint_us = 0;
pspatel321 37:2207b58b9a7f 68 period_us = period * 1.0e6;
pspatel321 37:2207b58b9a7f 69 pwm.period_us(period_us);
pspatel321 37:2207b58b9a7f 70 pwm = 0;
pspatel321 37:2207b58b9a7f 71 maxChange_us = (period / slew) * period_us;
pspatel321 37:2207b58b9a7f 72
pspatel321 37:2207b58b9a7f 73 LPC_PWM1->IR = 0x73F; // Clear interrupts
pspatel321 37:2207b58b9a7f 74 NVIC_SetVector(PWM1_IRQn, (uint32_t)&pwmIRQ);
pspatel321 37:2207b58b9a7f 75 NVIC_SetPriority(PWM1_IRQn, 0);
pspatel321 37:2207b58b9a7f 76 NVIC_EnableIRQ(PWM1_IRQn);
pspatel321 37:2207b58b9a7f 77 }
pspatel321 37:2207b58b9a7f 78
pspatel321 37:2207b58b9a7f 79 void FanPump::write(float duty)
pspatel321 37:2207b58b9a7f 80 {
pspatel321 37:2207b58b9a7f 81 if (duty < 0) duty = 0;
pspatel321 37:2207b58b9a7f 82 if (duty > 1) duty = 1;
pspatel321 37:2207b58b9a7f 83 setPoint_us = duty * period_us;
pspatel321 37:2207b58b9a7f 84 LPC_PWM1->MCR = 1; // Enable interrupt on MR0 (when the pwm period expires)
pspatel321 37:2207b58b9a7f 85 }
pspatel321 37:2207b58b9a7f 86 void FanPump::directOff()
pspatel321 37:2207b58b9a7f 87 {
pspatel321 37:2207b58b9a7f 88 S_ATOMIC // Ensure that it happens now, no thread-switching
pspatel321 37:2207b58b9a7f 89 pwm.pulsewidth_us(0);
pspatel321 37:2207b58b9a7f 90 setPoint_us = 0;
pspatel321 37:2207b58b9a7f 91 E_ATOMIC
pspatel321 37:2207b58b9a7f 92 }
pspatel321 37:2207b58b9a7f 93 float FanPump::read()
pspatel321 37:2207b58b9a7f 94 {
pspatel321 37:2207b58b9a7f 95 return (float)(setPoint_us)/(float)(period_us);
pspatel321 37:2207b58b9a7f 96 }
pspatel321 37:2207b58b9a7f 97 float FanPump::readRaw()
pspatel321 37:2207b58b9a7f 98 {
pspatel321 37:2207b58b9a7f 99 uint32_t currPulseT = *MR_base; // Get the current pulsewidth ticks
pspatel321 37:2207b58b9a7f 100 return ((float)(currPulseT) / (float)(PCLK/1e6)) / (float)(period_us);
pspatel321 37:2207b58b9a7f 101 }