Small project to display some OBD values from the Toyota GT86/ Subaru BRZ/ Scion FRS on an OLED display.
Dependencies: Adafruit_GFX MODSERIAL mbed-rtos mbed
IsoTpHandler.h@3:eb807d330292, 2014-04-27 (annotated)
- Committer:
- chrta
- Date:
- Sun Apr 27 17:11:32 2014 +0000
- Revision:
- 3:eb807d330292
- Parent:
- 1:ca506b88b1d6
Working pid decoder
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
chrta | 0:6b1f6139fb25 | 1 | #ifndef ISO_TP_HANDLER |
chrta | 0:6b1f6139fb25 | 2 | #define ISO_TP_HANDLER |
chrta | 0:6b1f6139fb25 | 3 | |
chrta | 0:6b1f6139fb25 | 4 | #include "mbed.h" |
chrta | 0:6b1f6139fb25 | 5 | |
chrta | 0:6b1f6139fb25 | 6 | /** |
chrta | 0:6b1f6139fb25 | 7 | * http://en.wikipedia.org/wiki/ISO_15765-2 |
chrta | 0:6b1f6139fb25 | 8 | */ |
chrta | 0:6b1f6139fb25 | 9 | class IsoTpHandler |
chrta | 0:6b1f6139fb25 | 10 | { |
chrta | 0:6b1f6139fb25 | 11 | private: |
chrta | 1:ca506b88b1d6 | 12 | |
chrta | 1:ca506b88b1d6 | 13 | /** |
chrta | 1:ca506b88b1d6 | 14 | * Represents a state. |
chrta | 1:ca506b88b1d6 | 15 | */ |
chrta | 0:6b1f6139fb25 | 16 | class State |
chrta | 0:6b1f6139fb25 | 17 | { |
chrta | 0:6b1f6139fb25 | 18 | public: |
chrta | 1:ca506b88b1d6 | 19 | |
chrta | 1:ca506b88b1d6 | 20 | /** |
chrta | 1:ca506b88b1d6 | 21 | * Empty destructor. |
chrta | 1:ca506b88b1d6 | 22 | */ |
chrta | 0:6b1f6139fb25 | 23 | virtual ~State() {} |
chrta | 1:ca506b88b1d6 | 24 | |
chrta | 1:ca506b88b1d6 | 25 | /** |
chrta | 1:ca506b88b1d6 | 26 | * Processes the received can message. |
chrta | 1:ca506b88b1d6 | 27 | * |
chrta | 1:ca506b88b1d6 | 28 | * \param[in] message This can message it processed. |
chrta | 1:ca506b88b1d6 | 29 | * \param context This state machine (context) is used. |
chrta | 1:ca506b88b1d6 | 30 | */ |
chrta | 0:6b1f6139fb25 | 31 | virtual void processInput(const CANMessage* message, IsoTpHandler* context) const = 0; |
chrta | 1:ca506b88b1d6 | 32 | |
chrta | 1:ca506b88b1d6 | 33 | /** |
chrta | 1:ca506b88b1d6 | 34 | * This method is called when this state is entered. |
chrta | 1:ca506b88b1d6 | 35 | * \param context This state machine (context) is used. |
chrta | 1:ca506b88b1d6 | 36 | */ |
chrta | 0:6b1f6139fb25 | 37 | virtual void onEnter(IsoTpHandler* context) const = 0; |
chrta | 1:ca506b88b1d6 | 38 | |
chrta | 1:ca506b88b1d6 | 39 | /** |
chrta | 1:ca506b88b1d6 | 40 | * This method is called when leaving this state. |
chrta | 1:ca506b88b1d6 | 41 | * \param context This state machine (context) is used. |
chrta | 1:ca506b88b1d6 | 42 | */ |
chrta | 0:6b1f6139fb25 | 43 | virtual void onLeave(IsoTpHandler* context) const = 0; |
chrta | 0:6b1f6139fb25 | 44 | }; |
chrta | 0:6b1f6139fb25 | 45 | |
chrta | 0:6b1f6139fb25 | 46 | /** |
chrta | 0:6b1f6139fb25 | 47 | * No special packet expected |
chrta | 0:6b1f6139fb25 | 48 | */ |
chrta | 0:6b1f6139fb25 | 49 | class IdleState : public State |
chrta | 0:6b1f6139fb25 | 50 | { |
chrta | 0:6b1f6139fb25 | 51 | public: |
chrta | 0:6b1f6139fb25 | 52 | IdleState(); |
chrta | 0:6b1f6139fb25 | 53 | |
chrta | 0:6b1f6139fb25 | 54 | virtual void processInput(const CANMessage* message, IsoTpHandler* context) const; |
chrta | 0:6b1f6139fb25 | 55 | virtual void onEnter(IsoTpHandler* context) const; |
chrta | 0:6b1f6139fb25 | 56 | virtual void onLeave(IsoTpHandler* context) const; |
chrta | 0:6b1f6139fb25 | 57 | }; |
chrta | 0:6b1f6139fb25 | 58 | |
chrta | 0:6b1f6139fb25 | 59 | /** |
chrta | 0:6b1f6139fb25 | 60 | * Expect packets of type "consecutive frame" |
chrta | 0:6b1f6139fb25 | 61 | */ |
chrta | 0:6b1f6139fb25 | 62 | class ConsequtiveTransferState : public State |
chrta | 0:6b1f6139fb25 | 63 | { |
chrta | 0:6b1f6139fb25 | 64 | public: |
chrta | 0:6b1f6139fb25 | 65 | ConsequtiveTransferState(); |
chrta | 0:6b1f6139fb25 | 66 | |
chrta | 0:6b1f6139fb25 | 67 | virtual void processInput(const CANMessage* message, IsoTpHandler* context) const; |
chrta | 0:6b1f6139fb25 | 68 | virtual void onEnter(IsoTpHandler* context) const; |
chrta | 0:6b1f6139fb25 | 69 | virtual void onLeave(IsoTpHandler* context) const; |
chrta | 0:6b1f6139fb25 | 70 | }; |
chrta | 0:6b1f6139fb25 | 71 | public: |
chrta | 1:ca506b88b1d6 | 72 | |
chrta | 1:ca506b88b1d6 | 73 | /** |
chrta | 1:ca506b88b1d6 | 74 | * Constructor |
chrta | 1:ca506b88b1d6 | 75 | * |
chrta | 1:ca506b88b1d6 | 76 | * \param[in] canInterface The can interface the packets should be sent to. It must not be NULL. |
chrta | 1:ca506b88b1d6 | 77 | */ |
chrta | 0:6b1f6139fb25 | 78 | IsoTpHandler(CAN* canInterface); |
chrta | 1:ca506b88b1d6 | 79 | |
chrta | 1:ca506b88b1d6 | 80 | /** |
chrta | 1:ca506b88b1d6 | 81 | * Processes the given can message. |
chrta | 1:ca506b88b1d6 | 82 | * |
chrta | 1:ca506b88b1d6 | 83 | * This is the main method. It must be called for every received IsoTp can packet. |
chrta | 1:ca506b88b1d6 | 84 | * It updates the internal state and sends the can response. |
chrta | 1:ca506b88b1d6 | 85 | * |
chrta | 1:ca506b88b1d6 | 86 | * \param[in] message The received can message. It must not be NULL. |
chrta | 1:ca506b88b1d6 | 87 | */ |
chrta | 0:6b1f6139fb25 | 88 | void processCanMessage(const CANMessage* message); |
chrta | 0:6b1f6139fb25 | 89 | |
chrta | 1:ca506b88b1d6 | 90 | /** |
chrta | 1:ca506b88b1d6 | 91 | * This method is called when a complete Iso Tp message was received. |
chrta | 1:ca506b88b1d6 | 92 | * |
chrta | 1:ca506b88b1d6 | 93 | * Currently the packet is only printed out. |
chrta | 3:eb807d330292 | 94 | * Later a user callback must be executed from here. |
chrta | 1:ca506b88b1d6 | 95 | * |
chrta | 1:ca506b88b1d6 | 96 | * \param[in] data The content of the Iso Tp message. |
chrta | 1:ca506b88b1d6 | 97 | * \param[in] length The amount of bytes in data. |
chrta | 1:ca506b88b1d6 | 98 | */ |
chrta | 0:6b1f6139fb25 | 99 | void handle_decoded_packet(const uint8_t* data, uint16_t length); |
chrta | 0:6b1f6139fb25 | 100 | |
chrta | 0:6b1f6139fb25 | 101 | /** |
chrta | 0:6b1f6139fb25 | 102 | * |
chrta | 1:ca506b88b1d6 | 103 | * \param[in] messageSize Total bytes included in the consequtive transfer. |
chrta | 0:6b1f6139fb25 | 104 | * \param[in] data Always 6 bytes. |
chrta | 0:6b1f6139fb25 | 105 | */ |
chrta | 0:6b1f6139fb25 | 106 | void init_consequtive_reading(uint16_t messageSize, const uint8_t* data); |
chrta | 1:ca506b88b1d6 | 107 | |
chrta | 1:ca506b88b1d6 | 108 | /** |
chrta | 1:ca506b88b1d6 | 109 | * Returns the next expected index value of the can packet. |
chrta | 1:ca506b88b1d6 | 110 | * |
chrta | 1:ca506b88b1d6 | 111 | * \return The next expected index value. |
chrta | 1:ca506b88b1d6 | 112 | */ |
chrta | 0:6b1f6139fb25 | 113 | uint8_t getExpectedIndex() const; |
chrta | 1:ca506b88b1d6 | 114 | |
chrta | 1:ca506b88b1d6 | 115 | /** |
chrta | 1:ca506b88b1d6 | 116 | * Increments the expected index. |
chrta | 1:ca506b88b1d6 | 117 | * |
chrta | 1:ca506b88b1d6 | 118 | * This method ensures an automatic wrap around from 15 to 0. |
chrta | 1:ca506b88b1d6 | 119 | */ |
chrta | 0:6b1f6139fb25 | 120 | void incrementExpectedIndex(); |
chrta | 1:ca506b88b1d6 | 121 | |
chrta | 0:6b1f6139fb25 | 122 | /** |
chrta | 1:ca506b88b1d6 | 123 | * Appends the given data to the internal consequtive transfer buffer. |
chrta | 1:ca506b88b1d6 | 124 | * |
chrta | 0:6b1f6139fb25 | 125 | * \retval \c True if the state should be switched. |
chrta | 0:6b1f6139fb25 | 126 | * \retval \c False if the state not change. |
chrta | 0:6b1f6139fb25 | 127 | */ |
chrta | 0:6b1f6139fb25 | 128 | bool appendReceivedData(const uint8_t* data, uint8_t length); |
chrta | 0:6b1f6139fb25 | 129 | |
chrta | 1:ca506b88b1d6 | 130 | /** |
chrta | 1:ca506b88b1d6 | 131 | * Modifies the internal state. |
chrta | 1:ca506b88b1d6 | 132 | * |
chrta | 1:ca506b88b1d6 | 133 | * Should not be used externally. |
chrta | 1:ca506b88b1d6 | 134 | * |
chrta | 1:ca506b88b1d6 | 135 | * \param[in] The new state. |
chrta | 1:ca506b88b1d6 | 136 | */ |
chrta | 0:6b1f6139fb25 | 137 | void setState(const State* state); |
chrta | 0:6b1f6139fb25 | 138 | |
chrta | 0:6b1f6139fb25 | 139 | static const IdleState idleState; |
chrta | 0:6b1f6139fb25 | 140 | static const ConsequtiveTransferState consequtiveTransferState; |
chrta | 0:6b1f6139fb25 | 141 | |
chrta | 0:6b1f6139fb25 | 142 | static bool isValidIsoTpPacket(const CANMessage* message); |
chrta | 0:6b1f6139fb25 | 143 | |
chrta | 0:6b1f6139fb25 | 144 | private: |
chrta | 1:ca506b88b1d6 | 145 | |
chrta | 1:ca506b88b1d6 | 146 | /** The current state. */ |
chrta | 0:6b1f6139fb25 | 147 | const State* m_state; |
chrta | 0:6b1f6139fb25 | 148 | |
chrta | 1:ca506b88b1d6 | 149 | /** The used can interface. */ |
chrta | 0:6b1f6139fb25 | 150 | CAN* m_canInterface; |
chrta | 0:6b1f6139fb25 | 151 | |
chrta | 1:ca506b88b1d6 | 152 | /** This buffer must be able to store the maximum message size. */ |
chrta | 0:6b1f6139fb25 | 153 | uint8_t m_messageBuffer[256]; |
chrta | 1:ca506b88b1d6 | 154 | |
chrta | 1:ca506b88b1d6 | 155 | /** The expected size of the current message. */ |
chrta | 0:6b1f6139fb25 | 156 | uint16_t m_expectedMessageSize; |
chrta | 1:ca506b88b1d6 | 157 | |
chrta | 1:ca506b88b1d6 | 158 | /** The current size of the message that is currently received. */ |
chrta | 0:6b1f6139fb25 | 159 | uint16_t m_currentMessageSize; |
chrta | 1:ca506b88b1d6 | 160 | |
chrta | 1:ca506b88b1d6 | 161 | /** Stores the index that is expected in the next can packet. */ |
chrta | 0:6b1f6139fb25 | 162 | uint8_t m_expectedIndex; |
chrta | 0:6b1f6139fb25 | 163 | }; |
chrta | 0:6b1f6139fb25 | 164 | |
chrta | 0:6b1f6139fb25 | 165 | |
chrta | 1:ca506b88b1d6 | 166 | #endif //ISO_TP_HANDLER |