System Management code

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

Files at this revision

API Documentation at this revision

Comitter:
martydd3
Date:
Fri Oct 10 20:24:22 2014 +0000
Parent:
5:9258b685fea6
Child:
7:5f6e31faa08e
Commit message:
Added Watchdog timer, put DC_DC converter and FanPump code into their own classes.; To do: Look into how to call class member functions in a thread. Current thread functions are not members of classes.

Changed in this revision

DC_DC/DC_DC.cpp Show annotated file Show diff for this revision Revisions of this file
DC_DC/DC_DC.h Show annotated file Show diff for this revision Revisions of this file
FanPump/FanPump.cpp Show annotated file Show diff for this revision Revisions of this file
FanPump/FanPump.h Show annotated file Show diff for this revision Revisions of this file
PollSwitch/PollSwitch.h Show annotated file Show diff for this revision Revisions of this file
SysMngmt.cpp Show annotated file Show diff for this revision Revisions of this file
Watchdog/Watchdog.cpp Show annotated file Show diff for this revision Revisions of this file
Watchdog/Watchdog.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DC_DC/DC_DC.cpp	Fri Oct 10 20:24:22 2014 +0000
@@ -0,0 +1,43 @@
+#include "mbed.h"
+#include "DC_DC.h"
+
+DigitalOut dc_pin(p20);
+FanPump *fanPump;
+CANBuffer *tx_DC_Buffer;
+bool status;
+
+DC::DC(FanPump *fp, CANBuffer *can){
+    status = false;
+    dc_pin = !status;
+    tx_DC_Buffer = can;
+    fanPump = fp;
+}
+
+bool DC::is_on(){
+    return status;
+}
+
+void DC::set(bool s){
+    status = s;
+    if(!status){
+        fanPump->shutdown_all();    
+    }
+    
+    dc_pin = !status;
+}
+
+void update(const void *arg){
+    char data[4] = {0};
+    while(1){
+        data[0] = status;
+        CANMessage txMessage(TX_DC_DC_ID, data, 4);
+        CANMessage msg(1);
+        tx_DC_Buffer->txWrite(msg);
+        
+        Thread::wait(100);          //10 Hz update
+    }
+}
+
+void DC::start_update(){
+    Thread update_thread(update);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DC_DC/DC_DC.h	Fri Oct 10 20:24:22 2014 +0000
@@ -0,0 +1,19 @@
+#ifndef _FILE_DC_DC_H
+#define _FILE_DC_DC_H
+
+#include "CANBuffer.h"
+#include "FanPump.h"
+#include "rtos.h"
+
+const int TX_DC_DC_ID = ((4 << 8) | 5);
+const int RX_DC_DC_ID = ((4 << 8) | 14);
+
+class DC{
+public:
+    DC(FanPump *fanPump, CANBuffer *can);          //constructor takes function to shut down certain processes when off
+    bool is_on();
+    void set(bool status);   
+    void start_update(); 
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FanPump/FanPump.cpp	Fri Oct 10 20:24:22 2014 +0000
@@ -0,0 +1,106 @@
+#include "mbed.h"
+#include "FanPump.h"
+
+PwmOut pwmPins[PIN_NUM] = { 
+    (P2_0),         // pump
+    (P2_1),         // fan 1
+    (P2_2),         // fan 2
+    (P2_3),         // fan 3
+};
+
+PinStatus pin_status[PIN_NUM];
+CANBuffer *txBuffer;
+
+FanPump::FanPump(CANBuffer *can){
+    for(int i = 0; i < PIN_NUM; i++){
+        pin_status[i].cur_duty = 0;
+        pin_status[i].new_duty = 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;
+    }  
+
+    txBuffer = can;
+}
+
+// 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_fan(void const *arg)
+{
+    PinStatus *pin_stat = (PinStatus *)arg;
+    unsigned char *cur_duty = &(pin_stat->cur_duty);
+    unsigned char *new_duty = &(pin_stat->new_duty);
+    
+    while(*cur_duty != *new_duty)
+    {
+        if(*new_duty > *cur_duty){
+            *cur_duty += 1;
+            
+            if(*cur_duty > *new_duty)
+                *cur_duty = *new_duty;   
+        } else if(*new_duty < *cur_duty){
+            *cur_duty -= 1;
+            
+            if(*cur_duty < *new_duty)
+                *cur_duty = *new_duty;   
+        }
+        
+        pin_stat->pin->write((*cur_duty)*0.01);
+        
+        Thread::wait(5);    //1% duty cycle per 0.005 s
+    }
+}
+
+void FanPump::set_fan(FanSelect fan, unsigned char duty){
+    if((int)fan >= PIN_NUM || duty > 100)
+        return;
+    
+    free_pin(fan);
+
+    pin_status[fan].new_duty = duty;
+    pin_threads[fan] = new Thread(ramp_fan, &pin_status[fan]);
+}
+
+void FanPump::shutdown(FanSelect fan){
+    free_pin(fan);
+    
+    pin_status[fan].cur_duty = 0;
+    pin_status[fan].new_duty = 0;
+    pin_status[fan].pin->write(0);
+}
+
+void FanPump::shutdown_all(){
+    for(int i = 0; i < PIN_NUM; i++)
+        FanPump::shutdown((FanSelect)i);    
+}
+
+void FanPump::free_pin(FanSelect fan){
+    if(pin_threads[fan] != NULL){
+        pin_threads[fan]->terminate();
+        free(pin_threads[fan]);    
+    }    
+}
+
+void update_fans(void const *arg){
+    char data[4] = {0};
+    while(1){
+        for(int i = 0; i < PIN_NUM; i++)
+        {
+            data[i] = pin_status[i].cur_duty;
+        }
+        
+        CANMessage txMessage(TX_FAN_ID, data, 4);
+        txBuffer->txWrite(txMessage);
+        
+        Thread::wait(100);  // 10 Hz update    
+    }    
+}
+
+void FanPump::start_update()
+{
+    Thread update_thread(update_fans);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FanPump/FanPump.h	Fri Oct 10 20:24:22 2014 +0000
@@ -0,0 +1,37 @@
+#ifndef _FILE_FANPUMP_H
+#define _FILE_FANPUMP_H
+
+#include "mbed.h"
+#include "rtos.h"
+#include "CANBuffer.h"
+
+typedef enum {
+    Pump = 0,
+    Fan1 = 1,
+    Fan2 = 2,
+    Fan3 = 3,
+} FanSelect;
+
+typedef struct{
+    unsigned char cur_duty;
+    unsigned char new_duty;
+    PwmOut *pin;    
+} PinStatus;
+
+const int PIN_NUM = 4;
+const int TX_FAN_ID = ((4 << 8) | 4);
+const int RX_FAN_ID = ((4 << 8) | 12);
+
+class FanPump{
+public:
+    FanPump(CANBuffer *can);
+    void set_fan(FanSelect fan, unsigned char duty);
+    void shutdown(FanSelect fan);
+    void shutdown_all();
+    void start_update();
+    
+private:
+    Thread *pin_threads[PIN_NUM];
+    void free_pin(FanSelect fan);
+};
+#endif
\ No newline at end of file
--- a/PollSwitch/PollSwitch.h	Wed Oct 08 20:56:41 2014 +0000
+++ b/PollSwitch/PollSwitch.h	Fri Oct 10 20:24:22 2014 +0000
@@ -1,7 +1,7 @@
-#include"LPCDigitalOut.h"
-#include"LPCDigitalIn.h"
+#include "LPCDigitalOut.h"
+#include "LPCDigitalIn.h"
 
-//Serial pc(USBTX,USBRX);
+
 
 uint16_t PollSwitch()
 {
@@ -21,13 +21,10 @@
                                 LPCDigitalOut(PollPin[10]),
                                 LPCDigitalOut(PollPin[11])};
     
-    /*
-    _(invariant each iteration input is mode neither)
-    _(ensures all are inputs mode neither)
-    _(at a time only one is ioutput)
-    */
-    
-    for(i=0; i<11; i++){
+    // poll each switch 1 at a time
+    // first failed switch is returned
+
+    for(i=0; i<11; i++){       
         ++switchn;
        
         poll[i].write(1);
--- a/SysMngmt.cpp	Wed Oct 08 20:56:41 2014 +0000
+++ b/SysMngmt.cpp	Fri Oct 10 20:24:22 2014 +0000
@@ -4,16 +4,20 @@
     Revised Sept 30, 2014: Began analyzing and commenting program, trying to figure out what the hell it does (Martin Deng)
 */
 
-#include"SysMngmt.h"
-#include"Get_IMD.h"
-#include"PollSwitch.h"
-#include"TemperatureRead.h"
-#include"Store_RTC.h"
-#include"XBee_Lib.h"
-#include"CANBuffer.h"
+#include "SysMngmt.h"
+#include "Get_IMD.h"
+#include "PollSwitch.h"
+#include "TemperatureRead.h"
+#include "Store_RTC.h"
+#include "XBee_Lib.h"
+#include "CANBuffer.h"
 
-#include"mbed.h"
-#include"rtos.h"
+#include "mbed.h"
+#include "rtos.h"
+
+#include "Watchdog.cpp"
+#include "FanPump.h"
+#include "DC_DC.h"
 
 //Possible problems in IMD coz change of counter
 //Possible problems in BatteryStatus coz change in library
@@ -259,138 +263,21 @@
 
 CANBuffer rxBuffer(CAN1, MEDIUM);
 XBee250x XbeeTx;
+Serial pc1(USBTX,USBRX);
 
 char sys_src_id = 4;                // source address of system management
 
-char fan_id = 1;                     // first byte of CANData, last byte states the duty cycle, second-last states which fan to control
-
-Thread *fan_threads[4] = {NULL, NULL, NULL, NULL};     // Threads currently running on the 4 output pins
-
-/*
-    Pins for Fans and Pumps
-    PUMP_PWM = p2.0
-    FAN1_PWM = p2.1
-    FAN2_PWM = p2.2
-    FAN3_PWM = p2.3
-*/
-
-PwmOut pump_pwm(P2_0);
-PwmOut fan1_pwm(P2_1);
-PwmOut fan2_pwm(P2_2);
-PwmOut fan3_pwm(P2_3);
-
-char fan1_duty = 0;
-char fan2_duty = 0;
-char fan3_duty = 0;
-char pump_duty = 0;
-
-int tx_fan_id = ((int)sys_src_id << 8)&((int)fan_id);
-
-// duty goes from 0 to 100
-void rampFans(void const *arg){
-    
-    char *data = (char *)arg;
-    
-    // bounds checking
-    char duty = data[1];
-    if(duty > 100)
-        return;
-    
-    char pin_id = data[0];
-    if(pin_id > 3)
-        return;
-    
-    char *cur_duty;
-    PwmOut *out_pin;
-    
-    switch(pin_id){
-        case 0: cur_duty = &pump_duty;
-            out_pin = &pump_pwm;
-            break;
-        case 1: cur_duty = &fan1_duty;
-            out_pin = &fan1_pwm;
-            break;
-        case 2: cur_duty = &fan2_duty;
-            out_pin = &fan2_pwm;
-            break;
-        case 3: cur_duty = &fan3_duty;
-            out_pin = &fan3_pwm;
-            break;
-        default:
-            return;
-    }
-    
-    while(*cur_duty != duty){
-        
-        if(duty > *cur_duty){
-            *cur_duty += 10;
-            
-            if(*cur_duty > duty)
-                *cur_duty = duty;   
-        } else if(duty < *cur_duty){
-            *cur_duty -= 10;
-            
-            if(*cur_duty < duty)
-                *cur_duty = duty;   
-        }
-        
-        out_pin->write((*cur_duty)*0.01);
-        
-        Thread::wait(10);
-    }
-}
-
-void updateFans(void const *arg){
-    char data[4] = {0, 0, 0, 0};
-    while(1){
-        data[0] = pump_duty;
-        data[1] = fan1_duty;
-        data[2] = fan2_duty;
-        data[3] = fan3_duty;
-        CANMessage txMessage(tx_fan_id, data, 4);
-        rxBuffer.txWrite(txMessage);
-        Thread::wait(100);
-    }    
-}
-
-char dc_id = 0;                   // first byte of CANData, last byte states whether to toggle on (1) or off (0)
-DigitalOut dcPin(p20);
-bool dc_on = false;
-
-int tx_dc_id = ((int)sys_src_id << 8)&((int)dc_id);
-
-void toggleDC_DC(bool toggle){
-    
-    //dcPin turns on DC_DC converter when 0, off when 1
-    
-    if(toggle && !dc_on){
-        dcPin = 0;
-        dc_on = true;
-    } else if(!toggle && dc_on){
-        dcPin = 1;
-        dc_on = false;   
-    }
-}
-
-void updateDC(void const *arg){
-    char data[4] = {0, 0, 0, 0};
-    while(1){
-        data[0] = dc_on;
-        CANMessage txMessage(tx_dc_id, data, 4);
-        rxBuffer.txWrite(txMessage);
-        Thread::wait(100);
-    }  
-}
+Watchdog wdt;
 
 int main() {
     CANMessage rx_msg;    
-
-    //turn off DC-DC converter on startup
-    toggleDC_DC(false);
+    wdt.kick(10.0);
+    pc1.baud(115200);
 
-    //CANMessage update threads
-    Thread fan_update(updateFans);
-    Thread dc_update(updateDC);
+    FanPump fanPump(&rxBuffer);
+    DC dc_dc(&fanPump, &rxBuffer);
+    
+    fanPump.start_update();
 
     while(1)
     {
@@ -401,29 +288,17 @@
                 char cont_id = (rx_msg.id & 0x00FF);        // get bits 7:0
                 
                 // only control fans of dc_dc converter is on
-                if(cont_id == fan_id && dc_on)
+                if(cont_id == RX_FAN_ID && dc_dc.is_on())
                 {
-                    char duty = rx_msg.data[1];
-                    if(duty > 100)
-                        break;
-                    
-                    char pin_id = rx_msg.data[0];
-                    if(pin_id > 3)
-                        break;
-                
-                    if(fan_threads[pin_id] != NULL){
-                        fan_threads[pin_id]->terminate();
-                        free(fan_threads[pin_id]);   
-                    }
-                
-                    fan_threads[pin_id] = new Thread(rampFans, rx_msg.data);
+                    fanPump.set_fan((FanSelect)rx_msg.data[0], rx_msg.data[1]);
                 }
                 
-                if(cont_id == dc_id){
-                    toggleDC_DC(rx_msg.data[0]);
+                if(cont_id == RX_DC_DC_ID){
+                    dc_dc.set(rx_msg.data[0]);
                 }
-                
             } // check for correct src_addr
         } // check CANBuffer
+        
+        wdt.kick();
     } // main while loop
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Watchdog/Watchdog.cpp	Fri Oct 10 20:24:22 2014 +0000
@@ -0,0 +1,22 @@
+// Simon's Watchdog code from
+// http://mbed.org/forum/mbed/topic/508/
+
+#include "mbed.h"
+
+class Watchdog {
+public:
+// Load timeout value in watchdog timer and enable
+    void kick(float s) {
+        LPC_WDT->WDCLKSEL = 0x1;                // Set CLK src to PCLK
+        uint32_t clk = SystemCoreClock / 16;    // WD has a fixed /4 prescaler, PCLK default is /4
+        LPC_WDT->WDTC = s * (float)clk;
+        LPC_WDT->WDMOD = 0x3;                   // Enabled and Reset
+        kick();
+    }
+// "kick" or "feed" the dog - reset the watchdog timer
+// by writing this required bit pattern
+    void kick() {
+        LPC_WDT->WDFEED = 0xAA;
+        LPC_WDT->WDFEED = 0x55;
+    }
+};
\ No newline at end of file