System Management code
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
FanPump.cpp
00001 #include "FanPump.h" 00002 00003 #define S_ATOMIC __disable_irq(); 00004 #define E_ATOMIC __enable_irq(); 00005 00006 static FanPump* instance[6] = { NULL }; // Access pwm object by channel# 00007 const int PCLK = 24e6; // 24Mhz default clock to PWM module 00008 00009 // Interrupt handler, must be called from static context, calls all the slew functions 00010 void pwmIRQ() 00011 { 00012 int sum = 0, items = 0; 00013 if (LPC_PWM1->IR & 1) { // Interrupt pending 00014 for (int i = 0; i < 6; i++) { // Check every channel 00015 if (instance[i] != NULL) { // Make sure it exists 00016 items++; // Count each number serviced 00017 sum += instance[i]->slew(); // Add the return values (1 if nothing was done in function) 00018 } 00019 } 00020 } 00021 LPC_PWM1->IR = 0x73F; // Clear interrupt 00022 if (items == sum) { 00023 LPC_PWM1->MCR = 0; // Disable the interrupts, every duty is already where it needs to be 00024 } 00025 } 00026 00027 // Called on each timer expire for each pwm object 00028 int FanPump::slew() 00029 { 00030 uint32_t currPulseT = *MR_base; // Get the current pulsewidth ticks 00031 uint32_t setPointT = setPoint_us * (PCLK/1e6); // Convert us into ticks 00032 if (currPulseT == setPointT) return 1; // Nothing to slew here, already at its setpoint 00033 00034 uint32_t currPulse_us = currPulseT / (PCLK/1e6); // Convert to us 00035 if (currPulseT < setPointT) { 00036 if (setPoint_us - currPulse_us <= maxChange_us) pwm.pulsewidth_us(setPoint_us); // Close to the setpoint, write it directly 00037 else pwm.pulsewidth_us(currPulse_us + maxChange_us); 00038 } else { 00039 if (currPulse_us - setPoint_us <= maxChange_us) pwm.pulsewidth_us(setPoint_us); // Close to the setpoint, write it directly 00040 else pwm.pulsewidth_us(currPulse_us - maxChange_us); 00041 } 00042 return 0; 00043 } 00044 00045 FanPump::FanPump(PinName pin, float period, float slew) : pwm(pin) 00046 { 00047 00048 // Match the pin# to the PWM object for the interrupt 00049 int channel = 0; 00050 if (pin == p26 || pin == LED1) channel = 1; 00051 if (pin == p25 || pin == LED2) channel = 2; 00052 if (pin == p24 || pin == LED3) channel = 3; 00053 if (pin == p23 || pin == LED4) channel = 4; 00054 if (pin == p22) channel = 5; 00055 if (pin == p21) channel = 6; 00056 if (channel == 0) return; // Invalid pin 00057 instance[channel-1] = this; // Attach this object to an instance pointer to access from interrupt 00058 00059 // Set the match register address 00060 if (channel == 1) MR_base = &LPC_PWM1->MR1; 00061 if (channel == 2) MR_base = &LPC_PWM1->MR2; 00062 if (channel == 3) MR_base = &LPC_PWM1->MR3; 00063 if (channel == 4) MR_base = &LPC_PWM1->MR4; 00064 if (channel == 5) MR_base = &LPC_PWM1->MR5; 00065 if (channel == 6) MR_base = &LPC_PWM1->MR6; 00066 00067 setPoint_us = 0; 00068 period_us = period * 1.0e6; 00069 pwm.period_us(period_us); 00070 pwm = 0; 00071 maxChange_us = (period / slew) * period_us; 00072 00073 LPC_PWM1->IR = 0x73F; // Clear interrupts 00074 NVIC_SetVector(PWM1_IRQn, (uint32_t)&pwmIRQ); 00075 NVIC_SetPriority(PWM1_IRQn, 0); 00076 NVIC_EnableIRQ(PWM1_IRQn); 00077 } 00078 00079 void FanPump::write(float duty) 00080 { 00081 if (duty < 0) duty = 0; 00082 if (duty > 1) duty = 1; 00083 setPoint_us = duty * period_us; 00084 LPC_PWM1->MCR = 1; // Enable interrupt on MR0 (when the pwm period expires) 00085 } 00086 void FanPump::directOff() 00087 { 00088 S_ATOMIC // Ensure that it happens now, no thread-switching 00089 pwm.pulsewidth_us(0); 00090 setPoint_us = 0; 00091 E_ATOMIC 00092 } 00093 float FanPump::read() 00094 { 00095 return (float)(setPoint_us)/(float)(period_us); 00096 } 00097 float FanPump::readRaw() 00098 { 00099 uint32_t currPulseT = *MR_base; // Get the current pulsewidth ticks 00100 return ((float)(currPulseT) / (float)(PCLK/1e6)) / (float)(period_us); 00101 }
Generated on Fri Jul 15 2022 06:07:18 by
1.7.2
