Part 2 - I placed the function ECANSendMessage() at the end of ms2_extra_user.c and added the broadcast code to the function user_defined()
Code: Select all
/* $Id: ms2_extra_user.c,v 1.3 2010-10-01 00:32:46 jsmcortina Exp $ */
#include "ms2_extra.h"
/*
modifications to files
ms2_extra.h
122 #define MSG_STD 11
1174 void ECANSendMessage(unsigned int id, unsigned char *data, unsigned char dataLen, unsigned char msgType) FAR_TEXT39_ATTR;
1221 void user_defined(long tmptime) FAR_TEXT3b_ATTR; // was 3a change to 3b
ms2_can_isr.c
29 case MSG_STD: // msg format 11 bit STD - do not let MSII mess with it
// reset identifier registers for standard ID
CAN_TB0_IDR0 = (unsigned char)(can[ix].cx_destvaroff[jx] >> 3);
// 8 high bits in IDR0, 3 low bits in IDR1
CAN_TB0_IDR1 = (unsigned char)((can[ix].cx_destvaroff[jx] & 0x0007) << 5);
CAN_TB0_IDR2 = (unsigned char)(0x00);
CAN_TB0_IDR3 = (unsigned char)(0x01);
CAN_TB0_DLR = (unsigned char) (can[ix].cx_varbyt[jx]);
for (kx = 0;kx < CAN_TB0_DLR;kx++) {
*(&CAN_TB0_DSR0 + kx) = can[ix].cx_datbuf[jx][kx];
}
break;
*/
#define Engine_RPM 0x280 // 996 - Motorsteuerger�t
void user_defined() {
/* 'user defined'
*
* So here is a place to put your code. The three variables are there ready
* for you.
* If you want to get data out to tuning software you can use outpc.user0 which is set
* aside specially (or outpc.status4 or outpc.istatus5 which are both free at time of
* writing this note.)
* Then those gauges can be enabled in Megatune or Tunerstudio.
*
* Other uses:
* Make custom comparisons to turn outputs on/off. One way to simplify this somewhat
* could be to use this code to change the value in status4 and then let the
* existing "outputs" code that you configure in the tuning software actually
* enable the output and turn it on or off - that might save a lot of customisation
* and digging around in the code. Once you have status4 changing value, you are
* nearly done.
*/
unsigned long ultmp;
DISABLE_INTERRUPTS;
ultmp = lmms;
ENABLE_INTERRUPTS;
if ( (ultmp > cansendclk) && (flash10.user_conf & 0x01)) { // is our user defined feature enabled
cansendclk = ultmp + 78; // 10ms ( 1s = 7812 x .128 ms) clk
// user_ulong = ????; variables for your use
// user_uint = ????;
// user_uchar = ????;
// flash10.user_conf } These are the data
// flash10.user_value1 } you can prog to
// flash10.user_value2 } flash from tuning software
// typedef signed char int8_t;
// typedef unsigned char uint8_t;
// typedef int int16_t;
// typedef unsigned int uint16_t;
// typedef long int32_t;
// typedef unsigned long uint32_t;
// typedef long long int64_t;
// typedef unsigned long long uint64_t;
// Send Message Variables
unsigned int id;
unsigned char data[8];
unsigned char dataLen;
id = Engine_RPM; //0x280 - Motorsteuergerat 640 - engine control unit RPM is 4:1 ratio = outpc.rpm*4
dataLen = 0x08;
data[0] = 0x00;
data[1] = 0x00;
data[2] = (unsigned char)((outpc.rpm*4) & 0x00FF ); //byte 3 = RPM, L
data[3] = (unsigned char)((outpc.rpm*4) /256 ); //byte 4 = RPM, H
data[4] = 0x00;
data[5] = 0x00;
data[6] = 0x00;
data[7] = 0x00;
ECANSendMessage(id, data, dataLen, MSG_STD);
}
return;
}
void ECANSendMessage(unsigned int id, unsigned char *data, unsigned char dataLen, unsigned char msgType) {
int ix;
int kx;
/* CAN message format:
* Reg Bits: 7<------------------- 0
* IDR0: |----STD ID(11 bits)----| (Header bits 28 <-- 21)
* IDR1: |cont'd 0 0 ------------| (Header bits 20 <-- 15)
* IDR2: |-----------------------| (Header bits 14 <-- 7)
* IDR3: |----------------------0| (Header bits 6 <-- 0,rtr)
*/
ix = can[0].cxno_in;
// Set to Standard 11Bit ID Format
can[0].cx_msg_type[ix] = msgType; // MSG_STD = 11
// set CANID and DLC of Message
can[0].cx_destvaroff[ix] = id; // CANID
can[0].cx_varbyt[ix] = dataLen; // 8 bytes DLC
// load Message Data
for (kx = 0;kx < dataLen ;kx++) {
can[0].cx_datbuf[ix][kx] = data[kx];
}
// set following to zero as not used in Standard CAN Header
can[0].cx_destvarblk[ix] = 0;
can[0].cx_dest[ix] = 0;
// This is where (in xmt ring buffer) to put next message
if (can[0].cxno_in < (NO_CANMSG - 1)) {
can[0].cxno_in++;
} else {
can[0].cxno_in = 0; // overwrite oldest msg in queue
}
// increment counter
if (can[0].cxno < NO_CANMSG) {
can[0].cxno++;
} else {
can[0].cxno = NO_CANMSG;
}
if (!(CANTIER & 0x07)) {
// Following will cause entry to TxIsr without sending msg
// since when CANTIER = 0, CANTFLG left as buff empty(>0).
// If CANTIER has at least 1 int buf enabled, will enter
// TxIsr automatically.
CANTBSEL = CANTFLG;
CANTIER = CANTBSEL;
}
}
as stated this has been running on a microsquirt and feeding a Porsche 996 CANbus instrument cluster with RPM / Vehicle Speed / Engine Temp and Warning Lights for 6 months now without problems.
I have not yet tested this with two MS units doing their data polling comms while running the 11bit broadcast but given the message type masks, the MS units should have no problems ignoring the 11 bit data, similarly the cluster is happily ignoring the 29bit data.
the code above in user defined has been edited to have one ID as a clean example. and should send a valid rpm to the tach of instruments expecting Bosch Motronic data (VW/Audi/Porsche)