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:
Wed Jan 07 03:36:43 2015 +0000
Revision:
35:9337ac9f4e1b
Parent:
30:91af74a299e1
Brought in changes from AMS code.  Added serial input to allow changing parameters as well.

Who changed what in which revision?

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