Working versione for L-tek FF1705
OneWire.h@13:573a546ef5f9, 2019-03-13 (annotated)
- Committer:
- marcozecchini
- Date:
- Wed Mar 13 10:05:02 2019 +0000
- Revision:
- 13:573a546ef5f9
- Parent:
- 12:27a1b359b95c
Working for FF1705 L-tek board;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hudakz | 0:acf75feb0947 | 1 | #ifndef OneWire_h |
hudakz | 0:acf75feb0947 | 2 | #define OneWire_h |
hudakz | 0:acf75feb0947 | 3 | |
hudakz | 0:acf75feb0947 | 4 | #include <inttypes.h> |
hudakz | 0:acf75feb0947 | 5 | #include <mbed.h> |
hudakz | 0:acf75feb0947 | 6 | |
hudakz | 10:c89b9ad6097c | 7 | #if defined(TARGET_STM) |
hudakz | 12:27a1b359b95c | 8 | #define MODE() output(); \ |
hudakz | 12:27a1b359b95c | 9 | mode(OpenDrain) |
hudakz | 10:c89b9ad6097c | 10 | #define INPUT() (*gpio.reg_set = gpio.mask) // write 1 to open drain |
hudakz | 11:bc8ed7280966 | 11 | #define OUTPUT() // configured as output in the constructor and stays like that forever |
hudakz | 11:bc8ed7280966 | 12 | #define READ() ((*gpio.reg_in & gpio.mask) != 0) |
hudakz | 10:c89b9ad6097c | 13 | #define WRITE(x) write(x) |
hudakz | 10:c89b9ad6097c | 14 | #else |
hudakz | 10:c89b9ad6097c | 15 | #define MODE() mode(PullUp) |
hudakz | 10:c89b9ad6097c | 16 | #define INPUT() input() |
hudakz | 10:c89b9ad6097c | 17 | #define OUTPUT() output() |
hudakz | 10:c89b9ad6097c | 18 | #define READ() read() |
hudakz | 10:c89b9ad6097c | 19 | #define WRITE(x) write(x) |
hudakz | 10:c89b9ad6097c | 20 | #endif |
hudakz | 10:c89b9ad6097c | 21 | |
hudakz | 12:27a1b359b95c | 22 | #ifdef TARGET_NORDIC |
hudakz | 12:27a1b359b95c | 23 | //NORDIC targets (NRF) use software delays since their ticker uses a 32kHz clock |
hudakz | 12:27a1b359b95c | 24 | static uint32_t loops_per_us = 0; |
hudakz | 12:27a1b359b95c | 25 | |
hudakz | 12:27a1b359b95c | 26 | #define INIT_WAIT init_soft_delay() |
hudakz | 12:27a1b359b95c | 27 | #define WAIT_US(x) for(int cnt = 0; cnt < (x * loops_per_us) >> 5; cnt++) {__NOP(); __NOP(); __NOP();} |
hudakz | 12:27a1b359b95c | 28 | |
hudakz | 12:27a1b359b95c | 29 | void init_soft_delay( void ) { |
hudakz | 12:27a1b359b95c | 30 | if (loops_per_us == 0) { |
hudakz | 12:27a1b359b95c | 31 | loops_per_us = 1; |
hudakz | 12:27a1b359b95c | 32 | Timer timey; |
hudakz | 12:27a1b359b95c | 33 | timey.start(); |
hudakz | 12:27a1b359b95c | 34 | ONEWIRE_DELAY_US(320000); |
hudakz | 12:27a1b359b95c | 35 | timey.stop(); |
hudakz | 12:27a1b359b95c | 36 | loops_per_us = (320000 + timey.read_us() / 2) / timey.read_us(); |
hudakz | 12:27a1b359b95c | 37 | } |
hudakz | 12:27a1b359b95c | 38 | } |
hudakz | 12:27a1b359b95c | 39 | #else |
hudakz | 12:27a1b359b95c | 40 | #define INIT_WAIT |
hudakz | 12:27a1b359b95c | 41 | #define WAIT_US(x) wait_us(x) |
hudakz | 12:27a1b359b95c | 42 | #endif |
hudakz | 12:27a1b359b95c | 43 | |
hudakz | 0:acf75feb0947 | 44 | // You can exclude certain features from OneWire. In theory, this |
hudakz | 0:acf75feb0947 | 45 | // might save some space. In practice, the compiler automatically |
hudakz | 0:acf75feb0947 | 46 | // removes unused code (technically, the linker, using -fdata-sections |
hudakz | 0:acf75feb0947 | 47 | // and -ffunction-sections when compiling, and Wl,--gc-sections |
hudakz | 0:acf75feb0947 | 48 | // when linking), so most of these will not result in any code size |
hudakz | 0:acf75feb0947 | 49 | // reduction. Well, unless you try to use the missing features |
hudakz | 0:acf75feb0947 | 50 | // and redesign your program to not need them! ONEWIRE_CRC8_TABLE |
hudakz | 0:acf75feb0947 | 51 | // is the exception, because it selects a fast but large algorithm |
hudakz | 0:acf75feb0947 | 52 | // or a small but slow algorithm. |
hudakz | 0:acf75feb0947 | 53 | |
hudakz | 0:acf75feb0947 | 54 | // you can exclude onewire_search by defining that to 0 |
hudakz | 0:acf75feb0947 | 55 | #ifndef ONEWIRE_SEARCH |
hudakz | 0:acf75feb0947 | 56 | #define ONEWIRE_SEARCH 1 |
hudakz | 0:acf75feb0947 | 57 | #endif |
hudakz | 0:acf75feb0947 | 58 | |
hudakz | 0:acf75feb0947 | 59 | // You can exclude CRC checks altogether by defining this to 0 |
hudakz | 0:acf75feb0947 | 60 | #ifndef ONEWIRE_CRC |
hudakz | 0:acf75feb0947 | 61 | #define ONEWIRE_CRC 1 |
hudakz | 0:acf75feb0947 | 62 | #endif |
hudakz | 0:acf75feb0947 | 63 | |
hudakz | 9:4af0015b0f47 | 64 | class OneWire : public DigitalInOut |
hudakz | 0:acf75feb0947 | 65 | { |
hudakz | 9:4af0015b0f47 | 66 | Timer timer; |
hudakz | 0:acf75feb0947 | 67 | |
hudakz | 0:acf75feb0947 | 68 | #if ONEWIRE_SEARCH |
hudakz | 0:acf75feb0947 | 69 | // global search state |
hudakz | 0:acf75feb0947 | 70 | unsigned char ROM_NO[8]; |
hudakz | 0:acf75feb0947 | 71 | uint8_t LastDiscrepancy; |
hudakz | 0:acf75feb0947 | 72 | uint8_t LastFamilyDiscrepancy; |
hudakz | 0:acf75feb0947 | 73 | uint8_t LastDeviceFlag; |
hudakz | 0:acf75feb0947 | 74 | #endif |
hudakz | 0:acf75feb0947 | 75 | |
hudakz | 9:4af0015b0f47 | 76 | public: |
hudakz | 0:acf75feb0947 | 77 | OneWire(PinName pin); |
hudakz | 0:acf75feb0947 | 78 | |
hudakz | 0:acf75feb0947 | 79 | // Perform a 1-Wire reset cycle. Returns 1 if a device responds |
hudakz | 0:acf75feb0947 | 80 | // with a presence pulse. Returns 0 if there is no device or the |
hudakz | 0:acf75feb0947 | 81 | // bus is shorted or otherwise held low for more than 250uS |
hudakz | 0:acf75feb0947 | 82 | uint8_t reset(void); |
hudakz | 0:acf75feb0947 | 83 | |
hudakz | 0:acf75feb0947 | 84 | // Issue a 1-Wire rom select command, you do the reset first. |
hudakz | 0:acf75feb0947 | 85 | void select(const uint8_t rom[8]); |
hudakz | 0:acf75feb0947 | 86 | |
hudakz | 0:acf75feb0947 | 87 | // Issue a 1-Wire rom skip command, to address all on bus. |
hudakz | 0:acf75feb0947 | 88 | void skip(void); |
hudakz | 0:acf75feb0947 | 89 | |
hudakz | 0:acf75feb0947 | 90 | // Write a byte. If 'power' is one then the wire is held high at |
hudakz | 0:acf75feb0947 | 91 | // the end for parasitically powered devices. You are responsible |
hudakz | 0:acf75feb0947 | 92 | // for eventually depowering it by calling depower() or doing |
hudakz | 0:acf75feb0947 | 93 | // another read or write. |
hudakz | 9:4af0015b0f47 | 94 | void write_byte(uint8_t v, uint8_t power = 0); |
hudakz | 0:acf75feb0947 | 95 | |
hudakz | 0:acf75feb0947 | 96 | void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0); |
hudakz | 0:acf75feb0947 | 97 | |
hudakz | 0:acf75feb0947 | 98 | // Read a byte. |
hudakz | 9:4af0015b0f47 | 99 | uint8_t read_byte(void); |
hudakz | 0:acf75feb0947 | 100 | |
hudakz | 0:acf75feb0947 | 101 | void read_bytes(uint8_t *buf, uint16_t count); |
hudakz | 0:acf75feb0947 | 102 | |
hudakz | 0:acf75feb0947 | 103 | // Write a bit. The bus is always left powered at the end, see |
hudakz | 0:acf75feb0947 | 104 | // note in write() about that. |
hudakz | 0:acf75feb0947 | 105 | void write_bit(uint8_t v); |
hudakz | 0:acf75feb0947 | 106 | |
hudakz | 0:acf75feb0947 | 107 | // Read a bit. |
hudakz | 0:acf75feb0947 | 108 | uint8_t read_bit(void); |
hudakz | 0:acf75feb0947 | 109 | |
hudakz | 0:acf75feb0947 | 110 | // Stop forcing power onto the bus. You only need to do this if |
hudakz | 0:acf75feb0947 | 111 | // you used the 'power' flag to write() or used a write_bit() call |
hudakz | 0:acf75feb0947 | 112 | // and aren't about to do another read or write. You would rather |
hudakz | 0:acf75feb0947 | 113 | // not leave this powered if you don't have to, just in case |
hudakz | 0:acf75feb0947 | 114 | // someone shorts your bus. |
hudakz | 0:acf75feb0947 | 115 | void depower(void); |
hudakz | 0:acf75feb0947 | 116 | |
hudakz | 0:acf75feb0947 | 117 | #if ONEWIRE_SEARCH |
hudakz | 0:acf75feb0947 | 118 | // Clear the search state so that if will start from the beginning again. |
hudakz | 0:acf75feb0947 | 119 | void reset_search(); |
hudakz | 0:acf75feb0947 | 120 | |
hudakz | 0:acf75feb0947 | 121 | // Setup the search to find the device type 'family_code' on the next call |
hudakz | 0:acf75feb0947 | 122 | // to search(*newAddr) if it is present. |
hudakz | 0:acf75feb0947 | 123 | void target_search(uint8_t family_code); |
hudakz | 0:acf75feb0947 | 124 | |
hudakz | 0:acf75feb0947 | 125 | // Look for the next device. Returns 1 if a new address has been |
hudakz | 0:acf75feb0947 | 126 | // returned. A zero might mean that the bus is shorted, there are |
hudakz | 0:acf75feb0947 | 127 | // no devices, or you have already retrieved all of them. It |
hudakz | 0:acf75feb0947 | 128 | // might be a good idea to check the CRC to make sure you didn't |
hudakz | 0:acf75feb0947 | 129 | // get garbage. The order is deterministic. You will always get |
hudakz | 0:acf75feb0947 | 130 | // the same devices in the same order. |
hudakz | 0:acf75feb0947 | 131 | uint8_t search(uint8_t *newAddr); |
hudakz | 0:acf75feb0947 | 132 | #endif |
hudakz | 0:acf75feb0947 | 133 | |
hudakz | 0:acf75feb0947 | 134 | #if ONEWIRE_CRC |
hudakz | 0:acf75feb0947 | 135 | // Compute a Dallas Semiconductor 8 bit CRC, these are used in the |
hudakz | 0:acf75feb0947 | 136 | // ROM and scratchpad registers. |
hudakz | 0:acf75feb0947 | 137 | static uint8_t crc8(const uint8_t *addr, uint8_t len); |
hudakz | 0:acf75feb0947 | 138 | |
hudakz | 0:acf75feb0947 | 139 | #if ONEWIRE_CRC16 |
hudakz | 0:acf75feb0947 | 140 | // Compute the 1-Wire CRC16 and compare it against the received CRC. |
hudakz | 0:acf75feb0947 | 141 | // Example usage (reading a DS2408): |
hudakz | 0:acf75feb0947 | 142 | // // Put everything in a buffer so we can compute the CRC easily. |
hudakz | 0:acf75feb0947 | 143 | // uint8_t buf[13]; |
hudakz | 0:acf75feb0947 | 144 | // buf[0] = 0xF0; // Read PIO Registers |
hudakz | 0:acf75feb0947 | 145 | // buf[1] = 0x88; // LSB address |
hudakz | 0:acf75feb0947 | 146 | // buf[2] = 0x00; // MSB address |
hudakz | 0:acf75feb0947 | 147 | // WriteBytes(net, buf, 3); // Write 3 cmd bytes |
hudakz | 0:acf75feb0947 | 148 | // ReadBytes(net, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16 |
hudakz | 0:acf75feb0947 | 149 | // if (!CheckCRC16(buf, 11, &buf[11])) { |
hudakz | 0:acf75feb0947 | 150 | // // Handle error. |
hudakz | 0:acf75feb0947 | 151 | // } |
hudakz | 0:acf75feb0947 | 152 | // |
hudakz | 0:acf75feb0947 | 153 | // @param input - Array of bytes to checksum. |
hudakz | 0:acf75feb0947 | 154 | // @param len - How many bytes to use. |
hudakz | 0:acf75feb0947 | 155 | // @param inverted_crc - The two CRC16 bytes in the received data. |
hudakz | 0:acf75feb0947 | 156 | // This should just point into the received data, |
hudakz | 0:acf75feb0947 | 157 | // *not* at a 16-bit integer. |
hudakz | 0:acf75feb0947 | 158 | // @param crc - The crc starting value (optional) |
hudakz | 0:acf75feb0947 | 159 | // @return True, iff the CRC matches. |
hudakz | 0:acf75feb0947 | 160 | static bool check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc = 0); |
hudakz | 0:acf75feb0947 | 161 | |
hudakz | 0:acf75feb0947 | 162 | // Compute a Dallas Semiconductor 16 bit CRC. This is required to check |
hudakz | 0:acf75feb0947 | 163 | // the integrity of data received from many 1-Wire devices. Note that the |
hudakz | 0:acf75feb0947 | 164 | // CRC computed here is *not* what you'll get from the 1-Wire network, |
hudakz | 0:acf75feb0947 | 165 | // for two reasons: |
hudakz | 0:acf75feb0947 | 166 | // 1) The CRC is transmitted bitwise inverted. |
hudakz | 0:acf75feb0947 | 167 | // 2) Depending on the endian-ness of your processor, the binary |
hudakz | 0:acf75feb0947 | 168 | // representation of the two-byte return value may have a different |
hudakz | 0:acf75feb0947 | 169 | // byte order than the two bytes you get from 1-Wire. |
hudakz | 0:acf75feb0947 | 170 | // @param input - Array of bytes to checksum. |
hudakz | 0:acf75feb0947 | 171 | // @param len - How many bytes to use. |
hudakz | 0:acf75feb0947 | 172 | // @param crc - The crc starting value (optional) |
hudakz | 0:acf75feb0947 | 173 | // @return The CRC16, as defined by Dallas Semiconductor. |
hudakz | 0:acf75feb0947 | 174 | static uint16_t crc16(const uint8_t* input, uint16_t len, uint16_t crc = 0); |
hudakz | 0:acf75feb0947 | 175 | #endif |
hudakz | 0:acf75feb0947 | 176 | #endif |
hudakz | 0:acf75feb0947 | 177 | }; |
hudakz | 0:acf75feb0947 | 178 | |
hudakz | 0:acf75feb0947 | 179 | #endif |
hudakz | 12:27a1b359b95c | 180 | |
hudakz | 12:27a1b359b95c | 181 |