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.
Transport.cpp
00001 #include "Transport.h" 00002 00003 /* This table helps with the compution of the CRC8 used in OneWire ROM 00004 * 00005 * The theory is that it precomputes all possible states that an eight bit shift register 00006 * can go to from a certain state when given a certain byte. Computationally and array 00007 * lookup should be considerably faster than simulating the shift register a bit at a time. 00008 * 00009 * Table was sourced from maxim document AN937 that describes the standard. 00010 */ 00011 const unsigned char crc8table[256] = { 00012 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 00013 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 00014 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 00015 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 00016 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 00017 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 00018 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 00019 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 00020 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 00021 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 00022 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 00023 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 00024 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 00025 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, 00026 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, 00027 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53}; 00028 00029 // read command 00030 00031 void OWTransport::read(OneWire_Instruction * inst, OneWire_ROM * out){ 00032 inst->network.code = READ_ROM; 00033 inst->network.inst = &OWTransport::_inst_readsetup; 00034 inst->network.args = out; 00035 *out = 0; // clear rom to a valid value (0 does pass CRC8 but is impossible to get as a device) 00036 } 00037 00038 void OWTransport::_inst_readsetup(OneWire * which){ 00039 // setup register 00040 ((TransportRead *)(which->registers))->read = 0; 00041 ((TransportRead *)(which->registers))->crc8 = 0; 00042 00043 // setup command 00044 which->readhandle = &OWTransport::_inst_readhandler; 00045 which->execute.inst = &OWTransport::_inst_read; 00046 00047 // execute command 00048 OWTransport::_inst_read(which); 00049 } 00050 00051 void OWTransport::_inst_read(OneWire * which){ 00052 if(((TransportRead *)(which->registers))->read < 64){ 00053 which->op_read(); 00054 }else{ 00055 // check if crc8 check passed (remainder 0), failure is not recoverable 00056 if(((TransportRead *)(which->registers))->crc8) which->abort(CRC_ERROR); 00057 else which->endInstruction(); 00058 } 00059 } 00060 00061 void OWTransport::_inst_readhandler(OneWire * which, char bit){ 00062 // store bit 00063 *((unsigned char *)(which->execute.args))|= bit<<(((TransportRead *)(which->registers))->read++%8); 00064 00065 // every 8 bits (byte) compute CRC8 and move to next byte 00066 if(!(((TransportRead *)(which->registers))->read % 8)){ 00067 ((TransportRead *)(which->registers))->crc8 = crc8table[((TransportRead *)(which->registers))->crc8 ^ (*((unsigned char *)(which->execute.args)))]; 00068 which->execute.args = (void *)(((unsigned char *)(which->execute.args))+1); 00069 } 00070 } 00071 00072 // search command 00073 00074 void TransportSearchPersist::clear(){ 00075 rom = 0; 00076 last = -1; 00077 done = false; 00078 } 00079 00080 void OWTransport::search(OneWire_Instruction * inst, TransportSearchPersist * search){ 00081 inst->network.code = SEARCH_ROM; 00082 inst->network.inst = &OWTransport::_inst_searchsetup; 00083 inst->network.args = search; 00084 } 00085 00086 void OWTransport::_inst_searchsetup(OneWire * which){ 00087 if(((TransportSearchPersist *)(which->execute.args))->done){ 00088 // the search had completed, there is nothing more to do 00089 which->abort(SUCCESS); 00090 return; 00091 } 00092 00093 // setup register 00094 ((TransportSearch *)(which->registers))->read = 0; 00095 ((TransportSearch *)(which->registers))->crc8 = 0; 00096 ((TransportSearch *)(which->registers))->marker = -1; 00097 ((TransportSearch *)(which->registers))->bit = 0; 00098 00099 // setup command 00100 which->readhandle = &OWTransport::_inst_searchhandler; 00101 which->execute.inst = &OWTransport::_inst_search; 00102 00103 // execute command 00104 OWTransport::_inst_search(which); 00105 } 00106 00107 void OWTransport::_inst_search(OneWire * which){ 00108 if(((TransportSearch *)(which->registers))->read < 64){ 00109 // state machine, read bit 1 -> read bit 2 and make choice -> send choice -> repeat up to 64 times 00110 if(((TransportSearch *)(which->registers))->bit>>3 & 0x01){ 00111 // send choosen bit and advance 00112 if(((unsigned char *)&(((TransportSearchPersist *)(which->execute.args))->rom))[((TransportSearch *)(which->registers))->read/8]>>(((TransportSearch *)(which->registers))->read%8) &0x01){ 00113 which->op_send1(); 00114 }else{ 00115 which->op_send0(); 00116 } 00117 // compute crc8 00118 if(((TransportSearch *)(which->registers))->read % 8 == 7){ 00119 ((TransportSearch *)(which->registers))->crc8 = crc8table[((TransportSearch *)(which->registers))->crc8 ^ ((unsigned char *)&(((TransportSearchPersist *)(which->execute.args))->rom))[((TransportSearch *)(which->registers))->read/8]]; 00120 } 00121 00122 // prepare for next cycle (reset state machine) 00123 ((TransportSearch *)(which->registers))->read+= 1; 00124 ((TransportSearch *)(which->registers))->bit = 0; 00125 }else{ 00126 // read bit 1 and 2 (read function advances state machine) 00127 which->op_read(); 00128 } 00129 }else{ 00130 ((TransportSearchPersist *)(which->execute.args))->last = ((TransportSearch *)(which->registers))->marker; 00131 if(((TransportSearchPersist *)(which->execute.args))->last == -1) ((TransportSearchPersist *)(which->execute.args))->done = true; 00132 00133 // check if crc8 check passed (remainder 0), failure is not recoverable 00134 if(((TransportSearch *)(which->registers))->crc8) which->abort(CRC_ERROR); 00135 else which->endInstruction(); 00136 } 00137 } 00138 00139 void OWTransport::_inst_searchhandler(OneWire * which, char bit){ 00140 // store bit 00141 ((TransportSearch *)(which->registers))->bit|= bit<<(((TransportSearch *)(which->registers))->bit>>2 & 0x01); 00142 00143 // advance state 00144 if(((TransportSearch *)(which->registers))->bit>>2 & 0x01){ 00145 if((((TransportSearch *)(which->registers))->bit & 0x03) == 3){ 00146 // all slaves were removed or broke? 00147 ((TransportSearchPersist *)(which->execute.args))->done = true; // any search results that were obtained could be invalid so end search 00148 which->abort(NO_PRESENCE); 00149 return; 00150 }else if((((TransportSearch *)(which->registers))->bit & 0x03) == 0){ 00151 // a conflict bit 00152 if(((TransportSearch *)(which->registers))->read == ((TransportSearchPersist *)(which->execute.args))->last){ 00153 // already searched 0 bit path, this time send a 1 00154 ((unsigned char *)&(((TransportSearchPersist *)(which->execute.args))->rom))[((TransportSearch *)(which->registers))->read/8]|= 0x01<<(((TransportSearch *)(which->registers))->read%8); 00155 }else if(((TransportSearch *)(which->registers))->read > ((TransportSearchPersist *)(which->execute.args))->last){ 00156 // a new branch to search 00157 ((unsigned char *)&(((TransportSearchPersist *)(which->execute.args))->rom))[((TransportSearch *)(which->registers))->read/8]&= ~(0x01<<(((TransportSearch *)(which->registers))->read%8)); 00158 ((TransportSearch *)(which->registers))->marker = ((TransportSearch *)(which->registers))->read; 00159 }else if( !(((unsigned char *)&(((TransportSearchPersist *)(which->execute.args))->rom))[((TransportSearch *)(which->registers))->read/8]>>(((TransportSearch *)(which->registers))->read%8) &0x01) ){ 00160 // a previous branch decision 00161 ((TransportSearch *)(which->registers))->marker = ((TransportSearch *)(which->registers))->read; 00162 } 00163 }else{ 00164 // no conflict so write the bit 00165 if(((TransportSearch *)(which->registers))->bit & 0x01){ 00166 ((unsigned char *)&(((TransportSearchPersist *)(which->execute.args))->rom))[((TransportSearch *)(which->registers))->read/8]|= 0x01<<(((TransportSearch *)(which->registers))->read%8); 00167 }else{ 00168 ((unsigned char *)&(((TransportSearchPersist *)(which->execute.args))->rom))[((TransportSearch *)(which->registers))->read/8]&= ~(0x01<<(((TransportSearch *)(which->registers))->read%8)); 00169 } 00170 } 00171 00172 // tell next call to send the choice 00173 ((TransportSearch *)(which->registers))->bit|= 0x08; 00174 }else{ 00175 // we need to read another bit 00176 ((TransportSearch *)(which->registers))->bit|= 0x04; 00177 } 00178 }
Generated on Mon Jul 18 2022 01:01:29 by
1.7.2