summaryrefslogtreecommitdiffstats
path: root/Master/Real-Time Systems/mki/src/mki.cpp
diff options
context:
space:
mode:
authorSven Eisenhauer <sven@sven-eisenhauer.net>2023-11-10 15:11:48 +0100
committerSven Eisenhauer <sven@sven-eisenhauer.net>2023-11-10 15:11:48 +0100
commit33613a85afc4b1481367fbe92a17ee59c240250b (patch)
tree670b842326116b376b505ec2263878912fca97e2 /Master/Real-Time Systems/mki/src/mki.cpp
downloadStudium-master.tar.gz
Studium-master.tar.bz2
add new repoHEADmaster
Diffstat (limited to 'Master/Real-Time Systems/mki/src/mki.cpp')
-rw-r--r--Master/Real-Time Systems/mki/src/mki.cpp439
1 files changed, 439 insertions, 0 deletions
diff --git a/Master/Real-Time Systems/mki/src/mki.cpp b/Master/Real-Time Systems/mki/src/mki.cpp
new file mode 100644
index 0000000..1438679
--- /dev/null
+++ b/Master/Real-Time Systems/mki/src/mki.cpp
@@ -0,0 +1,439 @@
+//============================================================================
+// Name:
+// mki.cpp
+//
+// Summary:
+// A pretty simple class for controlling the parts
+// we can on the mercedes-combi-instrument
+//
+// Created on:
+// Okt 1, 2010
+//
+// Author:
+// Christian Steiger
+//============================================================================
+
+#include "mki.h"
+
+// constructor
+mki::mki()
+{
+ // set data
+ m_alert = 0;
+
+ // clean up structs
+ memset(&m_can_id_200, 0, sizeof(m_can_id_200));
+ memset(&m_can_id_208, 0, sizeof(m_can_id_208));
+ memset(&m_can_id_210, 0, sizeof(m_can_id_210));
+ memset(&m_can_id_308, 0, sizeof(m_can_id_308));
+ memset(&m_can_id_312, 0, sizeof(m_can_id_312));
+ memset(&m_can_id_550, 0, sizeof(m_can_id_550));
+ memset(&m_can_id_608, 0, sizeof(m_can_id_608));
+
+ // set message ids
+ m_can_id_200.can_id = 0x200;
+ m_can_id_208.can_id = 0x208;
+ m_can_id_210.can_id = 0x210;
+ m_can_id_308.can_id = 0x308;
+ m_can_id_312.can_id = 0x312;
+ m_can_id_550.can_id = 0x550;
+ m_can_id_608.can_id = 0x608;
+
+ // set message length
+ m_can_id_200.can_dlc = 8;
+ m_can_id_208.can_dlc = 8;
+ m_can_id_210.can_dlc = 8;
+ m_can_id_308.can_dlc = 8;
+ m_can_id_312.can_dlc = 8;
+ m_can_id_550.can_dlc = 8;
+ m_can_id_608.can_dlc = 8;
+}
+
+// destructor
+mki::~mki()
+{
+
+}
+
+
+//============================================================================
+// Summary:
+// Connects to an socket can interface.
+// Parameters:
+// [in] interface - name of the can interface, e.g. can0, vcan0
+// [out] 0 on success, -1 on failure, sets errno.
+//============================================================================
+int mki::connect( const char* const interface )
+{
+ return m_can.connect( interface );
+
+}
+
+//============================================================================
+// Summary:
+// Enables some of the available lamps in the cockpit.
+//
+// Possible values are:
+// MKI_ABS, MKI_ESP, MKI_ENGINE, MKI_WARN,
+// MKI_WARN_BLINK, MKI_FUEL_LOW
+// MKI_HANDBRAKE will cause alarm beep when Mph > 0
+//
+// Combine them via logical OR to enable more than one at the same time.
+// Each call will reset the lamp status, so a setLamps(0) will disable all.
+//
+// Parameters:
+// [in] lamps - bitmask which contains the lamps to activate.
+//============================================================================
+void mki::setLamps( const unsigned int lamps )
+{
+ // erase the used bytes to make things easier
+ m_can_id_200.data[0] = 0;
+ m_can_id_308.data[3] = 0;
+
+ // activate handbrake lamp. can cause alarm beep when moving
+ if ( lamps & MKI_HANDBRAKE )
+ m_can_id_200.data[0] |= 0x02;
+
+ // activate abs lamp
+ if ( lamps & MKI_ABS )
+ m_can_id_200.data[0] |= 0x04;
+
+ // activate esp lamp
+ if ( lamps & MKI_ESP )
+ m_can_id_200.data[0] |= 0x08;
+
+ // activate warning triangle
+ if ( lamps & MKI_WARN )
+ m_can_id_200.data[0] |= 0x10;
+
+ // activate warning triangle and let it blink. ignores MKI_WARN.
+ if ( lamps & MKI_WARN_BLINK )
+ m_can_id_200.data[0] |= 0x20;
+
+ // activate fuel low lamp
+ if ( lamps & MKI_FUEL_LOW )
+ m_can_id_308.data[3] |= 0x01;
+
+ // activate engine lamp
+ if ( lamps & MKI_ENGINE )
+ m_can_id_308.data[3] |= 0x02;
+
+}
+
+void mki::setLampsOff( void )
+{
+ // erase the used bytes to make things easier
+ m_can_id_200.data[0] = 0;
+ m_can_id_308.data[3] = 0;
+
+ // activate handbrake lamp. can cause alarm beep when moving
+
+ m_can_id_200.data[0] |= 0x00;
+
+
+}
+
+
+
+
+
+//============================================================================
+// Summary:
+// Sets the Rpm.
+// Parameters:
+// [in] rpm - the rpm to be set, only values between 0 and 7000 make sense.
+//============================================================================
+void mki::setRpm( const unsigned short rpm )
+{
+ // dont allow values higher than 7000, or you may not see anyhting
+ const unsigned short int rpm_ = (rpm > 7000) ? 7000 : rpm;
+
+ // convert the rpm for the message bytes
+ const unsigned short int hbyte = rpm_ / 250;
+ const unsigned short int lbyte = rpm_ - (hbyte * 250);
+
+ // set variables
+ m_can_id_308.data[1] = hbyte;
+ m_can_id_308.data[2] = lbyte;
+}
+
+
+//============================================================================
+// Summary:
+// Sets the Mph.
+// Parameters:
+// [in] mph - the mph to be set, only values between 0 and 160 make sense.
+//============================================================================
+void mki::setMph( const unsigned char mph )
+{
+ // calculate low and high byte
+ unsigned short int hbyte = mph / 10;
+ unsigned short int lbyte = (mph - (hbyte * 10)) * 25;
+
+ // filter high byte, since bit 6 and 7 make the hbyte value invalid
+ hbyte &= 0x3F;
+
+ // set address 0x200 properties
+ m_can_id_200.data[2] = hbyte;
+ m_can_id_200.data[3] = lbyte;
+ m_can_id_200.data[4] = hbyte;
+ m_can_id_200.data[5] = lbyte;
+
+ // set address 0x208 properties
+ m_can_id_208.data[4] = hbyte;
+ m_can_id_208.data[5] = lbyte;
+ m_can_id_208.data[6] = hbyte;
+ m_can_id_208.data[7] = lbyte;
+
+}
+
+
+//============================================================================
+// Summary:
+// Sets the cooling water temperature.
+// Just give the value you want to see in degree, e.g. setCWTemp(85).
+// Only values between 40 and 130 make sense, everything else
+// wont be displayed due to display limitatios.
+//
+// Parameters:
+// [in] temp - the temperature to be set.
+//============================================================================
+void mki::setCWTemp( const unsigned char temp )
+{
+ // we need to add an offset of 40 to show the temperature 1:1,
+ // since the display wont show anything when we reach 0xFF,
+ // we will simply limit the value to the highest possible setting.
+ m_can_id_608.data[0] = ((temp + 40) > 176) ? 176 : temp + 40;
+}
+
+
+//============================================================================
+// Summary:
+// Sets the properties of the limit mode which is shown in the lcd-display.
+//
+// Possible values are:
+// MKI_LIMIT = activates a big limit view in the lcd-display,
+// if no changes are made it will switch back and forth
+// between the main and limit display for a short while,
+// and then stays in the main mode.
+// MKI_LIMIT_TEXT = activates a small limit text in the main display mode.
+// MKI_PERMANENT = make the MKI_LIMIT view permanently visible.
+// MKI_EXCEED = alarm beep and "exceeded" message in the limit view.
+// MKI_WINTER_TYRE = switches "limit" text to "winter tyre limit".
+// MKI_MPH_BLINK = let the mph value blink.
+// MKI_NO_MPH = show --- instad of the mph value.
+//
+// The mph value shown there can be controlled with setLimitMph(mph);
+//
+// Parameters:
+// [in] flags - a bitmask which control the different modes.
+//============================================================================
+void mki::setDisplay( const unsigned int flags )
+{
+
+ // just kill the data content except for byte 7
+ // makes life much easier for us in this function
+ unsigned short int i;
+ for (i = 0; i < 7; i++)
+ m_can_id_210.data[i] = 0;
+
+ // enable limit display
+ if ( flags & MKI_LIMIT )
+ m_can_id_210.data[5] |= 0x01;
+
+ // set permanent limit display
+ if ( flags & MKI_PERMANENT )
+ m_can_id_210.data[3] = 0x80;
+
+ // shall the mph value blink?
+ if ( flags & MKI_MPH_BLINK )
+ m_can_id_210.data[5] |= 0x02;
+
+ // --- instead of mph value?
+ if ( flags & MKI_NO_MPH )
+ m_can_id_210.data[5] |= 0x08;
+
+ // enable winter tyre message instad of limit
+ if ( flags & MKI_NO_MPH )
+ m_can_id_210.data[5] |= 0x08;
+
+ // exceed warning with alarm sound
+ if ( flags & MKI_EXCEED )
+ m_can_id_210.data[4] |= 0x01;
+
+ // exceed warning with alarm sound
+ if ( flags & MKI_LIMIT_TEXT )
+ m_can_id_210.data[4] |= 0x08;
+
+}
+
+
+//============================================================================
+// Summary:
+// Sets the Mph you see in the limit display if you activate
+// it via setDisplay(MKI_LIMIT) or setDisplay(MKI_LIMIT_TEXT).
+// Parameters:
+// [in] mph - the mph to be set, a value between 0 and 255.
+//============================================================================
+void mki::setDisplayMph( const unsigned char mph )
+{
+ // just copy the value
+ m_can_id_210.data[7] = mph;
+
+}
+
+
+//============================================================================
+// Summary:
+// Sets an alert message. Possible alerts are:
+//
+// MKI_OIL_LOW = shows "engine oil level, stop. ENGINE OFF!" alert.
+// MKI_TIRE_PRESSURE = shows "tire pressure low, check tires".
+// MKI_TIRE_DEFECT = shows "tire pressure low, caution tire defect!".
+//
+// The alerts can be combined via logical OR, in this case it will
+// alert beep once for every error and then switch back and forth
+// between the enabled alerts, MKI_TIRE_DEFECT however overrides
+// MKI_TIRE_PRESSURE, so you wont see it after setting MKI_TIRE_DEFECT.
+//
+// To deactivate the alerts just call setAlert(0).
+// It can also take a second or two until the alert gets active.
+//
+// Parameters:
+// [in] alert - see the description above.
+//============================================================================
+void mki::setAlert( const unsigned int alert )
+{
+ // we have a alert
+ if (alert)
+ {
+ // set the appropiate variable so
+ // sendData() will send the 0x550 message
+ m_alert = 1;
+
+ // kill byte to make things easier
+ m_can_id_550.data[0] = 0;
+
+ // tire pressure low alert
+ if ( alert & MKI_TIRE_PRESSURE )
+ m_can_id_550.data[0] |= 0x10;
+
+ // tire defect alert
+ if ( alert & MKI_TIRE_DEFECT )
+ m_can_id_550.data[0] |= 0x20;
+
+ }
+ else
+ {
+ // unset the appropiate variable so
+ // sendData() wont send the 0x550 message
+ m_alert = 0;
+ }
+}
+
+
+//============================================================================
+// Summary:
+// Sends all the messages the display needs to function.
+// You need to call this command every 50ms or so to keep
+// everything working, best use a while-loop like this:
+//
+// while (1) { mki_object.sendData(); usleep(50000); }
+//
+// It may be tedious, but makes usage a bit easier, and you can decide
+// on your own how to implement it (let it run in a seperate pthread or so).
+//
+// Be aware that the function itself sleeps a good time to prevent
+// write buffer overflows, together its roughly 50ms,
+// 60ms if you enabled alerts.
+//
+// Parameters:
+// none
+//============================================================================
+// TODO mki::sendData() - Implement error handling to make it more solid.
+void mki::sendData(void)
+{
+
+ // sleep 10ms between the messages to prevent
+ // write buffer error that will happen otherwise.
+ m_can.writeMsg(&m_can_id_200);
+ usleep(1000);
+
+ m_can.writeMsg(&m_can_id_208);
+ usleep(1000);
+
+ m_can.writeMsg(&m_can_id_210);
+ usleep(1000);
+
+ m_can.writeMsg(&m_can_id_308);
+ usleep(1000);
+
+ m_can.writeMsg(&m_can_id_312);
+ usleep(1000);
+
+ m_can.writeMsg(&m_can_id_608);
+ usleep(1000);
+
+ // Only write 550 if we have alerts
+ if (m_alert) {
+ m_can.writeMsg(&m_can_id_550);
+ usleep(1000);
+ }
+
+}
+
+//============================================================================
+// Summary:
+// Sets the Kmh.
+// Works the same wike like setMph(), the Kmh will be converted
+// into Mph and then shown on the display.
+//
+// Parameters:
+// [in] mph - the mph to be set, only values between 0 and 255 make sense.
+//============================================================================
+void mki::setKmh ( const unsigned char kmh )
+{
+ // convert bewteen kmh and mph
+ // and call the appropiate function
+ setMph( (char)(kmh * 0.6f) );
+}
+
+
+//============================================================================
+// Summary:
+// Sets the Kmh for the limit modes.
+// Works the same wike like setDisplayMph(), the Kmh will be converted
+// into Mph and then shown on the display if you used
+// setDisplay(MKI_LIMIT) or setDisplay(MKI_LIMIT_TEXT).
+//
+// Parameters:
+// [in] mph - the mph to be set, only values between 0 and 255 make sense.
+//============================================================================
+void mki::setDisplayKmh ( const unsigned char kmh )
+{
+ // convert bewteen kmh and mph
+ // and call the appropiate function
+ setMph( (char)(kmh * 0.6f) );
+}
+
+
+//============================================================================
+// Summary:
+// Gives back a pointer to the CanIO class that is used to connect
+// to the can interface. Allows you to set some properties like
+// hideErrors() or Loopback. Be cautious with it, the mki-class isnt
+// really prepared for some of the errors you could cause with it.
+//
+// Parameters:
+// [out] mph - the mph to be set, only values between 0 and 255 make sense.
+//============================================================================
+// TODO mki::getInterface - Try to optimize the class in a way that allows us to remove this function.
+// At the moment the error handling is pretty bad, so you will get spammed with error messages or
+// gibberisch when you try to send and the interface isnt up for example, so this needs work.
+CanIO* mki::getInterface(void)
+{
+ // return the reference
+ return &m_can;
+}
+
+