Official support library for using mbed as a programmable coprocessor in the Innomatix DAP-III+ telematics platform

example.cpp

Committer:
Innomatix
Date:
2016-04-15
Revision:
0:b9e1003fbee7
Child:
4:fd93c4cb05df

File content as of revision 0:b9e1003fbee7:

/*******************************************************************
 *
 *  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 "Timer.h"


/*-----------------------------------------------*/
#include "RemoteDataStoreAPI.h"
RdsResults_e eRDSReady = rdsGeneralError;

// Name of the data bins we'll use
char PCopVersBinName[] = "CoprocVersion";
char PCopStatusBinName[] = "CoprocStatus";

char Press1BinName[] = "LeftFrontPressure";
char Press2BinName[] = "RightFrontPressure";
char Press3BinName[] = "LeftRearPressure";
char Press4BinName[] = "RightRearPressure";

// Data bin identifiers returned from GetDataBinInfo()
unsigned int  VersBin = BinId_None;
unsigned int  StatusBin = BinId_None;

unsigned int  Press1Bin = BinId_None;
unsigned int  Press2Bin = BinId_None;
unsigned int  Press3Bin = BinId_None;
unsigned int  Press4Bin = BinId_None;

/*-----------------------------------------------*/
#include "InnomatixCanAPI.h"
CanResults_e eCan3Ready = canGeneralError;
CanResults_e eCan4Ready = canGeneralError;


/*************************************************************************/
unsigned int GetDBinInfo( const char * name )
{
    unsigned int id = BinId_None;
    RdsResults_e result = rdsNoConnection;
    BinInfoStruct_t info;

    /*-----------------------------------------------*/
    printf( "RemoteDataStore getting info for databin %s...", name );
    result = GetDataBinInfo( name, &info );
    if( rdsSuccess == result )
    {
        // we only care about the databin ID for this example
        id = info.BinId;
        printf( "SUCCESS, ID is %d\r\n", id );
    }else
    {
        printf( "FAILED (%d)\r\n", result );
    }
    return( id );
}

/*************************************************************************/
void ExampleInit()
{
    /*-----------------------------------------------*/
    // DataStoreInit params are not used by the MBED implementation
    eRDSReady = DataStoreInit( "usb", 0 );
    printf( "Innomatix RemoteDataStore API initialization: %s\r\n", (rdsSuccess == eRDSReady ? "INITIALIZED" : "FAILED") );

    if( rdsSuccess == eRDSReady )
    {
        VersBin = GetDBinInfo( PCopVersBinName );
        StatusBin = GetDBinInfo( PCopStatusBinName );

        Press1Bin = GetDBinInfo( Press1BinName );
        Press2Bin = GetDBinInfo( Press2BinName );
        Press3Bin = GetDBinInfo( Press3BinName );
        Press4Bin = GetDBinInfo( Press4BinName );
    }    

 
 
 	unsigned long can_baud = 500000;
    /*-----------------------------------------------*/
    // Params are: channel enum, baud rate
    eCan3Ready = CanInit( canChDAP3, can_baud );
    printf( "Innomatix CAN API initialization for Ch3 @ %dbps: %s\r\n", can_baud, (canSuccess == eCan3Ready ? "INITIALIZED" : "FAILED") );

    /*-----------------------------------------------*/
    eCan4Ready = CanInit( canChDAP4, can_baud );
    printf( "Innomatix CAN API initialization for Ch4 @ %dbps: %s\r\n", can_baud, (canSuccess == eCan4Ready ? "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 ExampleClose()
{
    CanClose( canChDAP3 );
    CanClose( canChDAP4 );
    DataStoreClose();
}

/*************************************************************************/
/*************************************************************************/
int DoExample( char *zVersion )
{
    char str[ 128 ] = {0};
    unsigned long count = 0;
    
	DigitalOut rxled(LED1);		// RX activity toggle
	DigitalOut rxeled(LED2);	// RX error (overrun) toggle
    DigitalOut txled(LED3);		// TX activity toggle
    DigitalOut txeled(LED4);	// TX error toggle

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

    unsigned char txbuff[ 8 ] = {0};
    unsigned short pressure = 0;
    
    Timer  TxTimer;
    

    /*-----------------------------------------------*/
    // Init the Support Library subsystems we'll use for this example
    ExampleInit();
    PutString( StatusBin, "Starting PCop Example" );
    PutString( VersBin, zVersion );


    /*-----------------------------------------------*/
    // Use the Remote DataStore's special "debug" API
    // The server will update a pre-determined data bin with the string.
    // Typically the debug data bin is shown on the diagnostic display
    // and is included in the data stream to the host.
    PutDebug( "Entering example loop" );


    /*-----------------------------------------------*/
    //
    // The coprocessor example is a CAN network bridge
    //
    // We will receive messages on CAN3 representing the air pressure in four tires.  
    // The four pressure values are published to the remote data store individually, 
    // and are combined into a single message which is transmitted on CAN4 at 1Hz
    //
    // CAN3 messages are ID 0x101, 0x102, 0x103, 0x104
    // Data in the CAN3 messages are a 2-byte value in bytes [0] and [1]
    //
    // CAN4 message is ID 0x200
    // Data in the CAN4 message are the same 2-byte values in order
    //
    
    TxTimer.start();
    while( 1 )
    {
        count++;

	    /*-----------------------------------------------*/
        // Get a message from CAN3
        canresult = CanReceive( canChDAP3, &timestamp, &msgid, (CanFormat_e *)&msgformat, msgbuff, &msglen );
        if( canSuccess == canresult )
        {
            //printf( "Got CAN message x%0x\r\n", msgid );
            rxled = !rxled;
            
            // if the message is one we are interested in
            if( 0x100 == msgid )
            {
                // Copy the 2-byte value from the rx buffer to the proper
                // location in the tx buffer
                txbuff[ 0 ] = msgbuff[ 0 ];
                txbuff[ 1 ] = msgbuff[ 1 ];

                // Assemble the 2 bytes into a 2-byte value and publish 
                // to the remote data store
                pressure = (msgbuff[ 0 ] << 8) + msgbuff[ 1 ];
                PutUnsignedInteger( Press1Bin, pressure );

            }else if( 0x101 == msgid )
            {
                txbuff[ 2 ] = msgbuff[ 0 ];
                txbuff[ 3 ] = msgbuff[ 1 ];
                pressure = (msgbuff[ 0 ] << 8) + msgbuff[ 1 ];
                PutUnsignedInteger( Press2Bin, pressure );

            }else if( 0x102 == msgid )
            {
                txbuff[ 4 ] = msgbuff[ 0 ];
                txbuff[ 5 ] = msgbuff[ 1 ];
                pressure = (msgbuff[ 0 ] << 8) + msgbuff[ 1 ];
                PutUnsignedInteger( Press3Bin, pressure );

            }else if( 0x103 == msgid )
            {
                txbuff[ 6 ] = msgbuff[ 0 ];
                txbuff[ 7 ] = msgbuff[ 1 ];
                pressure = (msgbuff[ 0 ] << 8) + msgbuff[ 1 ];
                PutUnsignedInteger( Press4Bin, pressure );
            }            
        }else if( canNoData != canresult )
        {
        	printf( "CanReceive() error %d\r\n", canresult );
        }
        
	    /*-----------------------------------------------*/
		// 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 )
		    {
				rxeled = !rxeled;		    	
				overflow = Stats.OverflowCount;
				// publish the overflow count to the RDS
				sprintf( str, "CAN3 OVF: %d", overflow );
			    PutString( StatusBin, str );
			    printf( "%s\r\n", str );
		    }
		}


        /*-----------------------------------------------*/
        // send the combined pressure message once per second
        if( TxTimer.read_ms() >= 1000 )
        {
            txled = !txled;

            canresult = CanSend( canChDAP4, 0x200, canFormatStandard, txbuff, 8 );
            if( canSuccess != canresult )
            {
                printf( "CanSend() error %d\r\n", canresult );
                txeled = !txeled;
			}

			// Also publish the loop count to the remote data store "debug" data bin
		    sprintf( str, "PCop Loop %d", count );
		    PutDebug( str );
            
			// And restart the timer at 0
            TxTimer.reset();
        }
    }

    ExampleClose();

    return( 0 );
}