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.
DS2.cpp@2:5a4b823759ac, 2011-05-20 (annotated)
- Committer:
- openobc
- Date:
- Fri May 20 22:38:54 2011 +0000
- Revision:
- 2:5a4b823759ac
- Parent:
- 1:c935b1619b83
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
openobc | 0:32d3cc3791c4 | 1 | #include "DS2.h" |
openobc | 0:32d3cc3791c4 | 2 | |
openobc | 0:32d3cc3791c4 | 3 | |
openobc | 0:32d3cc3791c4 | 4 | DS2Packet::DS2Packet(int maxlength) |
openobc | 0:32d3cc3791c4 | 5 | { |
openobc | 0:32d3cc3791c4 | 6 | has8BitAddr = 0; |
openobc | 0:32d3cc3791c4 | 7 | rawdata = (char*)malloc(maxlength); |
openobc | 0:32d3cc3791c4 | 8 | address = (unsigned short*)rawdata; |
openobc | 0:32d3cc3791c4 | 9 | length = rawdata + 2; |
openobc | 0:32d3cc3791c4 | 10 | data = rawdata + 3; |
openobc | 0:32d3cc3791c4 | 11 | checksum = rawdata + maxlength - 1; |
openobc | 0:32d3cc3791c4 | 12 | |
openobc | 0:32d3cc3791c4 | 13 | *length = 0; |
openobc | 0:32d3cc3791c4 | 14 | } |
openobc | 0:32d3cc3791c4 | 15 | |
openobc | 0:32d3cc3791c4 | 16 | DS2Packet::DS2Packet(int address, const char* data, int length) |
openobc | 0:32d3cc3791c4 | 17 | { |
openobc | 0:32d3cc3791c4 | 18 | has8BitAddr = 0; |
openobc | 0:32d3cc3791c4 | 19 | rawdata = (char*)malloc(length + 4); |
openobc | 0:32d3cc3791c4 | 20 | this->address = (unsigned short*)rawdata; |
openobc | 0:32d3cc3791c4 | 21 | this->length = rawdata + 2; |
openobc | 0:32d3cc3791c4 | 22 | this->data = rawdata + 3; |
openobc | 0:32d3cc3791c4 | 23 | this->checksum = rawdata + 3 + length; |
openobc | 0:32d3cc3791c4 | 24 | |
openobc | 0:32d3cc3791c4 | 25 | rawdata[0] = address & 0xff; |
openobc | 0:32d3cc3791c4 | 26 | rawdata[1] = (address >> 8) & 0xff; |
openobc | 0:32d3cc3791c4 | 27 | rawdata[2] = length + 4; |
openobc | 0:32d3cc3791c4 | 28 | memcpy(rawdata + 3, data, length); |
openobc | 0:32d3cc3791c4 | 29 | |
openobc | 0:32d3cc3791c4 | 30 | updateChecksum(); |
openobc | 0:32d3cc3791c4 | 31 | } |
openobc | 0:32d3cc3791c4 | 32 | |
openobc | 0:32d3cc3791c4 | 33 | DS2Packet::~DS2Packet() |
openobc | 0:32d3cc3791c4 | 34 | { |
openobc | 0:32d3cc3791c4 | 35 | free(rawdata); |
openobc | 0:32d3cc3791c4 | 36 | } |
openobc | 0:32d3cc3791c4 | 37 | |
openobc | 0:32d3cc3791c4 | 38 | void DS2Packet::has8BitAddress(bool b) |
openobc | 0:32d3cc3791c4 | 39 | { |
openobc | 0:32d3cc3791c4 | 40 | if(b && !has8BitAddr) |
openobc | 0:32d3cc3791c4 | 41 | { |
openobc | 0:32d3cc3791c4 | 42 | *address <<= 8; |
openobc | 0:32d3cc3791c4 | 43 | *length -= 1; |
openobc | 0:32d3cc3791c4 | 44 | rawdata += 1; |
openobc | 0:32d3cc3791c4 | 45 | updateChecksum(); |
openobc | 0:32d3cc3791c4 | 46 | } |
openobc | 0:32d3cc3791c4 | 47 | else if(!b && has8BitAddr) |
openobc | 0:32d3cc3791c4 | 48 | { |
openobc | 0:32d3cc3791c4 | 49 | *address >>= 8; |
openobc | 0:32d3cc3791c4 | 50 | *length += 1; |
openobc | 0:32d3cc3791c4 | 51 | rawdata -= 1; |
openobc | 0:32d3cc3791c4 | 52 | updateChecksum(); |
openobc | 0:32d3cc3791c4 | 53 | } |
openobc | 0:32d3cc3791c4 | 54 | has8BitAddr = b; |
openobc | 0:32d3cc3791c4 | 55 | } |
openobc | 0:32d3cc3791c4 | 56 | |
openobc | 0:32d3cc3791c4 | 57 | void DS2Packet::updateChecksum() |
openobc | 0:32d3cc3791c4 | 58 | { |
openobc | 0:32d3cc3791c4 | 59 | *checksum = 0; |
openobc | 0:32d3cc3791c4 | 60 | for(int i = 0; i < *length - 1; i++) |
openobc | 0:32d3cc3791c4 | 61 | *checksum ^= rawdata[i]; |
openobc | 0:32d3cc3791c4 | 62 | } |
openobc | 0:32d3cc3791c4 | 63 | |
openobc | 0:32d3cc3791c4 | 64 | |
openobc | 0:32d3cc3791c4 | 65 | DS2::DS2(Bus* KLine, Bus* LLine) : |
openobc | 0:32d3cc3791c4 | 66 | k(KLine), l(LLine) |
openobc | 0:32d3cc3791c4 | 67 | { |
openobc | 0:32d3cc3791c4 | 68 | k->baud(9600); |
openobc | 0:32d3cc3791c4 | 69 | l->baud(9600); |
openobc | 0:32d3cc3791c4 | 70 | k->format(8, Serial::Even, 1); |
openobc | 0:32d3cc3791c4 | 71 | l->format(8, Serial::Even, 1); |
openobc | 0:32d3cc3791c4 | 72 | } |
openobc | 0:32d3cc3791c4 | 73 | |
openobc | 0:32d3cc3791c4 | 74 | DS2::~DS2() |
openobc | 0:32d3cc3791c4 | 75 | { |
openobc | 0:32d3cc3791c4 | 76 | |
openobc | 0:32d3cc3791c4 | 77 | } |
openobc | 0:32d3cc3791c4 | 78 | |
openobc | 0:32d3cc3791c4 | 79 | int DS2::sendPacket(DS2Packet* packet, Bus* bus) |
openobc | 0:32d3cc3791c4 | 80 | { |
openobc | 0:32d3cc3791c4 | 81 | dbg.printf("sent: "); |
openobc | 0:32d3cc3791c4 | 82 | for(int i = 0; i < packet->getLength(); i++) |
openobc | 0:32d3cc3791c4 | 83 | { |
openobc | 0:32d3cc3791c4 | 84 | dbg.printf("%02x ", packet->getRawData()[i]); |
openobc | 0:32d3cc3791c4 | 85 | } |
openobc | 0:32d3cc3791c4 | 86 | dbg.printf("on %s bus\r\n", (bus == k)? "k":"l"); |
openobc | 0:32d3cc3791c4 | 87 | |
openobc | 0:32d3cc3791c4 | 88 | return bus->send(packet->getRawData(), packet->getLength()); |
openobc | 0:32d3cc3791c4 | 89 | } |
openobc | 0:32d3cc3791c4 | 90 | |
openobc | 0:32d3cc3791c4 | 91 | //reads in a whole packet without verification; assumes the whole packet is in the uart buffer |
openobc | 0:32d3cc3791c4 | 92 | DS2Packet* DS2::getPacket(Bus* bus) |
openobc | 0:32d3cc3791c4 | 93 | { |
openobc | 0:32d3cc3791c4 | 94 | DS2Packet* packet = new DS2Packet(DS2_MTU); |
openobc | 0:32d3cc3791c4 | 95 | int count = bus->get(packet->getRawData(), DS2_MTU); |
openobc | 0:32d3cc3791c4 | 96 | |
openobc | 0:32d3cc3791c4 | 97 | dbg.printf("received: "); |
openobc | 0:32d3cc3791c4 | 98 | for(int i = 0; i < count; i++) |
openobc | 0:32d3cc3791c4 | 99 | dbg.printf("%02x ", packet->getRawData()[i]); |
openobc | 0:32d3cc3791c4 | 100 | dbg.printf("on %s bus\r\n", (bus == k)? "k":"l"); |
openobc | 0:32d3cc3791c4 | 101 | |
openobc | 0:32d3cc3791c4 | 102 | return packet; |
openobc | 0:32d3cc3791c4 | 103 | } |
openobc | 0:32d3cc3791c4 | 104 | |
openobc | 0:32d3cc3791c4 | 105 | DS2Packet* DS2::getPacket8(Bus* bus) |
openobc | 0:32d3cc3791c4 | 106 | { |
openobc | 0:32d3cc3791c4 | 107 | DS2Packet* packet = new DS2Packet(DS2_MTU); |
openobc | 0:32d3cc3791c4 | 108 | packet->has8BitAddress(1); |
openobc | 0:32d3cc3791c4 | 109 | int count = bus->get(packet->getRawData(), DS2_MTU); |
openobc | 0:32d3cc3791c4 | 110 | |
openobc | 0:32d3cc3791c4 | 111 | dbg.printf("received: "); |
openobc | 0:32d3cc3791c4 | 112 | for(int i = 0; i < count; i++) |
openobc | 0:32d3cc3791c4 | 113 | dbg.printf("%02x ", packet->getRawData()[i]); |
openobc | 0:32d3cc3791c4 | 114 | dbg.printf("on %s bus\r\n", (bus == k)? "k":"l"); |
openobc | 0:32d3cc3791c4 | 115 | |
openobc | 0:32d3cc3791c4 | 116 | return packet; |
openobc | 0:32d3cc3791c4 | 117 | } |
openobc | 0:32d3cc3791c4 | 118 | |
openobc | 0:32d3cc3791c4 | 119 | //snoop k and l traffic and print it to dbg |
openobc | 0:32d3cc3791c4 | 120 | //doesn't return |
openobc | 0:32d3cc3791c4 | 121 | void DS2::snoop() |
openobc | 0:32d3cc3791c4 | 122 | { |
openobc | 0:32d3cc3791c4 | 123 | dbg.printf("sniffing data on k and l\r\n"); |
openobc | 0:32d3cc3791c4 | 124 | dbg.printf("k = <0x??>\r\nl = [0x??]\r\n"); |
openobc | 0:32d3cc3791c4 | 125 | dbg.printf("begin INPA traffic now\r\n"); |
openobc | 0:32d3cc3791c4 | 126 | int squelch = 0; |
openobc | 0:32d3cc3791c4 | 127 | while(1) |
openobc | 0:32d3cc3791c4 | 128 | { |
openobc | 0:32d3cc3791c4 | 129 | if(k->readable()) |
openobc | 0:32d3cc3791c4 | 130 | { |
openobc | 0:32d3cc3791c4 | 131 | dbg.printf("<%02x>", k->getc()); |
openobc | 0:32d3cc3791c4 | 132 | squelch = 10000; |
openobc | 0:32d3cc3791c4 | 133 | } |
openobc | 0:32d3cc3791c4 | 134 | else if(l->readable()) |
openobc | 0:32d3cc3791c4 | 135 | { |
openobc | 0:32d3cc3791c4 | 136 | dbg.printf("[%02x]", l->getc()); |
openobc | 0:32d3cc3791c4 | 137 | squelch = 10000; |
openobc | 0:32d3cc3791c4 | 138 | } |
openobc | 0:32d3cc3791c4 | 139 | else if(squelch) |
openobc | 0:32d3cc3791c4 | 140 | { |
openobc | 0:32d3cc3791c4 | 141 | if(!--squelch) |
openobc | 0:32d3cc3791c4 | 142 | dbg.printf("\r\n"); |
openobc | 0:32d3cc3791c4 | 143 | } |
openobc | 0:32d3cc3791c4 | 144 | } |
openobc | 0:32d3cc3791c4 | 145 | } |
openobc | 0:32d3cc3791c4 | 146 | |
openobc | 0:32d3cc3791c4 | 147 | //try to query a module on the two different buses and with the two different packet types |
openobc | 0:32d3cc3791c4 | 148 | void DS2::testModule(int address) |
openobc | 0:32d3cc3791c4 | 149 | { |
openobc | 0:32d3cc3791c4 | 150 | //assemble an identification request packet |
openobc | 0:32d3cc3791c4 | 151 | DS2Packet *packet = new DS2Packet(address, DS2_IDENTIFY, sizeof(DS2_IDENTIFY)); |
openobc | 0:32d3cc3791c4 | 152 | |
openobc | 0:32d3cc3791c4 | 153 | //try on k first |
openobc | 0:32d3cc3791c4 | 154 | dbg.printf("trying module with 16 bit address 0x%02x on k bus\r\n", packet->getAddress()); |
openobc | 0:32d3cc3791c4 | 155 | sendPacket(packet, k); |
openobc | 0:32d3cc3791c4 | 156 | wait(0.5); |
openobc | 0:32d3cc3791c4 | 157 | if(k->readable()) //the module sent a reply |
openobc | 0:32d3cc3791c4 | 158 | { |
openobc | 0:32d3cc3791c4 | 159 | DS2Packet* reply = getPacket(k); |
openobc | 2:5a4b823759ac | 160 | dbg.printf("***received %i bytes from module at 0x%02x on k bus\r\n", reply->getLength(), reply->getAddress()); |
openobc | 0:32d3cc3791c4 | 161 | delete reply; |
openobc | 0:32d3cc3791c4 | 162 | |
openobc | 0:32d3cc3791c4 | 163 | } |
openobc | 0:32d3cc3791c4 | 164 | |
openobc | 0:32d3cc3791c4 | 165 | //then try with 8 bit address |
openobc | 0:32d3cc3791c4 | 166 | packet->has8BitAddress(1); |
openobc | 0:32d3cc3791c4 | 167 | dbg.printf("trying module with 8 bit address 0x%02x on k bus\r\n", packet->getAddress()); |
openobc | 0:32d3cc3791c4 | 168 | sendPacket(packet, k); |
openobc | 1:c935b1619b83 | 169 | wait(0.5); |
openobc | 0:32d3cc3791c4 | 170 | if(k->readable()) |
openobc | 0:32d3cc3791c4 | 171 | { |
openobc | 0:32d3cc3791c4 | 172 | DS2Packet* reply = getPacket8(k); |
openobc | 2:5a4b823759ac | 173 | dbg.printf("***received %i bytes from module at 0x%02x on k bus\r\n", reply->getLength(), reply->getAddress()); |
openobc | 0:32d3cc3791c4 | 174 | delete reply; |
openobc | 0:32d3cc3791c4 | 175 | } |
openobc | 0:32d3cc3791c4 | 176 | |
openobc | 0:32d3cc3791c4 | 177 | //now try on l |
openobc | 0:32d3cc3791c4 | 178 | packet->has8BitAddress(0); |
openobc | 0:32d3cc3791c4 | 179 | dbg.printf("trying module with 16 bit address 0x%02x on l bus\r\n", packet->getAddress()); |
openobc | 0:32d3cc3791c4 | 180 | sendPacket(packet, l); |
openobc | 0:32d3cc3791c4 | 181 | wait(0.5); |
openobc | 0:32d3cc3791c4 | 182 | if(k->readable()) |
openobc | 0:32d3cc3791c4 | 183 | { |
openobc | 0:32d3cc3791c4 | 184 | DS2Packet* reply = getPacket(k); |
openobc | 2:5a4b823759ac | 185 | dbg.printf("***received %i bytes from module at 0x%02x on k bus\r\n", reply->getLength(), reply->getAddress()); |
openobc | 0:32d3cc3791c4 | 186 | delete reply; |
openobc | 0:32d3cc3791c4 | 187 | } |
openobc | 0:32d3cc3791c4 | 188 | |
openobc | 0:32d3cc3791c4 | 189 | //8 bit address again |
openobc | 0:32d3cc3791c4 | 190 | packet->has8BitAddress(1); |
openobc | 0:32d3cc3791c4 | 191 | dbg.printf("trying module with 8 bit address 0x%02x on l bus\r\n", packet->getAddress()); |
openobc | 0:32d3cc3791c4 | 192 | sendPacket(packet, l); |
openobc | 0:32d3cc3791c4 | 193 | wait(0.5); |
openobc | 0:32d3cc3791c4 | 194 | if(k->readable()) |
openobc | 0:32d3cc3791c4 | 195 | { |
openobc | 0:32d3cc3791c4 | 196 | DS2Packet* reply = getPacket8(k); |
openobc | 0:32d3cc3791c4 | 197 | reply->has8BitAddress(1); |
openobc | 2:5a4b823759ac | 198 | dbg.printf("***received %i bytes from module at 0x%02x on k bus\r\n", reply->getLength(), reply->getAddress()); |
openobc | 0:32d3cc3791c4 | 199 | delete reply; |
openobc | 0:32d3cc3791c4 | 200 | } |
openobc | 0:32d3cc3791c4 | 201 | |
openobc | 0:32d3cc3791c4 | 202 | |
openobc | 0:32d3cc3791c4 | 203 | delete packet; |
openobc | 0:32d3cc3791c4 | 204 | } |
openobc | 0:32d3cc3791c4 | 205 | |
openobc | 0:32d3cc3791c4 | 206 | //if I knew of a module that was guaranteed to be the same in every car I'd test querying it here |
openobc | 0:32d3cc3791c4 | 207 | bool DS2::test() |
openobc | 0:32d3cc3791c4 | 208 | { |
openobc | 0:32d3cc3791c4 | 209 | return 1; |
openobc | 0:32d3cc3791c4 | 210 | } |