From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- Master/Real-Time Systems/mki/src/mki.cpp | 439 +++++++++++++++++++++++++++++++ 1 file changed, 439 insertions(+) create mode 100644 Master/Real-Time Systems/mki/src/mki.cpp (limited to 'Master/Real-Time Systems/mki/src/mki.cpp') 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; +} + + -- cgit v1.2.3