Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
Diff: FanPump/FanPump.cpp
- 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
