/*******************************************************************
 *
 *  File: main.cpp
 *
 *  Description: Example of using Innomatix Coprocessor Support functionality
 *
 *  Copyright 2015 Innomatix, LLC., All Rights Reserved
 *
 *  THIS DOCUMENT AND ITS CONTENTS ARE INTELLECTUAL PROPERTY
 *  OF INNOMATIX, LLC.  ANY DUPLICATION IN PART OR WHOLE
 *  WITHOUT PRIOR WRITTEN CONSENT IS STRICTLY PROHIBITED.
 *
 *******************************************************************/
#include "mbed.h"

#include "UpdateClientAPI.h"
#include "RemoteDataStoreAPI.h"
#include "InnomatixCanAPI.h"
#include "InnomatixMeta.h"

/******************************************************************************/
extern "C" void HardFault_Handler() { error("Innnomatix Coprocessor: Hard Fault!\n"); }
extern "C" void mbed_reset();
extern void DoExample( char *zVersion );



/******************************************************************************/
#define APPVERS       "1.0.7"
#define APPDESC       "Coprocessor example application"

// v1.0.7  Remove retry loop from SystemUpdate() in favor of letting the library
//              handle timeouts.  Rework the example app to be RDS-centric so
//              users do not need CAN channels wired in order to try it.
// v1.0.6  initial release
//=================================================================


/******************************************************************************/
// Create variables using the metadata macros to embed metadata the in the compiled
// application.  When the application is uploaded to the InnomatixData host,
// the host will scan the file and extract the metadata info.
const char *VersionMeta = TFVERSION( APPVERS );
char dummyV = *VersionMeta;
const char *DescriptionMeta = TFDESCRIPTION( APPDESC );
char dummyD = *DescriptionMeta;


/******************************************************************************/
// Use the LEDs to report status during system updates
DigitalOut led1( LED1 );
DigitalOut led2( LED2 );
DigitalOut led3( LED3 );
DigitalOut led4( LED4 );

/*************************************************************************/
void SystemUpdate()
{
	UpdateStatus_e eUpdateResult = statusNoUpdate;

    // Make the file system object local to the funciton so it is cleaned
    // up when we exit
	LocalFileSystem tmpfs("local");		

    led1 = 1;
    /*====================================================================*/
    // UpdateInit params are not used by the MBED implementation
    eUpdateResult = UpdateInit( "usb", 0 );
    printf( "Innomatix Update API initialization: %s\r\n", (statusSuccess == eUpdateResult ? "INITIALIZED" : "FAILED") );


    /*====================================================================*/
    if( statusSuccess == eUpdateResult )
    {
		led2 = 1;
		printf( "Innomatix Coprocessor Checking for Firmware Update\r\n" );

        // The coprocessor gets to this point much quicker than the DAP
        // gets started and launches the coprocessor update server, we'll
        // wait here until he is ready.  Timeout is in milliseconds
        eUpdateResult = PerformUpdate( 15000 );
        
        // Go ahead and close the update library here, we're done
        // with it regardless of the outcome
		led3 = 1;
        UpdateClose();


		if( statusSuccess == eUpdateResult )
        {
			led4 = 1;
            printf( "    Update performed, restarting\r\n" );
            wait_ms( 1000 );
            mbed_reset();

        }else if( statusNoConnection == eUpdateResult )
        {
            printf( "    Update failed, no remote connection\r\n" );
        }else
        {
            printf( "    Update skipped, reason: (%d)%s\r\n", eUpdateResult, UpdateStatusNames[ eUpdateResult ] );
        }
    }
    led1 = led2 = led3 = led4 = 0;
}

/*************************************************************************/
// Only need to define this so that we can change the baud rate
// Else the default baud rate on the USB console is 9600
Serial console(USBTX, USBRX);

/*************************************************************************/
int main()
{
    console.baud(115200);

    printf( "===========================================\r\n" );
    printf( "Starting Coprocessor Support Example App\r\n" );
    printf( "Built at %s on %s\r\n", __TIME__, __DATE__ );
    printf( "Version: %s\r\n", APPVERS );
    printf( "Description: %s\r\n", APPDESC );
    printf( "===========================================\r\n" );

    SystemUpdate();

    DoExample( APPVERS );

	error( "Coprocessor exited main loop, waiting for system reset\r\n" );

    return( 0 );
}
