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, ×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 ); }