Official support library for using mbed as a programmable coprocessor in the Innomatix DAP-III+ telematics platform
Diff: example.cpp
- Revision:
- 0:b9e1003fbee7
- Child:
- 4:fd93c4cb05df
diff -r 000000000000 -r b9e1003fbee7 example.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example.cpp Fri Apr 15 18:35:31 2016 +0000 @@ -0,0 +1,268 @@ +/******************************************************************* + * + * 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, ×tamp, &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 ); +} +