/*
 * gs_puppet_master.c
 *
 * Created: 3/9/2018 11:02:32 PM
 *  Author: adnew
 */ 

#include <asf.h>
#include <stdio.h>
#include <string.h>
#include "gs_puppet_master.h"

void usart_read_callback(struct usart_module *const usart_module);
void usart_write_callback(struct usart_module *const usart_module);

void configure_usart(void);
void configure_usart_callbacks(void);

struct usart_module usart_instance;

#define MAX_RX_BUFFER_LENGTH   2

char newline = '\n';

volatile uint8_t rx_buffer[MAX_RX_BUFFER_LENGTH];

volatile int rf_switch_state = sdr_a;
volatile int amp_state = amp_rx;
volatile int curr_command = rx;

void usart_read_callback(struct usart_module *const usart_module)
{
	//usart_write_buffer_job(&usart_instance, (uint8_t *)rx_buffer, MAX_RX_BUFFER_LENGTH);
	read_command();
}

void usart_write_callback(struct usart_module *const usart_module)
{
	port_pin_toggle_output_level(LED_0_PIN);
}

void configure_usart(void)
{
	struct usart_config config_usart;
	usart_get_config_defaults(&config_usart);

	config_usart.baudrate    = 115200;
	config_usart.mux_setting = EDBG_CDC_SERCOM_MUX_SETTING;
	config_usart.pinmux_pad0 = EDBG_CDC_SERCOM_PINMUX_PAD0;
	config_usart.pinmux_pad1 = EDBG_CDC_SERCOM_PINMUX_PAD1;
	config_usart.pinmux_pad2 = EDBG_CDC_SERCOM_PINMUX_PAD2;
	config_usart.pinmux_pad3 = EDBG_CDC_SERCOM_PINMUX_PAD3;

	while (usart_init(&usart_instance,
			EDBG_CDC_MODULE, &config_usart) != STATUS_OK) {
	}

	usart_enable(&usart_instance);
}

void configure_usart_callbacks(void)
{
	usart_register_callback(&usart_instance,
			usart_write_callback, USART_CALLBACK_BUFFER_TRANSMITTED);
	usart_register_callback(&usart_instance,
			usart_read_callback, USART_CALLBACK_BUFFER_RECEIVED);

	usart_enable_callback(&usart_instance, USART_CALLBACK_BUFFER_TRANSMITTED);
	usart_enable_callback(&usart_instance, USART_CALLBACK_BUFFER_RECEIVED);
}

void read_command(void) {
	for(volatile uint8_t i=0; i < sizeof(command_strs)-1; i++) {
		if(strcmp) {
			//usart_write_buffer_wait(&usart_instance, amp_state_strs[amp_state], sizeof(amp_state_strs[amp_state])+2);
			curr_command = i;
			*rx_buffer = 0;
			return;
		}
	}
}

void send_status(void) {
	usart_write_buffer_wait(&usart_instance, rf_switch_strs[rf_switch_state], sizeof(rf_switch_strs[rf_switch_state])+1);
	usart_write_buffer_wait(&usart_instance, amp_state_strs[amp_state], sizeof(amp_state_strs[amp_state])+2);
	curr_command = wt;
}

void run_command(void) {
	switch(curr_command) {
		case tx:
			port_pin_set_output_level(LED_0_PIN, 1);
			amp_state = tx;
			curr_command = wt;
			break;
		case rx:
			port_pin_set_output_level(LED_0_PIN, 0);
			amp_state = rx;
			curr_command = wt;
			break;
		case st:
			send_status();
			curr_command = wt;
			break;
		case ra:
			rf_switch_state = sdr_a;
			curr_command = wt;
			break;
		case rb:
			rf_switch_state = sdr_b;
			curr_command = wt;
			break;
		default:
			break;			
	}
}

int main(void)
{
	system_init();

	configure_usart();
	configure_usart_callbacks();

	system_interrupt_enable_global();

	//uint8_t string[] = "Hello World!\r\n";
	//usart_write_buffer_wait(&usart_instance, string, sizeof(string));
	while (true) {
		usart_read_buffer_job(&usart_instance, (uint8_t *)rx_buffer, MAX_RX_BUFFER_LENGTH);
		run_command();
	}
}