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