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

Committer:
Innomatix
Date:
Fri Apr 15 18:35:31 2016 +0000
Revision:
0:b9e1003fbee7
Child:
4:fd93c4cb05df
v1.0.2 Rework to use USB for comms, rework example, add user guides

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Innomatix 0:b9e1003fbee7 1 /*******************************************************************
Innomatix 0:b9e1003fbee7 2 *
Innomatix 0:b9e1003fbee7 3 * File: main.cpp
Innomatix 0:b9e1003fbee7 4 *
Innomatix 0:b9e1003fbee7 5 * Description: Example of using Innomatix Coprocessor Support functionality
Innomatix 0:b9e1003fbee7 6 *
Innomatix 0:b9e1003fbee7 7 * Copyright 2015 Innomatix, LLC., All Rights Reserved
Innomatix 0:b9e1003fbee7 8 *
Innomatix 0:b9e1003fbee7 9 * THIS DOCUMENT AND ITS CONTENTS ARE INTELLECTUAL PROPERTY
Innomatix 0:b9e1003fbee7 10 * OF INNOMATIX, LLC. ANY DUPLICATION IN PART OR WHOLE
Innomatix 0:b9e1003fbee7 11 * WITHOUT PRIOR WRITTEN CONSENT IS STRICTLY PROHIBITED.
Innomatix 0:b9e1003fbee7 12 *
Innomatix 0:b9e1003fbee7 13 *******************************************************************/
Innomatix 0:b9e1003fbee7 14 #include "mbed.h"
Innomatix 0:b9e1003fbee7 15 #include "Timer.h"
Innomatix 0:b9e1003fbee7 16
Innomatix 0:b9e1003fbee7 17
Innomatix 0:b9e1003fbee7 18 /*-----------------------------------------------*/
Innomatix 0:b9e1003fbee7 19 #include "RemoteDataStoreAPI.h"
Innomatix 0:b9e1003fbee7 20 RdsResults_e eRDSReady = rdsGeneralError;
Innomatix 0:b9e1003fbee7 21
Innomatix 0:b9e1003fbee7 22 // Name of the data bins we'll use
Innomatix 0:b9e1003fbee7 23 char PCopVersBinName[] = "CoprocVersion";
Innomatix 0:b9e1003fbee7 24 char PCopStatusBinName[] = "CoprocStatus";
Innomatix 0:b9e1003fbee7 25
Innomatix 0:b9e1003fbee7 26 char Press1BinName[] = "LeftFrontPressure";
Innomatix 0:b9e1003fbee7 27 char Press2BinName[] = "RightFrontPressure";
Innomatix 0:b9e1003fbee7 28 char Press3BinName[] = "LeftRearPressure";
Innomatix 0:b9e1003fbee7 29 char Press4BinName[] = "RightRearPressure";
Innomatix 0:b9e1003fbee7 30
Innomatix 0:b9e1003fbee7 31 // Data bin identifiers returned from GetDataBinInfo()
Innomatix 0:b9e1003fbee7 32 unsigned int VersBin = BinId_None;
Innomatix 0:b9e1003fbee7 33 unsigned int StatusBin = BinId_None;
Innomatix 0:b9e1003fbee7 34
Innomatix 0:b9e1003fbee7 35 unsigned int Press1Bin = BinId_None;
Innomatix 0:b9e1003fbee7 36 unsigned int Press2Bin = BinId_None;
Innomatix 0:b9e1003fbee7 37 unsigned int Press3Bin = BinId_None;
Innomatix 0:b9e1003fbee7 38 unsigned int Press4Bin = BinId_None;
Innomatix 0:b9e1003fbee7 39
Innomatix 0:b9e1003fbee7 40 /*-----------------------------------------------*/
Innomatix 0:b9e1003fbee7 41 #include "InnomatixCanAPI.h"
Innomatix 0:b9e1003fbee7 42 CanResults_e eCan3Ready = canGeneralError;
Innomatix 0:b9e1003fbee7 43 CanResults_e eCan4Ready = canGeneralError;
Innomatix 0:b9e1003fbee7 44
Innomatix 0:b9e1003fbee7 45
Innomatix 0:b9e1003fbee7 46 /*************************************************************************/
Innomatix 0:b9e1003fbee7 47 unsigned int GetDBinInfo( const char * name )
Innomatix 0:b9e1003fbee7 48 {
Innomatix 0:b9e1003fbee7 49 unsigned int id = BinId_None;
Innomatix 0:b9e1003fbee7 50 RdsResults_e result = rdsNoConnection;
Innomatix 0:b9e1003fbee7 51 BinInfoStruct_t info;
Innomatix 0:b9e1003fbee7 52
Innomatix 0:b9e1003fbee7 53 /*-----------------------------------------------*/
Innomatix 0:b9e1003fbee7 54 printf( "RemoteDataStore getting info for databin %s...", name );
Innomatix 0:b9e1003fbee7 55 result = GetDataBinInfo( name, &info );
Innomatix 0:b9e1003fbee7 56 if( rdsSuccess == result )
Innomatix 0:b9e1003fbee7 57 {
Innomatix 0:b9e1003fbee7 58 // we only care about the databin ID for this example
Innomatix 0:b9e1003fbee7 59 id = info.BinId;
Innomatix 0:b9e1003fbee7 60 printf( "SUCCESS, ID is %d\r\n", id );
Innomatix 0:b9e1003fbee7 61 }else
Innomatix 0:b9e1003fbee7 62 {
Innomatix 0:b9e1003fbee7 63 printf( "FAILED (%d)\r\n", result );
Innomatix 0:b9e1003fbee7 64 }
Innomatix 0:b9e1003fbee7 65 return( id );
Innomatix 0:b9e1003fbee7 66 }
Innomatix 0:b9e1003fbee7 67
Innomatix 0:b9e1003fbee7 68 /*************************************************************************/
Innomatix 0:b9e1003fbee7 69 void ExampleInit()
Innomatix 0:b9e1003fbee7 70 {
Innomatix 0:b9e1003fbee7 71 /*-----------------------------------------------*/
Innomatix 0:b9e1003fbee7 72 // DataStoreInit params are not used by the MBED implementation
Innomatix 0:b9e1003fbee7 73 eRDSReady = DataStoreInit( "usb", 0 );
Innomatix 0:b9e1003fbee7 74 printf( "Innomatix RemoteDataStore API initialization: %s\r\n", (rdsSuccess == eRDSReady ? "INITIALIZED" : "FAILED") );
Innomatix 0:b9e1003fbee7 75
Innomatix 0:b9e1003fbee7 76 if( rdsSuccess == eRDSReady )
Innomatix 0:b9e1003fbee7 77 {
Innomatix 0:b9e1003fbee7 78 VersBin = GetDBinInfo( PCopVersBinName );
Innomatix 0:b9e1003fbee7 79 StatusBin = GetDBinInfo( PCopStatusBinName );
Innomatix 0:b9e1003fbee7 80
Innomatix 0:b9e1003fbee7 81 Press1Bin = GetDBinInfo( Press1BinName );
Innomatix 0:b9e1003fbee7 82 Press2Bin = GetDBinInfo( Press2BinName );
Innomatix 0:b9e1003fbee7 83 Press3Bin = GetDBinInfo( Press3BinName );
Innomatix 0:b9e1003fbee7 84 Press4Bin = GetDBinInfo( Press4BinName );
Innomatix 0:b9e1003fbee7 85 }
Innomatix 0:b9e1003fbee7 86
Innomatix 0:b9e1003fbee7 87
Innomatix 0:b9e1003fbee7 88
Innomatix 0:b9e1003fbee7 89 unsigned long can_baud = 500000;
Innomatix 0:b9e1003fbee7 90 /*-----------------------------------------------*/
Innomatix 0:b9e1003fbee7 91 // Params are: channel enum, baud rate
Innomatix 0:b9e1003fbee7 92 eCan3Ready = CanInit( canChDAP3, can_baud );
Innomatix 0:b9e1003fbee7 93 printf( "Innomatix CAN API initialization for Ch3 @ %dbps: %s\r\n", can_baud, (canSuccess == eCan3Ready ? "INITIALIZED" : "FAILED") );
Innomatix 0:b9e1003fbee7 94
Innomatix 0:b9e1003fbee7 95 /*-----------------------------------------------*/
Innomatix 0:b9e1003fbee7 96 eCan4Ready = CanInit( canChDAP4, can_baud );
Innomatix 0:b9e1003fbee7 97 printf( "Innomatix CAN API initialization for Ch4 @ %dbps: %s\r\n", can_baud, (canSuccess == eCan4Ready ? "INITIALIZED" : "FAILED") );
Innomatix 0:b9e1003fbee7 98
Innomatix 0:b9e1003fbee7 99 // Pause a moment to let all the CAN init stuff take effect, else
Innomatix 0:b9e1003fbee7 100 // sometimes we dont receive the first message on the bus
Innomatix 0:b9e1003fbee7 101 wait_ms( 100 );
Innomatix 0:b9e1003fbee7 102
Innomatix 0:b9e1003fbee7 103 }
Innomatix 0:b9e1003fbee7 104 /*************************************************************************/
Innomatix 0:b9e1003fbee7 105 void ExampleClose()
Innomatix 0:b9e1003fbee7 106 {
Innomatix 0:b9e1003fbee7 107 CanClose( canChDAP3 );
Innomatix 0:b9e1003fbee7 108 CanClose( canChDAP4 );
Innomatix 0:b9e1003fbee7 109 DataStoreClose();
Innomatix 0:b9e1003fbee7 110 }
Innomatix 0:b9e1003fbee7 111
Innomatix 0:b9e1003fbee7 112 /*************************************************************************/
Innomatix 0:b9e1003fbee7 113 /*************************************************************************/
Innomatix 0:b9e1003fbee7 114 int DoExample( char *zVersion )
Innomatix 0:b9e1003fbee7 115 {
Innomatix 0:b9e1003fbee7 116 char str[ 128 ] = {0};
Innomatix 0:b9e1003fbee7 117 unsigned long count = 0;
Innomatix 0:b9e1003fbee7 118
Innomatix 0:b9e1003fbee7 119 DigitalOut rxled(LED1); // RX activity toggle
Innomatix 0:b9e1003fbee7 120 DigitalOut rxeled(LED2); // RX error (overrun) toggle
Innomatix 0:b9e1003fbee7 121 DigitalOut txled(LED3); // TX activity toggle
Innomatix 0:b9e1003fbee7 122 DigitalOut txeled(LED4); // TX error toggle
Innomatix 0:b9e1003fbee7 123
Innomatix 0:b9e1003fbee7 124
Innomatix 0:b9e1003fbee7 125 /*-----------------------------------------------*/
Innomatix 0:b9e1003fbee7 126 CanResults_e canresult;
Innomatix 0:b9e1003fbee7 127 unsigned char msgbuff[ 8 ] = {0};
Innomatix 0:b9e1003fbee7 128 unsigned long msgid;
Innomatix 0:b9e1003fbee7 129 char msglen;
Innomatix 0:b9e1003fbee7 130 CanFormat_e msgformat;
Innomatix 0:b9e1003fbee7 131 unsigned long timestamp;
Innomatix 0:b9e1003fbee7 132
Innomatix 0:b9e1003fbee7 133 unsigned char txbuff[ 8 ] = {0};
Innomatix 0:b9e1003fbee7 134 unsigned short pressure = 0;
Innomatix 0:b9e1003fbee7 135
Innomatix 0:b9e1003fbee7 136 Timer TxTimer;
Innomatix 0:b9e1003fbee7 137
Innomatix 0:b9e1003fbee7 138
Innomatix 0:b9e1003fbee7 139 /*-----------------------------------------------*/
Innomatix 0:b9e1003fbee7 140 // Init the Support Library subsystems we'll use for this example
Innomatix 0:b9e1003fbee7 141 ExampleInit();
Innomatix 0:b9e1003fbee7 142 PutString( StatusBin, "Starting PCop Example" );
Innomatix 0:b9e1003fbee7 143 PutString( VersBin, zVersion );
Innomatix 0:b9e1003fbee7 144
Innomatix 0:b9e1003fbee7 145
Innomatix 0:b9e1003fbee7 146 /*-----------------------------------------------*/
Innomatix 0:b9e1003fbee7 147 // Use the Remote DataStore's special "debug" API
Innomatix 0:b9e1003fbee7 148 // The server will update a pre-determined data bin with the string.
Innomatix 0:b9e1003fbee7 149 // Typically the debug data bin is shown on the diagnostic display
Innomatix 0:b9e1003fbee7 150 // and is included in the data stream to the host.
Innomatix 0:b9e1003fbee7 151 PutDebug( "Entering example loop" );
Innomatix 0:b9e1003fbee7 152
Innomatix 0:b9e1003fbee7 153
Innomatix 0:b9e1003fbee7 154 /*-----------------------------------------------*/
Innomatix 0:b9e1003fbee7 155 //
Innomatix 0:b9e1003fbee7 156 // The coprocessor example is a CAN network bridge
Innomatix 0:b9e1003fbee7 157 //
Innomatix 0:b9e1003fbee7 158 // We will receive messages on CAN3 representing the air pressure in four tires.
Innomatix 0:b9e1003fbee7 159 // The four pressure values are published to the remote data store individually,
Innomatix 0:b9e1003fbee7 160 // and are combined into a single message which is transmitted on CAN4 at 1Hz
Innomatix 0:b9e1003fbee7 161 //
Innomatix 0:b9e1003fbee7 162 // CAN3 messages are ID 0x101, 0x102, 0x103, 0x104
Innomatix 0:b9e1003fbee7 163 // Data in the CAN3 messages are a 2-byte value in bytes [0] and [1]
Innomatix 0:b9e1003fbee7 164 //
Innomatix 0:b9e1003fbee7 165 // CAN4 message is ID 0x200
Innomatix 0:b9e1003fbee7 166 // Data in the CAN4 message are the same 2-byte values in order
Innomatix 0:b9e1003fbee7 167 //
Innomatix 0:b9e1003fbee7 168
Innomatix 0:b9e1003fbee7 169 TxTimer.start();
Innomatix 0:b9e1003fbee7 170 while( 1 )
Innomatix 0:b9e1003fbee7 171 {
Innomatix 0:b9e1003fbee7 172 count++;
Innomatix 0:b9e1003fbee7 173
Innomatix 0:b9e1003fbee7 174 /*-----------------------------------------------*/
Innomatix 0:b9e1003fbee7 175 // Get a message from CAN3
Innomatix 0:b9e1003fbee7 176 canresult = CanReceive( canChDAP3, &timestamp, &msgid, (CanFormat_e *)&msgformat, msgbuff, &msglen );
Innomatix 0:b9e1003fbee7 177 if( canSuccess == canresult )
Innomatix 0:b9e1003fbee7 178 {
Innomatix 0:b9e1003fbee7 179 //printf( "Got CAN message x%0x\r\n", msgid );
Innomatix 0:b9e1003fbee7 180 rxled = !rxled;
Innomatix 0:b9e1003fbee7 181
Innomatix 0:b9e1003fbee7 182 // if the message is one we are interested in
Innomatix 0:b9e1003fbee7 183 if( 0x100 == msgid )
Innomatix 0:b9e1003fbee7 184 {
Innomatix 0:b9e1003fbee7 185 // Copy the 2-byte value from the rx buffer to the proper
Innomatix 0:b9e1003fbee7 186 // location in the tx buffer
Innomatix 0:b9e1003fbee7 187 txbuff[ 0 ] = msgbuff[ 0 ];
Innomatix 0:b9e1003fbee7 188 txbuff[ 1 ] = msgbuff[ 1 ];
Innomatix 0:b9e1003fbee7 189
Innomatix 0:b9e1003fbee7 190 // Assemble the 2 bytes into a 2-byte value and publish
Innomatix 0:b9e1003fbee7 191 // to the remote data store
Innomatix 0:b9e1003fbee7 192 pressure = (msgbuff[ 0 ] << 8) + msgbuff[ 1 ];
Innomatix 0:b9e1003fbee7 193 PutUnsignedInteger( Press1Bin, pressure );
Innomatix 0:b9e1003fbee7 194
Innomatix 0:b9e1003fbee7 195 }else if( 0x101 == msgid )
Innomatix 0:b9e1003fbee7 196 {
Innomatix 0:b9e1003fbee7 197 txbuff[ 2 ] = msgbuff[ 0 ];
Innomatix 0:b9e1003fbee7 198 txbuff[ 3 ] = msgbuff[ 1 ];
Innomatix 0:b9e1003fbee7 199 pressure = (msgbuff[ 0 ] << 8) + msgbuff[ 1 ];
Innomatix 0:b9e1003fbee7 200 PutUnsignedInteger( Press2Bin, pressure );
Innomatix 0:b9e1003fbee7 201
Innomatix 0:b9e1003fbee7 202 }else if( 0x102 == msgid )
Innomatix 0:b9e1003fbee7 203 {
Innomatix 0:b9e1003fbee7 204 txbuff[ 4 ] = msgbuff[ 0 ];
Innomatix 0:b9e1003fbee7 205 txbuff[ 5 ] = msgbuff[ 1 ];
Innomatix 0:b9e1003fbee7 206 pressure = (msgbuff[ 0 ] << 8) + msgbuff[ 1 ];
Innomatix 0:b9e1003fbee7 207 PutUnsignedInteger( Press3Bin, pressure );
Innomatix 0:b9e1003fbee7 208
Innomatix 0:b9e1003fbee7 209 }else if( 0x103 == msgid )
Innomatix 0:b9e1003fbee7 210 {
Innomatix 0:b9e1003fbee7 211 txbuff[ 6 ] = msgbuff[ 0 ];
Innomatix 0:b9e1003fbee7 212 txbuff[ 7 ] = msgbuff[ 1 ];
Innomatix 0:b9e1003fbee7 213 pressure = (msgbuff[ 0 ] << 8) + msgbuff[ 1 ];
Innomatix 0:b9e1003fbee7 214 PutUnsignedInteger( Press4Bin, pressure );
Innomatix 0:b9e1003fbee7 215 }
Innomatix 0:b9e1003fbee7 216 }else if( canNoData != canresult )
Innomatix 0:b9e1003fbee7 217 {
Innomatix 0:b9e1003fbee7 218 printf( "CanReceive() error %d\r\n", canresult );
Innomatix 0:b9e1003fbee7 219 }
Innomatix 0:b9e1003fbee7 220
Innomatix 0:b9e1003fbee7 221 /*-----------------------------------------------*/
Innomatix 0:b9e1003fbee7 222 // detect receive overruns - this means CAN messages are arrving faster
Innomatix 0:b9e1003fbee7 223 // than the application is reading them via CanReceive()
Innomatix 0:b9e1003fbee7 224 {
Innomatix 0:b9e1003fbee7 225 static unsigned long overflow = 0;
Innomatix 0:b9e1003fbee7 226 StatisticsStruct_t Stats;
Innomatix 0:b9e1003fbee7 227
Innomatix 0:b9e1003fbee7 228 // Check if there are more overrun errors this time than last time
Innomatix 0:b9e1003fbee7 229 CanStatistics( canChDAP3, &Stats );
Innomatix 0:b9e1003fbee7 230 if( Stats.OverflowCount > 0 && Stats.OverflowCount != overflow )
Innomatix 0:b9e1003fbee7 231 {
Innomatix 0:b9e1003fbee7 232 rxeled = !rxeled;
Innomatix 0:b9e1003fbee7 233 overflow = Stats.OverflowCount;
Innomatix 0:b9e1003fbee7 234 // publish the overflow count to the RDS
Innomatix 0:b9e1003fbee7 235 sprintf( str, "CAN3 OVF: %d", overflow );
Innomatix 0:b9e1003fbee7 236 PutString( StatusBin, str );
Innomatix 0:b9e1003fbee7 237 printf( "%s\r\n", str );
Innomatix 0:b9e1003fbee7 238 }
Innomatix 0:b9e1003fbee7 239 }
Innomatix 0:b9e1003fbee7 240
Innomatix 0:b9e1003fbee7 241
Innomatix 0:b9e1003fbee7 242 /*-----------------------------------------------*/
Innomatix 0:b9e1003fbee7 243 // send the combined pressure message once per second
Innomatix 0:b9e1003fbee7 244 if( TxTimer.read_ms() >= 1000 )
Innomatix 0:b9e1003fbee7 245 {
Innomatix 0:b9e1003fbee7 246 txled = !txled;
Innomatix 0:b9e1003fbee7 247
Innomatix 0:b9e1003fbee7 248 canresult = CanSend( canChDAP4, 0x200, canFormatStandard, txbuff, 8 );
Innomatix 0:b9e1003fbee7 249 if( canSuccess != canresult )
Innomatix 0:b9e1003fbee7 250 {
Innomatix 0:b9e1003fbee7 251 printf( "CanSend() error %d\r\n", canresult );
Innomatix 0:b9e1003fbee7 252 txeled = !txeled;
Innomatix 0:b9e1003fbee7 253 }
Innomatix 0:b9e1003fbee7 254
Innomatix 0:b9e1003fbee7 255 // Also publish the loop count to the remote data store "debug" data bin
Innomatix 0:b9e1003fbee7 256 sprintf( str, "PCop Loop %d", count );
Innomatix 0:b9e1003fbee7 257 PutDebug( str );
Innomatix 0:b9e1003fbee7 258
Innomatix 0:b9e1003fbee7 259 // And restart the timer at 0
Innomatix 0:b9e1003fbee7 260 TxTimer.reset();
Innomatix 0:b9e1003fbee7 261 }
Innomatix 0:b9e1003fbee7 262 }
Innomatix 0:b9e1003fbee7 263
Innomatix 0:b9e1003fbee7 264 ExampleClose();
Innomatix 0:b9e1003fbee7 265
Innomatix 0:b9e1003fbee7 266 return( 0 );
Innomatix 0:b9e1003fbee7 267 }
Innomatix 0:b9e1003fbee7 268