Dallas' 1-Wire bus protocol library
Dependents: DS1825 DISCO-F746-Dessiccateur-V1 watersenor_and_temp_code DS1820 ... more
OneWire.h
00001 #ifndef OneWire_h 00002 #define OneWire_h 00003 00004 #include <inttypes.h> 00005 #include <mbed.h> 00006 #include "SerialBase.h" 00007 00008 #define MODE() _gpio->mode(PullUp) 00009 #define INPUT() _gpio->input() 00010 #define OUTPUT() _gpio->output() 00011 #define READ() _gpio->read() 00012 #define WRITE(x) _gpio->write(x) 00013 00014 #ifdef TARGET_NORDIC 00015 //NORDIC targets (NRF) use software delays since their ticker uses a 32kHz clock 00016 static uint32_t loops_per_us = 0; 00017 00018 #define INIT_WAIT init_soft_delay() 00019 #define WAIT_US(x) for(int cnt = 0; cnt < (x * loops_per_us) >> 5; cnt++) {__NOP(); __NOP(); __NOP();} 00020 00021 void init_soft_delay( void ) { 00022 if (loops_per_us == 0) { 00023 loops_per_us = 1; 00024 Timer timey; 00025 timey.start(); 00026 ONEWIRE_DELAY_US(320000); 00027 timey.stop(); 00028 loops_per_us = (320000 + timey.read_us() / 2) / timey.read_us(); 00029 } 00030 } 00031 #else 00032 #define INIT_WAIT 00033 #define WAIT_US(x) wait_us(x) 00034 #endif 00035 00036 // You can exclude certain features from OneWire. In theory, this 00037 // might save some space. In practice, the compiler automatically 00038 // removes unused code (technically, the linker, using -fdata-sections 00039 // and -ffunction-sections when compiling, and Wl,--gc-sections 00040 // when linking), so most of these will not result in any code size 00041 // reduction. Well, unless you try to use the missing features 00042 // and redesign your program to not need them! ONEWIRE_CRC8_TABLE 00043 // is the exception, because it selects a fast but large algorithm 00044 // or a small but slow algorithm. 00045 00046 // you can exclude onewire_search by defining that to 0 00047 #ifndef ONEWIRE_SEARCH 00048 #define ONEWIRE_SEARCH 1 00049 #endif 00050 00051 // You can exclude CRC checks altogether by defining this to 0 00052 #ifndef ONEWIRE_CRC 00053 #define ONEWIRE_CRC 1 00054 #endif 00055 00056 class UART : 00057 public SerialBase, 00058 private NonCopyable<UART> 00059 { 00060 UART(const UART&); 00061 public: 00062 UART(PinName tx, PinName rx, int baud) : SerialBase(tx, rx, baud) {} 00063 00064 using SerialBase::_base_getc; 00065 using SerialBase::_base_putc; 00066 }; 00067 00068 class OneWire 00069 { 00070 DigitalInOut* _gpio; 00071 UART* _uart; 00072 00073 int _samplePoint_us; 00074 int _outToInTransition_us; 00075 00076 #if ONEWIRE_SEARCH 00077 // global search state 00078 unsigned char ROM_NO[8]; 00079 uint8_t LastDiscrepancy; 00080 uint8_t LastFamilyDiscrepancy; 00081 uint8_t LastDeviceFlag; 00082 #endif 00083 00084 public: 00085 00086 // Constructors 00087 OneWire(PinName gpioPin, int samplePoint_us = 13); // GPIO 00088 OneWire(PinName txPin, PinName rxPin, int baud = 115200); // UART 00089 00090 // Destructor 00091 ~OneWire(); 00092 00093 // Perform a 1-Wire reset cycle. Returns 1 if a device responds 00094 // with a presence pulse. Returns 0 if there is no device or the 00095 // bus is shorted or otherwise held low for more than 250uS 00096 uint8_t reset(void); 00097 00098 // Issue a 1-Wire rom select command, you do the reset first. 00099 void select(const uint8_t rom[8]); 00100 00101 // Issue a 1-Wire rom skip command, to address all on bus. 00102 void skip(void); 00103 00104 // Write a byte. If 'power' is one then the wire is held high at 00105 // the end for parasitically powered devices. You are responsible 00106 // for eventually depowering it by calling depower() or doing 00107 // another read or write. 00108 void write_byte(uint8_t v, uint8_t power = 0); 00109 00110 void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0); 00111 00112 // Read a byte. 00113 uint8_t read_byte(void); 00114 00115 void read_bytes(uint8_t *buf, uint16_t count); 00116 00117 // Write a bit. The bus is always left powered at the end, see 00118 // note in write() about that. 00119 void write_bit(uint8_t v); 00120 00121 // Read a bit. 00122 uint8_t read_bit(void); 00123 00124 // Stop forcing power onto the bus. You only need to do this if 00125 // you used the 'power' flag to write() or used a write_bit() call 00126 // and aren't about to do another read or write. You would rather 00127 // not leave this powered if you don't have to, just in case 00128 // someone shorts your bus. 00129 void depower(void); 00130 00131 #if ONEWIRE_SEARCH 00132 // Clear the search state so that if will start from the beginning again. 00133 void reset_search(); 00134 00135 // Setup the search to find the device type 'family_code' on the next call 00136 // to search(*newAddr) if it is present. 00137 void target_search(uint8_t family_code); 00138 00139 // Look for the next device. Returns 1 if a new address has been 00140 // returned. A zero might mean that the bus is shorted, there are 00141 // no devices, or you have already retrieved all of them. It 00142 // might be a good idea to check the CRC to make sure you didn't 00143 // get garbage. The order is deterministic. You will always get 00144 // the same devices in the same order. 00145 uint8_t search(uint8_t *newAddr); 00146 #endif 00147 00148 #if ONEWIRE_CRC 00149 // Compute a Dallas Semiconductor 8 bit CRC, these are used in the 00150 // ROM and scratchpad registers. 00151 static uint8_t crc8(const uint8_t *addr, uint8_t len); 00152 00153 #if ONEWIRE_CRC16 00154 // Compute the 1-Wire CRC16 and compare it against the received CRC. 00155 // Example usage (reading a DS2408): 00156 // // Put everything in a buffer so we can compute the CRC easily. 00157 // uint8_t buf[13]; 00158 // buf[0] = 0xF0; // Read PIO Registers 00159 // buf[1] = 0x88; // LSB address 00160 // buf[2] = 0x00; // MSB address 00161 // WriteBytes(net, buf, 3); // Write 3 cmd bytes 00162 // ReadBytes(net, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16 00163 // if (!CheckCRC16(buf, 11, &buf[11])) { 00164 // // Handle error. 00165 // } 00166 // 00167 // @param input - Array of bytes to checksum. 00168 // @param len - How many bytes to use. 00169 // @param inverted_crc - The two CRC16 bytes in the received data. 00170 // This should just point into the received data, 00171 // *not* at a 16-bit integer. 00172 // @param crc - The crc starting value (optional) 00173 // @return True, iff the CRC matches. 00174 static bool check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc = 0); 00175 00176 // Compute a Dallas Semiconductor 16 bit CRC. This is required to check 00177 // the integrity of data received from many 1-Wire devices. Note that the 00178 // CRC computed here is *not* what you'll get from the 1-Wire network, 00179 // for two reasons: 00180 // 1) The CRC is transmitted bitwise inverted. 00181 // 2) Depending on the endian-ness of your processor, the binary 00182 // representation of the two-byte return value may have a different 00183 // byte order than the two bytes you get from 1-Wire. 00184 // @param input - Array of bytes to checksum. 00185 // @param len - How many bytes to use. 00186 // @param crc - The crc starting value (optional) 00187 // @return The CRC16, as defined by Dallas Semiconductor. 00188 static uint16_t crc16(const uint8_t* input, uint16_t len, uint16_t crc = 0); 00189 #endif 00190 #endif 00191 }; 00192 00193 #endif 00194 00195
Generated on Fri Jul 15 2022 08:26:11 by 1.7.2