//////////////////////////////////////////////////////////////////
//
// App:			Ports Controller Task
// Author:		Milan Korinek
// Version:		1.0
// Notice:		Control of I/O expander
//////////////////////////////////////////////////////////////////

#include "ports_controller.h"
#include "support/USB.h"

typedef struct {
	xQueueHandle control_pipe;
} ports_controller_task_param_t;

const char *const ports_controller_msg_type_str_t[] = {
	 FOREACH_ports_controller_msg_type(GENERATE_STRING)
 };

status_code_t ports_controller_init(ports_controller_handle_t * task_handle)
{
	status_code_t ret;
	portBASE_TYPE retTask;
	
	static ports_controller_task_param_t task_param = {
		.control_pipe = 0,
	};
	
	task_handle->task_handle = NULL;
	task_handle->control_pipe = 0;
	
	
	/* Initialize Atmel FreeRTOS TWI peripheral driver */
	ret = freertos_io_expander_init(TASK_PORTS_CONTROLLER_INTERRUPT_PRIORITY, TASK_PORTS_CONTROLLER_MAX_BLOCKS_TIME);
	if(ret != STATUS_OK)
	{
		return ret;
	}
	
	/* Create FreeRTOS queue for task control pipe */
	task_param.control_pipe = xQueueCreate(TASK_PORTS_CONTROLLER_CONTROL_PIPE_LEN, sizeof(ports_controller_msg_t));
	if (task_param.control_pipe == 0) {
		return ERR_NO_MEMORY;
	}
	task_handle->control_pipe = task_param.control_pipe;

	/* Create the task. */
	retTask = xTaskCreate(ports_controller_task, (const signed char *const) TASK_PORTS_CONTROLLER_NAME,
		TASK_PORTS_CONTROLLER_STACK_DEPTH_WORDS, (void *)(& task_param), TASK_PORTS_CONTROLLER_PRIORITY, &(task_handle->task_handle));
		
	if ((retTask != pdPASS) || (task_handle->task_handle == NULL))	{
		return ERR_NO_MEMORY;
	}
	
	return STATUS_OK;
}

void ports_controller_task(void *pvParameters)
{
	ports_controller_task_param_t *task_param = (ports_controller_task_param_t *)pvParameters;
	ports_controller_msg_t control_msg;
	status_code_t ret;
	
	ret = freertos_io_expander_configure();
	if (ret != STATUS_OK)
	{
		debug_error(DIO_SEVERITY_CRITICAL, "Initialization of IO Expander failed.");
		for(;;)
		{
			
		}
	}
	usb_enable();
	debug_event(DIO_SEVERITY_IMPORTANT, "Task 'Ports controller' running...");
	for(;;)	{
		if (xQueueReceive(task_param->control_pipe, (void *)(&control_msg) , portMAX_DELAY) == pdPASS) { /* Nothing to do if queue is empty */
			switch(control_msg.message){
				case PORTS_CNTR_MSG_LED_SET:
					ret = freertos_io_expander_run_led(control_msg.enable);
					break;
				case PORTS_CNTR_MSG_PWR_SET:
					ret = freertos_io_expander_ports_pwr(control_msg.enable);
					break;
				case PORTS_CNTR_MSG_DIR_SET:
					ret = freertos_io_expander_ports_dir(control_msg.devices, control_msg.settings);
					break;
				case PORTS_CNTR_MSG_PULL_RES_SET:
					ret = freertos_io_expander_ports_pull_res(control_msg.devices, control_msg.enable, control_msg.settings);
					break;
				case PORTS_CNTR_MSG_FAULT_GET:
					// For Guardian
					break;
				default:
				/* !!!!!!!!!!!!!!*/
					break;
			}
		}
	}

	/* If all is well, the following line will never be reached. */
	vTaskDelete(NULL);
}
