andrewm@0: /*
andrewm@0:  * StatusLED.cpp
andrewm@0:  *
andrewm@0:  * Routines for manipulating the status LED
andrewm@0:  *
andrewm@0:  * (c) 2014 Andrew McPherson and Victor Zappi
andrewm@0:  * QMUL, Centre for Digital Music
andrewm@0:  */
andrewm@0: 
andrewm@0: #include <iostream>
andrewm@0: #include "StatusLED.h"
andrewm@68: #include <GPIOcontrol.h>
andrewm@0: 
andrewm@0: extern int gShouldStop;
andrewm@0: extern int gVerbose;
andrewm@0: 
andrewm@0: using namespace std;
andrewm@0: 
andrewm@0: StatusLED::StatusLED() {
andrewm@0: 	gpio_number = -1;
andrewm@0: 	milliseconds_on = 0;
andrewm@0: 	milliseconds_off = 100;
andrewm@0: 	blink_thread = -1;
andrewm@0: }
andrewm@0: 
andrewm@0: StatusLED::~StatusLED() {
andrewm@0: 	if(gpio_number >= 0) {
andrewm@0: 		this_should_stop = true;
andrewm@0: 		pthread_join(blink_thread, NULL);
andrewm@0: 		gpio_unexport(gpio_number);
andrewm@0: 	}
andrewm@0: }
andrewm@0: 
andrewm@0: bool StatusLED::init(int gpio_pin) {
andrewm@0: 	gpio_number = gpio_pin;
andrewm@0: 	this_should_stop = false;
andrewm@0: 
andrewm@0: 	if(gpio_export(gpio_number)) {
andrewm@0: 		if(gVerbose)
andrewm@0: 			cout << "Warning: couldn't export status LED pin\n";
andrewm@0: 	}
andrewm@0: 	if(gpio_set_dir(gpio_number, OUTPUT_PIN)) {
andrewm@0: 		if(gVerbose)
andrewm@0: 			cout << "Couldn't set direction on status LED pin\n";
andrewm@0: 		return false;
andrewm@0: 	}
andrewm@0: 	if(gpio_set_value(gpio_number, LOW)) {
andrewm@0: 		if(gVerbose)
andrewm@0: 			cout << "Couldn't set value on status LED pin\n";
andrewm@0: 		return false;
andrewm@0: 	}
andrewm@0: 
andrewm@0: 
andrewm@0: 	if ( pthread_create(&blink_thread, NULL, static_blink_loop, this) )
andrewm@0: 	{
andrewm@0: 		cout << "Error:unable to create status LED thread" << endl;
andrewm@0: 		return false;
andrewm@0: 	}
andrewm@0: 
andrewm@0: 	return true;
andrewm@0: }
andrewm@0: 
andrewm@0: void StatusLED::on() {
andrewm@0: 	milliseconds_on = 100;
andrewm@0: 	milliseconds_off = 0;
andrewm@0: }
andrewm@0: 
andrewm@0: void StatusLED::off() {
andrewm@0: 	milliseconds_on = 0;
andrewm@0: 	milliseconds_off = 100;
andrewm@0: }
andrewm@0: 
andrewm@0: void StatusLED::blink(int ms_on, int ms_off) {
andrewm@0: 	milliseconds_on = ms_on;
andrewm@0: 	milliseconds_off = ms_off;
andrewm@0: }
andrewm@0: 
andrewm@0: void* StatusLED::blink_loop(void *) {
andrewm@0: 	while(!gShouldStop && !this_should_stop) {
andrewm@0: 		if(milliseconds_on != 0)
andrewm@0: 			gpio_set_value(gpio_number, HIGH);
andrewm@0: 		usleep(1000 * milliseconds_on);
andrewm@0: 		if(gShouldStop)
andrewm@0: 			break;
andrewm@0: 		if(milliseconds_off != 0)
andrewm@0: 			gpio_set_value(gpio_number, LOW);
andrewm@0: 		usleep(1000 * milliseconds_off);
andrewm@0: 	}
andrewm@0: 	pthread_exit(NULL);
andrewm@0: }