/*
io4ledbtn.c
20200707 rwbl
*/
#include "io4ledbtn.h"

#include <stdio.h>

#include "../bindings/bricklet_io4_v2.h"
#include "../bindings/errors.h"

TF_IO4V2 io;
IO4_UID = "G4d";
IO4_CALLBACK_PERIOD = 100;	// in ms
IO4_TICK_TIMEOUT = 1000;	// ms

bool button_pressed = false;	// button released
bool led_state = false;			// led off

// Callback function for input value callback
// Sets the state of the button_pressed
void io4ledbtn_cb_input_value(struct TF_IO4V2 *device, uint8_t channel, bool changed, bool value, void *user_data) {
    (void)user_data; // avoid unused parameter warning
   	// If value = true, the button is pressed or released. Init with button released. Inverse led state
	if (value == true) {
		button_pressed = true;
		led_state = !led_state;
		// tf_hal_log_info("Channel: ch=%u, c=%s, v=%s", channel, changed ? "true" : "false", value ? "true" : "false");
	}
}

/*
Check if device object is created
*/
void io4ledbtn_check(int rc, char *msg) {
    if (rc >= 0)
        return;
    tf_hal_log_error("Failed to %s: %d", msg, rc);
}

/*
Setup the io4 bricklet channels & callback
Channel 0 = led = output value lowvideo
Channel 1 = push-button = input pullup
*/
void io4ledbtn_setup(TF_HalContext *hal) {
	io4ledbtn_check(tf_io4_v2_create(&io, IO4_UID, hal), "Create io4 device object");
	tf_io4_v2_set_configuration(&io, 0, 'o', false);
	tf_io4_v2_set_configuration(&io, 1, 'i', true);
    tf_io4_v2_register_input_value_callback(&io, io4ledbtn_cb_input_value, NULL);
    tf_io4_v2_set_input_value_callback_configuration(&io, 1, IO4_CALLBACK_PERIOD, true);
	tf_hal_log_info("Setup io4 done");
}

/*
Handle push-button callback ticks.
If button pressed set the led state on or off.
The button_pressed & led_state state is set in the button callback io4ledbtn_cb_input_value()
*/
void io4ledbtn_loop(TF_HalContext *hal) {
	tf_io4_v2_callback_tick(&io, IO4_TICK_TIMEOUT);
	if (button_pressed == true){
		button_pressed = false;
		int rc = tf_io4_v2_set_selected_value(&io, 0, led_state);
		if(rc != TF_E_OK)
			tf_hal_log_error("rc %d", rc);
		tf_hal_log_info("LED state=%s", led_state ? "ON" : "OFF");
	}
}

