Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Ken_CAN_test.cpp@11:abd3df435a2b, 2022-07-06 (annotated)
- Committer:
- kendunlop
- Date:
- Wed Jul 06 11:19:51 2022 +0000
- Revision:
- 11:abd3df435a2b
- Parent:
- 10:3e15baff40e7
- Child:
- 12:e950feba910d
Fixed a lot of reporting errors with info not appearing.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kendunlop | 1:19d183cf2689 | 1 | //This program was created by Ken 8th June 2022 to test the CAN output of a CAN Gateway. |
kendunlop | 4:e8e9bc25b1ca | 2 | #define kMajorVersion 0 //Defines a major and minor version to be shown later in the program. |
kendunlop | 1:19d183cf2689 | 3 | #define kMinorVersion 5 |
kendunlop | 1:19d183cf2689 | 4 | |
kendunlop | 1:19d183cf2689 | 5 | #include "mbed.h" //Including mbed libraries. This should be all it needs to use the Mbed and CAN. |
kendunlop | 1:19d183cf2689 | 6 | #include <string> //This is needed to make text strings work |
kendunlop | 1:19d183cf2689 | 7 | #include <stdio.h> |
kendunlop | 1:19d183cf2689 | 8 | #include <ctype.h> //For 'is digit' condition |
kendunlop | 1:19d183cf2689 | 9 | #include <sstream> //This is used to convert an integer to hex |
kendunlop | 2:11339018dda6 | 10 | #include <time.h> //To measure how long a process took? Includes clock_t and CLOCKS_PER_SEC |
kendunlop | 1:19d183cf2689 | 11 | |
kendunlop | 3:79133dcea836 | 12 | RawSerial pc(USBTX, USBRX); // USB UART Terminal, tx, rx. Is needed for 'pc.printf' functions to work. |
kendunlop | 3:79133dcea836 | 13 | |
kendunlop | 3:79133dcea836 | 14 | // NOTE: Original pins for CAN Bus 1 are 9 and 10. |
kendunlop | 7:a9150dc1e481 | 15 | CAN CanBus(p9, p10); //CANBus to use pins 9 and 10. This defines CanBus so other 'CanBus' lines will work. |
kendunlop | 7:a9150dc1e481 | 16 | CAN CanBus2(p30, p29); //CANBus2 for recieving to use pins 30 and 29 (in that order!). |
kendunlop | 1:19d183cf2689 | 17 | CANMessage messageIn; |
kendunlop | 1:19d183cf2689 | 18 | |
kendunlop | 1:19d183cf2689 | 19 | //Define a CAN message to send |
kendunlop | 1:19d183cf2689 | 20 | CANMessage messageOut1; |
kendunlop | 1:19d183cf2689 | 21 | |
kendunlop | 1:19d183cf2689 | 22 | //Set messageOutText to a default message so it's defined. |
kendunlop | 5:bf4c6278ca8b | 23 | string messageOutText = ""; |
kendunlop | 7:a9150dc1e481 | 24 | string messageOutTextWithSpaces = ""; |
kendunlop | 8:6f096b45ca15 | 25 | string buttonPressMessageOutText = ""; |
kendunlop | 1:19d183cf2689 | 26 | string part = ""; |
kendunlop | 1:19d183cf2689 | 27 | int partincrement = 0; |
kendunlop | 3:79133dcea836 | 28 | __int64 incrementer = 0; |
kendunlop | 1:19d183cf2689 | 29 | int CANCount = 0; |
kendunlop | 9:7c27efe30a77 | 30 | |
kendunlop | 4:e8e9bc25b1ca | 31 | int spamon = 0; |
kendunlop | 6:2882710e4f1e | 32 | int idspamon = 0; |
kendunlop | 8:6f096b45ca15 | 33 | int idscheckedcount = 0; |
kendunlop | 1:19d183cf2689 | 34 | int spamcount = 0; |
kendunlop | 3:79133dcea836 | 35 | int totalspamsever = 0; |
kendunlop | 2:11339018dda6 | 36 | int spamstarttime = 0; |
kendunlop | 2:11339018dda6 | 37 | int spamendtime = 0; |
kendunlop | 9:7c27efe30a77 | 38 | int spamsecondstotal = 0; |
kendunlop | 9:7c27efe30a77 | 39 | int spamspersecond = 0; |
kendunlop | 10:3e15baff40e7 | 40 | int messagesinpersecond = 0; |
kendunlop | 9:7c27efe30a77 | 41 | |
kendunlop | 3:79133dcea836 | 42 | int vlistincrementer = 0; |
kendunlop | 6:2882710e4f1e | 43 | int idlistincrementer = 0; |
kendunlop | 6:2882710e4f1e | 44 | string spampreamble = "333"; |
kendunlop | 7:a9150dc1e481 | 45 | int expected1 = 0; |
kendunlop | 7:a9150dc1e481 | 46 | int expected2 = 0; |
kendunlop | 7:a9150dc1e481 | 47 | unsigned char expected3 = 0; |
kendunlop | 7:a9150dc1e481 | 48 | unsigned char expected4 = 0; |
kendunlop | 7:a9150dc1e481 | 49 | unsigned char expected5 = 0; |
kendunlop | 7:a9150dc1e481 | 50 | unsigned char expected6 = 0; |
kendunlop | 7:a9150dc1e481 | 51 | unsigned char expected7 = 0; |
kendunlop | 7:a9150dc1e481 | 52 | unsigned char expected8 = 0; |
kendunlop | 7:a9150dc1e481 | 53 | unsigned char expected9 = 0; |
kendunlop | 7:a9150dc1e481 | 54 | unsigned char expected10 = 0; |
kendunlop | 8:6f096b45ca15 | 55 | int expectationwasfulfilled = -1; |
kendunlop | 8:6f096b45ca15 | 56 | int expectationresolved = 1; |
kendunlop | 8:6f096b45ca15 | 57 | int expectationtimer = 0; |
kendunlop | 8:6f096b45ca15 | 58 | int shouldntcomein = 0; |
kendunlop | 9:7c27efe30a77 | 59 | int goodnoreplies = 0; |
kendunlop | 9:7c27efe30a77 | 60 | int goodnoreplystreak = 0; |
kendunlop | 9:7c27efe30a77 | 61 | int goodnoreplystreakstartid = 0; |
kendunlop | 9:7c27efe30a77 | 62 | int CANmatchstreak = 0; |
kendunlop | 9:7c27efe30a77 | 63 | int CANmatchstreakstartID = 0; |
kendunlop | 9:7c27efe30a77 | 64 | int unexpectedCANfails = 0; |
kendunlop | 9:7c27efe30a77 | 65 | int unexpectedCANstreak = 0; |
kendunlop | 9:7c27efe30a77 | 66 | int unexpectedCANstreakstartid = 0; |
kendunlop | 7:a9150dc1e481 | 67 | int failsthistest = 0; |
kendunlop | 11:abd3df435a2b | 68 | int failsstreak = 0; |
kendunlop | 11:abd3df435a2b | 69 | int failsstreakstart = 0; |
kendunlop | 11:abd3df435a2b | 70 | int reportfailsindividually = 0; |
kendunlop | 8:6f096b45ca15 | 71 | int noreplyfailsthistest = 0; |
kendunlop | 9:7c27efe30a77 | 72 | int noreplystreak = 0; |
kendunlop | 9:7c27efe30a77 | 73 | int noreplystreakstartid = 0; |
kendunlop | 9:7c27efe30a77 | 74 | |
kendunlop | 8:6f096b45ca15 | 75 | int mismatchfailsthistest = 0; |
kendunlop | 9:7c27efe30a77 | 76 | int matchesthistest = 0; |
kendunlop | 7:a9150dc1e481 | 77 | int addnewlinetonextmessage = 0; |
kendunlop | 11:abd3df435a2b | 78 | int checklaterbytes = 1; |
kendunlop | 8:6f096b45ca15 | 79 | int aspamisgoing = 0; |
kendunlop | 8:6f096b45ca15 | 80 | int CANpassthrough = 1; |
kendunlop | 10:3e15baff40e7 | 81 | int speedspamison = 0; |
kendunlop | 10:3e15baff40e7 | 82 | int messagesincount = 0; |
kendunlop | 11:abd3df435a2b | 83 | int messageinisneeded = 0; |
kendunlop | 11:abd3df435a2b | 84 | |
kendunlop | 11:abd3df435a2b | 85 | int idwasfound = 0; |
kendunlop | 11:abd3df435a2b | 86 | int columnidwasfound = 0; |
kendunlop | 8:6f096b45ca15 | 87 | |
kendunlop | 9:7c27efe30a77 | 88 | int mbedCANbusspeed = 500 * 1000; |
kendunlop | 9:7c27efe30a77 | 89 | int CANGatewayCANbusspeed = 500 * 1000; |
kendunlop | 10:3e15baff40e7 | 90 | int listen = 1; |
kendunlop | 11:abd3df435a2b | 91 | int testwasaborted = 0; |
kendunlop | 11:abd3df435a2b | 92 | |
kendunlop | 11:abd3df435a2b | 93 | int customentry = 0; |
kendunlop | 11:abd3df435a2b | 94 | int normalkeypresses = 1; |
kendunlop | 11:abd3df435a2b | 95 | string customentrystring = ""; |
kendunlop | 11:abd3df435a2b | 96 | int hextotal = 0; |
kendunlop | 9:7c27efe30a77 | 97 | |
kendunlop | 8:6f096b45ca15 | 98 | //Array of IDs to translate can be overwritten with the 'copyarray'. |
kendunlop | 8:6f096b45ca15 | 99 | //It's arranged in columns of IDs that are translated to the ID in the next column. |
kendunlop | 8:6f096b45ca15 | 100 | //NOTE: Array must be a large enough size to contain all ID translations. |
kendunlop | 11:abd3df435a2b | 101 | int idsarray[2][8][10] = {}; |
kendunlop | 8:6f096b45ca15 | 102 | int arrayx = 2; |
kendunlop | 8:6f096b45ca15 | 103 | int arrayy = 8; |
kendunlop | 11:abd3df435a2b | 104 | int arrayz = 10; |
kendunlop | 8:6f096b45ca15 | 105 | |
kendunlop | 9:7c27efe30a77 | 106 | //A function to easily get the total of seconds a spam has taken |
kendunlop | 9:7c27efe30a77 | 107 | int getspamsecondstotal(void) |
kendunlop | 9:7c27efe30a77 | 108 | { |
kendunlop | 9:7c27efe30a77 | 109 | //pc.printf("\r\nHere I'll get the spam seconds total!\r\n"); |
kendunlop | 9:7c27efe30a77 | 110 | //pc.printf("Spam start/end time was %d / %d.\r\n", spamstarttime, spamendtime); |
kendunlop | 9:7c27efe30a77 | 111 | int spamtickstotal = (spamendtime - spamstarttime); |
kendunlop | 9:7c27efe30a77 | 112 | //pc.printf("Spam ticks total is %d.\r\n", spamtickstotal); |
kendunlop | 9:7c27efe30a77 | 113 | //pc.printf("CLOCKS_PER_SEC are %d.\r\n", CLOCKS_PER_SEC); |
kendunlop | 9:7c27efe30a77 | 114 | //pc.printf("Spamcount this test is %d.\r\n", spamcount); |
kendunlop | 9:7c27efe30a77 | 115 | spamsecondstotal = ((spamendtime - spamstarttime) / CLOCKS_PER_SEC); |
kendunlop | 9:7c27efe30a77 | 116 | //pc.printf("Spam seconds total is %d.\r\n", spamsecondstotal); |
kendunlop | 9:7c27efe30a77 | 117 | spamspersecond = (10000 * spamcount); |
kendunlop | 10:3e15baff40e7 | 118 | messagesinpersecond = (10000 * messagesincount); |
kendunlop | 9:7c27efe30a77 | 119 | //pc.printf("Spams biggened x 10,000 is %d.\r\n", spamspersecond); |
kendunlop | 9:7c27efe30a77 | 120 | spamspersecond = (spamspersecond / spamtickstotal); |
kendunlop | 10:3e15baff40e7 | 121 | messagesinpersecond = (messagesinpersecond / spamtickstotal); |
kendunlop | 9:7c27efe30a77 | 122 | //pc.printf("Spams per tick, still biggened, is %d.\r\n", spamspersecond); |
kendunlop | 9:7c27efe30a77 | 123 | spamspersecond = (spamspersecond * CLOCKS_PER_SEC); |
kendunlop | 10:3e15baff40e7 | 124 | messagesinpersecond = (messagesinpersecond * CLOCKS_PER_SEC); |
kendunlop | 9:7c27efe30a77 | 125 | //pc.printf("Spams per second, still biggened, given %d ticks per second, is %d.\r\n", CLOCKS_PER_SEC, spamspersecond); |
kendunlop | 10:3e15baff40e7 | 126 | spamspersecond = (spamspersecond / 10000); |
kendunlop | 10:3e15baff40e7 | 127 | messagesinpersecond = (messagesinpersecond / 10000); |
kendunlop | 9:7c27efe30a77 | 128 | //pc.printf("Spams per second, un-biggened, is %d.\r\n", spamspersecond); |
kendunlop | 10:3e15baff40e7 | 129 | //pc.printf("\r\nSent %d messages for %d ticks (%d seconds) at %d ticks per second. Messages per second is %d.\r\n", spamcount, spamtickstotal, spamsecondstotal, CLOCKS_PER_SEC, spamspersecond); //Old version of the message |
kendunlop | 10:3e15baff40e7 | 130 | if (speedspamison == 0) |
kendunlop | 10:3e15baff40e7 | 131 | { |
kendunlop | 11:abd3df435a2b | 132 | if (aspamisgoing == 1) |
kendunlop | 11:abd3df435a2b | 133 | { |
kendunlop | 11:abd3df435a2b | 134 | pc.printf("\n"); |
kendunlop | 11:abd3df435a2b | 135 | } |
kendunlop | 10:3e15baff40e7 | 136 | pc.printf("\rSent %d messages over %d seconds. Messages per second is %d.\r\n", spamcount, spamsecondstotal, spamspersecond); |
kendunlop | 10:3e15baff40e7 | 137 | } |
kendunlop | 9:7c27efe30a77 | 138 | return(spamsecondstotal, spamspersecond); |
kendunlop | 9:7c27efe30a77 | 139 | } |
kendunlop | 9:7c27efe30a77 | 140 | |
kendunlop | 10:3e15baff40e7 | 141 | //A function to report if baud rates differ |
kendunlop | 10:3e15baff40e7 | 142 | void reportbaudrates(void) |
kendunlop | 10:3e15baff40e7 | 143 | { |
kendunlop | 10:3e15baff40e7 | 144 | if (mbedCANbusspeed != CANGatewayCANbusspeed) |
kendunlop | 10:3e15baff40e7 | 145 | { |
kendunlop | 10:3e15baff40e7 | 146 | pc.printf("Mbed baud rate (%d) is different from assumed CAN Gateway baud rate (%d), will expect no CAN.\r\n", (mbedCANbusspeed / 1000), (CANGatewayCANbusspeed / 1000)); |
kendunlop | 10:3e15baff40e7 | 147 | } |
kendunlop | 10:3e15baff40e7 | 148 | } |
kendunlop | 10:3e15baff40e7 | 149 | |
kendunlop | 8:6f096b45ca15 | 150 | //A function to handle when CAN-expectations are not fulfilled |
kendunlop | 8:6f096b45ca15 | 151 | void expectationwasnotfulfilled(void) |
kendunlop | 8:6f096b45ca15 | 152 | { |
kendunlop | 8:6f096b45ca15 | 153 | //pc.printf("Expectation was not fulfilled for that message!\r\n"); |
kendunlop | 8:6f096b45ca15 | 154 | } |
kendunlop | 7:a9150dc1e481 | 155 | |
kendunlop | 7:a9150dc1e481 | 156 | //A function to clear all test-related variables |
kendunlop | 11:abd3df435a2b | 157 | void resetCANbuses()//A quick method to reset both CAN buses conveniently |
kendunlop | 11:abd3df435a2b | 158 | { |
kendunlop | 11:abd3df435a2b | 159 | CanBus.reset(); // Clear any bus errors. Will this stop the 'cached' CAN sticking around? |
kendunlop | 11:abd3df435a2b | 160 | CanBus2.reset(); // Clear any bus errors. Will this stop the 'cached' CAN sticking around? |
kendunlop | 11:abd3df435a2b | 161 | } |
kendunlop | 11:abd3df435a2b | 162 | |
kendunlop | 7:a9150dc1e481 | 163 | void resettest(void) |
kendunlop | 7:a9150dc1e481 | 164 | { |
kendunlop | 9:7c27efe30a77 | 165 | //pc.printf("Resetting test.\r\n"); |
kendunlop | 11:abd3df435a2b | 166 | listen = 1; |
kendunlop | 7:a9150dc1e481 | 167 | failsthistest = 0; |
kendunlop | 11:abd3df435a2b | 168 | failsstreak = 0; |
kendunlop | 11:abd3df435a2b | 169 | failsstreakstart = 0; |
kendunlop | 9:7c27efe30a77 | 170 | spamcount = 0; |
kendunlop | 8:6f096b45ca15 | 171 | noreplyfailsthistest = 0; |
kendunlop | 9:7c27efe30a77 | 172 | goodnoreplies = 0; |
kendunlop | 9:7c27efe30a77 | 173 | goodnoreplystreak = 0; |
kendunlop | 9:7c27efe30a77 | 174 | goodnoreplystreakstartid = 0; |
kendunlop | 9:7c27efe30a77 | 175 | noreplystreak = 0; |
kendunlop | 9:7c27efe30a77 | 176 | noreplystreakstartid = 0; |
kendunlop | 9:7c27efe30a77 | 177 | CANmatchstreak = 0; |
kendunlop | 9:7c27efe30a77 | 178 | CANmatchstreakstartID = 0; |
kendunlop | 8:6f096b45ca15 | 179 | mismatchfailsthistest = 0; |
kendunlop | 9:7c27efe30a77 | 180 | matchesthistest = 0; |
kendunlop | 8:6f096b45ca15 | 181 | idscheckedcount = 0; |
kendunlop | 9:7c27efe30a77 | 182 | unexpectedCANfails = 0; |
kendunlop | 9:7c27efe30a77 | 183 | unexpectedCANstreak = 0; |
kendunlop | 9:7c27efe30a77 | 184 | unexpectedCANstreakstartid = 0; |
kendunlop | 10:3e15baff40e7 | 185 | messagesincount = 0; |
kendunlop | 11:abd3df435a2b | 186 | testwasaborted = 0; |
kendunlop | 7:a9150dc1e481 | 187 | } |
kendunlop | 7:a9150dc1e481 | 188 | |
kendunlop | 7:a9150dc1e481 | 189 | //A function to add a carriage return in the output if the system has been writing out the CAN messages it sends. |
kendunlop | 7:a9150dc1e481 | 190 | void addnewlineifneeded(void) |
kendunlop | 7:a9150dc1e481 | 191 | { |
kendunlop | 7:a9150dc1e481 | 192 | if (addnewlinetonextmessage == 1) |
kendunlop | 7:a9150dc1e481 | 193 | { |
kendunlop | 7:a9150dc1e481 | 194 | pc.printf("\r\n"); |
kendunlop | 7:a9150dc1e481 | 195 | addnewlinetonextmessage = 0; |
kendunlop | 7:a9150dc1e481 | 196 | } |
kendunlop | 7:a9150dc1e481 | 197 | } |
kendunlop | 7:a9150dc1e481 | 198 | |
kendunlop | 9:7c27efe30a77 | 199 | void reportsentCAN() //A function to print out the CAN that was sent. Messages can only be positioned correctly once their results are known. |
kendunlop | 9:7c27efe30a77 | 200 | { |
kendunlop | 9:7c27efe30a77 | 201 | pc.printf("\033[1;33m\rSent out : %s \033[0m", messageOutTextWithSpaces); |
kendunlop | 9:7c27efe30a77 | 202 | } |
kendunlop | 9:7c27efe30a77 | 203 | |
kendunlop | 7:a9150dc1e481 | 204 | |
kendunlop | 7:a9150dc1e481 | 205 | //A function to end a test and report on findings. |
kendunlop | 7:a9150dc1e481 | 206 | void endtest() |
kendunlop | 7:a9150dc1e481 | 207 | { |
kendunlop | 11:abd3df435a2b | 208 | listen = 0; |
kendunlop | 8:6f096b45ca15 | 209 | expectationresolved = 1; |
kendunlop | 11:abd3df435a2b | 210 | if (testwasaborted == 1) |
kendunlop | 7:a9150dc1e481 | 211 | { |
kendunlop | 11:abd3df435a2b | 212 | pc.printf("\033[1;35mTest was aborted, results invalid.\033[0m\r\n"); |
kendunlop | 11:abd3df435a2b | 213 | pc.printf("\033[1;35m%d IDs sent out. %d failures found so far.\033[0m\r\n", spamcount, failsthistest); |
kendunlop | 9:7c27efe30a77 | 214 | if (CANpassthrough == 0) |
kendunlop | 9:7c27efe30a77 | 215 | { |
kendunlop | 11:abd3df435a2b | 216 | pc.printf("\033[1;35m%d expected non-replies found so far. \033[0m", goodnoreplies); |
kendunlop | 9:7c27efe30a77 | 217 | } |
kendunlop | 11:abd3df435a2b | 218 | pc.printf("\033[1;35m%d CAN matches found so far.\033[0m\r\n", matchesthistest); |
kendunlop | 7:a9150dc1e481 | 219 | } |
kendunlop | 11:abd3df435a2b | 220 | if (failsthistest == 0 and testwasaborted == 0) |
kendunlop | 7:a9150dc1e481 | 221 | { |
kendunlop | 11:abd3df435a2b | 222 | pc.printf("\033[1;32mTest passed.\033[0m\r\n"); |
kendunlop | 11:abd3df435a2b | 223 | pc.printf("\033[1;32m%d IDs sent out. \033[0m", spamcount); |
kendunlop | 11:abd3df435a2b | 224 | pc.printf("\033[1;32m%d failures found.\033[0m\r\n", failsthistest); |
kendunlop | 11:abd3df435a2b | 225 | if (CANpassthrough == 0) |
kendunlop | 11:abd3df435a2b | 226 | { |
kendunlop | 11:abd3df435a2b | 227 | pc.printf("\033[1;32m%d expected non-replies found. \033[0m", goodnoreplies); |
kendunlop | 11:abd3df435a2b | 228 | } |
kendunlop | 11:abd3df435a2b | 229 | pc.printf("\033[1;32m%d CAN matches found.\033[0m\r\n", matchesthistest); |
kendunlop | 11:abd3df435a2b | 230 | } |
kendunlop | 11:abd3df435a2b | 231 | if (failsthistest > 0 and testwasaborted == 0) |
kendunlop | 11:abd3df435a2b | 232 | { |
kendunlop | 11:abd3df435a2b | 233 | pc.printf("\033[1;31mTest failed.\r\n%d failures found.\033[0m\r\n", failsthistest); |
kendunlop | 9:7c27efe30a77 | 234 | pc.printf("\033[1;31m%d mismatch failures, %d 'no reply' failures, %d unexpected CAN messages.\033[0m\r\n", mismatchfailsthistest, noreplyfailsthistest, unexpectedCANfails); |
kendunlop | 9:7c27efe30a77 | 235 | if (goodnoreplies > 0) |
kendunlop | 9:7c27efe30a77 | 236 | { |
kendunlop | 9:7c27efe30a77 | 237 | pc.printf("\033[1;31m%d expected non-replies occurred.\033[0m\r\n", goodnoreplies); |
kendunlop | 9:7c27efe30a77 | 238 | } |
kendunlop | 7:a9150dc1e481 | 239 | } |
kendunlop | 9:7c27efe30a77 | 240 | //addnewlineifneeded(); |
kendunlop | 7:a9150dc1e481 | 241 | pc.printf("-------------------------------------\r\n"); |
kendunlop | 7:a9150dc1e481 | 242 | failsthistest = 0; |
kendunlop | 11:abd3df435a2b | 243 | normalkeypresses = 1; |
kendunlop | 11:abd3df435a2b | 244 | } |
kendunlop | 11:abd3df435a2b | 245 | |
kendunlop | 11:abd3df435a2b | 246 | //'End ID spam test' function so you can end it by reaching 2048 IDs or pressing 'Esc' while it's running |
kendunlop | 11:abd3df435a2b | 247 | void endidspamtest() |
kendunlop | 11:abd3df435a2b | 248 | { |
kendunlop | 11:abd3df435a2b | 249 | spamendtime = clock(); |
kendunlop | 11:abd3df435a2b | 250 | getspamsecondstotal();//Process the spam information |
kendunlop | 11:abd3df435a2b | 251 | idspamon = 0; |
kendunlop | 11:abd3df435a2b | 252 | aspamisgoing = 0; |
kendunlop | 11:abd3df435a2b | 253 | normalkeypresses = 0; |
kendunlop | 11:abd3df435a2b | 254 | addnewlinetonextmessage = 1; |
kendunlop | 11:abd3df435a2b | 255 | //addnewlineifneeded(); |
kendunlop | 11:abd3df435a2b | 256 | //pc.printf("Ending ID spam sequence. %d IDs checked total.\r\n", idscheckedcount); |
kendunlop | 11:abd3df435a2b | 257 | idlistincrementer = 0; |
kendunlop | 11:abd3df435a2b | 258 | endtest(); |
kendunlop | 7:a9150dc1e481 | 259 | } |
kendunlop | 10:3e15baff40e7 | 260 | |
kendunlop | 10:3e15baff40e7 | 261 | void endspeedtest()//A different 'end' routine for speed tests. |
kendunlop | 10:3e15baff40e7 | 262 | { |
kendunlop | 10:3e15baff40e7 | 263 | //if (messagesincount == spamcount - 1)//If the messages in are only one less than messages out, adjust since it's probably just the test cancelling before getting that last message. |
kendunlop | 10:3e15baff40e7 | 264 | //{ |
kendunlop | 10:3e15baff40e7 | 265 | //pc.printf("messagesincount is only one less than spamcount, setting it.\r\n"); |
kendunlop | 10:3e15baff40e7 | 266 | //messagesincount = spamcount; |
kendunlop | 10:3e15baff40e7 | 267 | //} |
kendunlop | 11:abd3df435a2b | 268 | listen = 0; |
kendunlop | 10:3e15baff40e7 | 269 | pc.printf("Ending CAN speed test.\r\n"); |
kendunlop | 10:3e15baff40e7 | 270 | pc.printf("%d messages sent. ", spamcount); |
kendunlop | 11:abd3df435a2b | 271 | pc.printf("%d messages detected coming back in over %d seconds.\r\n", messagesincount, spamsecondstotal); |
kendunlop | 10:3e15baff40e7 | 272 | int speedtestpercentage = ((messagesincount * 100)/spamcount); |
kendunlop | 10:3e15baff40e7 | 273 | int speedtestpasslevel = 90; |
kendunlop | 10:3e15baff40e7 | 274 | if (speedtestpercentage >= speedtestpasslevel) |
kendunlop | 10:3e15baff40e7 | 275 | { |
kendunlop | 11:abd3df435a2b | 276 | //pc.printf("\033[1;32mTest pass: %d%% of messages detected back.\033[0m\r\n\n", speedtestpercentage); |
kendunlop | 10:3e15baff40e7 | 277 | } |
kendunlop | 10:3e15baff40e7 | 278 | else |
kendunlop | 10:3e15baff40e7 | 279 | { |
kendunlop | 11:abd3df435a2b | 280 | //pc.printf("\033[1;31mTest fail: %d%% of messages detected back.\033[0m\r\n\n", speedtestpercentage); |
kendunlop | 10:3e15baff40e7 | 281 | } |
kendunlop | 11:abd3df435a2b | 282 | speedtestpasslevel = (CANGatewayCANbusspeed / 1000) * 8; //The HD2 can do 80 channels at 100Hz, so 8,000 messages per second are required at top baud rate (1000kbit/s) |
kendunlop | 11:abd3df435a2b | 283 | if (CANGatewayCANbusspeed == mbedCANbusspeed) |
kendunlop | 11:abd3df435a2b | 284 | { |
kendunlop | 11:abd3df435a2b | 285 | if (messagesinpersecond >= speedtestpasslevel) |
kendunlop | 11:abd3df435a2b | 286 | { |
kendunlop | 11:abd3df435a2b | 287 | pc.printf("\033[1;32mTest pass: %d messages in per second. (%d required for pass at Gateway baud rate %d.)\033[0m\r\n", messagesinpersecond, speedtestpasslevel, CANGatewayCANbusspeed / 1000); |
kendunlop | 11:abd3df435a2b | 288 | } |
kendunlop | 11:abd3df435a2b | 289 | if (messagesinpersecond < speedtestpasslevel) |
kendunlop | 11:abd3df435a2b | 290 | { |
kendunlop | 11:abd3df435a2b | 291 | pc.printf("\033[1;31mTest fail: %d messages in per second. (%d required for pass at Gateway baud rate %d.)\033[0m\r\n", messagesinpersecond, speedtestpasslevel, CANGatewayCANbusspeed / 1000); |
kendunlop | 11:abd3df435a2b | 292 | } |
kendunlop | 11:abd3df435a2b | 293 | } |
kendunlop | 11:abd3df435a2b | 294 | if (CANGatewayCANbusspeed != mbedCANbusspeed) |
kendunlop | 11:abd3df435a2b | 295 | { |
kendunlop | 11:abd3df435a2b | 296 | pc.printf("\033[1;35mTest invalid: Mbed CAN bus baud rate (%d) does not match presumed CAN Gateway baud rate (%d).\033[0m\r\n", mbedCANbusspeed / 1000, CANGatewayCANbusspeed / 1000); |
kendunlop | 11:abd3df435a2b | 297 | } |
kendunlop | 11:abd3df435a2b | 298 | pc.printf("\n");//Add an extra new line so the whole baud rate test is separate from the rest of the text. |
kendunlop | 10:3e15baff40e7 | 299 | } |
kendunlop | 7:a9150dc1e481 | 300 | |
kendunlop | 7:a9150dc1e481 | 301 | //A generic 'send CAN' function to send CAN with a standard message |
kendunlop | 7:a9150dc1e481 | 302 | void sendCAN(void) |
kendunlop | 7:a9150dc1e481 | 303 | { |
kendunlop | 7:a9150dc1e481 | 304 | CanBus.write(messageOut1); |
kendunlop | 7:a9150dc1e481 | 305 | //addnewlineifneeded(); |
kendunlop | 8:6f096b45ca15 | 306 | if (aspamisgoing == 0) |
kendunlop | 8:6f096b45ca15 | 307 | { |
kendunlop | 8:6f096b45ca15 | 308 | //pc.printf("\r\n"); |
kendunlop | 8:6f096b45ca15 | 309 | } |
kendunlop | 8:6f096b45ca15 | 310 | expectationresolved = 0; |
kendunlop | 8:6f096b45ca15 | 311 | //pc.printf("Expectationresolved now is %d.", expectationresolved); |
kendunlop | 8:6f096b45ca15 | 312 | expectationtimer = 0; |
kendunlop | 7:a9150dc1e481 | 313 | //addnewlinetonextmessage = 1; |
kendunlop | 7:a9150dc1e481 | 314 | } |
kendunlop | 1:19d183cf2689 | 315 | |
kendunlop | 2:11339018dda6 | 316 | //A function to deal with each CAN message part (e.g.: 301, 8, 01, 02...) |
kendunlop | 1:19d183cf2689 | 317 | void dealwithpart(void) |
kendunlop | 1:19d183cf2689 | 318 | { |
kendunlop | 11:abd3df435a2b | 319 | hextotal = 0; |
kendunlop | 1:19d183cf2689 | 320 | partincrement = partincrement + 1; |
kendunlop | 1:19d183cf2689 | 321 | //pc.printf("Dealing with part %d. (%s)\r\n", partincrement, part); |
kendunlop | 1:19d183cf2689 | 322 | //int partincrementb = 0; |
kendunlop | 1:19d183cf2689 | 323 | int textlength = part.length(); |
kendunlop | 1:19d183cf2689 | 324 | //int characterinc = 0; |
kendunlop | 1:19d183cf2689 | 325 | //pc.printf("That's %d characters long.\r\n", textlength); |
kendunlop | 1:19d183cf2689 | 326 | for (int i = 0; i < part.size(); i++) |
kendunlop | 1:19d183cf2689 | 327 | { |
kendunlop | 1:19d183cf2689 | 328 | //pc.printf("Examining character %d/%d.\r\n", (i+1), textlength); |
kendunlop | 1:19d183cf2689 | 329 | char individualcharacter = part.at(i); |
kendunlop | 1:19d183cf2689 | 330 | //pc.printf("That's '%c'.\r\n", individualcharacter); |
kendunlop | 1:19d183cf2689 | 331 | int numberized = 0; |
kendunlop | 1:19d183cf2689 | 332 | if(isdigit(individualcharacter)) |
kendunlop | 1:19d183cf2689 | 333 | { |
kendunlop | 1:19d183cf2689 | 334 | //pc.printf("That character is a digit.\r\n"); |
kendunlop | 1:19d183cf2689 | 335 | numberized = individualcharacter - '0'; |
kendunlop | 1:19d183cf2689 | 336 | //pc.printf("Numberized that's '%d'.\r\n", numberized); |
kendunlop | 1:19d183cf2689 | 337 | } |
kendunlop | 1:19d183cf2689 | 338 | else |
kendunlop | 1:19d183cf2689 | 339 | { |
kendunlop | 1:19d183cf2689 | 340 | //pc.printf("That character is NOT a digit.\r\n"); |
kendunlop | 1:19d183cf2689 | 341 | int asciivalue = toupper(individualcharacter); |
kendunlop | 1:19d183cf2689 | 342 | //pc.printf("Ascii value is %d.\r\n", asciivalue); |
kendunlop | 1:19d183cf2689 | 343 | numberized = asciivalue - 55; |
kendunlop | 1:19d183cf2689 | 344 | //pc.printf("Hex value is %d.\r\n", numberized); |
kendunlop | 1:19d183cf2689 | 345 | } |
kendunlop | 1:19d183cf2689 | 346 | //pc.printf("Eventual numberization is %d.\r\n", numberized); |
kendunlop | 1:19d183cf2689 | 347 | //pc.printf("Hex total is now %d.\r\n", hextotal); |
kendunlop | 1:19d183cf2689 | 348 | int powertoraise = part.size() - (i+1); |
kendunlop | 1:19d183cf2689 | 349 | //pc.printf("Must multiply by 16 to the power of %d.\r\n", powertoraise); |
kendunlop | 1:19d183cf2689 | 350 | int amounttoadd = numberized; |
kendunlop | 1:19d183cf2689 | 351 | //pc.printf("powertoraise is '%d'.\r\n", powertoraise); |
kendunlop | 1:19d183cf2689 | 352 | if (powertoraise == 1) |
kendunlop | 1:19d183cf2689 | 353 | { |
kendunlop | 1:19d183cf2689 | 354 | amounttoadd = numberized * 16; |
kendunlop | 1:19d183cf2689 | 355 | //pc.printf("Multiplying by 16.\r\n"); |
kendunlop | 1:19d183cf2689 | 356 | //pc.printf("powertoraise is '%d'.\r\n", powertoraise); |
kendunlop | 1:19d183cf2689 | 357 | } |
kendunlop | 1:19d183cf2689 | 358 | if (powertoraise == 2) |
kendunlop | 1:19d183cf2689 | 359 | { |
kendunlop | 1:19d183cf2689 | 360 | amounttoadd = numberized * 256; |
kendunlop | 1:19d183cf2689 | 361 | //pc.printf("Multiplying by 256.\r\n"); |
kendunlop | 1:19d183cf2689 | 362 | } |
kendunlop | 1:19d183cf2689 | 363 | //pc.printf("Amount to add is therefore %d.\r\n", amounttoadd); |
kendunlop | 1:19d183cf2689 | 364 | hextotal = hextotal + amounttoadd; |
kendunlop | 1:19d183cf2689 | 365 | //pc.printf("hextotal so far for this part is therefore %d.\r\n", hextotal); |
kendunlop | 1:19d183cf2689 | 366 | } |
kendunlop | 1:19d183cf2689 | 367 | //pc.printf("hextotal for whole part is therefore %d.\r\n", hextotal); |
kendunlop | 1:19d183cf2689 | 368 | //pc.printf("Need to convert that into true hex.\r\n"); |
kendunlop | 1:19d183cf2689 | 369 | std::stringstream sstream; |
kendunlop | 1:19d183cf2689 | 370 | sstream << std::hex << hextotal; |
kendunlop | 1:19d183cf2689 | 371 | //pc.printf("StringSteam says '%s'.\r\n", sstream.str()); |
kendunlop | 1:19d183cf2689 | 372 | if (partincrement == 1) |
kendunlop | 7:a9150dc1e481 | 373 | { |
kendunlop | 11:abd3df435a2b | 374 | if (hextotal > 0xFFF) |
kendunlop | 11:abd3df435a2b | 375 | { |
kendunlop | 11:abd3df435a2b | 376 | hextotal = 0xFFF; |
kendunlop | 11:abd3df435a2b | 377 | } |
kendunlop | 7:a9150dc1e481 | 378 | messageOut1.id = hextotal; |
kendunlop | 7:a9150dc1e481 | 379 | expected1 = hextotal; |
kendunlop | 11:abd3df435a2b | 380 | if (customentry == 1) |
kendunlop | 11:abd3df435a2b | 381 | { |
kendunlop | 11:abd3df435a2b | 382 | idlistincrementer = hextotal; |
kendunlop | 11:abd3df435a2b | 383 | } |
kendunlop | 8:6f096b45ca15 | 384 | //For IDs, check if the ID is represented in the idsarray. |
kendunlop | 8:6f096b45ca15 | 385 | shouldntcomein = 0; |
kendunlop | 9:7c27efe30a77 | 386 | if (mbedCANbusspeed != CANGatewayCANbusspeed) |
kendunlop | 9:7c27efe30a77 | 387 | { |
kendunlop | 9:7c27efe30a77 | 388 | shouldntcomein = 1; |
kendunlop | 9:7c27efe30a77 | 389 | } |
kendunlop | 11:abd3df435a2b | 390 | idwasfound = 0; |
kendunlop | 8:6f096b45ca15 | 391 | if (CANpassthrough == 0) |
kendunlop | 8:6f096b45ca15 | 392 | { |
kendunlop | 8:6f096b45ca15 | 393 | for(int i = 0; i <=arrayy-1; i++) |
kendunlop | 8:6f096b45ca15 | 394 | { |
kendunlop | 11:abd3df435a2b | 395 | if(idsarray[0][i][0] == expected1) |
kendunlop | 8:6f096b45ca15 | 396 | { |
kendunlop | 11:abd3df435a2b | 397 | //pc.printf("ID was found in the array at %d.\r\n", i); |
kendunlop | 8:6f096b45ca15 | 398 | idwasfound = 1; |
kendunlop | 11:abd3df435a2b | 399 | //pc.printf("IDwasfound is now '%d'.\r\n", idwasfound); |
kendunlop | 11:abd3df435a2b | 400 | columnidwasfound = i; |
kendunlop | 8:6f096b45ca15 | 401 | int originalexpectedvalue = expected1; |
kendunlop | 9:7c27efe30a77 | 402 | //Get string of hex code for original expected value (ID code found in array) |
kendunlop | 9:7c27efe30a77 | 403 | std::stringstream sstream; |
kendunlop | 9:7c27efe30a77 | 404 | sstream << std::hex << originalexpectedvalue; |
kendunlop | 9:7c27efe30a77 | 405 | string tempstring = sstream.str(); |
kendunlop | 9:7c27efe30a77 | 406 | //Get string of hex code for value to adjust to |
kendunlop | 9:7c27efe30a77 | 407 | std::stringstream sstream2; |
kendunlop | 9:7c27efe30a77 | 408 | sstream2 << std::hex << expected1; |
kendunlop | 9:7c27efe30a77 | 409 | string tempstring2 = sstream2.str(); |
kendunlop | 9:7c27efe30a77 | 410 | //pc.printf("\r\nFound message ID %s at 0,%d in idsarray! Will adjust expected value to %s.\r\n", tempstring, i, tempstring2); |
kendunlop | 8:6f096b45ca15 | 411 | } |
kendunlop | 8:6f096b45ca15 | 412 | } |
kendunlop | 8:6f096b45ca15 | 413 | if (idwasfound == 0 and CANpassthrough == 0) |
kendunlop | 8:6f096b45ca15 | 414 | { |
kendunlop | 8:6f096b45ca15 | 415 | //pc.printf("CANpassthrough is %d.\r\n", CANpassthrough); |
kendunlop | 8:6f096b45ca15 | 416 | shouldntcomein = 1; |
kendunlop | 11:abd3df435a2b | 417 | //pc.printf("ID of %d was never found, expecting it NOT to come in.\r\n", expected1); |
kendunlop | 8:6f096b45ca15 | 418 | } |
kendunlop | 9:7c27efe30a77 | 419 | if (shouldntcomein == 0 and unexpectedCANstreak > 0) //If data is expected to come in, this ends any unexpected-CAN streak. |
kendunlop | 9:7c27efe30a77 | 420 | { |
kendunlop | 9:7c27efe30a77 | 421 | if (aspamisgoing == 1) //Add a new line if it's in spam mode here to report new non-unexpected-CAN-streak stuff. |
kendunlop | 9:7c27efe30a77 | 422 | { |
kendunlop | 11:abd3df435a2b | 423 | //pc.printf("\r\n(FrombreakingunexpectedCANstreak 2)\n"); |
kendunlop | 9:7c27efe30a77 | 424 | pc.printf("\r\n\n"); |
kendunlop | 9:7c27efe30a77 | 425 | } |
kendunlop | 9:7c27efe30a77 | 426 | unexpectedCANstreak = 0; |
kendunlop | 9:7c27efe30a77 | 427 | unexpectedCANstreakstartid = 0; |
kendunlop | 9:7c27efe30a77 | 428 | } |
kendunlop | 8:6f096b45ca15 | 429 | } |
kendunlop | 7:a9150dc1e481 | 430 | } |
kendunlop | 1:19d183cf2689 | 431 | if (partincrement == 2) |
kendunlop | 7:a9150dc1e481 | 432 | { |
kendunlop | 7:a9150dc1e481 | 433 | messageOut1.len = hextotal; |
kendunlop | 7:a9150dc1e481 | 434 | expected2 = hextotal; |
kendunlop | 7:a9150dc1e481 | 435 | } |
kendunlop | 1:19d183cf2689 | 436 | if (partincrement >= 3) |
kendunlop | 7:a9150dc1e481 | 437 | { |
kendunlop | 7:a9150dc1e481 | 438 | messageOut1.data[partincrement-3] = hextotal; |
kendunlop | 7:a9150dc1e481 | 439 | } |
kendunlop | 7:a9150dc1e481 | 440 | if (partincrement == 3) |
kendunlop | 7:a9150dc1e481 | 441 | { |
kendunlop | 7:a9150dc1e481 | 442 | expected3 = hextotal; |
kendunlop | 7:a9150dc1e481 | 443 | } |
kendunlop | 7:a9150dc1e481 | 444 | if (partincrement == 4) |
kendunlop | 7:a9150dc1e481 | 445 | { |
kendunlop | 7:a9150dc1e481 | 446 | expected4 = hextotal; |
kendunlop | 7:a9150dc1e481 | 447 | } |
kendunlop | 7:a9150dc1e481 | 448 | if (partincrement == 5) |
kendunlop | 7:a9150dc1e481 | 449 | { |
kendunlop | 7:a9150dc1e481 | 450 | expected5 = hextotal; |
kendunlop | 7:a9150dc1e481 | 451 | } |
kendunlop | 7:a9150dc1e481 | 452 | if (partincrement == 6) |
kendunlop | 7:a9150dc1e481 | 453 | { |
kendunlop | 7:a9150dc1e481 | 454 | expected6 = hextotal; |
kendunlop | 7:a9150dc1e481 | 455 | } |
kendunlop | 7:a9150dc1e481 | 456 | if (partincrement == 7) |
kendunlop | 7:a9150dc1e481 | 457 | { |
kendunlop | 7:a9150dc1e481 | 458 | expected7 = hextotal; |
kendunlop | 7:a9150dc1e481 | 459 | } |
kendunlop | 7:a9150dc1e481 | 460 | if (partincrement == 8) |
kendunlop | 7:a9150dc1e481 | 461 | { |
kendunlop | 7:a9150dc1e481 | 462 | expected8 = hextotal; |
kendunlop | 7:a9150dc1e481 | 463 | } |
kendunlop | 7:a9150dc1e481 | 464 | if (partincrement == 9) |
kendunlop | 7:a9150dc1e481 | 465 | { |
kendunlop | 7:a9150dc1e481 | 466 | expected9 = hextotal; |
kendunlop | 7:a9150dc1e481 | 467 | } |
kendunlop | 7:a9150dc1e481 | 468 | if (partincrement == 10) |
kendunlop | 7:a9150dc1e481 | 469 | { |
kendunlop | 7:a9150dc1e481 | 470 | expected10 = hextotal; |
kendunlop | 7:a9150dc1e481 | 471 | } |
kendunlop | 11:abd3df435a2b | 472 | //pc.printf("IDwasfound says '%d'.\r\n", idwasfound); |
kendunlop | 11:abd3df435a2b | 473 | if (idwasfound == 1 and partincrement == 10)//If the ID was found in the table earlier, use it as the basis for the expected values instead. |
kendunlop | 11:abd3df435a2b | 474 | { |
kendunlop | 11:abd3df435a2b | 475 | //pc.printf("ID was found in table earlier, setting expectations\r\n"); |
kendunlop | 11:abd3df435a2b | 476 | int i = columnidwasfound; |
kendunlop | 11:abd3df435a2b | 477 | expected1 = idsarray[1][i][0]; |
kendunlop | 11:abd3df435a2b | 478 | expected2 = idsarray[1][i][1]; |
kendunlop | 11:abd3df435a2b | 479 | expected3 = idsarray[1][i][2]; |
kendunlop | 11:abd3df435a2b | 480 | expected4 = idsarray[1][i][3]; |
kendunlop | 11:abd3df435a2b | 481 | expected5 = idsarray[1][i][4]; |
kendunlop | 11:abd3df435a2b | 482 | expected6 = idsarray[1][i][5]; |
kendunlop | 11:abd3df435a2b | 483 | expected7 = idsarray[1][i][6]; |
kendunlop | 11:abd3df435a2b | 484 | expected8 = idsarray[1][i][7]; |
kendunlop | 11:abd3df435a2b | 485 | expected9 = idsarray[1][i][8]; |
kendunlop | 11:abd3df435a2b | 486 | expected10 = idsarray[1][i][9]; |
kendunlop | 11:abd3df435a2b | 487 | } |
kendunlop | 1:19d183cf2689 | 488 | //pc.printf("Part %d complete.\r\n", partincrement); |
kendunlop | 1:19d183cf2689 | 489 | //pc.printf("--------------------------------------\r\n"); |
kendunlop | 1:19d183cf2689 | 490 | } |
kendunlop | 1:19d183cf2689 | 491 | |
kendunlop | 3:79133dcea836 | 492 | //A function to get a coherent CAN message from one, uninterrupted string |
kendunlop | 6:2882710e4f1e | 493 | void getCANfrommessageOutText(void) |
kendunlop | 1:19d183cf2689 | 494 | { |
kendunlop | 11:abd3df435a2b | 495 | //pc.printf("messageOutText before space-removal is '%s'\r\n", messageOutText); |
kendunlop | 7:a9150dc1e481 | 496 | messageOutTextWithSpaces = messageOutText; |
kendunlop | 1:19d183cf2689 | 497 | remove(messageOutText.begin(), messageOutText.end(), ' '); //Remove the spaces from the text to send out so it can be parsed. |
kendunlop | 1:19d183cf2689 | 498 | //pc.printf("After removing spaces, messageOutText is '%s'\r\n", messageOutText); |
kendunlop | 1:19d183cf2689 | 499 | string startofstring = messageOutText.substr(0,20); //Take the first 20 characters of the newly-formed string to get a spaceless CAN message. |
kendunlop | 1:19d183cf2689 | 500 | //pc.printf("String to parse is '%s'.\r\n", startofstring); |
kendunlop | 8:6f096b45ca15 | 501 | expectationresolved = 0; |
kendunlop | 8:6f096b45ca15 | 502 | if (expectationwasfulfilled == 0) |
kendunlop | 8:6f096b45ca15 | 503 | { |
kendunlop | 8:6f096b45ca15 | 504 | expectationwasnotfulfilled(); |
kendunlop | 8:6f096b45ca15 | 505 | } |
kendunlop | 8:6f096b45ca15 | 506 | if (expectationwasfulfilled == -1) |
kendunlop | 8:6f096b45ca15 | 507 | { |
kendunlop | 8:6f096b45ca15 | 508 | expectationwasfulfilled = 0; |
kendunlop | 8:6f096b45ca15 | 509 | } |
kendunlop | 8:6f096b45ca15 | 510 | expectationwasfulfilled = 0; |
kendunlop | 1:19d183cf2689 | 511 | partincrement = 0; |
kendunlop | 11:abd3df435a2b | 512 | if (mbedCANbusspeed != CANGatewayCANbusspeed) // If the two bus speeds don't match, note that CAN should not be expected to ocme in and report the issue. |
kendunlop | 11:abd3df435a2b | 513 | { |
kendunlop | 11:abd3df435a2b | 514 | shouldntcomein = 1; |
kendunlop | 11:abd3df435a2b | 515 | if (aspamisgoing == 0) |
kendunlop | 11:abd3df435a2b | 516 | { |
kendunlop | 11:abd3df435a2b | 517 | reportbaudrates(); |
kendunlop | 11:abd3df435a2b | 518 | } |
kendunlop | 11:abd3df435a2b | 519 | } |
kendunlop | 1:19d183cf2689 | 520 | part = startofstring.substr(0,3); |
kendunlop | 1:19d183cf2689 | 521 | dealwithpart(); |
kendunlop | 1:19d183cf2689 | 522 | part = startofstring.substr(3,1); |
kendunlop | 1:19d183cf2689 | 523 | dealwithpart(); |
kendunlop | 1:19d183cf2689 | 524 | part = startofstring.substr(4,2); |
kendunlop | 1:19d183cf2689 | 525 | dealwithpart(); |
kendunlop | 1:19d183cf2689 | 526 | part = startofstring.substr(6,2); |
kendunlop | 1:19d183cf2689 | 527 | dealwithpart(); |
kendunlop | 1:19d183cf2689 | 528 | part = startofstring.substr(8,2); |
kendunlop | 1:19d183cf2689 | 529 | dealwithpart(); |
kendunlop | 1:19d183cf2689 | 530 | part = startofstring.substr(10,2); |
kendunlop | 1:19d183cf2689 | 531 | dealwithpart(); |
kendunlop | 1:19d183cf2689 | 532 | part = startofstring.substr(12,2); |
kendunlop | 1:19d183cf2689 | 533 | dealwithpart(); |
kendunlop | 1:19d183cf2689 | 534 | part = startofstring.substr(14,2); |
kendunlop | 1:19d183cf2689 | 535 | dealwithpart(); |
kendunlop | 1:19d183cf2689 | 536 | part = startofstring.substr(16,2); |
kendunlop | 1:19d183cf2689 | 537 | dealwithpart(); |
kendunlop | 1:19d183cf2689 | 538 | part = startofstring.substr(18,2); |
kendunlop | 1:19d183cf2689 | 539 | dealwithpart(); |
kendunlop | 1:19d183cf2689 | 540 | } |
kendunlop | 1:19d183cf2689 | 541 | |
kendunlop | 11:abd3df435a2b | 542 | void displayhelp(void) |
kendunlop | 11:abd3df435a2b | 543 | { |
kendunlop | 11:abd3df435a2b | 544 | pc.printf("\033[1;32m---------------HELP---------------\r\n"); |
kendunlop | 11:abd3df435a2b | 545 | pc.printf("Ken_CAN_Test is a program designed by Ken Dunlop to test CAN on the CAN Gateway.\r\n"); |
kendunlop | 11:abd3df435a2b | 546 | pc.printf("The program is designed to send CAN, then test the response.\r\n"); |
kendunlop | 11:abd3df435a2b | 547 | pc.printf("Press 'z' to begin sending a series of incrementing messages. Press 'Esc' to finish the test.\r\n"); |
kendunlop | 11:abd3df435a2b | 548 | pc.printf("Press 'v' to send a message on all IDs (000 - 7FF). Press 'Esc' to abort the test.\r\n"); |
kendunlop | 11:abd3df435a2b | 549 | pc.printf("Use 'q', 'w', 'e', and 'r' to change the Mbed's CAN bus speed.\r\n"); |
kendunlop | 11:abd3df435a2b | 550 | pc.printf("Use 't', 'y', 'u', and 'i' to change the presumed CAN bus speed of the CAN Gateway.\r\n"); |
kendunlop | 11:abd3df435a2b | 551 | pc.printf("If the two CAN bus speeds are different, the program will expect to get no CAN messages back.\r\n"); |
kendunlop | 11:abd3df435a2b | 552 | pc.printf("Press 'a' to begin a baud rate test. This sends CAN messages quickly and measures how many come back.\r\n"); |
kendunlop | 11:abd3df435a2b | 553 | pc.printf("Press 'k' to enter Custom Entry mode. This allows you to enter an CAN ID manually and then send a CAN message.\r\n"); |
kendunlop | 11:abd3df435a2b | 554 | pc.printf("Press 'z' to begin sending incrementing CAN messages. The data in the message will increment by 1 each time.\r\n"); |
kendunlop | 11:abd3df435a2b | 555 | pc.printf("Press 'o' while sending incrementing messages to multiply the incrementation by 16. This shifts the number up one half-byte.\r\n"); |
kendunlop | 11:abd3df435a2b | 556 | pc.printf("Press 'k' to enter Custom Entry mode. This allows you to enter an CAN ID manually and then send a CAN message.\r\n"); |
kendunlop | 11:abd3df435a2b | 557 | pc.printf("Press 'm' to set up an expectation table. This changes what CAN the system expects back when sending certain CAN IDs.\r\n"); |
kendunlop | 11:abd3df435a2b | 558 | pc.printf("Press 'n' to cancel the expectation table and re-enter CAN passthrough mode. This will simply expect the same CAN back as was sent.\r\n"); |
kendunlop | 11:abd3df435a2b | 559 | pc.printf("Press the number keys from '1' to '0' to send various pre-defined CAN messages out.\r\n"); |
kendunlop | 11:abd3df435a2b | 560 | pc.printf("Press '?' to bring up this help screen!\r\n"); |
kendunlop | 11:abd3df435a2b | 561 | pc.printf("---------------------------------\033[0m\r\n"); |
kendunlop | 11:abd3df435a2b | 562 | } |
kendunlop | 1:19d183cf2689 | 563 | |
kendunlop | 3:79133dcea836 | 564 | void printMessageOut (void) |
kendunlop | 3:79133dcea836 | 565 | { |
kendunlop | 1:19d183cf2689 | 566 | //This function will print out whatever the CAN bus is sending out. Can't be used constantly as it sends '000 8 00 00 00 00 00 00 00 00' all the time. |
kendunlop | 1:19d183cf2689 | 567 | pc.printf("Message OUT: %03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\r\n",messageOut1.id,messageOut1.len,messageOut1.data[0],messageOut1.data[1],messageOut1.data[2],messageOut1.data[3],messageOut1.data[4],messageOut1.data[5],messageOut1.data[6],messageOut1.data[7]); |
kendunlop | 1:19d183cf2689 | 568 | } |
kendunlop | 1:19d183cf2689 | 569 | |
kendunlop | 3:79133dcea836 | 570 | void printMessageIn (void) |
kendunlop | 3:79133dcea836 | 571 | { |
kendunlop | 8:6f096b45ca15 | 572 | //This function will print out whatever the CAN bus is receiving. |
kendunlop | 8:6f096b45ca15 | 573 | //addnewlineifneeded(); |
kendunlop | 10:3e15baff40e7 | 574 | pc.printf("\033[0;36mMessage IN: %03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\033[0m\r\n",messageIn.id,messageIn.len,messageIn.data[0],messageIn.data[1],messageIn.data[2],messageIn.data[3],messageIn.data[4],messageIn.data[5],messageIn.data[6],messageIn.data[7]); |
kendunlop | 1:19d183cf2689 | 575 | } |
kendunlop | 0:7a500ebaa7a6 | 576 | |
kendunlop | 0:7a500ebaa7a6 | 577 | //The 'main' function will run as soon as the program starts. |
kendunlop | 0:7a500ebaa7a6 | 578 | int main() |
kendunlop | 1:19d183cf2689 | 579 | { |
kendunlop | 1:19d183cf2689 | 580 | pc.baud(115200); // serial port at 115200 |
kendunlop | 1:19d183cf2689 | 581 | CanBus.frequency(500 * 1000); // CAN bus at 500k |
kendunlop | 3:79133dcea836 | 582 | CanBus2.frequency(500 * 1000); // CAN bus at 500k |
kendunlop | 1:19d183cf2689 | 583 | CanBus.reset(); // clear any bus errors |
kendunlop | 3:79133dcea836 | 584 | CanBus2.reset(); // clear any bus errors |
kendunlop | 1:19d183cf2689 | 585 | //NOTE: Print messages must be below this line to work. |
kendunlop | 8:6f096b45ca15 | 586 | pc.printf("\033[0m------------------------------------------\r\n"); |
kendunlop | 1:19d183cf2689 | 587 | pc.printf("Welcome to Ken CAN test.\r\n"); |
kendunlop | 1:19d183cf2689 | 588 | pc.printf("Setting CAN bus to 500k.\r\n"); |
kendunlop | 6:2882710e4f1e | 589 | pc.printf("Setting serial port to baud rate 115200.\r\n"); |
kendunlop | 8:6f096b45ca15 | 590 | pc.printf("Using pins 9 and 10 for CANBus 1 (out) and 30 and 29 for CANBus 2 (in).\r\n"); |
kendunlop | 1:19d183cf2689 | 591 | pc.printf("Version %d.%d\r\n",kMajorVersion,kMinorVersion); |
kendunlop | 1:19d183cf2689 | 592 | pc.printf("Build date %s %s\r\n",__DATE__,__TIME__); |
kendunlop | 11:abd3df435a2b | 593 | pc.printf("\033[1;32mFor help, press '?'.\033[0m\r\n"); |
kendunlop | 1:19d183cf2689 | 594 | pc.printf("------------------------------------------\r\n"); |
kendunlop | 1:19d183cf2689 | 595 | char c; |
kendunlop | 1:19d183cf2689 | 596 | |
kendunlop | 1:19d183cf2689 | 597 | //Check for button presses |
kendunlop | 1:19d183cf2689 | 598 | while (1) |
kendunlop | 0:7a500ebaa7a6 | 599 | { |
kendunlop | 8:6f096b45ca15 | 600 | if (expectationtimer < 100 and expectationresolved == 0) |
kendunlop | 8:6f096b45ca15 | 601 | { |
kendunlop | 8:6f096b45ca15 | 602 | if (expectationresolved == 0) |
kendunlop | 8:6f096b45ca15 | 603 | { |
kendunlop | 9:7c27efe30a77 | 604 | expectationtimer++; |
kendunlop | 9:7c27efe30a77 | 605 | if (expectationtimer >= 2)//If expectation timer gets too high, the CAN reply is deemed not to have arrived. |
kendunlop | 8:6f096b45ca15 | 606 | { |
kendunlop | 9:7c27efe30a77 | 607 | if (CANmatchstreak > 0) //CAN not arriving breaks any CAN match streak |
kendunlop | 9:7c27efe30a77 | 608 | { |
kendunlop | 9:7c27efe30a77 | 609 | CANmatchstreak = 0; |
kendunlop | 9:7c27efe30a77 | 610 | CANmatchstreakstartID = 0; |
kendunlop | 9:7c27efe30a77 | 611 | if (aspamisgoing == 1) |
kendunlop | 9:7c27efe30a77 | 612 | { |
kendunlop | 11:abd3df435a2b | 613 | pc.printf("\r\n\nFrombreakingCANmatchstreak");//Add a return into the terminal to show the old streak on a line by itself. |
kendunlop | 9:7c27efe30a77 | 614 | } |
kendunlop | 9:7c27efe30a77 | 615 | } |
kendunlop | 9:7c27efe30a77 | 616 | if (goodnoreplystreak > 0 and shouldntcomein == 0) //A missing expected reply breaks any combos for expected no-replies |
kendunlop | 9:7c27efe30a77 | 617 | { |
kendunlop | 9:7c27efe30a77 | 618 | if (aspamisgoing == 1) |
kendunlop | 9:7c27efe30a77 | 619 | { |
kendunlop | 9:7c27efe30a77 | 620 | //pc.printf("\r\n(From breaking goodnoreplystreak)\n\r"); |
kendunlop | 9:7c27efe30a77 | 621 | pc.printf("\r\n\n"); |
kendunlop | 9:7c27efe30a77 | 622 | } |
kendunlop | 9:7c27efe30a77 | 623 | goodnoreplystreak = 0; |
kendunlop | 9:7c27efe30a77 | 624 | goodnoreplystreakstartid = 0; |
kendunlop | 9:7c27efe30a77 | 625 | } |
kendunlop | 11:abd3df435a2b | 626 | // If data did not come in when it was expected... |
kendunlop | 8:6f096b45ca15 | 627 | if (shouldntcomein == 0) |
kendunlop | 8:6f096b45ca15 | 628 | { |
kendunlop | 8:6f096b45ca15 | 629 | expectationwasfulfilled = 0; |
kendunlop | 8:6f096b45ca15 | 630 | failsthistest++; |
kendunlop | 8:6f096b45ca15 | 631 | noreplyfailsthistest++; |
kendunlop | 8:6f096b45ca15 | 632 | if (aspamisgoing == 0) |
kendunlop | 8:6f096b45ca15 | 633 | { |
kendunlop | 9:7c27efe30a77 | 634 | noreplystreakstartid = idlistincrementer; |
kendunlop | 9:7c27efe30a77 | 635 | } |
kendunlop | 9:7c27efe30a77 | 636 | if (goodnoreplystreak > 0) |
kendunlop | 9:7c27efe30a77 | 637 | { |
kendunlop | 9:7c27efe30a77 | 638 | goodnoreplystreak = 0; |
kendunlop | 9:7c27efe30a77 | 639 | if (aspamisgoing == 1) |
kendunlop | 9:7c27efe30a77 | 640 | { |
kendunlop | 11:abd3df435a2b | 641 | pc.printf("(\r\n\n");//Add an extra line if breaking an 'as expected' no reply streak. |
kendunlop | 9:7c27efe30a77 | 642 | } |
kendunlop | 8:6f096b45ca15 | 643 | } |
kendunlop | 11:abd3df435a2b | 644 | if (failsstreak > 0) |
kendunlop | 11:abd3df435a2b | 645 | { |
kendunlop | 11:abd3df435a2b | 646 | if (aspamisgoing == 1) |
kendunlop | 11:abd3df435a2b | 647 | { |
kendunlop | 11:abd3df435a2b | 648 | pc.printf("\r\n\n");//Add an extra line if breaking a failure 'does not match expectation' streak |
kendunlop | 11:abd3df435a2b | 649 | } |
kendunlop | 11:abd3df435a2b | 650 | failsstreak = 0; |
kendunlop | 11:abd3df435a2b | 651 | failsstreakstart = 0; |
kendunlop | 11:abd3df435a2b | 652 | } |
kendunlop | 9:7c27efe30a77 | 653 | if (aspamisgoing == 1) |
kendunlop | 9:7c27efe30a77 | 654 | { |
kendunlop | 9:7c27efe30a77 | 655 | if (noreplystreak == 0) |
kendunlop | 9:7c27efe30a77 | 656 | { |
kendunlop | 9:7c27efe30a77 | 657 | noreplystreakstartid = idlistincrementer; |
kendunlop | 9:7c27efe30a77 | 658 | } |
kendunlop | 9:7c27efe30a77 | 659 | noreplystreak++; |
kendunlop | 9:7c27efe30a77 | 660 | } |
kendunlop | 9:7c27efe30a77 | 661 | reportsentCAN();//Now that it's known the CAN has no reply, you can safely write out the sent CAN. (The needed line-returns have been added.) |
kendunlop | 9:7c27efe30a77 | 662 | if (noreplystreakstartid != idlistincrementer) |
kendunlop | 9:7c27efe30a77 | 663 | { |
kendunlop | 9:7c27efe30a77 | 664 | pc.printf("\033[38;5;220mNo reply message detected for IDs %03X to %03X.\033[0m\r", noreplystreakstartid, idlistincrementer); |
kendunlop | 9:7c27efe30a77 | 665 | } |
kendunlop | 9:7c27efe30a77 | 666 | if (noreplystreakstartid == idlistincrementer) |
kendunlop | 9:7c27efe30a77 | 667 | { |
kendunlop | 9:7c27efe30a77 | 668 | pc.printf("\033[38;5;220mNo reply message detected for ID %03X.\033[0m\r", idlistincrementer); |
kendunlop | 9:7c27efe30a77 | 669 | } |
kendunlop | 9:7c27efe30a77 | 670 | if (aspamisgoing == 0) |
kendunlop | 9:7c27efe30a77 | 671 | { |
kendunlop | 9:7c27efe30a77 | 672 | pc.printf("\r\n\n"); //If it's not spamming, you can safely add a new line after the fail message. |
kendunlop | 9:7c27efe30a77 | 673 | } |
kendunlop | 8:6f096b45ca15 | 674 | } |
kendunlop | 8:6f096b45ca15 | 675 | if (shouldntcomein == 1) |
kendunlop | 8:6f096b45ca15 | 676 | { |
kendunlop | 8:6f096b45ca15 | 677 | expectationwasfulfilled = 1; |
kendunlop | 9:7c27efe30a77 | 678 | //Getting an expected non-reply breaks any unexpected reply streaks |
kendunlop | 9:7c27efe30a77 | 679 | if (unexpectedCANstreak > 0) |
kendunlop | 9:7c27efe30a77 | 680 | { |
kendunlop | 9:7c27efe30a77 | 681 | if (aspamisgoing == 1) //Add a new line if it's in spam mode here to report new expected-non-message stuff. |
kendunlop | 9:7c27efe30a77 | 682 | { |
kendunlop | 11:abd3df435a2b | 683 | //pc.printf("\r\n\n(FrombreakingunexpectedCANstreak)"); |
kendunlop | 9:7c27efe30a77 | 684 | pc.printf("\r\n\n"); |
kendunlop | 9:7c27efe30a77 | 685 | } |
kendunlop | 9:7c27efe30a77 | 686 | unexpectedCANstreak = 0; |
kendunlop | 9:7c27efe30a77 | 687 | unexpectedCANstreakstartid = 0; |
kendunlop | 9:7c27efe30a77 | 688 | } |
kendunlop | 9:7c27efe30a77 | 689 | //Getting an expected non-reply also breaks any unexpected non-reply streaks |
kendunlop | 9:7c27efe30a77 | 690 | if (noreplystreak > 0) |
kendunlop | 9:7c27efe30a77 | 691 | { |
kendunlop | 9:7c27efe30a77 | 692 | if (aspamisgoing == 1) //Add a new line if it's in spam mode here to report new expected-non-message stuff. |
kendunlop | 9:7c27efe30a77 | 693 | { |
kendunlop | 9:7c27efe30a77 | 694 | //pc.printf("\r\n(From breaking noreplystreak)\n"); |
kendunlop | 9:7c27efe30a77 | 695 | pc.printf("\r\n\n"); |
kendunlop | 9:7c27efe30a77 | 696 | } |
kendunlop | 9:7c27efe30a77 | 697 | noreplystreak = 0; |
kendunlop | 9:7c27efe30a77 | 698 | noreplystreakstartid = 0; |
kendunlop | 9:7c27efe30a77 | 699 | } |
kendunlop | 11:abd3df435a2b | 700 | // Also, getting an expected non-reply breaks any CAN-fail streaks |
kendunlop | 11:abd3df435a2b | 701 | if (failsstreak > 0 ) |
kendunlop | 11:abd3df435a2b | 702 | { |
kendunlop | 11:abd3df435a2b | 703 | if (aspamisgoing == 1) |
kendunlop | 11:abd3df435a2b | 704 | { |
kendunlop | 11:abd3df435a2b | 705 | //pc.printf("\r\n(From breaking CAN-mismatch streak)\n"); |
kendunlop | 11:abd3df435a2b | 706 | pc.printf("\r\n\n"); |
kendunlop | 11:abd3df435a2b | 707 | } |
kendunlop | 11:abd3df435a2b | 708 | failsstreak = 0; |
kendunlop | 11:abd3df435a2b | 709 | failsstreakstart = 0; |
kendunlop | 11:abd3df435a2b | 710 | } |
kendunlop | 9:7c27efe30a77 | 711 | if (goodnoreplystreak == 0) //If there isn't yet a good no-reply streak, set the starting no-reply ID to this one |
kendunlop | 9:7c27efe30a77 | 712 | { |
kendunlop | 9:7c27efe30a77 | 713 | goodnoreplystreakstartid = idlistincrementer; |
kendunlop | 9:7c27efe30a77 | 714 | if (CANmatchstreak > 0 and aspamisgoing == 1)//Also add an extra return for the breaking of the old CANmatchstreak if needed |
kendunlop | 9:7c27efe30a77 | 715 | { |
kendunlop | 9:7c27efe30a77 | 716 | CANmatchstreak = 0; |
kendunlop | 9:7c27efe30a77 | 717 | pc.printf("(From breaking of CANmatchstreak)\r\n"); |
kendunlop | 9:7c27efe30a77 | 718 | } |
kendunlop | 9:7c27efe30a77 | 719 | } |
kendunlop | 9:7c27efe30a77 | 720 | reportsentCAN();//Now that it's known the CAN has no reply, you can safely write out the sent CAN. (The needed line-returns have been added.) |
kendunlop | 9:7c27efe30a77 | 721 | if (aspamisgoing == 0) |
kendunlop | 9:7c27efe30a77 | 722 | { |
kendunlop | 9:7c27efe30a77 | 723 | goodnoreplystreakstartid = idlistincrementer; |
kendunlop | 9:7c27efe30a77 | 724 | } |
kendunlop | 9:7c27efe30a77 | 725 | if (goodnoreplystreakstartid != idlistincrementer) |
kendunlop | 9:7c27efe30a77 | 726 | { |
kendunlop | 9:7c27efe30a77 | 727 | pc.printf("\033[0;32mNo reply message detected from %03X to %03X, as expected.\033[0m\r", goodnoreplystreakstartid, idlistincrementer); |
kendunlop | 9:7c27efe30a77 | 728 | } |
kendunlop | 9:7c27efe30a77 | 729 | if (goodnoreplystreakstartid == idlistincrementer) |
kendunlop | 9:7c27efe30a77 | 730 | { |
kendunlop | 9:7c27efe30a77 | 731 | pc.printf("\033[0;32mNo reply message detected for ID %03X, as expected.\033[0m\r", goodnoreplystreakstartid); |
kendunlop | 9:7c27efe30a77 | 732 | } |
kendunlop | 9:7c27efe30a77 | 733 | if (aspamisgoing == 0) |
kendunlop | 9:7c27efe30a77 | 734 | { |
kendunlop | 11:abd3df435a2b | 735 | pc.printf("\r\n\n"); //If it's not spamming, you can safely add a new line after the fail message. |
kendunlop | 9:7c27efe30a77 | 736 | } |
kendunlop | 9:7c27efe30a77 | 737 | goodnoreplies++; |
kendunlop | 9:7c27efe30a77 | 738 | goodnoreplystreak++; |
kendunlop | 8:6f096b45ca15 | 739 | } |
kendunlop | 8:6f096b45ca15 | 740 | expectationresolved = 1; |
kendunlop | 8:6f096b45ca15 | 741 | //pc.printf("Expectation timer reached %d!\r\n", expectationtimer); |
kendunlop | 8:6f096b45ca15 | 742 | expectationtimer = 0; |
kendunlop | 8:6f096b45ca15 | 743 | if (idspamon == 1) |
kendunlop | 8:6f096b45ca15 | 744 | { |
kendunlop | 8:6f096b45ca15 | 745 | idscheckedcount++; |
kendunlop | 9:7c27efe30a77 | 746 | idlistincrementer++; //Only add 1 to the idlist incrementer at the end so the first ID it sends is '000'. |
kendunlop | 8:6f096b45ca15 | 747 | } |
kendunlop | 11:abd3df435a2b | 748 | if (customentry == 1) |
kendunlop | 11:abd3df435a2b | 749 | { |
kendunlop | 11:abd3df435a2b | 750 | pc.printf("Enter CAN ID to send: "); |
kendunlop | 11:abd3df435a2b | 751 | } |
kendunlop | 8:6f096b45ca15 | 752 | } |
kendunlop | 8:6f096b45ca15 | 753 | wait(0.01); |
kendunlop | 8:6f096b45ca15 | 754 | } |
kendunlop | 8:6f096b45ca15 | 755 | } |
kendunlop | 1:19d183cf2689 | 756 | if (pc.readable()) |
kendunlop | 1:19d183cf2689 | 757 | { |
kendunlop | 9:7c27efe30a77 | 758 | c = tolower(pc.getc()); |
kendunlop | 3:79133dcea836 | 759 | if (c != NULL) |
kendunlop | 1:19d183cf2689 | 760 | { |
kendunlop | 3:79133dcea836 | 761 | //When the a key is pressed, define a CAN message and send it. |
kendunlop | 1:19d183cf2689 | 762 | //pc.printf("A key was pressed! (%c)\r\n", c); |
kendunlop | 1:19d183cf2689 | 763 | messageOutText = ""; |
kendunlop | 8:6f096b45ca15 | 764 | buttonPressMessageOutText = ""; |
kendunlop | 11:abd3df435a2b | 765 | if (c == '1' and normalkeypresses == 1) |
kendunlop | 7:a9150dc1e481 | 766 | { |
kendunlop | 11:abd3df435a2b | 767 | buttonPressMessageOutText = "301 8 01 02 03 04 05 06 07 08"; |
kendunlop | 9:7c27efe30a77 | 768 | idlistincrementer = 0x301; |
kendunlop | 7:a9150dc1e481 | 769 | } |
kendunlop | 11:abd3df435a2b | 770 | if (c == '2' and normalkeypresses == 1) |
kendunlop | 7:a9150dc1e481 | 771 | { |
kendunlop | 11:abd3df435a2b | 772 | buttonPressMessageOutText = "302 8 01 02 03 04 05 06 07 08"; |
kendunlop | 9:7c27efe30a77 | 773 | idlistincrementer = 0x302; |
kendunlop | 7:a9150dc1e481 | 774 | } |
kendunlop | 11:abd3df435a2b | 775 | if (c == '3' and normalkeypresses == 1) |
kendunlop | 7:a9150dc1e481 | 776 | { |
kendunlop | 11:abd3df435a2b | 777 | buttonPressMessageOutText = "303 8 01 02 03 04 05 06 07 08"; |
kendunlop | 9:7c27efe30a77 | 778 | idlistincrementer = 0x303; |
kendunlop | 7:a9150dc1e481 | 779 | } |
kendunlop | 11:abd3df435a2b | 780 | if (c == '4' and normalkeypresses == 1) |
kendunlop | 7:a9150dc1e481 | 781 | { |
kendunlop | 11:abd3df435a2b | 782 | buttonPressMessageOutText = "304 8 01 02 03 04 05 06 07 08"; |
kendunlop | 9:7c27efe30a77 | 783 | idlistincrementer = 0x304; |
kendunlop | 7:a9150dc1e481 | 784 | } |
kendunlop | 11:abd3df435a2b | 785 | if (c == '5' and normalkeypresses == 1) |
kendunlop | 7:a9150dc1e481 | 786 | { |
kendunlop | 11:abd3df435a2b | 787 | buttonPressMessageOutText = "15B 8 01 02 03 04 05 06 07 08"; |
kendunlop | 11:abd3df435a2b | 788 | idlistincrementer = 0x15B; |
kendunlop | 7:a9150dc1e481 | 789 | } |
kendunlop | 11:abd3df435a2b | 790 | if (c == '6' and normalkeypresses == 1) |
kendunlop | 7:a9150dc1e481 | 791 | { |
kendunlop | 11:abd3df435a2b | 792 | buttonPressMessageOutText = "306 8 01 02 03 04 05 06 07 08"; |
kendunlop | 9:7c27efe30a77 | 793 | idlistincrementer = 0x306; |
kendunlop | 7:a9150dc1e481 | 794 | } |
kendunlop | 11:abd3df435a2b | 795 | if (c == '7' and normalkeypresses == 1) |
kendunlop | 7:a9150dc1e481 | 796 | { |
kendunlop | 11:abd3df435a2b | 797 | buttonPressMessageOutText = "307 8 01 02 03 04 05 06 07 08"; |
kendunlop | 9:7c27efe30a77 | 798 | idlistincrementer = 0x307; |
kendunlop | 7:a9150dc1e481 | 799 | } |
kendunlop | 11:abd3df435a2b | 800 | if (c == '8' and normalkeypresses == 1) |
kendunlop | 7:a9150dc1e481 | 801 | { |
kendunlop | 11:abd3df435a2b | 802 | buttonPressMessageOutText = "308 8 01 02 03 04 05 06 07 08"; |
kendunlop | 9:7c27efe30a77 | 803 | idlistincrementer = 0x308; |
kendunlop | 7:a9150dc1e481 | 804 | } |
kendunlop | 11:abd3df435a2b | 805 | if (c == '9' and normalkeypresses == 1) |
kendunlop | 7:a9150dc1e481 | 806 | { |
kendunlop | 11:abd3df435a2b | 807 | buttonPressMessageOutText = "309 8 01 02 03 04 05 06 07 08"; |
kendunlop | 9:7c27efe30a77 | 808 | idlistincrementer = 0x309; |
kendunlop | 7:a9150dc1e481 | 809 | } |
kendunlop | 11:abd3df435a2b | 810 | if (c == '0' and normalkeypresses == 1) |
kendunlop | 7:a9150dc1e481 | 811 | { |
kendunlop | 9:7c27efe30a77 | 812 | buttonPressMessageOutText = "7FF 8 FF FF FF FF FF FF FF FF";//NOTE: CAN IDs only go to 7FF, not FFF. |
kendunlop | 10:3e15baff40e7 | 813 | idlistincrementer = 0x7FF; |
kendunlop | 10:3e15baff40e7 | 814 | } |
kendunlop | 11:abd3df435a2b | 815 | if (c == 'a' and normalkeypresses == 1) |
kendunlop | 10:3e15baff40e7 | 816 | { |
kendunlop | 11:abd3df435a2b | 817 | listen = 1; |
kendunlop | 11:abd3df435a2b | 818 | pc.printf("Starting baud rate speed test. Mbed at %d and CAN Gateway presumed %d. (Press 'Esc' to end.)\r\n", mbedCANbusspeed / 1000, CANGatewayCANbusspeed / 1000); |
kendunlop | 10:3e15baff40e7 | 819 | pc.printf(""); |
kendunlop | 10:3e15baff40e7 | 820 | resettest(); |
kendunlop | 10:3e15baff40e7 | 821 | incrementer = 0x333; |
kendunlop | 10:3e15baff40e7 | 822 | spamstarttime = clock(); |
kendunlop | 10:3e15baff40e7 | 823 | speedspamison = 1; |
kendunlop | 10:3e15baff40e7 | 824 | aspamisgoing = 1; |
kendunlop | 11:abd3df435a2b | 825 | normalkeypresses = 0; |
kendunlop | 10:3e15baff40e7 | 826 | messageOut1.format = CANStandard; //Quickly define a convenient messageOut for the speed spam to use. |
kendunlop | 10:3e15baff40e7 | 827 | messageOut1.id = 0x301; |
kendunlop | 10:3e15baff40e7 | 828 | messageOut1.len = 8; |
kendunlop | 10:3e15baff40e7 | 829 | messageOut1.data[0] = 0x06; |
kendunlop | 10:3e15baff40e7 | 830 | messageOut1.data[1] = 0x3f; |
kendunlop | 10:3e15baff40e7 | 831 | messageOut1.data[2] = 0xb2; |
kendunlop | 10:3e15baff40e7 | 832 | messageOut1.data[3] = 0x29; |
kendunlop | 10:3e15baff40e7 | 833 | messageOut1.data[4] = 0x19; |
kendunlop | 10:3e15baff40e7 | 834 | messageOut1.data[5] = 0x97; |
kendunlop | 10:3e15baff40e7 | 835 | messageOut1.data[6] = 0x67; |
kendunlop | 10:3e15baff40e7 | 836 | messageOut1.data[7] = 0x37; |
kendunlop | 11:abd3df435a2b | 837 | pc.printf("Will send out '%03X %01X %02X %02X %02X %02X %02X %02X %02X %02X' as fast as possible.\r\n", messageOut1.id, messageOut1.len, messageOut1.data[0], messageOut1.data[1], messageOut1.data[2], messageOut1.data[3], messageOut1.data[4], messageOut1.data[5], messageOut1.data[6], messageOut1.data[7]); |
kendunlop | 10:3e15baff40e7 | 838 | } |
kendunlop | 11:abd3df435a2b | 839 | if (c == 27 and speedspamison == 1)//Cancel speed spam mode |
kendunlop | 10:3e15baff40e7 | 840 | { |
kendunlop | 10:3e15baff40e7 | 841 | //pc.printf("\r\nEnding baud rate speed test mode from upper key press method.\r\n"); |
kendunlop | 10:3e15baff40e7 | 842 | aspamisgoing = 0; |
kendunlop | 11:abd3df435a2b | 843 | normalkeypresses = 1; |
kendunlop | 10:3e15baff40e7 | 844 | spamendtime = clock(); |
kendunlop | 10:3e15baff40e7 | 845 | //endtest(); |
kendunlop | 10:3e15baff40e7 | 846 | getspamsecondstotal(); |
kendunlop | 10:3e15baff40e7 | 847 | endspeedtest(); |
kendunlop | 10:3e15baff40e7 | 848 | speedspamison = 0; |
kendunlop | 8:6f096b45ca15 | 849 | } |
kendunlop | 8:6f096b45ca15 | 850 | if (buttonPressMessageOutText != "")//Centralized 'button press MessageOut' routine that applies to all button presses. |
kendunlop | 8:6f096b45ca15 | 851 | { |
kendunlop | 8:6f096b45ca15 | 852 | if (aspamisgoing == 0) |
kendunlop | 8:6f096b45ca15 | 853 | { |
kendunlop | 9:7c27efe30a77 | 854 | //addnewlineifneeded(); |
kendunlop | 11:abd3df435a2b | 855 | //resetCANbuses(); |
kendunlop | 11:abd3df435a2b | 856 | listen = 1; |
kendunlop | 8:6f096b45ca15 | 857 | messageOutText = buttonPressMessageOutText; |
kendunlop | 8:6f096b45ca15 | 858 | addnewlinetonextmessage = 1; |
kendunlop | 8:6f096b45ca15 | 859 | checklaterbytes = 1;//Check all bytes for button-press messages. |
kendunlop | 8:6f096b45ca15 | 860 | } |
kendunlop | 8:6f096b45ca15 | 861 | buttonPressMessageOutText = ""; |
kendunlop | 7:a9150dc1e481 | 862 | } |
kendunlop | 11:abd3df435a2b | 863 | if (c == '/' and normalkeypresses == 1) |
kendunlop | 11:abd3df435a2b | 864 | { |
kendunlop | 11:abd3df435a2b | 865 | displayhelp(); |
kendunlop | 11:abd3df435a2b | 866 | } |
kendunlop | 11:abd3df435a2b | 867 | if (c == '?' and normalkeypresses == 1) |
kendunlop | 11:abd3df435a2b | 868 | { |
kendunlop | 11:abd3df435a2b | 869 | displayhelp(); |
kendunlop | 11:abd3df435a2b | 870 | } |
kendunlop | 11:abd3df435a2b | 871 | if (c == 'q' and normalkeypresses == 1) |
kendunlop | 3:79133dcea836 | 872 | { |
kendunlop | 9:7c27efe30a77 | 873 | pc.printf("Changing Mbed CAN bus speed to 125.\r\n"); |
kendunlop | 3:79133dcea836 | 874 | CanBus.frequency(125 * 1000); // CAN bus at 125k |
kendunlop | 5:bf4c6278ca8b | 875 | CanBus2.frequency(125 * 1000); // CAN bus at 125k |
kendunlop | 9:7c27efe30a77 | 876 | mbedCANbusspeed = (125 * 1000); |
kendunlop | 3:79133dcea836 | 877 | } |
kendunlop | 11:abd3df435a2b | 878 | if (c == 'w' and normalkeypresses == 1) |
kendunlop | 3:79133dcea836 | 879 | { |
kendunlop | 9:7c27efe30a77 | 880 | pc.printf("Changing Mbed CAN bus speed to 250.\r\n"); |
kendunlop | 3:79133dcea836 | 881 | CanBus.frequency(250 * 1000); // CAN bus at 250k |
kendunlop | 5:bf4c6278ca8b | 882 | CanBus2.frequency(250 * 1000); // CAN bus at 250k |
kendunlop | 9:7c27efe30a77 | 883 | mbedCANbusspeed = (250 * 1000); |
kendunlop | 3:79133dcea836 | 884 | } |
kendunlop | 11:abd3df435a2b | 885 | if (c == 'e' and normalkeypresses == 1) |
kendunlop | 3:79133dcea836 | 886 | { |
kendunlop | 9:7c27efe30a77 | 887 | pc.printf("Changing Mbed CAN bus speed to 500.\r\n"); |
kendunlop | 3:79133dcea836 | 888 | CanBus.frequency(500 * 1000); // CAN bus at 500k |
kendunlop | 3:79133dcea836 | 889 | CanBus2.frequency(500 * 1000);// CAN bus at 500k |
kendunlop | 9:7c27efe30a77 | 890 | mbedCANbusspeed = (500 * 1000); |
kendunlop | 3:79133dcea836 | 891 | } |
kendunlop | 11:abd3df435a2b | 892 | if (c == 'r' and normalkeypresses == 1) |
kendunlop | 3:79133dcea836 | 893 | { |
kendunlop | 9:7c27efe30a77 | 894 | pc.printf("Changing Mbed CAN bus speed to 1000.\r\n"); |
kendunlop | 3:79133dcea836 | 895 | CanBus.frequency(1000 * 1000); // CAN bus at 1000k |
kendunlop | 3:79133dcea836 | 896 | CanBus2.frequency(1000 * 1000); // CAN bus at 1000k |
kendunlop | 9:7c27efe30a77 | 897 | mbedCANbusspeed = (1000 * 1000); |
kendunlop | 3:79133dcea836 | 898 | } |
kendunlop | 11:abd3df435a2b | 899 | if (c == 't' and normalkeypresses == 1) |
kendunlop | 9:7c27efe30a77 | 900 | { |
kendunlop | 9:7c27efe30a77 | 901 | CANGatewayCANbusspeed = (125 * 1000); |
kendunlop | 9:7c27efe30a77 | 902 | pc.printf("CAN Gateway is now presumed to be at CAN bus speed %d.\r\n", CANGatewayCANbusspeed / 1000); |
kendunlop | 9:7c27efe30a77 | 903 | } |
kendunlop | 11:abd3df435a2b | 904 | if (c == 'y' and normalkeypresses == 1) |
kendunlop | 9:7c27efe30a77 | 905 | { |
kendunlop | 9:7c27efe30a77 | 906 | CANGatewayCANbusspeed = (250 * 1000); |
kendunlop | 9:7c27efe30a77 | 907 | pc.printf("CAN Gateway is now presumed to be at CAN bus speed %d.\r\n", CANGatewayCANbusspeed / 1000); |
kendunlop | 9:7c27efe30a77 | 908 | } |
kendunlop | 11:abd3df435a2b | 909 | if (c == 'u' and normalkeypresses == 1) |
kendunlop | 8:6f096b45ca15 | 910 | { |
kendunlop | 9:7c27efe30a77 | 911 | CANGatewayCANbusspeed = (500 * 1000); |
kendunlop | 9:7c27efe30a77 | 912 | pc.printf("CAN Gateway is now presumed to be at CAN bus speed %d.\r\n", CANGatewayCANbusspeed / 1000); |
kendunlop | 9:7c27efe30a77 | 913 | } |
kendunlop | 11:abd3df435a2b | 914 | if (c == 'i' and normalkeypresses == 1) |
kendunlop | 9:7c27efe30a77 | 915 | { |
kendunlop | 9:7c27efe30a77 | 916 | CANGatewayCANbusspeed = (1000 * 1000); |
kendunlop | 9:7c27efe30a77 | 917 | pc.printf("CAN Gateway is now presumed to be at CAN bus speed %d.\r\n", CANGatewayCANbusspeed / 1000); |
kendunlop | 9:7c27efe30a77 | 918 | } |
kendunlop | 11:abd3df435a2b | 919 | if (c == 'k' and normalkeypresses == 1) |
kendunlop | 11:abd3df435a2b | 920 | { |
kendunlop | 11:abd3df435a2b | 921 | pc.printf("Will enter custom CAN entry mode. (Press 'Esc' to end.)\r\nEnter CAN ID to send: "); |
kendunlop | 11:abd3df435a2b | 922 | customentry = 1; |
kendunlop | 11:abd3df435a2b | 923 | normalkeypresses = 0; |
kendunlop | 11:abd3df435a2b | 924 | c = NULL; |
kendunlop | 11:abd3df435a2b | 925 | customentrystring = ""; |
kendunlop | 11:abd3df435a2b | 926 | } |
kendunlop | 11:abd3df435a2b | 927 | if (c == 27 and customentry == 1)//Pressing Esc ends Custom Entry mode |
kendunlop | 11:abd3df435a2b | 928 | { |
kendunlop | 11:abd3df435a2b | 929 | customentry = 0; |
kendunlop | 11:abd3df435a2b | 930 | normalkeypresses = 1; |
kendunlop | 11:abd3df435a2b | 931 | pc.printf("\r\nEnding custom entry mode.\r\n"); |
kendunlop | 11:abd3df435a2b | 932 | c = NULL; |
kendunlop | 11:abd3df435a2b | 933 | } |
kendunlop | 11:abd3df435a2b | 934 | if (c == 13 and customentry == 1 and customentrystring != "")//Pressing enter in Custom Entry mode tries to send a CAN message |
kendunlop | 11:abd3df435a2b | 935 | { |
kendunlop | 11:abd3df435a2b | 936 | pc.printf("\r\n"); |
kendunlop | 11:abd3df435a2b | 937 | //pc.printf("Will try to confirm CES ('%s').\r\n", customentrystring); |
kendunlop | 11:abd3df435a2b | 938 | if (customentrystring.length() < 3) |
kendunlop | 11:abd3df435a2b | 939 | { |
kendunlop | 11:abd3df435a2b | 940 | customentrystring = "0" + customentrystring; |
kendunlop | 11:abd3df435a2b | 941 | } |
kendunlop | 11:abd3df435a2b | 942 | if (customentrystring.length() < 3) |
kendunlop | 11:abd3df435a2b | 943 | { |
kendunlop | 11:abd3df435a2b | 944 | customentrystring = "0" + customentrystring; |
kendunlop | 11:abd3df435a2b | 945 | } |
kendunlop | 11:abd3df435a2b | 946 | checklaterbytes = 1; |
kendunlop | 11:abd3df435a2b | 947 | partincrement = 0; |
kendunlop | 11:abd3df435a2b | 948 | part = customentrystring; |
kendunlop | 11:abd3df435a2b | 949 | dealwithpart(); |
kendunlop | 11:abd3df435a2b | 950 | //pc.printf("Hextotal now says '%d'.\r\n", hextotal); |
kendunlop | 11:abd3df435a2b | 951 | if (hextotal > 0x7FF)//If the measured total is more than 0x7FF (the max ID), reduce it. |
kendunlop | 11:abd3df435a2b | 952 | { |
kendunlop | 11:abd3df435a2b | 953 | hextotal = 0x7FF; |
kendunlop | 11:abd3df435a2b | 954 | customentrystring = "7FF"; |
kendunlop | 11:abd3df435a2b | 955 | } |
kendunlop | 11:abd3df435a2b | 956 | if (hextotal < 0) // If the measured total is less than zero, make it zero instead. |
kendunlop | 11:abd3df435a2b | 957 | { |
kendunlop | 11:abd3df435a2b | 958 | hextotal = 0x000; |
kendunlop | 11:abd3df435a2b | 959 | customentrystring = "000"; |
kendunlop | 11:abd3df435a2b | 960 | } |
kendunlop | 11:abd3df435a2b | 961 | messageOutText = customentrystring + " 8 01 02 03 04 05 06 07 08"; |
kendunlop | 11:abd3df435a2b | 962 | customentrystring = ""; |
kendunlop | 11:abd3df435a2b | 963 | if (expectationresolved == 1 and messageOutText == "") |
kendunlop | 11:abd3df435a2b | 964 | { |
kendunlop | 11:abd3df435a2b | 965 | pc.printf("Enter CAN ID to send: "); |
kendunlop | 11:abd3df435a2b | 966 | } |
kendunlop | 11:abd3df435a2b | 967 | } |
kendunlop | 11:abd3df435a2b | 968 | if (c != NULL and customentry == 1 and expectationresolved == 1 and messageOutText == "") |
kendunlop | 11:abd3df435a2b | 969 | { |
kendunlop | 11:abd3df435a2b | 970 | //pc.printf("Custom entry detected! (%c)\r\n", c); |
kendunlop | 11:abd3df435a2b | 971 | if (c != '\r' and c != 8 and customentrystring.length() < 3) //Normal key presses add to the custom string. |
kendunlop | 11:abd3df435a2b | 972 | { |
kendunlop | 11:abd3df435a2b | 973 | customentrystring.push_back(toupper(c)); |
kendunlop | 11:abd3df435a2b | 974 | //pc.printf("Custom entry string now says '%s'.", customentrystring); |
kendunlop | 11:abd3df435a2b | 975 | } |
kendunlop | 11:abd3df435a2b | 976 | if (c == 8 and customentrystring.length() > 0) //Backspace (character 8) causes the text to go back one character. |
kendunlop | 11:abd3df435a2b | 977 | { |
kendunlop | 11:abd3df435a2b | 978 | pc.printf("\b "); |
kendunlop | 11:abd3df435a2b | 979 | customentrystring.erase(customentrystring.size()-1,1); |
kendunlop | 11:abd3df435a2b | 980 | } |
kendunlop | 11:abd3df435a2b | 981 | pc.printf("\rEnter CAN ID to send: %s", customentrystring); |
kendunlop | 11:abd3df435a2b | 982 | } |
kendunlop | 11:abd3df435a2b | 983 | if (c == 'n' and CANpassthrough == 0 and normalkeypresses == 1) |
kendunlop | 9:7c27efe30a77 | 984 | { |
kendunlop | 9:7c27efe30a77 | 985 | pc.printf("Starting CAN passthrough mode. Will expect to recieve the same CAN that is sent.\r\n"); |
kendunlop | 9:7c27efe30a77 | 986 | CANpassthrough = 1; |
kendunlop | 9:7c27efe30a77 | 987 | } |
kendunlop | 11:abd3df435a2b | 988 | if (c == 'm' and CANpassthrough == 1 and normalkeypresses == 1) |
kendunlop | 9:7c27efe30a77 | 989 | { |
kendunlop | 9:7c27efe30a77 | 990 | pc.printf("Will make a CAN ID translation array.\r\n"); |
kendunlop | 8:6f096b45ca15 | 991 | //Making a two-dimensional array with 301-309 in the first column, then 401-409 in the second column. |
kendunlop | 11:abd3df435a2b | 992 | int copyarray[2][8][10] = { |
kendunlop | 11:abd3df435a2b | 993 | { {0x301,0x8, 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}, {0x302,0x8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}, {0x303,0x8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}, {0x304,0x8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}, {0x305,0x8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}, {0x306,0x8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}, {0x308,0x8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}, {0x309,0x8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08} }, |
kendunlop | 11:abd3df435a2b | 994 | { {0x401,0x8,0x08,0x00,0x00,0x00,0x04,0x05,0x06,0x01}, {0x402,0x8,0x04,0x05,0x06,0x07,0x06,0x07,0x08,0x00}, {0x403,0x8,0x03,0x04,0x05,0x05,0x06,0x80,0x00,0x00}, {0x404,0x8,0x04,0x05,0x06,0x07,0x06,0x07,0x08,0x00}, {0x405,0x8,0x04,0x05,0x06,0x07,0x06,0x07,0x08,0x00}, {0x406,0x8,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x00}, {0x408,0x8,0x06,0x07,0x08,0x00,0x00,0x00,0x00,0x00}, {0x409,0x8,0x06,0x07,0x08,0x00,0x00,0x00,0x00,0x00} }, |
kendunlop | 11:abd3df435a2b | 995 | }; |
kendunlop | 11:abd3df435a2b | 996 | //int copyarray[2][8][10] = {{769, 770, 771, 772, 773, 774, 776, 777}, {1025, 1026, 1027, 1028, 1029, 1030, 1032, 1033}}; |
kendunlop | 8:6f096b45ca15 | 997 | //int copyarray[2][1] = {{2047}, {1025}}; |
kendunlop | 8:6f096b45ca15 | 998 | memcpy(idsarray, copyarray, sizeof(copyarray)); //Copy the new array over the old 'idsarray'. |
kendunlop | 8:6f096b45ca15 | 999 | arrayx = 2; |
kendunlop | 8:6f096b45ca15 | 1000 | arrayy = 8; |
kendunlop | 11:abd3df435a2b | 1001 | arrayz = 10; |
kendunlop | 9:7c27efe30a77 | 1002 | //pc.printf("Array is %dx%d.\r\n", arrayx, arrayy); //Report the size variables of the new array. |
kendunlop | 11:abd3df435a2b | 1003 | for(int i = 0; i <arrayy; i++) |
kendunlop | 11:abd3df435a2b | 1004 | { |
kendunlop | 11:abd3df435a2b | 1005 | //pc.printf("Will show contents of table at column %d.\r\n", i); |
kendunlop | 11:abd3df435a2b | 1006 | pc.printf("1st column of CAN array (%d) says \033[0;30;47m%03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\033[0m\r\n", i, idsarray[0][i][0], idsarray[0][i][1], idsarray[0][i][2], idsarray[0][i][3], idsarray[0][i][4], idsarray[0][i][5], idsarray[0][i][6], idsarray[0][i][7], idsarray[0][i][8], idsarray[0][i][9]); |
kendunlop | 11:abd3df435a2b | 1007 | pc.printf("2nd column of CAN array (%d) says \033[0;30;47m%03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\033[0m\r\n", i, idsarray[1][i][0], idsarray[1][i][1], idsarray[1][i][2], idsarray[1][i][3], idsarray[1][i][4], idsarray[1][i][5], idsarray[1][i][6], idsarray[1][i][7], idsarray[1][i][8], idsarray[1][i][9]); |
kendunlop | 11:abd3df435a2b | 1008 | } |
kendunlop | 11:abd3df435a2b | 1009 | //pc.printf("1st column of IDs array says \033[0;30;47m%03X, %01X, %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\033[0m\r\n", idsarray[0][0][0], idsarray[0][0][1], idsarray[0][0][2], idsarray[0][0][3], idsarray[0][0][4], idsarray[0][0][5], idsarray[0][0][6], idsarray[0][0][7], idsarray[0][0][8], idsarray[0][0][9]); |
kendunlop | 11:abd3df435a2b | 1010 | //pc.printf("2nd column of IDs array says \033[0;30;47m%03X, %01X, %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\033[0m\r\n", idsarray[1][0][0], idsarray[1][0][1], idsarray[1][0][2], idsarray[1][0][3], idsarray[1][0][4], idsarray[1][0][5], idsarray[1][0][6], idsarray[1][0][7], idsarray[1][0][8], idsarray[1][0][9]); |
kendunlop | 8:6f096b45ca15 | 1011 | //pc.printf("1st column of IDs array says %d.\r\n", idsarray[0][0]); |
kendunlop | 8:6f096b45ca15 | 1012 | //pc.printf("2nd column of IDs array says %d.\r\n", idsarray[1][0]); |
kendunlop | 8:6f096b45ca15 | 1013 | CANpassthrough = 0; |
kendunlop | 8:6f096b45ca15 | 1014 | pc.printf("CANpassthrough is now set to %d.\r\n", CANpassthrough); |
kendunlop | 8:6f096b45ca15 | 1015 | /* |
kendunlop | 8:6f096b45ca15 | 1016 | pc.printf("Will search for '305' in row 1.\r\n"); |
kendunlop | 8:6f096b45ca15 | 1017 | //Search for '305' in the array. |
kendunlop | 8:6f096b45ca15 | 1018 | for(int i = 0; i <=arrayy; i++) |
kendunlop | 8:6f096b45ca15 | 1019 | { |
kendunlop | 8:6f096b45ca15 | 1020 | if(idsarray[0][i] == 305) |
kendunlop | 8:6f096b45ca15 | 1021 | { |
kendunlop | 8:6f096b45ca15 | 1022 | pc.printf("Element is found at 0,%d.\r\n", i); |
kendunlop | 8:6f096b45ca15 | 1023 | } |
kendunlop | 8:6f096b45ca15 | 1024 | } |
kendunlop | 8:6f096b45ca15 | 1025 | */ |
kendunlop | 8:6f096b45ca15 | 1026 | } |
kendunlop | 7:a9150dc1e481 | 1027 | //if (c == 's') |
kendunlop | 7:a9150dc1e481 | 1028 | // { |
kendunlop | 7:a9150dc1e481 | 1029 | // pc.printf("Sending authentic sats message.\r\n"); |
kendunlop | 7:a9150dc1e481 | 1030 | // messageOutText = "301 8 06 3F B2 29 12 97 67 37"; |
kendunlop | 7:a9150dc1e481 | 1031 | // } |
kendunlop | 8:6f096b45ca15 | 1032 | if (c == 'o' and idspamon == 0 and spamon == 1) |
kendunlop | 3:79133dcea836 | 1033 | { |
kendunlop | 3:79133dcea836 | 1034 | incrementer = (incrementer * 16); |
kendunlop | 10:3e15baff40e7 | 1035 | pc.printf("\n\rMultiplied Incrementer by 16. It's now %d.\r\n", incrementer); |
kendunlop | 3:79133dcea836 | 1036 | } |
kendunlop | 9:7c27efe30a77 | 1037 | if (c == 'i' and spamon == 1) |
kendunlop | 1:19d183cf2689 | 1038 | { |
kendunlop | 1:19d183cf2689 | 1039 | incrementer = incrementer + 16; |
kendunlop | 1:19d183cf2689 | 1040 | std::stringstream sstream; |
kendunlop | 1:19d183cf2689 | 1041 | sstream << std::hex << incrementer; |
kendunlop | 1:19d183cf2689 | 1042 | string stringsofar = sstream.str(); |
kendunlop | 1:19d183cf2689 | 1043 | //pc.printf("Incrementer is now %d.\r\n", incrementer); |
kendunlop | 1:19d183cf2689 | 1044 | //pc.printf("StringStream says '%s'.\r\n", stringsofar); |
kendunlop | 1:19d183cf2689 | 1045 | int length = stringsofar.length(); |
kendunlop | 1:19d183cf2689 | 1046 | //pc.printf("Length is %d/16.\r\n", length); |
kendunlop | 1:19d183cf2689 | 1047 | for (int i = 0; i < (16-length); i++) |
kendunlop | 1:19d183cf2689 | 1048 | stringsofar = "0" + stringsofar; |
kendunlop | 1:19d183cf2689 | 1049 | //pc.printf("stringsofar says '%s'.\r\n", stringsofar); |
kendunlop | 9:7c27efe30a77 | 1050 | //messageOutText = "305 8 " + stringsofar; |
kendunlop | 1:19d183cf2689 | 1051 | //pc.printf("Will try to send '%s'.\r\n", messageOutText); |
kendunlop | 1:19d183cf2689 | 1052 | } |
kendunlop | 1:19d183cf2689 | 1053 | messageOut1.format = CANStandard; |
kendunlop | 11:abd3df435a2b | 1054 | if (c == 'z' and normalkeypresses == 1) |
kendunlop | 1:19d183cf2689 | 1055 | { |
kendunlop | 7:a9150dc1e481 | 1056 | resettest(); |
kendunlop | 11:abd3df435a2b | 1057 | pc.printf("Starting spam sequence for ID %s. Press 'Esc' to end. Press 'o' to increase incrementer.\r\n", spampreamble); |
kendunlop | 10:3e15baff40e7 | 1058 | idlistincrementer = 0x333; |
kendunlop | 10:3e15baff40e7 | 1059 | reportbaudrates(); |
kendunlop | 1:19d183cf2689 | 1060 | spamon = 1; |
kendunlop | 8:6f096b45ca15 | 1061 | aspamisgoing = 1; |
kendunlop | 11:abd3df435a2b | 1062 | normalkeypresses = 0; |
kendunlop | 8:6f096b45ca15 | 1063 | checklaterbytes = 1; |
kendunlop | 1:19d183cf2689 | 1064 | incrementer = 0; |
kendunlop | 2:11339018dda6 | 1065 | spamcount = 0; |
kendunlop | 3:79133dcea836 | 1066 | spamstarttime = clock(); |
kendunlop | 9:7c27efe30a77 | 1067 | //pc.printf("Spam start time is %d.\r\n", spamstarttime); |
kendunlop | 1:19d183cf2689 | 1068 | } |
kendunlop | 11:abd3df435a2b | 1069 | if (c == 27 and spamon == 1)//Cancel normal '333' incrementing spam mode |
kendunlop | 1:19d183cf2689 | 1070 | { |
kendunlop | 10:3e15baff40e7 | 1071 | pc.printf("\r\n"); |
kendunlop | 8:6f096b45ca15 | 1072 | spamon = 2; |
kendunlop | 8:6f096b45ca15 | 1073 | aspamisgoing = 0; |
kendunlop | 11:abd3df435a2b | 1074 | normalkeypresses = 1; |
kendunlop | 3:79133dcea836 | 1075 | spamendtime = clock(); |
kendunlop | 9:7c27efe30a77 | 1076 | getspamsecondstotal();//Process the spam information |
kendunlop | 9:7c27efe30a77 | 1077 | //pc.printf("Total spams ever are %d.\r\n", totalspamsever); |
kendunlop | 7:a9150dc1e481 | 1078 | endtest(); |
kendunlop | 7:a9150dc1e481 | 1079 | //pc.printf("-------------------------\r\n"); |
kendunlop | 3:79133dcea836 | 1080 | } |
kendunlop | 11:abd3df435a2b | 1081 | if (c == 27 and idspamon == 1)//Cancel CAN ID spam mode |
kendunlop | 11:abd3df435a2b | 1082 | { |
kendunlop | 11:abd3df435a2b | 1083 | //pc.printf("Cancelling ID test mode.\r\n"); |
kendunlop | 11:abd3df435a2b | 1084 | testwasaborted = 1; |
kendunlop | 11:abd3df435a2b | 1085 | endidspamtest(); |
kendunlop | 11:abd3df435a2b | 1086 | normalkeypresses = 1; |
kendunlop | 11:abd3df435a2b | 1087 | } |
kendunlop | 11:abd3df435a2b | 1088 | if (c == 'v' and normalkeypresses == 1) |
kendunlop | 3:79133dcea836 | 1089 | { |
kendunlop | 7:a9150dc1e481 | 1090 | resettest(); |
kendunlop | 6:2882710e4f1e | 1091 | idspamon = 1; //Set the 'idspamon' integer to 1 so ID spam happens. |
kendunlop | 8:6f096b45ca15 | 1092 | aspamisgoing = 1; |
kendunlop | 11:abd3df435a2b | 1093 | normalkeypresses = 0; |
kendunlop | 11:abd3df435a2b | 1094 | checklaterbytes = 1; |
kendunlop | 6:2882710e4f1e | 1095 | idlistincrementer = 0; |
kendunlop | 11:abd3df435a2b | 1096 | pc.printf("Beginning check of all possible CAN IDs (000 - 7FF). Press 'Esc' to abort.\r\n"); |
kendunlop | 10:3e15baff40e7 | 1097 | reportbaudrates(); |
kendunlop | 9:7c27efe30a77 | 1098 | spamstarttime = clock(); |
kendunlop | 9:7c27efe30a77 | 1099 | //pc.printf("Spam started at clock time %d.\r\n", spamstarttime); |
kendunlop | 8:6f096b45ca15 | 1100 | if (checklaterbytes == 0) |
kendunlop | 8:6f096b45ca15 | 1101 | { |
kendunlop | 8:6f096b45ca15 | 1102 | pc.printf("Will only check CAN IDs, not later bytes.\r\n"); |
kendunlop | 8:6f096b45ca15 | 1103 | } |
kendunlop | 11:abd3df435a2b | 1104 | if (checklaterbytes == 1) |
kendunlop | 11:abd3df435a2b | 1105 | { |
kendunlop | 11:abd3df435a2b | 1106 | pc.printf("Will check all bytes in each CAN message.\r\n"); |
kendunlop | 11:abd3df435a2b | 1107 | } |
kendunlop | 1:19d183cf2689 | 1108 | } |
kendunlop | 10:3e15baff40e7 | 1109 | if (messageOutText != "" and speedspamison == 0) |
kendunlop | 1:19d183cf2689 | 1110 | { |
kendunlop | 6:2882710e4f1e | 1111 | getCANfrommessageOutText(); |
kendunlop | 7:a9150dc1e481 | 1112 | sendCAN(); |
kendunlop | 7:a9150dc1e481 | 1113 | //CanBus.write(messageOut1); |
kendunlop | 7:a9150dc1e481 | 1114 | //CanBus2.write(messageOut1); |
kendunlop | 6:2882710e4f1e | 1115 | if (spamon == 0 and idspamon == 0) |
kendunlop | 3:79133dcea836 | 1116 | { |
kendunlop | 7:a9150dc1e481 | 1117 | //printMessageOut(); |
kendunlop | 3:79133dcea836 | 1118 | } |
kendunlop | 3:79133dcea836 | 1119 | messageOutText = ""; |
kendunlop | 1:19d183cf2689 | 1120 | } |
kendunlop | 5:bf4c6278ca8b | 1121 | } |
kendunlop | 4:e8e9bc25b1ca | 1122 | } |
kendunlop | 5:bf4c6278ca8b | 1123 | |
kendunlop | 4:e8e9bc25b1ca | 1124 | |
kendunlop | 7:a9150dc1e481 | 1125 | //If spam mode is on, spam an incrementing CAN message |
kendunlop | 8:6f096b45ca15 | 1126 | if (spamon == 1 and expectationresolved == 1) |
kendunlop | 5:bf4c6278ca8b | 1127 | { |
kendunlop | 5:bf4c6278ca8b | 1128 | spamcount ++; |
kendunlop | 5:bf4c6278ca8b | 1129 | totalspamsever ++; |
kendunlop | 5:bf4c6278ca8b | 1130 | incrementer ++; |
kendunlop | 5:bf4c6278ca8b | 1131 | std::stringstream sstream; |
kendunlop | 5:bf4c6278ca8b | 1132 | sstream << std::hex << incrementer; |
kendunlop | 5:bf4c6278ca8b | 1133 | string stringsofar = sstream.str(); |
kendunlop | 5:bf4c6278ca8b | 1134 | int length = stringsofar.length(); |
kendunlop | 5:bf4c6278ca8b | 1135 | for (int i = 0; i < (16-length); i++) |
kendunlop | 5:bf4c6278ca8b | 1136 | stringsofar = "0" + stringsofar; |
kendunlop | 6:2882710e4f1e | 1137 | messageOutText = spampreamble + " 8 " + stringsofar; |
kendunlop | 6:2882710e4f1e | 1138 | getCANfrommessageOutText(); |
kendunlop | 7:a9150dc1e481 | 1139 | sendCAN(); |
kendunlop | 5:bf4c6278ca8b | 1140 | } |
kendunlop | 8:6f096b45ca15 | 1141 | if (idspamon == 1 and idlistincrementer >= 2048 and expectationresolved == 1) //If the spam value gets to 2048 (7FF), end the spam sequence. RL only go up to 7FF. |
kendunlop | 8:6f096b45ca15 | 1142 | { |
kendunlop | 11:abd3df435a2b | 1143 | endidspamtest(); |
kendunlop | 8:6f096b45ca15 | 1144 | } |
kendunlop | 8:6f096b45ca15 | 1145 | if (idspamon == 1 and expectationresolved == 1) |
kendunlop | 6:2882710e4f1e | 1146 | { |
kendunlop | 9:7c27efe30a77 | 1147 | spamcount++; |
kendunlop | 6:2882710e4f1e | 1148 | std::stringstream sstream; |
kendunlop | 6:2882710e4f1e | 1149 | sstream << std::hex << idlistincrementer; |
kendunlop | 6:2882710e4f1e | 1150 | string idstring = ""; |
kendunlop | 6:2882710e4f1e | 1151 | idstring = sstream.str(); |
kendunlop | 6:2882710e4f1e | 1152 | //pc.printf("idstring says '%s'\r\n", idstring); |
kendunlop | 6:2882710e4f1e | 1153 | if (idstring.length() < 3) |
kendunlop | 6:2882710e4f1e | 1154 | { |
kendunlop | 6:2882710e4f1e | 1155 | for (int i = 0; i < (4 - idstring.length()); i++) |
kendunlop | 6:2882710e4f1e | 1156 | { |
kendunlop | 6:2882710e4f1e | 1157 | idstring = "0" + idstring; |
kendunlop | 6:2882710e4f1e | 1158 | } |
kendunlop | 6:2882710e4f1e | 1159 | } |
kendunlop | 6:2882710e4f1e | 1160 | //pc.printf("idstring now says '%s'\r\n", idstring); |
kendunlop | 6:2882710e4f1e | 1161 | //pc.printf("%s\r\n", idstring); |
kendunlop | 7:a9150dc1e481 | 1162 | idstring = idstring + " 8 01 02 03 04 05 06 07 08"; |
kendunlop | 6:2882710e4f1e | 1163 | //pc.printf("...and now idstring now says '%s'\r\n", idstring); |
kendunlop | 6:2882710e4f1e | 1164 | messageOutText = idstring; |
kendunlop | 6:2882710e4f1e | 1165 | getCANfrommessageOutText(); |
kendunlop | 7:a9150dc1e481 | 1166 | sendCAN(); |
kendunlop | 7:a9150dc1e481 | 1167 | //CanBus.write(messageOut1); |
kendunlop | 7:a9150dc1e481 | 1168 | //CanBus2.write(messageOut1); |
kendunlop | 6:2882710e4f1e | 1169 | //pc.printf("ID list incrementer is now %d\r\n", idlistincrementer); |
kendunlop | 6:2882710e4f1e | 1170 | wait(0.01);//ID spam at 100Hz |
kendunlop | 6:2882710e4f1e | 1171 | } |
kendunlop | 11:abd3df435a2b | 1172 | |
kendunlop | 11:abd3df435a2b | 1173 | //Optional: mention any un-listened-to CAN messages. Having this stopped it from reading messages in when listen was on. |
kendunlop | 11:abd3df435a2b | 1174 | //if (CanBus2.read(messageIn) and listen == 0) |
kendunlop | 10:3e15baff40e7 | 1175 | // { |
kendunlop | 11:abd3df435a2b | 1176 | // pc.printf("(Un-listened-to CAN message came in.)\r\n"); |
kendunlop | 10:3e15baff40e7 | 1177 | // } |
kendunlop | 11:abd3df435a2b | 1178 | |
kendunlop | 11:abd3df435a2b | 1179 | //Check for CAN messages coming in |
kendunlop | 11:abd3df435a2b | 1180 | if (CanBus2.read(messageIn) and listen == 1) |
kendunlop | 7:a9150dc1e481 | 1181 | { |
kendunlop | 10:3e15baff40e7 | 1182 | if (speedspamison == 1) |
kendunlop | 9:7c27efe30a77 | 1183 | { |
kendunlop | 10:3e15baff40e7 | 1184 | messagesincount++; |
kendunlop | 10:3e15baff40e7 | 1185 | //pc.printf("\033[0;36m Speed spam message IN: %03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\033[0m\r\n",messageIn.id,messageIn.len,messageIn.data[0],messageIn.data[1],messageIn.data[2],messageIn.data[3],messageIn.data[4],messageIn.data[5],messageIn.data[6],messageIn.data[7]); |
kendunlop | 8:6f096b45ca15 | 1186 | } |
kendunlop | 10:3e15baff40e7 | 1187 | if (speedspamison == 0) |
kendunlop | 7:a9150dc1e481 | 1188 | { |
kendunlop | 10:3e15baff40e7 | 1189 | //pc.printf("\033[0;36mNormal message IN: %03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\033[0m\r\n",messageIn.id,messageIn.len,messageIn.data[0],messageIn.data[1],messageIn.data[2],messageIn.data[3],messageIn.data[4],messageIn.data[5],messageIn.data[6],messageIn.data[7]); |
kendunlop | 10:3e15baff40e7 | 1190 | if (noreplystreak > 0) |
kendunlop | 9:7c27efe30a77 | 1191 | { |
kendunlop | 10:3e15baff40e7 | 1192 | noreplystreak = 0; |
kendunlop | 10:3e15baff40e7 | 1193 | noreplystreakstartid = 0; |
kendunlop | 10:3e15baff40e7 | 1194 | pc.printf("\r\n\n"); |
kendunlop | 10:3e15baff40e7 | 1195 | } |
kendunlop | 10:3e15baff40e7 | 1196 | if (goodnoreplystreak > 0) |
kendunlop | 10:3e15baff40e7 | 1197 | { |
kendunlop | 10:3e15baff40e7 | 1198 | goodnoreplystreak = 0; |
kendunlop | 10:3e15baff40e7 | 1199 | goodnoreplystreakstartid = 0; |
kendunlop | 11:abd3df435a2b | 1200 | if (aspamisgoing == 1) |
kendunlop | 11:abd3df435a2b | 1201 | { |
kendunlop | 11:abd3df435a2b | 1202 | pc.printf("\r\n\n"); |
kendunlop | 11:abd3df435a2b | 1203 | } |
kendunlop | 9:7c27efe30a77 | 1204 | } |
kendunlop | 10:3e15baff40e7 | 1205 | CANCount++; |
kendunlop | 10:3e15baff40e7 | 1206 | if (1 == 1)//Prepare to print out the message coming in |
kendunlop | 7:a9150dc1e481 | 1207 | { |
kendunlop | 10:3e15baff40e7 | 1208 | //Data shouldn't come in at all if 'shouldntcomein' is 1! |
kendunlop | 11:abd3df435a2b | 1209 | //pc.printf("Wah! Unexpected CAN came in!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n"); |
kendunlop | 10:3e15baff40e7 | 1210 | if (shouldntcomein == 1) |
kendunlop | 9:7c27efe30a77 | 1211 | { |
kendunlop | 11:abd3df435a2b | 1212 | if (failsstreak > 0) |
kendunlop | 11:abd3df435a2b | 1213 | { |
kendunlop | 11:abd3df435a2b | 1214 | failsstreak = 0; |
kendunlop | 11:abd3df435a2b | 1215 | failsstreakstart = 0; |
kendunlop | 11:abd3df435a2b | 1216 | if (aspamisgoing == 1) |
kendunlop | 11:abd3df435a2b | 1217 | { |
kendunlop | 11:abd3df435a2b | 1218 | pc.printf("\n\n\r"); |
kendunlop | 11:abd3df435a2b | 1219 | } |
kendunlop | 11:abd3df435a2b | 1220 | } |
kendunlop | 10:3e15baff40e7 | 1221 | if (unexpectedCANstreak == 0)//If it's the start of a new unexpected-CAN streak, mark the starting ID. |
kendunlop | 10:3e15baff40e7 | 1222 | { |
kendunlop | 10:3e15baff40e7 | 1223 | unexpectedCANstreakstartid = idlistincrementer; |
kendunlop | 10:3e15baff40e7 | 1224 | } |
kendunlop | 10:3e15baff40e7 | 1225 | if (aspamisgoing == 0) |
kendunlop | 10:3e15baff40e7 | 1226 | { |
kendunlop | 10:3e15baff40e7 | 1227 | unexpectedCANstreakstartid = idlistincrementer; |
kendunlop | 10:3e15baff40e7 | 1228 | } |
kendunlop | 11:abd3df435a2b | 1229 | reportsentCAN(); |
kendunlop | 10:3e15baff40e7 | 1230 | if (unexpectedCANstreakstartid != idlistincrementer) |
kendunlop | 10:3e15baff40e7 | 1231 | { |
kendunlop | 10:3e15baff40e7 | 1232 | pc.printf("\033[0;35mUnexpected data came in for IDs %03X to %03X!\033[0m", unexpectedCANstreakstartid, idlistincrementer); |
kendunlop | 10:3e15baff40e7 | 1233 | } |
kendunlop | 10:3e15baff40e7 | 1234 | if (unexpectedCANstreakstartid == idlistincrementer) |
kendunlop | 10:3e15baff40e7 | 1235 | { |
kendunlop | 10:3e15baff40e7 | 1236 | pc.printf("\033[0;35mUnexpected data came in for %03X!\033[0m", idlistincrementer); |
kendunlop | 10:3e15baff40e7 | 1237 | } |
kendunlop | 10:3e15baff40e7 | 1238 | failsthistest++; |
kendunlop | 10:3e15baff40e7 | 1239 | unexpectedCANfails++; |
kendunlop | 10:3e15baff40e7 | 1240 | unexpectedCANstreak++; |
kendunlop | 10:3e15baff40e7 | 1241 | } |
kendunlop | 10:3e15baff40e7 | 1242 | //Establish earlier whether it's a match in the 10 places |
kendunlop | 10:3e15baff40e7 | 1243 | int itsamatch = 1; |
kendunlop | 10:3e15baff40e7 | 1244 | if (expected1 != messageIn.id) |
kendunlop | 10:3e15baff40e7 | 1245 | {itsamatch = 0;} |
kendunlop | 10:3e15baff40e7 | 1246 | if (expected2 != messageIn.len and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1247 | {itsamatch = 0;} |
kendunlop | 10:3e15baff40e7 | 1248 | if (expected3 != messageIn.data[0] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1249 | {itsamatch = 0;} |
kendunlop | 10:3e15baff40e7 | 1250 | if (expected4 != messageIn.data[1] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1251 | {itsamatch = 0;} |
kendunlop | 10:3e15baff40e7 | 1252 | if (expected5 != messageIn.data[2] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1253 | {itsamatch = 0;} |
kendunlop | 10:3e15baff40e7 | 1254 | if (expected6 != messageIn.data[3] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1255 | {itsamatch = 0;} |
kendunlop | 10:3e15baff40e7 | 1256 | if (expected7 != messageIn.data[4] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1257 | {itsamatch = 0;} |
kendunlop | 10:3e15baff40e7 | 1258 | if (expected8 != messageIn.data[5] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1259 | {itsamatch = 0;} |
kendunlop | 10:3e15baff40e7 | 1260 | if (expected9 != messageIn.data[6] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1261 | {itsamatch = 0;} |
kendunlop | 10:3e15baff40e7 | 1262 | if (expected10 != messageIn.data[7] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1263 | {itsamatch = 0;} |
kendunlop | 11:abd3df435a2b | 1264 | |
kendunlop | 11:abd3df435a2b | 1265 | //pc.printf("itsamatch %d, shouldntcomein %d.", itsamatch, shouldntcomein); |
kendunlop | 10:3e15baff40e7 | 1266 | if (itsamatch == 0 and shouldntcomein == 0) |
kendunlop | 10:3e15baff40e7 | 1267 | { |
kendunlop | 11:abd3df435a2b | 1268 | if (failsstreak == 0) |
kendunlop | 11:abd3df435a2b | 1269 | { |
kendunlop | 11:abd3df435a2b | 1270 | failsstreakstart = idlistincrementer; |
kendunlop | 11:abd3df435a2b | 1271 | } |
kendunlop | 11:abd3df435a2b | 1272 | failsstreak++; |
kendunlop | 11:abd3df435a2b | 1273 | if (aspamisgoing == 0) |
kendunlop | 11:abd3df435a2b | 1274 | { |
kendunlop | 11:abd3df435a2b | 1275 | failsstreakstart = idlistincrementer; |
kendunlop | 11:abd3df435a2b | 1276 | } |
kendunlop | 11:abd3df435a2b | 1277 | reportsentCAN(); //Report sent CAN before any 'does not match...' messages |
kendunlop | 11:abd3df435a2b | 1278 | if (failsstreakstart == idlistincrementer) |
kendunlop | 11:abd3df435a2b | 1279 | { |
kendunlop | 11:abd3df435a2b | 1280 | pc.printf("\033[0;31mData for ID %03X does not match expectation!\033[0m", idlistincrementer); |
kendunlop | 11:abd3df435a2b | 1281 | } |
kendunlop | 11:abd3df435a2b | 1282 | if (failsstreakstart != idlistincrementer) |
kendunlop | 11:abd3df435a2b | 1283 | { |
kendunlop | 11:abd3df435a2b | 1284 | pc.printf("\033[0;31mData for IDs %03X to %03X does not match expectation!\033[0m", failsstreakstart, idlistincrementer); |
kendunlop | 11:abd3df435a2b | 1285 | } |
kendunlop | 11:abd3df435a2b | 1286 | } |
kendunlop | 11:abd3df435a2b | 1287 | //Decide if a message in will need to be printed ('Message received was:...') |
kendunlop | 11:abd3df435a2b | 1288 | messageinisneeded = 0; |
kendunlop | 11:abd3df435a2b | 1289 | if (aspamisgoing == 0) |
kendunlop | 11:abd3df435a2b | 1290 | {messageinisneeded = 1;} |
kendunlop | 11:abd3df435a2b | 1291 | //if (itsamatch == 0 and shouldntcomein == 0) |
kendunlop | 11:abd3df435a2b | 1292 | // {messageinisneeded = 1;} |
kendunlop | 11:abd3df435a2b | 1293 | if (reportfailsindividually == 1) |
kendunlop | 11:abd3df435a2b | 1294 | {messageinisneeded = 1;} |
kendunlop | 11:abd3df435a2b | 1295 | // If a message in is destined to be printed, reset the failsstreak if needed |
kendunlop | 11:abd3df435a2b | 1296 | if (messageinisneeded == 1 and failsstreak > 0) |
kendunlop | 11:abd3df435a2b | 1297 | { |
kendunlop | 11:abd3df435a2b | 1298 | failsstreak = 0; |
kendunlop | 11:abd3df435a2b | 1299 | failsstreakstart = 0; |
kendunlop | 10:3e15baff40e7 | 1300 | } |
kendunlop | 10:3e15baff40e7 | 1301 | // Once it's known whether the data matches expectation, set the match streak |
kendunlop | 10:3e15baff40e7 | 1302 | if (itsamatch == 1 and shouldntcomein == 0) |
kendunlop | 10:3e15baff40e7 | 1303 | { |
kendunlop | 11:abd3df435a2b | 1304 | if (failsstreak > 0) |
kendunlop | 11:abd3df435a2b | 1305 | { |
kendunlop | 11:abd3df435a2b | 1306 | failsstreak = 0; |
kendunlop | 11:abd3df435a2b | 1307 | failsstreakstart = 0; |
kendunlop | 11:abd3df435a2b | 1308 | if (aspamisgoing == 1) |
kendunlop | 11:abd3df435a2b | 1309 | { |
kendunlop | 11:abd3df435a2b | 1310 | pc.printf("\r\n\n"); |
kendunlop | 11:abd3df435a2b | 1311 | } |
kendunlop | 11:abd3df435a2b | 1312 | } |
kendunlop | 10:3e15baff40e7 | 1313 | if (CANmatchstreak == 0) |
kendunlop | 10:3e15baff40e7 | 1314 | { |
kendunlop | 10:3e15baff40e7 | 1315 | CANmatchstreakstartID = idlistincrementer; |
kendunlop | 10:3e15baff40e7 | 1316 | } |
kendunlop | 10:3e15baff40e7 | 1317 | CANmatchstreak++; |
kendunlop | 10:3e15baff40e7 | 1318 | } |
kendunlop | 10:3e15baff40e7 | 1319 | if (itsamatch == 0 and CANmatchstreak > 0) //If it's NOT a match, break any CANmatchstreak |
kendunlop | 10:3e15baff40e7 | 1320 | { |
kendunlop | 10:3e15baff40e7 | 1321 | CANmatchstreak = 0; |
kendunlop | 10:3e15baff40e7 | 1322 | CANmatchstreakstartID = 0; |
kendunlop | 10:3e15baff40e7 | 1323 | } |
kendunlop | 10:3e15baff40e7 | 1324 | // Print needed message |
kendunlop | 11:abd3df435a2b | 1325 | reportsentCAN(); |
kendunlop | 10:3e15baff40e7 | 1326 | if (messageinisneeded == 0) //If a message in is NOT needed, simply report what the CAN is doing on the same line. |
kendunlop | 10:3e15baff40e7 | 1327 | { |
kendunlop | 10:3e15baff40e7 | 1328 | if (itsamatch == 1 and CANmatchstreakstartID == idlistincrementer and CANmatchstreak > 0) |
kendunlop | 10:3e15baff40e7 | 1329 | { |
kendunlop | 10:3e15baff40e7 | 1330 | pc.printf("\033[0;32mCAN matches expected values on ID %03X.\033[0m", idlistincrementer); |
kendunlop | 10:3e15baff40e7 | 1331 | } |
kendunlop | 10:3e15baff40e7 | 1332 | if (itsamatch == 1 and CANmatchstreakstartID != idlistincrementer and CANmatchstreak > 0) |
kendunlop | 10:3e15baff40e7 | 1333 | { |
kendunlop | 10:3e15baff40e7 | 1334 | pc.printf("\033[0;32mCAN matches expected values from IDs %03X to %03X.\033[0m", CANmatchstreakstartID, idlistincrementer); |
kendunlop | 10:3e15baff40e7 | 1335 | } |
kendunlop | 9:7c27efe30a77 | 1336 | } |
kendunlop | 10:3e15baff40e7 | 1337 | if (messageinisneeded == 1) //Only if message in is needed do you need to look at printing each part of the message |
kendunlop | 9:7c27efe30a77 | 1338 | { |
kendunlop | 10:3e15baff40e7 | 1339 | pc.printf("\r\nMessage received was: "); |
kendunlop | 10:3e15baff40e7 | 1340 | if (expected1 != messageIn.id) |
kendunlop | 10:3e15baff40e7 | 1341 | { |
kendunlop | 10:3e15baff40e7 | 1342 | //pc.printf("\r\nID of %d does NOT match %d.\r\n", messageIn.id, expected1); |
kendunlop | 10:3e15baff40e7 | 1343 | pc.printf("\033[1;31m%03X\033[0m ", messageIn.id);//Show the ID in red if it doesn't match. |
kendunlop | 10:3e15baff40e7 | 1344 | } |
kendunlop | 10:3e15baff40e7 | 1345 | if (expected1 == messageIn.id) |
kendunlop | 10:3e15baff40e7 | 1346 | { |
kendunlop | 10:3e15baff40e7 | 1347 | pc.printf("\033[1;32m%03X\033[0m ", messageIn.id);//Show the ID in green if it matches. |
kendunlop | 10:3e15baff40e7 | 1348 | } |
kendunlop | 10:3e15baff40e7 | 1349 | if (expected2 != messageIn.len and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1350 | { |
kendunlop | 10:3e15baff40e7 | 1351 | //pc.printf("Length of %d does NOT match %d.\r\n", messageIn.len, expected2); |
kendunlop | 10:3e15baff40e7 | 1352 | pc.printf("\033[1;31m%01X\033[0m ", messageIn.len); |
kendunlop | 10:3e15baff40e7 | 1353 | } |
kendunlop | 10:3e15baff40e7 | 1354 | else |
kendunlop | 10:3e15baff40e7 | 1355 | { |
kendunlop | 11:abd3df435a2b | 1356 | pc.printf("\033[1;32m%01X\033[0m ", messageIn.len); |
kendunlop | 10:3e15baff40e7 | 1357 | } |
kendunlop | 10:3e15baff40e7 | 1358 | if (expected3 != messageIn.data[0] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1359 | { |
kendunlop | 10:3e15baff40e7 | 1360 | //pc.printf("Data 0 of %d does NOT match %d.\r\n", messageIn.data[0], expected3); |
kendunlop | 10:3e15baff40e7 | 1361 | pc.printf("\033[1;31m%02X\033[0m ", messageIn.data[0]); |
kendunlop | 10:3e15baff40e7 | 1362 | } |
kendunlop | 10:3e15baff40e7 | 1363 | else |
kendunlop | 10:3e15baff40e7 | 1364 | { |
kendunlop | 11:abd3df435a2b | 1365 | pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[0]); |
kendunlop | 10:3e15baff40e7 | 1366 | } |
kendunlop | 10:3e15baff40e7 | 1367 | if (expected4 != messageIn.data[1] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1368 | { |
kendunlop | 10:3e15baff40e7 | 1369 | //pc.printf("Data 1 of %d does NOT match %d.\r\n", messageIn.data[1], expected4); |
kendunlop | 10:3e15baff40e7 | 1370 | pc.printf("\033[1;31m%02X\033[0m ", messageIn.data[1]); |
kendunlop | 10:3e15baff40e7 | 1371 | } |
kendunlop | 10:3e15baff40e7 | 1372 | else |
kendunlop | 10:3e15baff40e7 | 1373 | { |
kendunlop | 11:abd3df435a2b | 1374 | pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[1]); |
kendunlop | 10:3e15baff40e7 | 1375 | } |
kendunlop | 10:3e15baff40e7 | 1376 | if (expected5 != messageIn.data[2] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1377 | { |
kendunlop | 10:3e15baff40e7 | 1378 | //pc.printf("Data 2 of %d does NOT match %d.\r\n", messageIn.data[2], expected5); |
kendunlop | 10:3e15baff40e7 | 1379 | pc.printf("\033[1;31m%02X\033[0m ", messageIn.data[2]); |
kendunlop | 10:3e15baff40e7 | 1380 | } |
kendunlop | 10:3e15baff40e7 | 1381 | else |
kendunlop | 10:3e15baff40e7 | 1382 | { |
kendunlop | 11:abd3df435a2b | 1383 | pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[2]); |
kendunlop | 10:3e15baff40e7 | 1384 | } |
kendunlop | 10:3e15baff40e7 | 1385 | if (expected6 != messageIn.data[3] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1386 | { |
kendunlop | 10:3e15baff40e7 | 1387 | //pc.printf("Data 3 of %d does NOT match %d.\r\n", messageIn.data[3], expected6); |
kendunlop | 10:3e15baff40e7 | 1388 | pc.printf("\033[1;31m%02X\033[0m ", messageIn.data[3]); |
kendunlop | 10:3e15baff40e7 | 1389 | } |
kendunlop | 10:3e15baff40e7 | 1390 | |
kendunlop | 10:3e15baff40e7 | 1391 | else |
kendunlop | 10:3e15baff40e7 | 1392 | { |
kendunlop | 11:abd3df435a2b | 1393 | pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[3]); |
kendunlop | 10:3e15baff40e7 | 1394 | } |
kendunlop | 10:3e15baff40e7 | 1395 | if (expected7 != messageIn.data[4] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1396 | { |
kendunlop | 10:3e15baff40e7 | 1397 | //pc.printf("Data 4 of %d does NOT match %d.\r\n", messageIn.data[4], expected7); |
kendunlop | 10:3e15baff40e7 | 1398 | pc.printf("\033[1;31m%02X\033[0m ", messageIn.data[4]); |
kendunlop | 10:3e15baff40e7 | 1399 | } |
kendunlop | 10:3e15baff40e7 | 1400 | else |
kendunlop | 10:3e15baff40e7 | 1401 | { |
kendunlop | 11:abd3df435a2b | 1402 | pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[4]); |
kendunlop | 10:3e15baff40e7 | 1403 | } |
kendunlop | 10:3e15baff40e7 | 1404 | if (expected8 != messageIn.data[5] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1405 | { |
kendunlop | 10:3e15baff40e7 | 1406 | //pc.printf("Data 5 of %d does NOT match %d.\r\n", messageIn.data[5], expected8); |
kendunlop | 10:3e15baff40e7 | 1407 | pc.printf("\033[1;31m%02X\033[0m ", messageIn.data[5]); |
kendunlop | 10:3e15baff40e7 | 1408 | } |
kendunlop | 10:3e15baff40e7 | 1409 | else |
kendunlop | 10:3e15baff40e7 | 1410 | { |
kendunlop | 11:abd3df435a2b | 1411 | pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[5]); |
kendunlop | 10:3e15baff40e7 | 1412 | } |
kendunlop | 10:3e15baff40e7 | 1413 | if (expected9 != messageIn.data[6] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1414 | { |
kendunlop | 10:3e15baff40e7 | 1415 | //pc.printf("Data 6 of %d does NOT match %d.\r\n", messageIn.data[6], expected9); |
kendunlop | 10:3e15baff40e7 | 1416 | pc.printf("\033[1;31m%02X\033[0m ", messageIn.data[6]); |
kendunlop | 10:3e15baff40e7 | 1417 | } |
kendunlop | 10:3e15baff40e7 | 1418 | else |
kendunlop | 10:3e15baff40e7 | 1419 | { |
kendunlop | 11:abd3df435a2b | 1420 | pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[6]); |
kendunlop | 10:3e15baff40e7 | 1421 | } |
kendunlop | 10:3e15baff40e7 | 1422 | if (expected10 != messageIn.data[7] and checklaterbytes >= 1) |
kendunlop | 10:3e15baff40e7 | 1423 | { |
kendunlop | 10:3e15baff40e7 | 1424 | //pc.printf("Data 7 of %d does NOT match %d.\r\n", messageIn.data[7], expected10); |
kendunlop | 10:3e15baff40e7 | 1425 | pc.printf("\033[1;31m%02X\033[0m ", messageIn.data[7]); |
kendunlop | 10:3e15baff40e7 | 1426 | } |
kendunlop | 10:3e15baff40e7 | 1427 | else |
kendunlop | 10:3e15baff40e7 | 1428 | { |
kendunlop | 11:abd3df435a2b | 1429 | pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[7]); |
kendunlop | 10:3e15baff40e7 | 1430 | } |
kendunlop | 11:abd3df435a2b | 1431 | if (messageinisneeded == 1) |
kendunlop | 10:3e15baff40e7 | 1432 | { |
kendunlop | 11:abd3df435a2b | 1433 | //pc.printf("\r\n(Aftersentoutmessage)"); |
kendunlop | 10:3e15baff40e7 | 1434 | pc.printf("\r\n");//Add a return and a new line after the 'Sent out' message is finished if it's not spam mode. |
kendunlop | 10:3e15baff40e7 | 1435 | } |
kendunlop | 9:7c27efe30a77 | 1436 | } |
kendunlop | 10:3e15baff40e7 | 1437 | if (itsamatch == 0) |
kendunlop | 9:7c27efe30a77 | 1438 | { |
kendunlop | 10:3e15baff40e7 | 1439 | mismatchfailsthistest++; |
kendunlop | 10:3e15baff40e7 | 1440 | if (aspamisgoing == 1) |
kendunlop | 10:3e15baff40e7 | 1441 | { |
kendunlop | 11:abd3df435a2b | 1442 | //pc.printf("\r\n(ToseparateMRWfromDNM)"); //Having a new line here separated 'message received was:...' from 'Does NOT match...' too much. |
kendunlop | 10:3e15baff40e7 | 1443 | } |
kendunlop | 11:abd3df435a2b | 1444 | if (messageinisneeded == 1) |
kendunlop | 10:3e15baff40e7 | 1445 | { |
kendunlop | 11:abd3df435a2b | 1446 | pc.printf("Does NOT match : %03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\r", expected1, expected2, expected3, expected4, expected5, expected6, expected7, expected8, expected9, expected10); |
kendunlop | 11:abd3df435a2b | 1447 | //pc.printf("Check later bytes is %d.\r\n", checklaterbytes); |
kendunlop | 11:abd3df435a2b | 1448 | if (messageinisneeded == 1 and aspamisgoing == 0) |
kendunlop | 11:abd3df435a2b | 1449 | { |
kendunlop | 11:abd3df435a2b | 1450 | pc.printf("\n\n"); |
kendunlop | 11:abd3df435a2b | 1451 | } |
kendunlop | 11:abd3df435a2b | 1452 | if (messageinisneeded == 1 and aspamisgoing == 1) |
kendunlop | 11:abd3df435a2b | 1453 | { |
kendunlop | 11:abd3df435a2b | 1454 | pc.printf("\n\n"); |
kendunlop | 11:abd3df435a2b | 1455 | } |
kendunlop | 10:3e15baff40e7 | 1456 | } |
kendunlop | 10:3e15baff40e7 | 1457 | failsthistest++; //Add 1 to failsthistest to mark the fail |
kendunlop | 10:3e15baff40e7 | 1458 | expectationwasfulfilled = 0; |
kendunlop | 10:3e15baff40e7 | 1459 | expectationresolved = 1; |
kendunlop | 10:3e15baff40e7 | 1460 | } |
kendunlop | 10:3e15baff40e7 | 1461 | if (itsamatch == 1) |
kendunlop | 10:3e15baff40e7 | 1462 | { |
kendunlop | 10:3e15baff40e7 | 1463 | expectationwasfulfilled = 1; |
kendunlop | 10:3e15baff40e7 | 1464 | expectationresolved = 1; |
kendunlop | 10:3e15baff40e7 | 1465 | matchesthistest++; |
kendunlop | 10:3e15baff40e7 | 1466 | //If it's a match, write out a 'Matches expectation...' message |
kendunlop | 11:abd3df435a2b | 1467 | if (messageinisneeded == 1) |
kendunlop | 10:3e15baff40e7 | 1468 | { |
kendunlop | 11:abd3df435a2b | 1469 | pc.printf("Matches expectation : %03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\r", expected1, expected2, expected3, expected4, expected5, expected6, expected7, expected8, expected9, expected10); |
kendunlop | 11:abd3df435a2b | 1470 | if (aspamisgoing == 0) |
kendunlop | 11:abd3df435a2b | 1471 | { |
kendunlop | 11:abd3df435a2b | 1472 | pc.printf("\n\n"); |
kendunlop | 11:abd3df435a2b | 1473 | } |
kendunlop | 10:3e15baff40e7 | 1474 | } |
kendunlop | 9:7c27efe30a77 | 1475 | } |
kendunlop | 9:7c27efe30a77 | 1476 | } |
kendunlop | 10:3e15baff40e7 | 1477 | if (idspamon == 1) |
kendunlop | 9:7c27efe30a77 | 1478 | { |
kendunlop | 10:3e15baff40e7 | 1479 | idscheckedcount++; |
kendunlop | 10:3e15baff40e7 | 1480 | idlistincrementer++; //Only add 1 to the idlist incrementer at the end so the first ID it sends is '000'. |
kendunlop | 7:a9150dc1e481 | 1481 | } |
kendunlop | 11:abd3df435a2b | 1482 | if (customentry == 1) |
kendunlop | 11:abd3df435a2b | 1483 | { |
kendunlop | 11:abd3df435a2b | 1484 | pc.printf("Enter CAN ID to send: "); |
kendunlop | 11:abd3df435a2b | 1485 | } |
kendunlop | 7:a9150dc1e481 | 1486 | } |
kendunlop | 10:3e15baff40e7 | 1487 | //If speed-spam is on, spam a CAN message as fast as possible. |
kendunlop | 1:19d183cf2689 | 1488 | } |
kendunlop | 10:3e15baff40e7 | 1489 | if (speedspamison == 1) |
kendunlop | 10:3e15baff40e7 | 1490 | { |
kendunlop | 10:3e15baff40e7 | 1491 | //sendCAN(); |
kendunlop | 10:3e15baff40e7 | 1492 | CanBus.write(messageOut1); |
kendunlop | 10:3e15baff40e7 | 1493 | spamcount++; |
kendunlop | 10:3e15baff40e7 | 1494 | //pc.printf("\rSent %d '%03X %01X %02X %02X %02X %02X %02X %02X %02X %02X' messages...", spamcount, messageOut1.id, messageOut1.len, messageOut1.data[0], messageOut1.data[1], messageOut1.data[2], messageOut1.data[3], messageOut1.data[4], messageOut1.data[5], messageOut1.data[6], messageOut1.data[7]); |
kendunlop | 11:abd3df435a2b | 1495 | //Pressing 'Esc' switches off speed spam mode |
kendunlop | 11:abd3df435a2b | 1496 | wait(0.00001); |
kendunlop | 10:3e15baff40e7 | 1497 | } |
kendunlop | 10:3e15baff40e7 | 1498 | } |
kendunlop | 10:3e15baff40e7 | 1499 | } |