/*
 * api_debug.c
 *
 *  Created on: Jul 7, 2011
 *      Author: Peter Zumbruch, GSI, P.Zumbruch@gsi.de
 */

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <stddef.h>
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/iocan128.h>
#include <avr/iocanxx.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>

#include "api.h"
#include "api_define.h"
#include "api_global.h"
#include "api_constants.h"
#include "api_debug.h"
#include "api_show.h"
#include "api_help.h"

static const char debugLevelName00[] PROGMEM = "          noDebug";
static const char debugLevelName01[] PROGMEM = "     verboseDebug";
static const char debugLevelName02[] PROGMEM = "       eventDebug";
static const char debugLevelName03[] PROGMEM = "eventDebugVerbose";
static const char debugLevelName04[] PROGMEM = "    periodicDebug";

const char *debugLevelNames[] PROGMEM = {
         debugLevelName00,
         debugLevelName01,
         debugLevelName02,
         debugLevelName03,
         debugLevelName04
};

static const char debugSystemName00[] PROGMEM = "             Main";
static const char debugSystemName01[] PROGMEM = "              Api";
static const char debugSystemName02[] PROGMEM = "          ApiMisc";
static const char debugSystemName03[] PROGMEM = "             UART";
static const char debugSystemName04[] PROGMEM = "              CAN";
static const char debugSystemName05[] PROGMEM = "       GETVOLTAGE";
static const char debugSystemName06[] PROGMEM = "            RELAY";
static const char debugSystemName07[] PROGMEM = "       CommandKey";
static const char debugSystemName08[] PROGMEM = "              OWI";
static const char debugSystemName09[] PROGMEM = "  OWITemperatures";
static const char debugSystemName10[] PROGMEM = "          Decrypt";
static const char debugSystemName11[] PROGMEM = "            DEBUG";
static const char debugSystemName12[] PROGMEM = "           OWIADC";
static const char debugSystemName13[] PROGMEM = "  OWIDualSwitches";
static const char debugSystemName14[] PROGMEM = "OWISingleSwitches";
static const char debugSystemName15[] PROGMEM = " OWIOctalSwitches";
static const char debugSystemName16[] PROGMEM = "             SHOW";
static const char debugSystemName17[] PROGMEM = "   OWIApiSettings";
static const char debugSystemName18[] PROGMEM = "           TIMER0";
static const char debugSystemName19[] PROGMEM = "           TIMER1";
static const char debugSystemName20[] PROGMEM = "          TIMER0A";
static const char debugSystemName21[] PROGMEM = " TIMER0AScheduler";

const char *debugSystemNames[] PROGMEM =
{
   debugSystemName00,
   debugSystemName01,
   debugSystemName02,
   debugSystemName03,
   debugSystemName04,
   debugSystemName05,
   debugSystemName06,
   debugSystemName07,
   debugSystemName08,
   debugSystemName09,
   debugSystemName10,
   debugSystemName11,
   debugSystemName12,
   debugSystemName13,
   debugSystemName14,
   debugSystemName15,
   debugSystemName16,
   debugSystemName17,
   debugSystemName18,
   debugSystemName19,
   debugSystemName20,
   debugSystemName21
};

void readModifyDebugLevelAndMask(struct uartStruct *ptr_uartStruct)
{
	/* command : DEBG [level [mask]]
	 * set response: ...
	 * get response: RECV DEBG level mask*/

	/*TODO: change CAN naming to more general */

	switch (ptr_uartStruct->number_of_arguments)
	{
	case 0: /*read*/
		snprintf_P(uart_message_string, BUFFER_SIZE - 1, PSTR("RECV DEBG %i %lx"), debug, debugMask);
		UART0_Send_Message_String(NULL,0);
		break;
	case 1: /*write debug*/
		if ( 0xFF < ptr_uartStruct->Uart_Message_ID )
		{
			CommunicationError(ERRA, SERIAL_ERROR_arguments_exceed_boundaries, 0, NULL, 0);
			return;
		}
		debug = (uint8_t) (ptr_uartStruct->Uart_Message_ID & 0xFF);
		break;
	default:
		if ( 0xFFFF < ptr_uartStruct->Uart_Mask )
		{
			CommunicationError(ERRA, SERIAL_ERROR_mask_is_too_long, 0, NULL, 0);
			return;
		}
		debugMask = (uint32_t) (ptr_uartStruct->Uart_Mask & 0xFFFFFFFF);
		break;
	}

	if ( verboseDebug <= debug && ((debugMask >> debugDEBUG) & 1))
	{
		if ( 0 < ptr_uartStruct->number_of_arguments)
		{
			ptr_uartStruct->number_of_arguments = 0;
			readModifyDebugLevelAndMask(ptr_uartStruct);
		}
	}
}

void readModifyDebugLevel(struct uartStruct *ptr_uartStruct)
{
	/* command : DBGL [level [mask]]
	 * set response: ...
	 * get response: RECV DBGL level*/

	/*TODO: change CAN naming to more general */

	switch (ptr_uartStruct->number_of_arguments)
	{
	case 0: /*read*/
		snprintf_P(uart_message_string, BUFFER_SIZE - 1, PSTR("RECV DBGL %x"), debug);
		UART0_Send_Message_String(NULL,0);
		break;
	default: /*write debug*/
		if ( 0xFF < ptr_uartStruct->Uart_Message_ID )
		{
			CommunicationError(ERRA, SERIAL_ERROR_arguments_exceed_boundaries, 0, NULL, 0);
			return;
		}
		debug = (uint8_t) (ptr_uartStruct->Uart_Message_ID & 0xFF);
		break;
	}

	if ( verboseDebug <= debug && ( ( debugMask >> debugDEBUG ) & 0x1 ) )
	{
		if ( 0 < ptr_uartStruct->number_of_arguments)
		{
			ptr_uartStruct->number_of_arguments = 0;
			readModifyDebugLevel(ptr_uartStruct);
		}
	}
}

void readModifyDebugMask(struct uartStruct *ptr_uartStruct)
{
	/* command : DBGM [level [mask]]
	 * set response: ...
	 * get response: RECV DBGM level*/

	/*TODO: change CAN naming to more general */
	switch (ptr_uartStruct->number_of_arguments)
	{
	case 0: /*read*/
		snprintf_P(uart_message_string, BUFFER_SIZE - 1, PSTR("RECV DBGM 0x%x"), debugMask);
		UART0_Send_Message_String(NULL,0);
		break;
	default: /*write debug*/
		if ( 0xFF < ptr_uartStruct->Uart_Message_ID )
		{
			CommunicationError(ERRA, SERIAL_ERROR_mask_is_too_long, 0, NULL, 0);
			return;
		}
		debugMask = (uint32_t) (ptr_uartStruct->Uart_Message_ID & 0xFFFFFFFF);
		break;
	}

	if ( verboseDebug <= debug && ((debugMask >> debugDEBUG) & 1))
	{
		if ( 0 < ptr_uartStruct->number_of_arguments)
		{
			ptr_uartStruct->number_of_arguments = 0;
			readModifyDebugMask(ptr_uartStruct);
		}
	}
}



