/*****************************************************************************
 * FILE: lejos_c_interface.c
 *
 * COPYRIGHT 2007 Takashi Chikamasa <takashic@cybernet.co.jp>
 *
 * DESCRIPTION:
 *   This is a glue code to execute Embedded Coder Robot NXT generated code
 *   by using LEJOS NXJ and TOPPERS OSEK. 
 *
 *   <About LEJOS NXJ>
 *    LEJOS NXJ is a full firmware replacement of LEGO Mindstorms NXT and 
 *   designed for Java programming environment for the NXT 
 *   ( For more detailed information, please see: http://lejos.sourceforge.net/ )
 *   In the LEJOS NXJ distribution, C source files for NXT platform layer is also
 *   included besides with the Java VM. The platform C source code is well
 *   structured, comprehensive, and achieved higher performance than the LEGO's
 *   one. Therefore, LEJOS NXJ (platform) is also the best GCC based C/C++  
 *   development platform for NXT.
 *
 *   The contents of this file are subject to the Mozilla Public License
 *   Version 1.0 (the "License"); you may not use this file except in
 *   compliance with the License. You may obtain a copy of the License at
 *   http://www.mozilla.org/MPL/
 *
 *   Software distributed under the License is distributed on an "AS IS"
 *   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 *   License for the specific language governing rights and limitations
 *   under the License.
 *
 *   The Original Code is TinyVM code, first released March 6, 2000,
 *   later released as leJOS on September 23, 2000.
 *
 *   The Initial Developer of the Original Code is Jose H. Solorzano.
 *
 *   Contributor(s): see LEJOS NXJ ACKNOWLEDGEMENTS .
 *
 *****************************************************************************/

/* LEJOS NXJ platform C */
#include "mytypes.h"
#include "interrupts.h"
#include "aic.h"
#include "AT91SAM7.h"
#include "uart.h"
#include "systick.h"
#include "nxt_avr.h"
#include "twi.h"
#include "platform_hooks.h"
#include "nxt_avr.h"
#include "nxt_lcd.h"
#include "nxt_motors.h"
#include "sensors.h"
#include "display.h"
#include "i2c.h"

/* ECRobot NXT */
#include "ecrobot_interface.h"
#include "ecrobot_image1.txt"
#include "ecrobot_image2.txt"
#include "ecrobot_image2_bt.txt"


/*==============================================================================
 * LEJOS C private functions
 *=============================================================================*/
static void show_ecrobot_splash(void)
{
	display_clear(0);
	display_bitmap_copy(ecrobot_image1, 100, 8, 0, 0);
	display_update();
}


static void show_ecrobot_instruction(U8 bt_status)
{
	display_clear(0);
	if (bt_status == BLUETOOTH_CONNECTED)
	{
		display_bitmap_copy(ecrobot_image2_bt, 100, 8, 0, 0);
	}
	else
	{
		display_bitmap_copy(ecrobot_image2, 100, 8, 0, 0);
	}
	display_update();
}

/*==============================================================================
 * LEJOS C main function
 *=============================================================================*/
int main(void)
{
	register int st;
	int last_nxtstate_time = 0;
	int last_monitor_time = 0;
	U32 event_state = 0;
	 U8 device_status_old;
	 U8 state = ECROBOT_WAIT;

	/* When we get here:
	 * PLL and flash have been initialised and
	 * interrupts are off, but the AIC has not been initialised.
	 */
	aic_initialise();
	interrupts_enable();
	systick_init();
	nxt_avr_init();
	display_init();
	nxt_motor_init();
	i2c_init();
	init_sensors();

	/* show initial screen */
	systick_wait_ms(100);
	show_ecrobot_splash();
	systick_wait_ms(3000);
	
	gDevice_status = DEVICE_NO_INIT;
	while(1)
	{
		st = systick_get_ms();
		if (st >= last_nxtstate_time + 10)
		{
			/* polling buttons and battery every 10ms */
			ecrobot_poll_nxtstate();
			last_nxtstate_time = st;
		}

		switch(state)
		{
			case ECROBOT_WAIT:
				/* initialize ECRobot used devices
				 * inside of init function, low level 
				 * initializations are done only first time.
				 */
				ecrobot_device_initialize();
				if (gDevice_status == DEVICE_NO_INIT)
				{
					show_ecrobot_instruction(0);
					gDevice_status = DEVICE_INITIALIZED;
				}
				else if (gDevice_status == BLUETOOTH_CONNECTED &&
					device_status_old != BLUETOOTH_CONNECTED)
				{
					show_ecrobot_instruction(BLUETOOTH_CONNECTED);
				}

	    		/* Check for RUN pressed */
				if (ecrobot_get_button_state() == RUN_PRESSED)
				{
					nxt_motor_set_count(NXT_PORT_A, 0);
					nxt_motor_set_count(NXT_PORT_B, 0);
					nxt_motor_set_count(NXT_PORT_C, 0);
					event_state |= INIT_EVENT; /* set init event flag */
					state = ECROBOT_RUN;
				}
				/* Check for EXIT pressed */
				else if (ecrobot_get_button_state() == EXIT_PRESSED)
				{
					state = ECROBOT_EXIT;
				}
				break;

			case ECROBOT_RUN:
	    		/* Check for STOP pressed */
				if (ecrobot_get_button_state() == STOP_PRESSED)
				{
					nxt_motor_set_speed(NXT_PORT_A, 0, 1);
					nxt_motor_set_speed(NXT_PORT_B, 0, 1);
					nxt_motor_set_speed(NXT_PORT_C, 0, 1);
					gDevice_status = DEVICE_NO_INIT;
					state = ECROBOT_WAIT;
				}
				else
				{ 
					/* Run RTW-EC generated functions */
					ecrobot_main(&event_state);

					st = systick_get_ms();
					/* update monitor every 500ms */
					if (st >= last_monitor_time + 500) {
						last_monitor_time = st;
						ecrobot_status_monitor();
		  			}
				}
				break;

			case ECROBOT_EXIT:
				/* Terminate ECRobot used devices */
				ecrobot_device_terminate();
				display_clear(1);

				while (1)
				{
					/* Send command to AVR to sleep ARM */
					nxt_avr_power_down();
				}
				break;

			default:
				/* Do nothing */
				;
		}
		device_status_old = gDevice_status;
	}
	/* never reached here */
	return 0;
}
