/*******************************************************************
 *
 *  File: can_example.cpp
 *
 *  Copyright 2017 Innomatix, LLC, All Rights Reserved
 *
 *  Example of using the Innomatix CAN API for mbed
 *
 *******************************************************************/
#include "InnomatixCanAPI.h"

// Create the CAN objects per "the mbed way"
CAN can0( p9, p10 );
CAN can1( p30, p29 );


/******************************************************************************/
void CanExampleOpen()
{
    CanResults_e canresult;
 	unsigned long can_baud = 500000;

    /*-----------------------------------------------*/
    // Initialize the CAN library
    CanInit( &can0, &can1 );

    /*-----------------------------------------------*/
    // Open the CAN channels at the specified baud rate
    canresult = CanOpen( canChDAP3, can_baud );
    // Have to manually attache the Rx event handler
    can0.attach( OnReceiveCanZero );
    printf( "Innomatix CAN API initialization for Ch3 @ %dbps: %s\r\n", can_baud, (canSuccess == canresult ? "INITIALIZED" : "FAILED") );

    /*-----------------------------------------------*/
    canresult = CanOpen( canChDAP4, can_baud );
    can1.attach( OnReceiveCanOne );
    printf( "Innomatix CAN API initialization for Ch4 @ %dbps: %s\r\n", can_baud, (canSuccess == canresult ? "INITIALIZED" : "FAILED") );

    /*-----------------------------------------------*/
    // Pause a moment to let all the CAN init stuff take effect, else
    // sometimes we dont receive the first message on the bus
    wait_ms( 100 );
}




/******************************************************************************/
void CanExampleClose()
{
    // Close the channels and clean up the library
    CanClose( canChDAP3 );
    CanClose( canChDAP4 );
}



/******************************************************************************/
void CanExampleMain()
{
    CanResults_e canresult;
    unsigned long msgid;
    char msglen;
    unsigned char msgbuff[ 8 ] = {0};
    CanFormat_e msgformat;
	unsigned long timestamp;


    /*-----------------------------------------------*/
    // Get a message from CAN3
    canresult = CanReceive( canChDAP3, &timestamp, &msgid, (CanFormat_e *)&msgformat, msgbuff, &msglen );
    if( canSuccess == canresult )
    {
        // Check msgid to see if we're interested in this message
        if( 0x100 == msgid )
        {
            // get some data from the message
            unsigned short val = 0;
            val += msgbuff[0] << 8;
            val += msgbuff[1];

            //TODO do something with the value....

    }else if( canNoData != canresult )
    {
        // No CAN message available
    }else
    {
        // Something went wrong, check InnomatixCanAPI.h for result codes
    }



    /*-----------------------------------------------*/
	// detect receive overruns - this means CAN messages are arrving faster
	// than the application is reading them via CanReceive()
    {
    	static unsigned long overflow = 0;
	    StatisticsStruct_t Stats;

		// Check if there are more overrun errors this time than last time
	    CanStatistics( canChDAP3, &Stats );
	    if( Stats.OverflowCount > 0 && Stats.OverflowCount != overflow )
	    {
            // save the new overflow count so we can tell if it changes next time
			overflow = Stats.OverflowCount;

			// publish the overflow count to a data bin
			sprintf( str, "CAN3 OVF: %d", overflow );
		    PutString( StatusBin, str );
	    }
	}



    /*-----------------------------------------------*/
    // Send a message on CAN4
    memset( msgbuff, 0x00, sizeof(txbuff) );
    msgbuff[ 0 ] = 0xF0;
    msgbuff[ 1 ] = 0x0D;
    canresult = CanSend( canChDAP4, 0x200, canFormatStandard, msgbuff, 8 );
    if( canSuccess == canresult )
    {
        // success
    }else
    {
        // fail - check InnomatixCanAPI.h for result codes
	}
}


