Added hardware failure detection to watchdog example.
Fork of Watchdog_sample_nocoverage by
Revision 6:6f93bce60d98, committed 2018-03-09
- Comitter:
- natgovor
- Date:
- Fri Mar 09 15:45:02 2018 +0000
- Parent:
- 5:9817756efc34
- Commit message:
- Added hardware failure detection to watchdog example.
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 9817756efc34 -r 6f93bce60d98 main.cpp --- a/main.cpp Tue Feb 27 10:29:30 2018 +0000 +++ b/main.cpp Fri Mar 09 15:45:02 2018 +0000 @@ -15,13 +15,77 @@ DigitalOut led1(PTC12, OFF); DigitalOut led2(PTC13, OFF); +DigitalOut redLed(LED1); +DigitalOut greenLed(LED2); + +// Analog inputs +AnalogIn ain1(A0); +AnalogIn ain2(A1); + +Serial pc(USBTX, USBRX); // tx, rx, for debugging + // This ticker is used to feed the watch dog -Ticker tick; +Ticker tick1; +Ticker tick2; // Threads -Thread threadT ; // timer thread -Thread threadLED1 ; // thread LED1 -Thread threadLED2 ; // thread LED2 +Thread threadT(osPriorityNormal, 1000); // timer thread +Thread threadLED1(osPriorityNormal, 1000); // thread LED1 +Thread threadLED2(osPriorityNormal, 1000); // thread LED2 +Thread threadCheckLED1(osPriorityNormal, 1000); +Thread threadCheckLED2(osPriorityNormal, 1000); + +// Message type +typedef struct { + uint16_t analog; /* Analog input value */ + bool buttonPressed; +} message_t; + +// Mail box +Mail<message_t, 2> mailbox1; +Mail<message_t, 2> mailbox2; + +volatile int samples1 = 0; +volatile uint16_t smoothed1 = 0; +void readA0() { + smoothed1 = (smoothed1 >> 1) + (ain1.read_u16() >> 1); + samples1++; + if (samples1 == 10) { + // send to thread + message_t *mess = mailbox1.alloc(); // may fail but does not block + if (mess) { + mess->analog = smoothed1; + mailbox1.put(mess); // fails but does not block if full + } + samples1 = 0; + } +} + +volatile int samples2 = 0; +volatile uint16_t smoothed2 = 0; +void readA1() { + smoothed2 = (smoothed2 >> 1) + (ain2.read_u16() >> 1); + samples2++; + if (samples2 == 10) { + // send to thread + message_t *mess = mailbox2.alloc(); // may fail but does not block + if (mess) { + mess->analog = smoothed2; + mailbox2.put(mess); // fails but does not block if full + } + samples2 = 0; + } +} + +// Write voltage digits +// v Voltage as scale int, e.g. 3.30 is 330 +void vToString(int v, char* s) { + s[3] = '0' + (v % 10) ; + v = v / 10 ; + s[2] = '0' + (v % 10) ; + v = v / 10 ; + s[0] = '0' + (v % 10) ; +} // ------------Fault Injection Button------------- // Wait while the button is down @@ -41,8 +105,9 @@ if (evt.status == osEventSignal) { if (evt.value.signals & 0x01) led1 = ON ; if (evt.value.signals & 0x02) led1 = OFF ; + wdt_kickA(); } - waitButton() ; // POSSIBLE FAULT HERE + //waitButton() ; // POSSIBLE FAULT HERE } } @@ -56,8 +121,9 @@ if (evt.status == osEventSignal) { if (evt.value.signals & 0x01) led2 = ON ; if (evt.value.signals & 0x02) led2 = OFF ; + wdt_kickB(); } - // waitButton() ; // POSSIBLE FAULT HERE + //waitButton() ; // POSSIBLE FAULT HERE } } @@ -72,7 +138,80 @@ Thread::wait(250) ; threadLED1.signal_set(0x2) ; threadLED2.signal_set(0x2) ; - // waitButton() ; // POSSIBLE FAULT HERE + + waitButton() ; // POSSIBLE FAULT HERE + } +} + +void check_led1() { + int volts = 0; + int counter = 0; + char vstring[] = "X.XX\r\n"; + + while (true) { + osEvent evt = mailbox1.get(); // wait for mail + if (evt.status == osEventMail) { + message_t* mess = (message_t*)evt.value.p; + volts = (mess->analog * 330) / 0xffff; + mailbox1.free(mess); // free the message space + + if (led1 == 1) { + if (volts < 160 && volts > 140) { + // normal + } else if (volts == 0) { + // failed open circuit + pc.printf("Failed open circuit 1\n\r"); + redLed = 0; + } else if (volts > 300) { + // failed short circuit + pc.printf("Failed short circuit 1\n\r"); + greenLed = 0; + } + } + + vToString(volts, vstring); + counter++; + if (counter == 10) { // limit bandwidth of serial + pc.printf(vstring); + counter = 0; + } + } + } +} + +void check_led2() { + int volts = 0; + int counter = 0; + char vstring[] = "X.XX\r\n"; + + while (true) { + osEvent evt = mailbox2.get(); // wait for mail + if (evt.status == osEventMail) { + message_t* mess = (message_t*)evt.value.p; + volts = (mess->analog * 330) / 0xffff; + mailbox2.free(mess); // free the message space + + if (led2 == 1) { + if (volts < 160 && volts > 140) { + // normal + } else if (volts == 0) { + // failed open circuit + pc.printf("Failed open circuit 2\n\r"); + redLed = 0; + } else if (volts > 300) { + // failed short circuit + pc.printf("Failed open circuit 2\n\r"); + greenLed = 0; + } + } + + vToString(volts, vstring); + counter++; + if (counter == 10) { // limit bandwidth of serial + pc.printf(vstring); + counter = 0; + } + } } } @@ -85,16 +224,23 @@ // ---------------------------------------------- int main(void) { - wdt_32ms() ; // initialise watchdog - 32ms timeout - tick.attach_us(callback(&wdt_kick_all), 20000); // ticks every 20ms + redLed = 1; + greenLed = 1; + + wdt_1sec(); // initialise watchdog - 1sec timeout + + tick1.attach_us(callback(&readA0), 10000); // ticks every 10ms + tick2.attach_us(callback(&readA1), 10000); // ticks every 10ms // start threads - threadT.start(&timer_thread) ; // start the timer thread - threadLED1.start(&led1_thread) ; // start the LED1 control thread - threadLED2.start(&led2_thread) ; // start the LED2 control thread + threadT.start(&timer_thread); // start the timer thread + threadLED1.start(&led1_thread); // start the LED1 control thread + threadLED2.start(&led2_thread); // start the LED2 control thread + threadCheckLED1.start(&check_led1); // start the LED2 control thread + threadCheckLED2.start(&check_led2); // start the LED2 control thread // show start-up led_red = OFF; - Thread::wait(1000) ; + Thread::wait(1000); led_red = ON; } \ No newline at end of file