Sample code for Arduino CAN
Dependencies: mbed
arduinoCAN.cpp@0:6ed8574c6258, 2016-02-29 (annotated)
- Committer:
- jedh
- Date:
- Mon Feb 29 19:33:12 2016 +0000
- Revision:
- 0:6ed8574c6258
Arduino CAN
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jedh | 0:6ed8574c6258 | 1 | /* |
jedh | 0:6ed8574c6258 | 2 | * Copyright (C) 2009 Libelium Comunicaciones Distribuidas S.L. |
jedh | 0:6ed8574c6258 | 3 | * http://www.libelium.com |
jedh | 0:6ed8574c6258 | 4 | * |
jedh | 0:6ed8574c6258 | 5 | * This program is free software: you can redistribute it and/or modify |
jedh | 0:6ed8574c6258 | 6 | * it under the terms of the GNU Lesser General Public License as published by |
jedh | 0:6ed8574c6258 | 7 | * the Free Software Foundation, either version 2.1 of the License, or |
jedh | 0:6ed8574c6258 | 8 | * (at your option) any later version. |
jedh | 0:6ed8574c6258 | 9 | |
jedh | 0:6ed8574c6258 | 10 | * This program is distributed in the hope that it will be useful, |
jedh | 0:6ed8574c6258 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
jedh | 0:6ed8574c6258 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
jedh | 0:6ed8574c6258 | 13 | * GNU Lesser General Public License for more details. |
jedh | 0:6ed8574c6258 | 14 | |
jedh | 0:6ed8574c6258 | 15 | * You should have received a copy of the GNU Lesser General Public License |
jedh | 0:6ed8574c6258 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
jedh | 0:6ed8574c6258 | 17 | * |
jedh | 0:6ed8574c6258 | 18 | * Version: 0.3 |
jedh | 0:6ed8574c6258 | 19 | * Design: David Gascon |
jedh | 0:6ed8574c6258 | 20 | * Implementation: Luis Antonio Martin & Ahmad Saad |
jedh | 0:6ed8574c6258 | 21 | */ |
jedh | 0:6ed8574c6258 | 22 | |
jedh | 0:6ed8574c6258 | 23 | #include "Arduino.h" |
jedh | 0:6ed8574c6258 | 24 | #include "arduinoCAN.h" |
jedh | 0:6ed8574c6258 | 25 | #include "../SPI/SPI.h" |
jedh | 0:6ed8574c6258 | 26 | #include "../arduino-api/arduinoMultiprotocol.h" |
jedh | 0:6ed8574c6258 | 27 | #include "../arduino-api/arduinoUtils.h" |
jedh | 0:6ed8574c6258 | 28 | |
jedh | 0:6ed8574c6258 | 29 | |
jedh | 0:6ed8574c6258 | 30 | |
jedh | 0:6ed8574c6258 | 31 | #define DEBUGMODE 0 |
jedh | 0:6ed8574c6258 | 32 | /*********************************************************************** |
jedh | 0:6ed8574c6258 | 33 | * Constructors |
jedh | 0:6ed8574c6258 | 34 | ***********************************************************************/ |
jedh | 0:6ed8574c6258 | 35 | |
jedh | 0:6ed8574c6258 | 36 | CAN::CAN(void){} |
jedh | 0:6ed8574c6258 | 37 | |
jedh | 0:6ed8574c6258 | 38 | |
jedh | 0:6ed8574c6258 | 39 | /*********************************************************************** |
jedh | 0:6ed8574c6258 | 40 | * PUBLIC METHODS |
jedh | 0:6ed8574c6258 | 41 | ***********************************************************************/ |
jedh | 0:6ed8574c6258 | 42 | |
jedh | 0:6ed8574c6258 | 43 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 44 | //! Name: ON() |
jedh | 0:6ed8574c6258 | 45 | //! Description: Initialization MCP2515 |
jedh | 0:6ed8574c6258 | 46 | //! Param : void |
jedh | 0:6ed8574c6258 | 47 | //! Returns: "1" if no error, "0" if error |
jedh | 0:6ed8574c6258 | 48 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 49 | bool CAN::begin(uint16_t speed) |
jedh | 0:6ed8574c6258 | 50 | { |
jedh | 0:6ed8574c6258 | 51 | |
jedh | 0:6ed8574c6258 | 52 | #if (DEBUGMODE ==1 ) |
jedh | 0:6ed8574c6258 | 53 | Serial.println("-- Constructor Can(uint16_t speed) --"); |
jedh | 0:6ed8574c6258 | 54 | #endif |
jedh | 0:6ed8574c6258 | 55 | |
jedh | 0:6ed8574c6258 | 56 | // Initialize in Socket1 |
jedh | 0:6ed8574c6258 | 57 | Utils.setONSocket0(); |
jedh | 0:6ed8574c6258 | 58 | Utils.setMUXSocket0(); |
jedh | 0:6ed8574c6258 | 59 | Utils.unsetCSSocket0(); |
jedh | 0:6ed8574c6258 | 60 | |
jedh | 0:6ed8574c6258 | 61 | //Initialization SPI |
jedh | 0:6ed8574c6258 | 62 | SPI.begin(); |
jedh | 0:6ed8574c6258 | 63 | SPI.detachInterrupt(); |
jedh | 0:6ed8574c6258 | 64 | SPI.setBitOrder(MSBFIRST); |
jedh | 0:6ed8574c6258 | 65 | // both mode 0 & 3 should work |
jedh | 0:6ed8574c6258 | 66 | SPI.setDataMode(SPI_MODE0); |
jedh | 0:6ed8574c6258 | 67 | |
jedh | 0:6ed8574c6258 | 68 | //Set the SPI frequency |
jedh | 0:6ed8574c6258 | 69 | SPI.setClockDivider(SPI_CLOCK_DIV128); |
jedh | 0:6ed8574c6258 | 70 | |
jedh | 0:6ed8574c6258 | 71 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 72 | Serial.println("SPI configured"); |
jedh | 0:6ed8574c6258 | 73 | #endif |
jedh | 0:6ed8574c6258 | 74 | |
jedh | 0:6ed8574c6258 | 75 | |
jedh | 0:6ed8574c6258 | 76 | //Software resets MCP2515 |
jedh | 0:6ed8574c6258 | 77 | reset(); |
jedh | 0:6ed8574c6258 | 78 | delay(10); |
jedh | 0:6ed8574c6258 | 79 | |
jedh | 0:6ed8574c6258 | 80 | //After the reset enters configuration mode |
jedh | 0:6ed8574c6258 | 81 | |
jedh | 0:6ed8574c6258 | 82 | //Choose the rate of CAN-bus |
jedh | 0:6ed8574c6258 | 83 | switch(speed){ |
jedh | 0:6ed8574c6258 | 84 | |
jedh | 0:6ed8574c6258 | 85 | case 1000: |
jedh | 0:6ed8574c6258 | 86 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 87 | Serial.println("Speed=1Mbps"); |
jedh | 0:6ed8574c6258 | 88 | #endif |
jedh | 0:6ed8574c6258 | 89 | Utils.setCSSocket0(); |
jedh | 0:6ed8574c6258 | 90 | SPI.transfer(SPI_WRITE); |
jedh | 0:6ed8574c6258 | 91 | SPI.transfer(CNF3); |
jedh | 0:6ed8574c6258 | 92 | SPI.transfer((1<<PHSEG21)); |
jedh | 0:6ed8574c6258 | 93 | SPI.transfer((1<<BTLMODE)|(1<<PHSEG11)); |
jedh | 0:6ed8574c6258 | 94 | Utils.unsetCSSocket0(); |
jedh | 0:6ed8574c6258 | 95 | break; |
jedh | 0:6ed8574c6258 | 96 | |
jedh | 0:6ed8574c6258 | 97 | case 500: |
jedh | 0:6ed8574c6258 | 98 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 99 | Serial.println("Speed=500kps"); |
jedh | 0:6ed8574c6258 | 100 | #endif |
jedh | 0:6ed8574c6258 | 101 | Utils.setCSSocket0(); |
jedh | 0:6ed8574c6258 | 102 | SPI.transfer(SPI_WRITE); |
jedh | 0:6ed8574c6258 | 103 | SPI.transfer(CNF3); |
jedh | 0:6ed8574c6258 | 104 | SPI.transfer((1<<PHSEG21)); |
jedh | 0:6ed8574c6258 | 105 | SPI.transfer((1<<BTLMODE)|(1<<PHSEG11)); |
jedh | 0:6ed8574c6258 | 106 | SPI.transfer((1<<BRP0)); |
jedh | 0:6ed8574c6258 | 107 | Utils.unsetCSSocket0(); |
jedh | 0:6ed8574c6258 | 108 | break; |
jedh | 0:6ed8574c6258 | 109 | |
jedh | 0:6ed8574c6258 | 110 | case 250: |
jedh | 0:6ed8574c6258 | 111 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 112 | Serial.println("Speed=250kps"); |
jedh | 0:6ed8574c6258 | 113 | #endif |
jedh | 0:6ed8574c6258 | 114 | Utils.setCSSocket0(); |
jedh | 0:6ed8574c6258 | 115 | SPI.transfer(SPI_WRITE); |
jedh | 0:6ed8574c6258 | 116 | SPI.transfer(CNF3); |
jedh | 0:6ed8574c6258 | 117 | SPI.transfer((1<<PHSEG20)|(1<<PHSEG22)); |
jedh | 0:6ed8574c6258 | 118 | SPI.transfer((1<<BTLMODE)|(1<<PHSEG12)|(1<<PHSEG11)|(1<<PHSEG10)); |
jedh | 0:6ed8574c6258 | 119 | SPI.transfer((1<<BRP0)); |
jedh | 0:6ed8574c6258 | 120 | Utils.unsetCSSocket0(); |
jedh | 0:6ed8574c6258 | 121 | break; |
jedh | 0:6ed8574c6258 | 122 | |
jedh | 0:6ed8574c6258 | 123 | default: |
jedh | 0:6ed8574c6258 | 124 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 125 | Serial.println("The rate requested is unavailable, is set to 125 Kbit/s by default"); |
jedh | 0:6ed8574c6258 | 126 | #endif |
jedh | 0:6ed8574c6258 | 127 | Utils.setCSSocket0(); |
jedh | 0:6ed8574c6258 | 128 | SPI.transfer(SPI_WRITE); |
jedh | 0:6ed8574c6258 | 129 | SPI.transfer(CNF3); |
jedh | 0:6ed8574c6258 | 130 | SPI.transfer((1<<PHSEG21)); |
jedh | 0:6ed8574c6258 | 131 | SPI.transfer((1<<BTLMODE)|(1<<PHSEG11)); |
jedh | 0:6ed8574c6258 | 132 | SPI.transfer((1<<BRP2)|(1<<BRP1)|(1<<BRP0)); |
jedh | 0:6ed8574c6258 | 133 | Utils.unsetCSSocket0(); |
jedh | 0:6ed8574c6258 | 134 | break; |
jedh | 0:6ed8574c6258 | 135 | |
jedh | 0:6ed8574c6258 | 136 | } |
jedh | 0:6ed8574c6258 | 137 | |
jedh | 0:6ed8574c6258 | 138 | //Enable interrupts the Rx Buffer |
jedh | 0:6ed8574c6258 | 139 | writeRegister(CANINTE,(1<<RX1IE)|(1<<RX0IE)); |
jedh | 0:6ed8574c6258 | 140 | |
jedh | 0:6ed8574c6258 | 141 | //Filters and masks |
jedh | 0:6ed8574c6258 | 142 | //Bufer 0: All the messages and Rollover |
jedh | 0:6ed8574c6258 | 143 | writeRegister(RXB0CTRL,(1<<RXM1)|(1<<RXM0)|(1<<BUKT)); |
jedh | 0:6ed8574c6258 | 144 | |
jedh | 0:6ed8574c6258 | 145 | //Bufer 1: All the messages |
jedh | 0:6ed8574c6258 | 146 | writeRegister(RXB1CTRL,(1<<RXM1)|(1<<RXM0)); |
jedh | 0:6ed8574c6258 | 147 | |
jedh | 0:6ed8574c6258 | 148 | //All bits of the mask reception delete |
jedh | 0:6ed8574c6258 | 149 | writeRegister( RXM0SIDH, 0 ); |
jedh | 0:6ed8574c6258 | 150 | writeRegister( RXM0SIDL, 0 ); |
jedh | 0:6ed8574c6258 | 151 | writeRegister( RXM0EID8, 0 ); |
jedh | 0:6ed8574c6258 | 152 | writeRegister( RXM0EID0, 0 ); |
jedh | 0:6ed8574c6258 | 153 | writeRegister( RXM1SIDH, 0 ); |
jedh | 0:6ed8574c6258 | 154 | writeRegister( RXM1SIDL, 0 ); |
jedh | 0:6ed8574c6258 | 155 | writeRegister( RXM1EID8, 0 ); |
jedh | 0:6ed8574c6258 | 156 | writeRegister( RXM1EID0, 0 ); |
jedh | 0:6ed8574c6258 | 157 | |
jedh | 0:6ed8574c6258 | 158 | //Disable pins RXnBF pins (high impedance state) |
jedh | 0:6ed8574c6258 | 159 | writeRegister( BFPCTRL, 0 ); |
jedh | 0:6ed8574c6258 | 160 | |
jedh | 0:6ed8574c6258 | 161 | //Set normal mode |
jedh | 0:6ed8574c6258 | 162 | setMode(NORMAL_MODE); |
jedh | 0:6ed8574c6258 | 163 | |
jedh | 0:6ed8574c6258 | 164 | //Test its correct mode |
jedh | 0:6ed8574c6258 | 165 | /* |
jedh | 0:6ed8574c6258 | 166 | if (read_register(CANSTAT) != 0) { |
jedh | 0:6ed8574c6258 | 167 | Serial.println("Failed to initialize the MCP2515, normal mode not activated"); |
jedh | 0:6ed8574c6258 | 168 | return false; |
jedh | 0:6ed8574c6258 | 169 | }*/ |
jedh | 0:6ed8574c6258 | 170 | |
jedh | 0:6ed8574c6258 | 171 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 172 | Serial.println("-- End Constructor Can(uint16_t speed) --"); |
jedh | 0:6ed8574c6258 | 173 | Serial.println(""); |
jedh | 0:6ed8574c6258 | 174 | #endif |
jedh | 0:6ed8574c6258 | 175 | |
jedh | 0:6ed8574c6258 | 176 | return 1; |
jedh | 0:6ed8574c6258 | 177 | } |
jedh | 0:6ed8574c6258 | 178 | |
jedh | 0:6ed8574c6258 | 179 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 180 | //! Name: getMessage() |
jedh | 0:6ed8574c6258 | 181 | //! Description: Take the CAN message |
jedh | 0:6ed8574c6258 | 182 | //! Param : messageCAN *rec_msje: pointer to reception buffer |
jedh | 0:6ed8574c6258 | 183 | //! Returns: "1" if no error, "0" if error |
jedh | 0:6ed8574c6258 | 184 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 185 | char CAN::getMessage(messageCAN *rec_msje) |
jedh | 0:6ed8574c6258 | 186 | { |
jedh | 0:6ed8574c6258 | 187 | //Bought that buffer is the message |
jedh | 0:6ed8574c6258 | 188 | char status = readStatus(SPI_RX_STATUS); |
jedh | 0:6ed8574c6258 | 189 | char addr; |
jedh | 0:6ed8574c6258 | 190 | static uint8_t previoSerialuffer; |
jedh | 0:6ed8574c6258 | 191 | |
jedh | 0:6ed8574c6258 | 192 | /* |
jedh | 0:6ed8574c6258 | 193 | if (bit_is_set(status,6)) { |
jedh | 0:6ed8574c6258 | 194 | //If the message is in the Buffer 1 |
jedh | 0:6ed8574c6258 | 195 | addr = SPI_READ_RX; |
jedh | 0:6ed8574c6258 | 196 | } |
jedh | 0:6ed8574c6258 | 197 | else if (bit_is_set(status,7)) |
jedh | 0:6ed8574c6258 | 198 | { |
jedh | 0:6ed8574c6258 | 199 | //If the message is in the Buffer 2 |
jedh | 0:6ed8574c6258 | 200 | addr = SPI_READ_RX | 0x04; |
jedh | 0:6ed8574c6258 | 201 | } |
jedh | 0:6ed8574c6258 | 202 | else { |
jedh | 0:6ed8574c6258 | 203 | // Error, the message is not available |
jedh | 0:6ed8574c6258 | 204 | return 0; |
jedh | 0:6ed8574c6258 | 205 | }*/ |
jedh | 0:6ed8574c6258 | 206 | |
jedh | 0:6ed8574c6258 | 207 | if ( (((status & 0b11000000)>>6)&0b00000011) >2 ) |
jedh | 0:6ed8574c6258 | 208 | { |
jedh | 0:6ed8574c6258 | 209 | addr=SPI_READ_RX | (previoSerialuffer++ & 0x01)<<2; |
jedh | 0:6ed8574c6258 | 210 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 211 | Serial.println("Data in buffer available"); |
jedh | 0:6ed8574c6258 | 212 | #endif |
jedh | 0:6ed8574c6258 | 213 | } |
jedh | 0:6ed8574c6258 | 214 | else if (bit_is_set(status,6)) |
jedh | 0:6ed8574c6258 | 215 | { |
jedh | 0:6ed8574c6258 | 216 | addr = SPI_READ_RX; |
jedh | 0:6ed8574c6258 | 217 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 218 | Serial.println("Data in buffer 0"); |
jedh | 0:6ed8574c6258 | 219 | #endif |
jedh | 0:6ed8574c6258 | 220 | } |
jedh | 0:6ed8574c6258 | 221 | else if (bit_is_set(status,7)) |
jedh | 0:6ed8574c6258 | 222 | { |
jedh | 0:6ed8574c6258 | 223 | addr = SPI_READ_RX | 0x04; |
jedh | 0:6ed8574c6258 | 224 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 225 | Serial.println("Data in buffer 1"); |
jedh | 0:6ed8574c6258 | 226 | #endif |
jedh | 0:6ed8574c6258 | 227 | } |
jedh | 0:6ed8574c6258 | 228 | else { |
jedh | 0:6ed8574c6258 | 229 | // Error: no message available |
jedh | 0:6ed8574c6258 | 230 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 231 | Serial.println("No messages"); |
jedh | 0:6ed8574c6258 | 232 | #endif |
jedh | 0:6ed8574c6258 | 233 | |
jedh | 0:6ed8574c6258 | 234 | return 0; |
jedh | 0:6ed8574c6258 | 235 | } |
jedh | 0:6ed8574c6258 | 236 | |
jedh | 0:6ed8574c6258 | 237 | Utils.setCSSocket0(); |
jedh | 0:6ed8574c6258 | 238 | SPI.transfer(addr); |
jedh | 0:6ed8574c6258 | 239 | |
jedh | 0:6ed8574c6258 | 240 | //Read id |
jedh | 0:6ed8574c6258 | 241 | rec_msje->id = (unsigned int) SPI.transfer(0xff) << 3; //Read the top |
jedh | 0:6ed8574c6258 | 242 | rec_msje->id |= SPI.transfer(0xff) >> 5; //Read the lower |
jedh | 0:6ed8574c6258 | 243 | |
jedh | 0:6ed8574c6258 | 244 | //Return the Extended ID |
jedh | 0:6ed8574c6258 | 245 | SPI.transfer(0xff); |
jedh | 0:6ed8574c6258 | 246 | SPI.transfer(0xff); |
jedh | 0:6ed8574c6258 | 247 | |
jedh | 0:6ed8574c6258 | 248 | //Read DLC |
jedh | 0:6ed8574c6258 | 249 | char length = SPI.transfer(0xff) & 0x0f; |
jedh | 0:6ed8574c6258 | 250 | |
jedh | 0:6ed8574c6258 | 251 | rec_msje->header.length = length; |
jedh | 0:6ed8574c6258 | 252 | rec_msje->header.rtr = (bit_is_set(status, 3)) ? 1 : 0; |
jedh | 0:6ed8574c6258 | 253 | |
jedh | 0:6ed8574c6258 | 254 | //Read data |
jedh | 0:6ed8574c6258 | 255 | for (char i=0;i<length;i++) { |
jedh | 0:6ed8574c6258 | 256 | rec_msje->data[i] = SPI.transfer(0xFF); |
jedh | 0:6ed8574c6258 | 257 | } |
jedh | 0:6ed8574c6258 | 258 | |
jedh | 0:6ed8574c6258 | 259 | Utils.unsetCSSocket0(); |
jedh | 0:6ed8574c6258 | 260 | |
jedh | 0:6ed8574c6258 | 261 | //Delete the interruptions flags |
jedh | 0:6ed8574c6258 | 262 | if (bit_is_set(status, 6)) { |
jedh | 0:6ed8574c6258 | 263 | bitModify(CANINTF, (1<<RX0IF), 0); |
jedh | 0:6ed8574c6258 | 264 | } |
jedh | 0:6ed8574c6258 | 265 | else { |
jedh | 0:6ed8574c6258 | 266 | bitModify(CANINTF, (1<<RX1IF), 0); |
jedh | 0:6ed8574c6258 | 267 | } |
jedh | 0:6ed8574c6258 | 268 | |
jedh | 0:6ed8574c6258 | 269 | return status; |
jedh | 0:6ed8574c6258 | 270 | } |
jedh | 0:6ed8574c6258 | 271 | |
jedh | 0:6ed8574c6258 | 272 | |
jedh | 0:6ed8574c6258 | 273 | |
jedh | 0:6ed8574c6258 | 274 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 275 | //! Name: sendMessage() |
jedh | 0:6ed8574c6258 | 276 | //! Description: Send the CAN message |
jedh | 0:6ed8574c6258 | 277 | //! Param: messageCAN *send_msje: pointer to transmission buffer |
jedh | 0:6ed8574c6258 | 278 | //! Returns: "1" if no error, "0" if error |
jedh | 0:6ed8574c6258 | 279 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 280 | char CAN::sendMessage(messageCAN *send_msje) |
jedh | 0:6ed8574c6258 | 281 | { |
jedh | 0:6ed8574c6258 | 282 | char status = readStatus(SPI_READ_STATUS); |
jedh | 0:6ed8574c6258 | 283 | |
jedh | 0:6ed8574c6258 | 284 | /* Status char: |
jedh | 0:6ed8574c6258 | 285 | * |
jedh | 0:6ed8574c6258 | 286 | * Bit Funcion |
jedh | 0:6ed8574c6258 | 287 | * 2 TXB0CNTRL.TXREQ |
jedh | 0:6ed8574c6258 | 288 | * 4 TXB1CNTRL.TXREQ |
jedh | 0:6ed8574c6258 | 289 | * 6 TXB2CNTRL.TXREQ |
jedh | 0:6ed8574c6258 | 290 | */ |
jedh | 0:6ed8574c6258 | 291 | |
jedh | 0:6ed8574c6258 | 292 | char address; |
jedh | 0:6ed8574c6258 | 293 | |
jedh | 0:6ed8574c6258 | 294 | if (bit_is_clear(status, 2)) { |
jedh | 0:6ed8574c6258 | 295 | address = 0x00; |
jedh | 0:6ed8574c6258 | 296 | } else if (bit_is_clear(status, 4)) { |
jedh | 0:6ed8574c6258 | 297 | address = 0x02; |
jedh | 0:6ed8574c6258 | 298 | } else if (bit_is_clear(status, 6)) { |
jedh | 0:6ed8574c6258 | 299 | address = 0x04; |
jedh | 0:6ed8574c6258 | 300 | } else { |
jedh | 0:6ed8574c6258 | 301 | //All buffers are used can not send messages (returns 0) |
jedh | 0:6ed8574c6258 | 302 | return 0; |
jedh | 0:6ed8574c6258 | 303 | } |
jedh | 0:6ed8574c6258 | 304 | |
jedh | 0:6ed8574c6258 | 305 | Utils.setCSSocket0(); |
jedh | 0:6ed8574c6258 | 306 | SPI.transfer(SPI_WRITE_TX | address); |
jedh | 0:6ed8574c6258 | 307 | //First, send the top ID10....ID3 |
jedh | 0:6ed8574c6258 | 308 | SPI.transfer(send_msje->id >> 3); |
jedh | 0:6ed8574c6258 | 309 | //After sending the lower ID2....ID0 |
jedh | 0:6ed8574c6258 | 310 | SPI.transfer(send_msje->id << 5); |
jedh | 0:6ed8574c6258 | 311 | |
jedh | 0:6ed8574c6258 | 312 | //As we will not use the Extended ID you set it to 0 |
jedh | 0:6ed8574c6258 | 313 | SPI.transfer(0); |
jedh | 0:6ed8574c6258 | 314 | SPI.transfer(0); |
jedh | 0:6ed8574c6258 | 315 | |
jedh | 0:6ed8574c6258 | 316 | char length = send_msje->header.length & 0x0F; |
jedh | 0:6ed8574c6258 | 317 | |
jedh | 0:6ed8574c6258 | 318 | if (send_msje->header.rtr) { |
jedh | 0:6ed8574c6258 | 319 | SPI.transfer((1<<RTR) | length); |
jedh | 0:6ed8574c6258 | 320 | } else { |
jedh | 0:6ed8574c6258 | 321 | //Send the message length |
jedh | 0:6ed8574c6258 | 322 | SPI.transfer(length); |
jedh | 0:6ed8574c6258 | 323 | //Send data |
jedh | 0:6ed8574c6258 | 324 | for (char i=0;i<length;i++) { |
jedh | 0:6ed8574c6258 | 325 | SPI.transfer(send_msje->data[i]); |
jedh | 0:6ed8574c6258 | 326 | } |
jedh | 0:6ed8574c6258 | 327 | } |
jedh | 0:6ed8574c6258 | 328 | |
jedh | 0:6ed8574c6258 | 329 | Utils.unsetCSSocket0(); |
jedh | 0:6ed8574c6258 | 330 | |
jedh | 0:6ed8574c6258 | 331 | //Send message |
jedh | 0:6ed8574c6258 | 332 | Utils.setCSSocket0(); |
jedh | 0:6ed8574c6258 | 333 | address = (address == 0) ? 1 : address; |
jedh | 0:6ed8574c6258 | 334 | SPI.transfer(SPI_RTS | address); |
jedh | 0:6ed8574c6258 | 335 | Utils.unsetCSSocket0(); |
jedh | 0:6ed8574c6258 | 336 | |
jedh | 0:6ed8574c6258 | 337 | return address; |
jedh | 0:6ed8574c6258 | 338 | } |
jedh | 0:6ed8574c6258 | 339 | |
jedh | 0:6ed8574c6258 | 340 | |
jedh | 0:6ed8574c6258 | 341 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 342 | //! Name: printMessage() |
jedh | 0:6ed8574c6258 | 343 | //! Description: CAN message print out the serial port |
jedh | 0:6ed8574c6258 | 344 | //! Param : messageCAN *msje: pointer to the message |
jedh | 0:6ed8574c6258 | 345 | //! Returns: "1" if no error, "0" if error |
jedh | 0:6ed8574c6258 | 346 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 347 | void CAN::printMessage(messageCAN *msje) |
jedh | 0:6ed8574c6258 | 348 | { |
jedh | 0:6ed8574c6258 | 349 | Serial.print(" id: "); |
jedh | 0:6ed8574c6258 | 350 | Serial.print(messageRx.id,HEX); |
jedh | 0:6ed8574c6258 | 351 | Serial.print(" rtr: "); |
jedh | 0:6ed8574c6258 | 352 | Serial.print(messageRx.header.rtr,HEX); |
jedh | 0:6ed8574c6258 | 353 | Serial.print(" => "); |
jedh | 0:6ed8574c6258 | 354 | |
jedh | 0:6ed8574c6258 | 355 | if (!msje->header.rtr) { |
jedh | 0:6ed8574c6258 | 356 | //Data |
jedh | 0:6ed8574c6258 | 357 | Serial.print(" data: "); |
jedh | 0:6ed8574c6258 | 358 | Serial.print(messageRx.data[0],HEX); Serial.print(","); |
jedh | 0:6ed8574c6258 | 359 | Serial.print(messageRx.data[1],HEX); Serial.print(","); |
jedh | 0:6ed8574c6258 | 360 | Serial.print(messageRx.data[2],HEX); Serial.print(","); |
jedh | 0:6ed8574c6258 | 361 | Serial.print(messageRx.data[3],HEX); Serial.print(","); |
jedh | 0:6ed8574c6258 | 362 | Serial.print(messageRx.data[4],HEX); Serial.print(","); |
jedh | 0:6ed8574c6258 | 363 | Serial.print(messageRx.data[5],HEX); Serial.print(","); |
jedh | 0:6ed8574c6258 | 364 | Serial.print(messageRx.data[6],HEX); Serial.print(","); |
jedh | 0:6ed8574c6258 | 365 | Serial.println(messageRx.data[7],HEX); |
jedh | 0:6ed8574c6258 | 366 | } |
jedh | 0:6ed8574c6258 | 367 | } |
jedh | 0:6ed8574c6258 | 368 | |
jedh | 0:6ed8574c6258 | 369 | |
jedh | 0:6ed8574c6258 | 370 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 371 | //! Name: setMode() |
jedh | 0:6ed8574c6258 | 372 | //! Description: Configure the MCP2515 |
jedh | 0:6ed8574c6258 | 373 | //! Param : uint8_t mode: The work mode |
jedh | 0:6ed8574c6258 | 374 | //! Returns: void |
jedh | 0:6ed8574c6258 | 375 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 376 | void CAN::setMode(uint8_t mode) |
jedh | 0:6ed8574c6258 | 377 | { |
jedh | 0:6ed8574c6258 | 378 | uint8_t mode_register = 0; |
jedh | 0:6ed8574c6258 | 379 | |
jedh | 0:6ed8574c6258 | 380 | if (mode == LISTEN_ONLY_MODE) { |
jedh | 0:6ed8574c6258 | 381 | mode_register = (0<<REQOP2)|(1<<REQOP1)|(1<<REQOP0); |
jedh | 0:6ed8574c6258 | 382 | } |
jedh | 0:6ed8574c6258 | 383 | else if (mode == LOOPBACK_MODE) { |
jedh | 0:6ed8574c6258 | 384 | mode_register = (0<<REQOP2)|(1<<REQOP1)|(0<<REQOP0); |
jedh | 0:6ed8574c6258 | 385 | } |
jedh | 0:6ed8574c6258 | 386 | else if (mode == SLEEP_MODE) { |
jedh | 0:6ed8574c6258 | 387 | mode_register = (0<<REQOP2)|(0<<REQOP1)|(1<<REQOP0); |
jedh | 0:6ed8574c6258 | 388 | } |
jedh | 0:6ed8574c6258 | 389 | else if (mode == NORMAL_MODE) { |
jedh | 0:6ed8574c6258 | 390 | mode_register = (0<<REQOP2)|(0<<REQOP1)|(0<<REQOP0); |
jedh | 0:6ed8574c6258 | 391 | } |
jedh | 0:6ed8574c6258 | 392 | |
jedh | 0:6ed8574c6258 | 393 | //Set the new mode |
jedh | 0:6ed8574c6258 | 394 | bitModify(CANCTRL, (1<<REQOP2)|(1<<REQOP1)|(1<<REQOP0), mode_register); |
jedh | 0:6ed8574c6258 | 395 | |
jedh | 0:6ed8574c6258 | 396 | //Wait until the mode has been changed |
jedh | 0:6ed8574c6258 | 397 | while ((readRegister(CANSTAT) & 0xe0) != mode_register) { } |
jedh | 0:6ed8574c6258 | 398 | } |
jedh | 0:6ed8574c6258 | 399 | |
jedh | 0:6ed8574c6258 | 400 | |
jedh | 0:6ed8574c6258 | 401 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 402 | //! Name: messageAvailable() |
jedh | 0:6ed8574c6258 | 403 | //! Description: Check if there is any message |
jedh | 0:6ed8574c6258 | 404 | //! Param : void |
jedh | 0:6ed8574c6258 | 405 | //! Returns: 1 if available, 0 if not. |
jedh | 0:6ed8574c6258 | 406 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 407 | uint8_t CAN::messageAvailable(void) |
jedh | 0:6ed8574c6258 | 408 | { |
jedh | 0:6ed8574c6258 | 409 | char status = readStatus(SPI_RX_STATUS); |
jedh | 0:6ed8574c6258 | 410 | |
jedh | 0:6ed8574c6258 | 411 | if ( (((status & 0b11000000)>>6)&0b00000011) >2 ) |
jedh | 0:6ed8574c6258 | 412 | { |
jedh | 0:6ed8574c6258 | 413 | return 1; |
jedh | 0:6ed8574c6258 | 414 | } else if (bit_is_set(status,6)) { |
jedh | 0:6ed8574c6258 | 415 | return 1; |
jedh | 0:6ed8574c6258 | 416 | } else if (bit_is_set(status,7)) { |
jedh | 0:6ed8574c6258 | 417 | return 1; |
jedh | 0:6ed8574c6258 | 418 | } else { |
jedh | 0:6ed8574c6258 | 419 | return 0; |
jedh | 0:6ed8574c6258 | 420 | |
jedh | 0:6ed8574c6258 | 421 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 422 | Serial.println("No data available"); |
jedh | 0:6ed8574c6258 | 423 | #endif |
jedh | 0:6ed8574c6258 | 424 | } |
jedh | 0:6ed8574c6258 | 425 | } |
jedh | 0:6ed8574c6258 | 426 | |
jedh | 0:6ed8574c6258 | 427 | //********************************************************************** |
jedh | 0:6ed8574c6258 | 428 | // Standars PIDs |
jedh | 0:6ed8574c6258 | 429 | //********************************************************************** |
jedh | 0:6ed8574c6258 | 430 | |
jedh | 0:6ed8574c6258 | 431 | |
jedh | 0:6ed8574c6258 | 432 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 433 | //! Name: getEngineLoad() |
jedh | 0:6ed8574c6258 | 434 | //! Description: Calculated engine load value |
jedh | 0:6ed8574c6258 | 435 | //! Param : void |
jedh | 0:6ed8574c6258 | 436 | //! Returns: unsigned int: engine load value (0-100) |
jedh | 0:6ed8574c6258 | 437 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 438 | unsigned int CAN::getEngineLoad() |
jedh | 0:6ed8574c6258 | 439 | { |
jedh | 0:6ed8574c6258 | 440 | unsigned int data; |
jedh | 0:6ed8574c6258 | 441 | |
jedh | 0:6ed8574c6258 | 442 | CiARequest(CALC_ENGINE_LOAD); |
jedh | 0:6ed8574c6258 | 443 | |
jedh | 0:6ed8574c6258 | 444 | if (messageRx.id==ID_RESPONSE) { |
jedh | 0:6ed8574c6258 | 445 | data = uint16_t(messageRx.data[3] * 100) / 255; |
jedh | 0:6ed8574c6258 | 446 | |
jedh | 0:6ed8574c6258 | 447 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 448 | printMessage(&messageRx); |
jedh | 0:6ed8574c6258 | 449 | #endif |
jedh | 0:6ed8574c6258 | 450 | } |
jedh | 0:6ed8574c6258 | 451 | |
jedh | 0:6ed8574c6258 | 452 | return data; |
jedh | 0:6ed8574c6258 | 453 | } |
jedh | 0:6ed8574c6258 | 454 | |
jedh | 0:6ed8574c6258 | 455 | |
jedh | 0:6ed8574c6258 | 456 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 457 | //! Name: getEngineCoolantTemp() |
jedh | 0:6ed8574c6258 | 458 | //! Description: Engine coolant temperature |
jedh | 0:6ed8574c6258 | 459 | //! Param : void |
jedh | 0:6ed8574c6258 | 460 | //! Returns: Engine coolant temperature(-40 - 215) |
jedh | 0:6ed8574c6258 | 461 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 462 | unsigned int CAN::getEngineCoolantTemp() |
jedh | 0:6ed8574c6258 | 463 | { |
jedh | 0:6ed8574c6258 | 464 | unsigned int data; |
jedh | 0:6ed8574c6258 | 465 | |
jedh | 0:6ed8574c6258 | 466 | CiARequest(ENGINE_COOLANT_TEMP); |
jedh | 0:6ed8574c6258 | 467 | |
jedh | 0:6ed8574c6258 | 468 | if (messageRx.id==ID_RESPONSE) { |
jedh | 0:6ed8574c6258 | 469 | data = uint16_t(messageRx.data[3] - 40); |
jedh | 0:6ed8574c6258 | 470 | |
jedh | 0:6ed8574c6258 | 471 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 472 | printMessage(&messageRx); |
jedh | 0:6ed8574c6258 | 473 | #endif |
jedh | 0:6ed8574c6258 | 474 | } |
jedh | 0:6ed8574c6258 | 475 | |
jedh | 0:6ed8574c6258 | 476 | return data; |
jedh | 0:6ed8574c6258 | 477 | } |
jedh | 0:6ed8574c6258 | 478 | |
jedh | 0:6ed8574c6258 | 479 | |
jedh | 0:6ed8574c6258 | 480 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 481 | //! Name: getFuelPressure() |
jedh | 0:6ed8574c6258 | 482 | //! Description: Fuel pressure |
jedh | 0:6ed8574c6258 | 483 | //! Param : void |
jedh | 0:6ed8574c6258 | 484 | //! Returns: unsigned int: Fuel pressure (0 - 765 Kpa) |
jedh | 0:6ed8574c6258 | 485 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 486 | unsigned int CAN::getFuelPressure() |
jedh | 0:6ed8574c6258 | 487 | { |
jedh | 0:6ed8574c6258 | 488 | unsigned int data; |
jedh | 0:6ed8574c6258 | 489 | |
jedh | 0:6ed8574c6258 | 490 | CiARequest(FUEL_PRESSURE); |
jedh | 0:6ed8574c6258 | 491 | |
jedh | 0:6ed8574c6258 | 492 | if (messageRx.id==ID_RESPONSE) { |
jedh | 0:6ed8574c6258 | 493 | data = uint16_t(messageRx.data[3] * 3) ; |
jedh | 0:6ed8574c6258 | 494 | |
jedh | 0:6ed8574c6258 | 495 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 496 | printMessage(&messageRx); |
jedh | 0:6ed8574c6258 | 497 | #endif |
jedh | 0:6ed8574c6258 | 498 | } |
jedh | 0:6ed8574c6258 | 499 | |
jedh | 0:6ed8574c6258 | 500 | return data; |
jedh | 0:6ed8574c6258 | 501 | } |
jedh | 0:6ed8574c6258 | 502 | |
jedh | 0:6ed8574c6258 | 503 | |
jedh | 0:6ed8574c6258 | 504 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 505 | //! Name: getIntakeMAPressure() |
jedh | 0:6ed8574c6258 | 506 | //! Description: Intake manifold absolute pressure |
jedh | 0:6ed8574c6258 | 507 | //! Param : void |
jedh | 0:6ed8574c6258 | 508 | //! Returns: unsigned int: absolute pressure (0 - 255 Kpa) |
jedh | 0:6ed8574c6258 | 509 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 510 | unsigned int CAN::getIntakeMAPressure() |
jedh | 0:6ed8574c6258 | 511 | { |
jedh | 0:6ed8574c6258 | 512 | unsigned int data; |
jedh | 0:6ed8574c6258 | 513 | |
jedh | 0:6ed8574c6258 | 514 | CiARequest(INTAKE_M_A_PRESSURE); |
jedh | 0:6ed8574c6258 | 515 | |
jedh | 0:6ed8574c6258 | 516 | if (messageRx.id==ID_RESPONSE) { |
jedh | 0:6ed8574c6258 | 517 | data = messageRx.data[3]; |
jedh | 0:6ed8574c6258 | 518 | |
jedh | 0:6ed8574c6258 | 519 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 520 | printMessage(&messageRx); |
jedh | 0:6ed8574c6258 | 521 | #endif |
jedh | 0:6ed8574c6258 | 522 | } |
jedh | 0:6ed8574c6258 | 523 | |
jedh | 0:6ed8574c6258 | 524 | return data; |
jedh | 0:6ed8574c6258 | 525 | |
jedh | 0:6ed8574c6258 | 526 | |
jedh | 0:6ed8574c6258 | 527 | } |
jedh | 0:6ed8574c6258 | 528 | |
jedh | 0:6ed8574c6258 | 529 | |
jedh | 0:6ed8574c6258 | 530 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 531 | //! Name: getEngineRPM() |
jedh | 0:6ed8574c6258 | 532 | //! Description: Engine RPM |
jedh | 0:6ed8574c6258 | 533 | //! Param : void |
jedh | 0:6ed8574c6258 | 534 | //! Returns: unsigned int: Engine RPM (0 - 16,383 RPM) |
jedh | 0:6ed8574c6258 | 535 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 536 | unsigned int CAN::getEngineRPM() |
jedh | 0:6ed8574c6258 | 537 | { |
jedh | 0:6ed8574c6258 | 538 | |
jedh | 0:6ed8574c6258 | 539 | unsigned int data; |
jedh | 0:6ed8574c6258 | 540 | |
jedh | 0:6ed8574c6258 | 541 | CiARequest(ENGINE_RPM); |
jedh | 0:6ed8574c6258 | 542 | |
jedh | 0:6ed8574c6258 | 543 | if (messageRx.id==ID_RESPONSE) { |
jedh | 0:6ed8574c6258 | 544 | data = (uint16_t(messageRx.data[3]*256) + messageRx.data[4])/4; |
jedh | 0:6ed8574c6258 | 545 | |
jedh | 0:6ed8574c6258 | 546 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 547 | printMessage(&messageRx); |
jedh | 0:6ed8574c6258 | 548 | #endif |
jedh | 0:6ed8574c6258 | 549 | } |
jedh | 0:6ed8574c6258 | 550 | |
jedh | 0:6ed8574c6258 | 551 | return data; |
jedh | 0:6ed8574c6258 | 552 | } |
jedh | 0:6ed8574c6258 | 553 | |
jedh | 0:6ed8574c6258 | 554 | |
jedh | 0:6ed8574c6258 | 555 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 556 | //! Name: getVehicleSpeed() |
jedh | 0:6ed8574c6258 | 557 | //! Description: Vehicle speed |
jedh | 0:6ed8574c6258 | 558 | //! Param : void |
jedh | 0:6ed8574c6258 | 559 | //! Returns: unsigned int: Vehicle speed (0 - 255) |
jedh | 0:6ed8574c6258 | 560 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 561 | unsigned int CAN::getVehicleSpeed() |
jedh | 0:6ed8574c6258 | 562 | { |
jedh | 0:6ed8574c6258 | 563 | unsigned int data; |
jedh | 0:6ed8574c6258 | 564 | |
jedh | 0:6ed8574c6258 | 565 | CiARequest(VEHICLE_SPEED); |
jedh | 0:6ed8574c6258 | 566 | |
jedh | 0:6ed8574c6258 | 567 | if (messageRx.id==ID_RESPONSE) { |
jedh | 0:6ed8574c6258 | 568 | data = uint16_t(messageRx.data[3]); |
jedh | 0:6ed8574c6258 | 569 | |
jedh | 0:6ed8574c6258 | 570 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 571 | printMessage(&messageRx); |
jedh | 0:6ed8574c6258 | 572 | #endif |
jedh | 0:6ed8574c6258 | 573 | } |
jedh | 0:6ed8574c6258 | 574 | |
jedh | 0:6ed8574c6258 | 575 | return data; |
jedh | 0:6ed8574c6258 | 576 | |
jedh | 0:6ed8574c6258 | 577 | } |
jedh | 0:6ed8574c6258 | 578 | |
jedh | 0:6ed8574c6258 | 579 | |
jedh | 0:6ed8574c6258 | 580 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 581 | //! Name: getTimingAdvance() |
jedh | 0:6ed8574c6258 | 582 | //! Description: Timing advance |
jedh | 0:6ed8574c6258 | 583 | //! Param : void |
jedh | 0:6ed8574c6258 | 584 | //! Returns: unsigned int: Time (-64 - 63.5) |
jedh | 0:6ed8574c6258 | 585 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 586 | unsigned int CAN::getTimingAdvance() |
jedh | 0:6ed8574c6258 | 587 | { |
jedh | 0:6ed8574c6258 | 588 | unsigned int data; |
jedh | 0:6ed8574c6258 | 589 | |
jedh | 0:6ed8574c6258 | 590 | CiARequest(TIMING_ADVANCE); |
jedh | 0:6ed8574c6258 | 591 | |
jedh | 0:6ed8574c6258 | 592 | if (messageRx.id==ID_RESPONSE) { |
jedh | 0:6ed8574c6258 | 593 | data = uint16_t(messageRx.data[3] / 2- 64); |
jedh | 0:6ed8574c6258 | 594 | |
jedh | 0:6ed8574c6258 | 595 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 596 | printMessage(&messageRx); |
jedh | 0:6ed8574c6258 | 597 | #endif |
jedh | 0:6ed8574c6258 | 598 | } |
jedh | 0:6ed8574c6258 | 599 | |
jedh | 0:6ed8574c6258 | 600 | return data; |
jedh | 0:6ed8574c6258 | 601 | } |
jedh | 0:6ed8574c6258 | 602 | |
jedh | 0:6ed8574c6258 | 603 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 604 | //! Name: getIntankeAirTemp() |
jedh | 0:6ed8574c6258 | 605 | //! Description: Intake air temperature |
jedh | 0:6ed8574c6258 | 606 | //! Param : void |
jedh | 0:6ed8574c6258 | 607 | //! Returns: unsigned int: Intake air temperature(-40 - 215) |
jedh | 0:6ed8574c6258 | 608 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 609 | unsigned int CAN::getIntankeAirTemp() |
jedh | 0:6ed8574c6258 | 610 | { |
jedh | 0:6ed8574c6258 | 611 | unsigned int data; |
jedh | 0:6ed8574c6258 | 612 | |
jedh | 0:6ed8574c6258 | 613 | CiARequest(INTAKE_AIR_TEMP); |
jedh | 0:6ed8574c6258 | 614 | |
jedh | 0:6ed8574c6258 | 615 | if (messageRx.id==ID_RESPONSE) { |
jedh | 0:6ed8574c6258 | 616 | data = uint16_t(messageRx.data[3] - 40); |
jedh | 0:6ed8574c6258 | 617 | |
jedh | 0:6ed8574c6258 | 618 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 619 | printMessage(&messageRx); |
jedh | 0:6ed8574c6258 | 620 | #endif |
jedh | 0:6ed8574c6258 | 621 | } |
jedh | 0:6ed8574c6258 | 622 | |
jedh | 0:6ed8574c6258 | 623 | return data; |
jedh | 0:6ed8574c6258 | 624 | } |
jedh | 0:6ed8574c6258 | 625 | |
jedh | 0:6ed8574c6258 | 626 | |
jedh | 0:6ed8574c6258 | 627 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 628 | //! Name: getMAFairFlowRate() |
jedh | 0:6ed8574c6258 | 629 | //! Description: MAF air flow rate |
jedh | 0:6ed8574c6258 | 630 | //! Param : void |
jedh | 0:6ed8574c6258 | 631 | //! Returns: unsigned int: air flow rate (0 - 655.35 g/s) |
jedh | 0:6ed8574c6258 | 632 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 633 | unsigned int CAN::getMAFairFlowRate() |
jedh | 0:6ed8574c6258 | 634 | { |
jedh | 0:6ed8574c6258 | 635 | unsigned int data; |
jedh | 0:6ed8574c6258 | 636 | |
jedh | 0:6ed8574c6258 | 637 | CiARequest(MAF_AIR_FLOW_RATE); |
jedh | 0:6ed8574c6258 | 638 | |
jedh | 0:6ed8574c6258 | 639 | if (messageRx.id==ID_RESPONSE) { |
jedh | 0:6ed8574c6258 | 640 | data = ( uint16_t(messageRx.data[3] * 256) + messageRx.data[4]) / 100; |
jedh | 0:6ed8574c6258 | 641 | |
jedh | 0:6ed8574c6258 | 642 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 643 | printMessage(&messageRx); |
jedh | 0:6ed8574c6258 | 644 | #endif |
jedh | 0:6ed8574c6258 | 645 | } |
jedh | 0:6ed8574c6258 | 646 | |
jedh | 0:6ed8574c6258 | 647 | return data; |
jedh | 0:6ed8574c6258 | 648 | |
jedh | 0:6ed8574c6258 | 649 | } |
jedh | 0:6ed8574c6258 | 650 | |
jedh | 0:6ed8574c6258 | 651 | |
jedh | 0:6ed8574c6258 | 652 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 653 | //! Name: getThrottlePosition() |
jedh | 0:6ed8574c6258 | 654 | //! Description: Throttle position |
jedh | 0:6ed8574c6258 | 655 | //! Param : void |
jedh | 0:6ed8574c6258 | 656 | //! Returns: unsigned int: Throttle position (0 - 100%) |
jedh | 0:6ed8574c6258 | 657 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 658 | unsigned int CAN::getThrottlePosition() |
jedh | 0:6ed8574c6258 | 659 | { |
jedh | 0:6ed8574c6258 | 660 | unsigned int data; |
jedh | 0:6ed8574c6258 | 661 | |
jedh | 0:6ed8574c6258 | 662 | CiARequest(THROTTLE_POSITION); |
jedh | 0:6ed8574c6258 | 663 | |
jedh | 0:6ed8574c6258 | 664 | if (messageRx.id==ID_RESPONSE) { |
jedh | 0:6ed8574c6258 | 665 | data = uint16_t(messageRx.data[3] * 100) / 255; |
jedh | 0:6ed8574c6258 | 666 | |
jedh | 0:6ed8574c6258 | 667 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 668 | printMessage(&messageRx); |
jedh | 0:6ed8574c6258 | 669 | #endif |
jedh | 0:6ed8574c6258 | 670 | } |
jedh | 0:6ed8574c6258 | 671 | |
jedh | 0:6ed8574c6258 | 672 | return data; |
jedh | 0:6ed8574c6258 | 673 | |
jedh | 0:6ed8574c6258 | 674 | |
jedh | 0:6ed8574c6258 | 675 | } |
jedh | 0:6ed8574c6258 | 676 | |
jedh | 0:6ed8574c6258 | 677 | |
jedh | 0:6ed8574c6258 | 678 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 679 | //! Name: getFuelLevel() |
jedh | 0:6ed8574c6258 | 680 | //! Description: Fuel Level Input |
jedh | 0:6ed8574c6258 | 681 | //! Param : void |
jedh | 0:6ed8574c6258 | 682 | //! Returns: unsigned int: Fuel Level Input (0 - 100%) |
jedh | 0:6ed8574c6258 | 683 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 684 | unsigned int CAN::getFuelLevel() |
jedh | 0:6ed8574c6258 | 685 | { |
jedh | 0:6ed8574c6258 | 686 | unsigned int data; |
jedh | 0:6ed8574c6258 | 687 | |
jedh | 0:6ed8574c6258 | 688 | CiARequest(FUEL_LEVEL); |
jedh | 0:6ed8574c6258 | 689 | |
jedh | 0:6ed8574c6258 | 690 | if (messageRx.id==ID_RESPONSE) { |
jedh | 0:6ed8574c6258 | 691 | data = uint16_t(messageRx.data[3] * 100) / 255; |
jedh | 0:6ed8574c6258 | 692 | |
jedh | 0:6ed8574c6258 | 693 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 694 | printMessage(&messageRx); |
jedh | 0:6ed8574c6258 | 695 | #endif |
jedh | 0:6ed8574c6258 | 696 | } |
jedh | 0:6ed8574c6258 | 697 | |
jedh | 0:6ed8574c6258 | 698 | return data; |
jedh | 0:6ed8574c6258 | 699 | |
jedh | 0:6ed8574c6258 | 700 | } |
jedh | 0:6ed8574c6258 | 701 | |
jedh | 0:6ed8574c6258 | 702 | |
jedh | 0:6ed8574c6258 | 703 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 704 | //! Name: getBarometricPressure() |
jedh | 0:6ed8574c6258 | 705 | //! Description: Barometric pressure |
jedh | 0:6ed8574c6258 | 706 | //! Param : void |
jedh | 0:6ed8574c6258 | 707 | //! Returns: unsigned int: Barometric pressure (0 - 255 Kpa) |
jedh | 0:6ed8574c6258 | 708 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 709 | unsigned int CAN::getBarometricPressure() |
jedh | 0:6ed8574c6258 | 710 | { |
jedh | 0:6ed8574c6258 | 711 | unsigned int data; |
jedh | 0:6ed8574c6258 | 712 | |
jedh | 0:6ed8574c6258 | 713 | CiARequest(BAROMETRIC_PRESSURE); |
jedh | 0:6ed8574c6258 | 714 | |
jedh | 0:6ed8574c6258 | 715 | if (messageRx.id==ID_RESPONSE) { |
jedh | 0:6ed8574c6258 | 716 | data = uint16_t(messageRx.data[3]); |
jedh | 0:6ed8574c6258 | 717 | |
jedh | 0:6ed8574c6258 | 718 | #if (DEBUGMODE == 1) |
jedh | 0:6ed8574c6258 | 719 | printMessage(&messageRx); |
jedh | 0:6ed8574c6258 | 720 | #endif |
jedh | 0:6ed8574c6258 | 721 | } |
jedh | 0:6ed8574c6258 | 722 | |
jedh | 0:6ed8574c6258 | 723 | return data; |
jedh | 0:6ed8574c6258 | 724 | } |
jedh | 0:6ed8574c6258 | 725 | |
jedh | 0:6ed8574c6258 | 726 | |
jedh | 0:6ed8574c6258 | 727 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 728 | //! Name: getEngineFuelRate() |
jedh | 0:6ed8574c6258 | 729 | //! Description: Engine fuel rate |
jedh | 0:6ed8574c6258 | 730 | //! Param : void |
jedh | 0:6ed8574c6258 | 731 | //! Returns: unsigned int: Engine fuel rate (0 - 3212 L/h) |
jedh | 0:6ed8574c6258 | 732 | //!************************************************************* |
jedh | 0:6ed8574c6258 | 733 | unsigned int CAN::getEngineFuelRate() |
jedh | 0:6ed8574c6258 | 734 | { |
jedh | 0:6ed8574c6258 | 735 | unsigned int data; |
jedh | 0:6ed8574c6258 | 736 | |
jedh | 0:6ed8574c6258 | 737 | CiARequest(ENGINE_FUEL_RATE); |
jedh | 0:6ed8574c6258 | 738 | |
jedh | 0:6ed8574c6258 | 739 | if (messageRx.id==ID_RESPONSE) { |
jedh | 0:6ed8574c6258 | 740 | data = uint16_t((messageRx.data[3] * 256) + messageRx.data[4]) * 0.05; |
jedh | 0:6ed8574c6258 | 741 | |
jedh | 0:6ed8574c6258 | 742 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 743 | printMessage(&messageRx); |
jedh | 0:6ed8574c6258 | 744 | #endif |
jedh | 0:6ed8574c6258 | 745 | } |
jedh | 0:6ed8574c6258 | 746 | |
jedh | 0:6ed8574c6258 | 747 | return data; |
jedh | 0:6ed8574c6258 | 748 | |
jedh | 0:6ed8574c6258 | 749 | } |
jedh | 0:6ed8574c6258 | 750 | |
jedh | 0:6ed8574c6258 | 751 | |
jedh | 0:6ed8574c6258 | 752 | /*********************************************************************** |
jedh | 0:6ed8574c6258 | 753 | CAN in Automation (CiA) |
jedh | 0:6ed8574c6258 | 754 | ***********************************************************************/ |
jedh | 0:6ed8574c6258 | 755 | |
jedh | 0:6ed8574c6258 | 756 | //Request information through OBD |
jedh | 0:6ed8574c6258 | 757 | void CAN::CiARequest(uint8_t PID) |
jedh | 0:6ed8574c6258 | 758 | { |
jedh | 0:6ed8574c6258 | 759 | messageTx.id = ID_QUERY; |
jedh | 0:6ed8574c6258 | 760 | messageTx.header.rtr = 0; |
jedh | 0:6ed8574c6258 | 761 | messageTx.header.length = 8; |
jedh | 0:6ed8574c6258 | 762 | messageTx.data[0]= 0x02; |
jedh | 0:6ed8574c6258 | 763 | messageTx.data[1]= 0x01; |
jedh | 0:6ed8574c6258 | 764 | messageTx.data[2]= PID; |
jedh | 0:6ed8574c6258 | 765 | |
jedh | 0:6ed8574c6258 | 766 | |
jedh | 0:6ed8574c6258 | 767 | sendMessage(&messageTx); |
jedh | 0:6ed8574c6258 | 768 | delay(5); |
jedh | 0:6ed8574c6258 | 769 | |
jedh | 0:6ed8574c6258 | 770 | if (messageAvailable()) { |
jedh | 0:6ed8574c6258 | 771 | //Read the message buffers |
jedh | 0:6ed8574c6258 | 772 | getMessage(&messageRx); |
jedh | 0:6ed8574c6258 | 773 | } |
jedh | 0:6ed8574c6258 | 774 | |
jedh | 0:6ed8574c6258 | 775 | } |
jedh | 0:6ed8574c6258 | 776 | |
jedh | 0:6ed8574c6258 | 777 | |
jedh | 0:6ed8574c6258 | 778 | /*********************************************************************** |
jedh | 0:6ed8574c6258 | 779 | * PRIVATE METHODS |
jedh | 0:6ed8574c6258 | 780 | ***********************************************************************/ |
jedh | 0:6ed8574c6258 | 781 | |
jedh | 0:6ed8574c6258 | 782 | //Write a MCP2515 register |
jedh | 0:6ed8574c6258 | 783 | void CAN::writeRegister( char direction, char data ) |
jedh | 0:6ed8574c6258 | 784 | { |
jedh | 0:6ed8574c6258 | 785 | //CS low to select the MCP2515 |
jedh | 0:6ed8574c6258 | 786 | Utils.setCSSocket0(); |
jedh | 0:6ed8574c6258 | 787 | |
jedh | 0:6ed8574c6258 | 788 | SPI.transfer(SPI_WRITE); |
jedh | 0:6ed8574c6258 | 789 | SPI.transfer(direction); |
jedh | 0:6ed8574c6258 | 790 | SPI.transfer(data); |
jedh | 0:6ed8574c6258 | 791 | |
jedh | 0:6ed8574c6258 | 792 | //CS line again to release |
jedh | 0:6ed8574c6258 | 793 | Utils.unsetCSSocket0(); |
jedh | 0:6ed8574c6258 | 794 | } |
jedh | 0:6ed8574c6258 | 795 | |
jedh | 0:6ed8574c6258 | 796 | |
jedh | 0:6ed8574c6258 | 797 | //********************************************************************** |
jedh | 0:6ed8574c6258 | 798 | |
jedh | 0:6ed8574c6258 | 799 | //Read a MCP2515 register |
jedh | 0:6ed8574c6258 | 800 | char CAN::readRegister(char direction) |
jedh | 0:6ed8574c6258 | 801 | { |
jedh | 0:6ed8574c6258 | 802 | char data; |
jedh | 0:6ed8574c6258 | 803 | |
jedh | 0:6ed8574c6258 | 804 | //CS low to select the MCP2515 |
jedh | 0:6ed8574c6258 | 805 | Utils.setCSSocket0(); |
jedh | 0:6ed8574c6258 | 806 | |
jedh | 0:6ed8574c6258 | 807 | SPI.transfer(SPI_READ); |
jedh | 0:6ed8574c6258 | 808 | SPI.transfer(direction); |
jedh | 0:6ed8574c6258 | 809 | //Read data SPI |
jedh | 0:6ed8574c6258 | 810 | data = SPI.transfer(0xff); |
jedh | 0:6ed8574c6258 | 811 | |
jedh | 0:6ed8574c6258 | 812 | //CS line again to release |
jedh | 0:6ed8574c6258 | 813 | Utils.unsetCSSocket0(); |
jedh | 0:6ed8574c6258 | 814 | |
jedh | 0:6ed8574c6258 | 815 | return data; |
jedh | 0:6ed8574c6258 | 816 | } |
jedh | 0:6ed8574c6258 | 817 | |
jedh | 0:6ed8574c6258 | 818 | |
jedh | 0:6ed8574c6258 | 819 | //*********************************************************************** |
jedh | 0:6ed8574c6258 | 820 | |
jedh | 0:6ed8574c6258 | 821 | //Modify a bit of the MCP2515 registers |
jedh | 0:6ed8574c6258 | 822 | void CAN::bitModify(char direction, char mask, char data) |
jedh | 0:6ed8574c6258 | 823 | { |
jedh | 0:6ed8574c6258 | 824 | //CS low to select the MCP2515 |
jedh | 0:6ed8574c6258 | 825 | Utils.setCSSocket0(); |
jedh | 0:6ed8574c6258 | 826 | |
jedh | 0:6ed8574c6258 | 827 | SPI.transfer(SPI_BIT_MODIFY); |
jedh | 0:6ed8574c6258 | 828 | SPI.transfer(direction); |
jedh | 0:6ed8574c6258 | 829 | SPI.transfer(mask); |
jedh | 0:6ed8574c6258 | 830 | SPI.transfer(data); |
jedh | 0:6ed8574c6258 | 831 | |
jedh | 0:6ed8574c6258 | 832 | //CS line again to release |
jedh | 0:6ed8574c6258 | 833 | Utils.unsetCSSocket0(); |
jedh | 0:6ed8574c6258 | 834 | } |
jedh | 0:6ed8574c6258 | 835 | |
jedh | 0:6ed8574c6258 | 836 | |
jedh | 0:6ed8574c6258 | 837 | //*********************************************************************** |
jedh | 0:6ed8574c6258 | 838 | |
jedh | 0:6ed8574c6258 | 839 | //Check the status of the MCP2515 registers (SPI_RX_STATUS / SPI_READ_STATUS) |
jedh | 0:6ed8574c6258 | 840 | char CAN::readStatus(char type) |
jedh | 0:6ed8574c6258 | 841 | { |
jedh | 0:6ed8574c6258 | 842 | char data; |
jedh | 0:6ed8574c6258 | 843 | |
jedh | 0:6ed8574c6258 | 844 | //CS low to select the MCP2515 |
jedh | 0:6ed8574c6258 | 845 | Utils.setCSSocket0(); |
jedh | 0:6ed8574c6258 | 846 | |
jedh | 0:6ed8574c6258 | 847 | SPI.transfer(type); |
jedh | 0:6ed8574c6258 | 848 | //Read data SPI |
jedh | 0:6ed8574c6258 | 849 | data = SPI.transfer(0xFF); |
jedh | 0:6ed8574c6258 | 850 | |
jedh | 0:6ed8574c6258 | 851 | //CS line again to release |
jedh | 0:6ed8574c6258 | 852 | Utils.unsetCSSocket0(); |
jedh | 0:6ed8574c6258 | 853 | |
jedh | 0:6ed8574c6258 | 854 | return data; |
jedh | 0:6ed8574c6258 | 855 | } |
jedh | 0:6ed8574c6258 | 856 | |
jedh | 0:6ed8574c6258 | 857 | |
jedh | 0:6ed8574c6258 | 858 | //*********************************************************************** |
jedh | 0:6ed8574c6258 | 859 | |
jedh | 0:6ed8574c6258 | 860 | //Check if the buffers are empty |
jedh | 0:6ed8574c6258 | 861 | bool CAN::checkFreeBuffer(void) |
jedh | 0:6ed8574c6258 | 862 | { |
jedh | 0:6ed8574c6258 | 863 | char status = readStatus(SPI_READ_STATUS); |
jedh | 0:6ed8574c6258 | 864 | |
jedh | 0:6ed8574c6258 | 865 | |
jedh | 0:6ed8574c6258 | 866 | if ((status & 0x54) == 0x54) |
jedh | 0:6ed8574c6258 | 867 | { |
jedh | 0:6ed8574c6258 | 868 | //All buffers used |
jedh | 0:6ed8574c6258 | 869 | return false; |
jedh | 0:6ed8574c6258 | 870 | } |
jedh | 0:6ed8574c6258 | 871 | |
jedh | 0:6ed8574c6258 | 872 | return true; |
jedh | 0:6ed8574c6258 | 873 | } |
jedh | 0:6ed8574c6258 | 874 | |
jedh | 0:6ed8574c6258 | 875 | |
jedh | 0:6ed8574c6258 | 876 | //*********************************************************************** |
jedh | 0:6ed8574c6258 | 877 | |
jedh | 0:6ed8574c6258 | 878 | //Reset MCP2515 |
jedh | 0:6ed8574c6258 | 879 | void CAN::reset(void) |
jedh | 0:6ed8574c6258 | 880 | { |
jedh | 0:6ed8574c6258 | 881 | //CS low to select the MCP2515 |
jedh | 0:6ed8574c6258 | 882 | Utils.setCSSocket0(); |
jedh | 0:6ed8574c6258 | 883 | |
jedh | 0:6ed8574c6258 | 884 | SPI.transfer(SPI_RESET); |
jedh | 0:6ed8574c6258 | 885 | //CS line again to release |
jedh | 0:6ed8574c6258 | 886 | Utils.unsetCSSocket0(); |
jedh | 0:6ed8574c6258 | 887 | |
jedh | 0:6ed8574c6258 | 888 | |
jedh | 0:6ed8574c6258 | 889 | //Wait a bit to be stabilized after the reset MCP2515 |
jedh | 0:6ed8574c6258 | 890 | delay(10); |
jedh | 0:6ed8574c6258 | 891 | |
jedh | 0:6ed8574c6258 | 892 | #if (DEBUGMODE==1) |
jedh | 0:6ed8574c6258 | 893 | Serial.println("The MCP2515 has been successfully reset, configuration mode activated"); |
jedh | 0:6ed8574c6258 | 894 | #endif |
jedh | 0:6ed8574c6258 | 895 | } |
jedh | 0:6ed8574c6258 | 896 | |
jedh | 0:6ed8574c6258 | 897 |