Andrew Boyson
/
iot
Backing up an unused program in case of future need
1-wire.cpp@7:024ace6d943c, 2016-06-02 (annotated)
- Committer:
- andrewboyson
- Date:
- Thu Jun 02 09:26:28 2016 +0000
- Revision:
- 7:024ace6d943c
- Parent:
- 6:be97d38e0b01
Added a routine to break time_t into a struct tm without using gmtime as that did not seem to work.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 6:be97d38e0b01 | 1 | #include "mbed.h" |
andrewboyson | 6:be97d38e0b01 | 2 | #include "log.h" |
andrewboyson | 6:be97d38e0b01 | 3 | #include "io.h" |
andrewboyson | 6:be97d38e0b01 | 4 | #include "1-wire.h" |
andrewboyson | 4:e076884ef8bd | 5 | |
andrewboyson | 7:024ace6d943c | 6 | #define DEBUG false //Set to true to add debug messages to the log |
andrewboyson | 7:024ace6d943c | 7 | |
andrewboyson | 4:e076884ef8bd | 8 | //Bus zone |
andrewboyson | 4:e076884ef8bd | 9 | //======== |
andrewboyson | 4:e076884ef8bd | 10 | static DigitalInOut pin(p25, PIN_INPUT, PullUp, 0); |
andrewboyson | 4:e076884ef8bd | 11 | |
andrewboyson | 6:be97d38e0b01 | 12 | static volatile int busvalue; |
andrewboyson | 4:e076884ef8bd | 13 | |
andrewboyson | 6:be97d38e0b01 | 14 | static Timer timer; |
andrewboyson | 6:be97d38e0b01 | 15 | static Timer busytimer; |
andrewboyson | 4:e076884ef8bd | 16 | |
andrewboyson | 4:e076884ef8bd | 17 | //Delays |
andrewboyson | 5:6226f3c566ef | 18 | #define ATTACH_US 7 |
andrewboyson | 5:6226f3c566ef | 19 | #define INITIAL_US 100 |
andrewboyson | 5:6226f3c566ef | 20 | #define RESET_BUS_LOW_US 480 |
andrewboyson | 5:6226f3c566ef | 21 | #define READ_PRESENCE_US 70 |
andrewboyson | 5:6226f3c566ef | 22 | #define RESET_RELEASE_US 410 |
andrewboyson | 5:6226f3c566ef | 23 | #define WRITE_0_BUS_LOW_US 60 |
andrewboyson | 5:6226f3c566ef | 24 | #define WRITE_0_RELEASE_US 10 |
andrewboyson | 5:6226f3c566ef | 25 | #define WRITE_1_BUS_LOW_US 6 |
andrewboyson | 5:6226f3c566ef | 26 | #define WRITE_1_RELEASE_US 64 |
andrewboyson | 5:6226f3c566ef | 27 | #define READ_BIT_BUS_LOW_US 6 |
andrewboyson | 5:6226f3c566ef | 28 | #define READ_BIT_US 9 |
andrewboyson | 5:6226f3c566ef | 29 | #define READ_BIT_RELEASE_US 55 |
andrewboyson | 6:be97d38e0b01 | 30 | #define BUS_TIMEOUT_MS 5000 |
andrewboyson | 4:e076884ef8bd | 31 | |
andrewboyson | 6:be97d38e0b01 | 32 | static void buslow (void) { pin.output(); pin = 0; } |
andrewboyson | 6:be97d38e0b01 | 33 | static void busfree(void) { pin.input (); } |
andrewboyson | 6:be97d38e0b01 | 34 | static void bushigh(void) { pin.output(); pin = 1; } |
andrewboyson | 6:be97d38e0b01 | 35 | static void busread(void) { busvalue = pin; } |
andrewboyson | 4:e076884ef8bd | 36 | |
andrewboyson | 4:e076884ef8bd | 37 | //Exchange zone |
andrewboyson | 4:e076884ef8bd | 38 | //============= |
andrewboyson | 6:be97d38e0b01 | 39 | #define STATE_IDLE 0 |
andrewboyson | 6:be97d38e0b01 | 40 | #define RESET_LOW 1 |
andrewboyson | 6:be97d38e0b01 | 41 | #define RESET_RELEASE 2 |
andrewboyson | 6:be97d38e0b01 | 42 | #define XCHG_WRITE 3 |
andrewboyson | 6:be97d38e0b01 | 43 | #define PULL_UP 4 |
andrewboyson | 6:be97d38e0b01 | 44 | #define XCHG_READ 5 |
andrewboyson | 6:be97d38e0b01 | 45 | #define SEARCH_WRITE 6 |
andrewboyson | 6:be97d38e0b01 | 46 | #define SEARCH_BIT 7 |
andrewboyson | 6:be97d38e0b01 | 47 | #define SEARCH_READ_BIT_TRUE 8 |
andrewboyson | 6:be97d38e0b01 | 48 | #define SEARCH_READ_BIT_COMP 9 |
andrewboyson | 6:be97d38e0b01 | 49 | #define SEARCH_WRITE_BIT 10 |
andrewboyson | 6:be97d38e0b01 | 50 | static int state = STATE_IDLE; |
andrewboyson | 6:be97d38e0b01 | 51 | |
andrewboyson | 6:be97d38e0b01 | 52 | #define JOB_NONE 0 |
andrewboyson | 6:be97d38e0b01 | 53 | #define JOB_XCHG 1 |
andrewboyson | 6:be97d38e0b01 | 54 | #define JOB_SEARCH 2 |
andrewboyson | 6:be97d38e0b01 | 55 | static int job = JOB_NONE; |
andrewboyson | 4:e076884ef8bd | 56 | |
andrewboyson | 4:e076884ef8bd | 57 | static int lensend = 0; |
andrewboyson | 4:e076884ef8bd | 58 | static int lenrecv = 0; |
andrewboyson | 4:e076884ef8bd | 59 | static char* psend = NULL; |
andrewboyson | 4:e076884ef8bd | 60 | static char* precv = NULL; |
andrewboyson | 4:e076884ef8bd | 61 | static int pullupms = 0; |
andrewboyson | 4:e076884ef8bd | 62 | |
andrewboyson | 6:be97d38e0b01 | 63 | static void initiateResetLow(int jobtype) |
andrewboyson | 6:be97d38e0b01 | 64 | { |
andrewboyson | 6:be97d38e0b01 | 65 | buslow(); |
andrewboyson | 6:be97d38e0b01 | 66 | timer.stop(); |
andrewboyson | 6:be97d38e0b01 | 67 | timer.reset(); |
andrewboyson | 6:be97d38e0b01 | 68 | timer.start(); |
andrewboyson | 6:be97d38e0b01 | 69 | state = RESET_LOW; |
andrewboyson | 6:be97d38e0b01 | 70 | job = jobtype; |
andrewboyson | 6:be97d38e0b01 | 71 | } |
andrewboyson | 6:be97d38e0b01 | 72 | static void readPresenceAndAwaitResetRelease() |
andrewboyson | 6:be97d38e0b01 | 73 | { |
andrewboyson | 6:be97d38e0b01 | 74 | busfree(); |
andrewboyson | 6:be97d38e0b01 | 75 | wait_us(READ_PRESENCE_US); |
andrewboyson | 6:be97d38e0b01 | 76 | busread(); |
andrewboyson | 6:be97d38e0b01 | 77 | timer.stop(); |
andrewboyson | 6:be97d38e0b01 | 78 | timer.reset(); |
andrewboyson | 6:be97d38e0b01 | 79 | timer.start(); |
andrewboyson | 6:be97d38e0b01 | 80 | state = RESET_RELEASE; |
andrewboyson | 6:be97d38e0b01 | 81 | } |
andrewboyson | 6:be97d38e0b01 | 82 | static void writeBit(int bit) |
andrewboyson | 6:be97d38e0b01 | 83 | { |
andrewboyson | 6:be97d38e0b01 | 84 | buslow(); |
andrewboyson | 6:be97d38e0b01 | 85 | wait_us(bit ? WRITE_1_BUS_LOW_US : WRITE_0_BUS_LOW_US); |
andrewboyson | 6:be97d38e0b01 | 86 | busfree(); |
andrewboyson | 6:be97d38e0b01 | 87 | wait_us(bit ? WRITE_1_RELEASE_US : WRITE_0_RELEASE_US); |
andrewboyson | 6:be97d38e0b01 | 88 | } |
andrewboyson | 6:be97d38e0b01 | 89 | static void writeBitWithPullUp(int bit) |
andrewboyson | 6:be97d38e0b01 | 90 | { |
andrewboyson | 6:be97d38e0b01 | 91 | buslow(); |
andrewboyson | 6:be97d38e0b01 | 92 | wait_us(bit ? WRITE_1_BUS_LOW_US : WRITE_0_BUS_LOW_US); |
andrewboyson | 6:be97d38e0b01 | 93 | bushigh(); |
andrewboyson | 6:be97d38e0b01 | 94 | timer.stop(); |
andrewboyson | 6:be97d38e0b01 | 95 | timer.reset(); |
andrewboyson | 6:be97d38e0b01 | 96 | timer.start(); |
andrewboyson | 6:be97d38e0b01 | 97 | state = PULL_UP; |
andrewboyson | 6:be97d38e0b01 | 98 | } |
andrewboyson | 6:be97d38e0b01 | 99 | static void readBit() |
andrewboyson | 6:be97d38e0b01 | 100 | { |
andrewboyson | 6:be97d38e0b01 | 101 | buslow(); |
andrewboyson | 6:be97d38e0b01 | 102 | wait_us(READ_BIT_BUS_LOW_US); |
andrewboyson | 6:be97d38e0b01 | 103 | busfree(); |
andrewboyson | 6:be97d38e0b01 | 104 | wait_us(READ_BIT_US); |
andrewboyson | 6:be97d38e0b01 | 105 | busread(); |
andrewboyson | 6:be97d38e0b01 | 106 | wait_us(READ_BIT_RELEASE_US); |
andrewboyson | 6:be97d38e0b01 | 107 | } |
andrewboyson | 6:be97d38e0b01 | 108 | |
andrewboyson | 5:6226f3c566ef | 109 | static char crc; |
andrewboyson | 5:6226f3c566ef | 110 | static void resetCrc() |
andrewboyson | 5:6226f3c566ef | 111 | { |
andrewboyson | 5:6226f3c566ef | 112 | crc = 0; |
andrewboyson | 5:6226f3c566ef | 113 | } |
andrewboyson | 5:6226f3c566ef | 114 | static void addBitToCrc(int bit) |
andrewboyson | 5:6226f3c566ef | 115 | { |
andrewboyson | 6:be97d38e0b01 | 116 | int feedback = !(crc & 0x80) != !bit; //Logical Exclusive Or of the msb of the shift register with the input |
andrewboyson | 6:be97d38e0b01 | 117 | crc <<= 1; //Move the shift register one place to the left leaving a zero in the lsb and losing the msb |
andrewboyson | 6:be97d38e0b01 | 118 | if (feedback) crc ^= 0x31; //Exclusive Or the shift register with polynomial X5 + X4 + 1 |
andrewboyson | 5:6226f3c566ef | 119 | } |
andrewboyson | 5:6226f3c566ef | 120 | |
andrewboyson | 4:e076884ef8bd | 121 | static void resetBitPosition(int* pByteIndex, char* pBitMask) |
andrewboyson | 4:e076884ef8bd | 122 | { |
andrewboyson | 4:e076884ef8bd | 123 | *pBitMask = 1; |
andrewboyson | 4:e076884ef8bd | 124 | *pByteIndex = 0; |
andrewboyson | 4:e076884ef8bd | 125 | } |
andrewboyson | 4:e076884ef8bd | 126 | static void incrementBitPosition(int* pByteIndex, char* pBitMask) |
andrewboyson | 4:e076884ef8bd | 127 | { |
andrewboyson | 4:e076884ef8bd | 128 | *pBitMask <<= 1; |
andrewboyson | 4:e076884ef8bd | 129 | if (!*pBitMask) |
andrewboyson | 4:e076884ef8bd | 130 | { |
andrewboyson | 4:e076884ef8bd | 131 | *pBitMask = 1; |
andrewboyson | 4:e076884ef8bd | 132 | *pByteIndex += 1; |
andrewboyson | 4:e076884ef8bd | 133 | } |
andrewboyson | 4:e076884ef8bd | 134 | } |
andrewboyson | 4:e076884ef8bd | 135 | |
andrewboyson | 4:e076884ef8bd | 136 | int getBitAtPosition(int byteIndex, char bitMask) |
andrewboyson | 4:e076884ef8bd | 137 | { |
andrewboyson | 4:e076884ef8bd | 138 | return psend[byteIndex] & bitMask; |
andrewboyson | 4:e076884ef8bd | 139 | } |
andrewboyson | 4:e076884ef8bd | 140 | void setBitAtPosition(int byteIndex, char bitMask, int bit) |
andrewboyson | 4:e076884ef8bd | 141 | { |
andrewboyson | 6:be97d38e0b01 | 142 | if ( bit) precv[byteIndex] |= bitMask; |
andrewboyson | 6:be97d38e0b01 | 143 | else precv[byteIndex] &= ~bitMask; |
andrewboyson | 4:e076884ef8bd | 144 | } |
andrewboyson | 4:e076884ef8bd | 145 | int moreBitsToRead(int byteIndex) |
andrewboyson | 4:e076884ef8bd | 146 | { |
andrewboyson | 4:e076884ef8bd | 147 | return byteIndex < lenrecv; |
andrewboyson | 4:e076884ef8bd | 148 | } |
andrewboyson | 4:e076884ef8bd | 149 | int moreBitsToWrite(int byteIndex) |
andrewboyson | 4:e076884ef8bd | 150 | { |
andrewboyson | 4:e076884ef8bd | 151 | return byteIndex < lensend; |
andrewboyson | 4:e076884ef8bd | 152 | } |
andrewboyson | 6:be97d38e0b01 | 153 | |
andrewboyson | 6:be97d38e0b01 | 154 | int result = ONE_WIRE_RESULT_OK; |
andrewboyson | 6:be97d38e0b01 | 155 | int OneWireResult() |
andrewboyson | 6:be97d38e0b01 | 156 | { |
andrewboyson | 6:be97d38e0b01 | 157 | return result; |
andrewboyson | 6:be97d38e0b01 | 158 | } |
andrewboyson | 4:e076884ef8bd | 159 | int OneWireInit() |
andrewboyson | 4:e076884ef8bd | 160 | { |
andrewboyson | 6:be97d38e0b01 | 161 | busfree(); |
andrewboyson | 6:be97d38e0b01 | 162 | busytimer.stop(); |
andrewboyson | 6:be97d38e0b01 | 163 | busytimer.reset(); |
andrewboyson | 6:be97d38e0b01 | 164 | state = STATE_IDLE; |
andrewboyson | 6:be97d38e0b01 | 165 | job = JOB_NONE; |
andrewboyson | 4:e076884ef8bd | 166 | return 0; |
andrewboyson | 4:e076884ef8bd | 167 | } |
andrewboyson | 4:e076884ef8bd | 168 | int OneWireBusy() |
andrewboyson | 4:e076884ef8bd | 169 | { |
andrewboyson | 6:be97d38e0b01 | 170 | return state; |
andrewboyson | 4:e076884ef8bd | 171 | } |
andrewboyson | 4:e076884ef8bd | 172 | void OneWireExchange(int lenBytesToSend, int lenBytesToRecv, char *pBytesToSend, char *pBytesToRecv, int msToPullUp) |
andrewboyson | 4:e076884ef8bd | 173 | { |
andrewboyson | 4:e076884ef8bd | 174 | lensend = lenBytesToSend; |
andrewboyson | 4:e076884ef8bd | 175 | lenrecv = lenBytesToRecv; |
andrewboyson | 4:e076884ef8bd | 176 | psend = pBytesToSend; |
andrewboyson | 4:e076884ef8bd | 177 | precv = pBytesToRecv; |
andrewboyson | 4:e076884ef8bd | 178 | pullupms = msToPullUp; |
andrewboyson | 6:be97d38e0b01 | 179 | initiateResetLow(JOB_XCHG); |
andrewboyson | 6:be97d38e0b01 | 180 | } |
andrewboyson | 6:be97d38e0b01 | 181 | static int* pallfound; |
andrewboyson | 6:be97d38e0b01 | 182 | static char* prom; |
andrewboyson | 6:be97d38e0b01 | 183 | static void setRomBit(int position, int bit) |
andrewboyson | 6:be97d38e0b01 | 184 | { |
andrewboyson | 6:be97d38e0b01 | 185 | int bitindex = position & 0x07; |
andrewboyson | 6:be97d38e0b01 | 186 | int byteindex = position >> 3; |
andrewboyson | 6:be97d38e0b01 | 187 | int bitmask = 1 << bitindex; |
andrewboyson | 6:be97d38e0b01 | 188 | if (bit) *(prom + byteindex) |= bitmask; |
andrewboyson | 6:be97d38e0b01 | 189 | else *(prom + byteindex) &= ~bitmask; |
andrewboyson | 6:be97d38e0b01 | 190 | } |
andrewboyson | 6:be97d38e0b01 | 191 | static int getRomBit(int position) |
andrewboyson | 6:be97d38e0b01 | 192 | { |
andrewboyson | 6:be97d38e0b01 | 193 | int bitindex = position & 0x07; |
andrewboyson | 6:be97d38e0b01 | 194 | int byteindex = position >> 3; |
andrewboyson | 6:be97d38e0b01 | 195 | int bitmask = 1 << bitindex; |
andrewboyson | 6:be97d38e0b01 | 196 | return *(prom + byteindex) & bitmask; |
andrewboyson | 6:be97d38e0b01 | 197 | } |
andrewboyson | 6:be97d38e0b01 | 198 | static int thisFurthestForkLeftPosn; |
andrewboyson | 6:be97d38e0b01 | 199 | static int lastFurthestForkLeftPosn; |
andrewboyson | 6:be97d38e0b01 | 200 | static char searchCommand; |
andrewboyson | 6:be97d38e0b01 | 201 | static int searchBitPosn; |
andrewboyson | 6:be97d38e0b01 | 202 | static int searchBitTrue; |
andrewboyson | 6:be97d38e0b01 | 203 | static int searchBitComp; |
andrewboyson | 6:be97d38e0b01 | 204 | static int chooseDirectionToTake() |
andrewboyson | 6:be97d38e0b01 | 205 | { |
andrewboyson | 6:be97d38e0b01 | 206 | if ( searchBitTrue && searchBitComp) return -1; //No devices are participating in the search |
andrewboyson | 6:be97d38e0b01 | 207 | if ( searchBitTrue && !searchBitComp) return 1; //Only devices with a one at this point are participating |
andrewboyson | 6:be97d38e0b01 | 208 | if (!searchBitTrue && searchBitComp) return 0; //Only devices with a zero at this point are participating |
andrewboyson | 6:be97d38e0b01 | 209 | //Both bits are zero so devices with both 0s and 1s at this point are still participating |
andrewboyson | 6:be97d38e0b01 | 210 | |
andrewboyson | 6:be97d38e0b01 | 211 | //If we have not yet reached the furthest away point we forked left (0) last time then just do whatever we did last time |
andrewboyson | 6:be97d38e0b01 | 212 | if (searchBitPosn < lastFurthestForkLeftPosn) return getRomBit(searchBitPosn); |
andrewboyson | 6:be97d38e0b01 | 213 | |
andrewboyson | 6:be97d38e0b01 | 214 | //If we are at the furthest away point that we forked left (0) last time then this time fork right (1) |
andrewboyson | 6:be97d38e0b01 | 215 | if (searchBitPosn == lastFurthestForkLeftPosn) return 1; |
andrewboyson | 6:be97d38e0b01 | 216 | |
andrewboyson | 6:be97d38e0b01 | 217 | //We are at a new fork point further than we have been before so fork left (0) and record that we did so. |
andrewboyson | 6:be97d38e0b01 | 218 | thisFurthestForkLeftPosn = searchBitPosn; |
andrewboyson | 6:be97d38e0b01 | 219 | return 0; |
andrewboyson | 6:be97d38e0b01 | 220 | } |
andrewboyson | 6:be97d38e0b01 | 221 | void OneWireSearch(char command, char* pDeviceRom, int* pAllDevicesFound) //Specify the buffer to receive the rom for the first search and NULL thereafter. |
andrewboyson | 6:be97d38e0b01 | 222 | { |
andrewboyson | 6:be97d38e0b01 | 223 | if (pDeviceRom) |
andrewboyson | 6:be97d38e0b01 | 224 | { |
andrewboyson | 6:be97d38e0b01 | 225 | pallfound = pAllDevicesFound; |
andrewboyson | 6:be97d38e0b01 | 226 | *pallfound = false; |
andrewboyson | 6:be97d38e0b01 | 227 | lastFurthestForkLeftPosn = -1; |
andrewboyson | 6:be97d38e0b01 | 228 | prom = pDeviceRom; |
andrewboyson | 6:be97d38e0b01 | 229 | for (int i = 0; i < 8; i++) *(prom + i) = 0; |
andrewboyson | 6:be97d38e0b01 | 230 | } |
andrewboyson | 6:be97d38e0b01 | 231 | thisFurthestForkLeftPosn = -1; |
andrewboyson | 6:be97d38e0b01 | 232 | lensend = 1; |
andrewboyson | 6:be97d38e0b01 | 233 | lenrecv = 0; |
andrewboyson | 6:be97d38e0b01 | 234 | searchCommand = command; |
andrewboyson | 6:be97d38e0b01 | 235 | psend = &searchCommand; |
andrewboyson | 6:be97d38e0b01 | 236 | precv = NULL; |
andrewboyson | 6:be97d38e0b01 | 237 | pullupms = 0; |
andrewboyson | 6:be97d38e0b01 | 238 | initiateResetLow(JOB_SEARCH); |
andrewboyson | 4:e076884ef8bd | 239 | } |
andrewboyson | 5:6226f3c566ef | 240 | char OneWireCrc() |
andrewboyson | 5:6226f3c566ef | 241 | { |
andrewboyson | 5:6226f3c566ef | 242 | return crc; |
andrewboyson | 5:6226f3c566ef | 243 | } |
andrewboyson | 4:e076884ef8bd | 244 | int OneWireMain() |
andrewboyson | 4:e076884ef8bd | 245 | { |
andrewboyson | 4:e076884ef8bd | 246 | static int byteindex; |
andrewboyson | 4:e076884ef8bd | 247 | static char bitmask; |
andrewboyson | 4:e076884ef8bd | 248 | |
andrewboyson | 6:be97d38e0b01 | 249 | if (state) |
andrewboyson | 4:e076884ef8bd | 250 | { |
andrewboyson | 6:be97d38e0b01 | 251 | busytimer.start(); |
andrewboyson | 6:be97d38e0b01 | 252 | if (busytimer.read_ms() > BUS_TIMEOUT_MS) |
andrewboyson | 4:e076884ef8bd | 253 | { |
andrewboyson | 4:e076884ef8bd | 254 | LogCrLf("1-wire bus timed out so protocol has been reset to idle."); |
andrewboyson | 4:e076884ef8bd | 255 | OneWireInit(); |
andrewboyson | 6:be97d38e0b01 | 256 | result = ONE_WIRE_RESULT_TIMED_OUT; |
andrewboyson | 6:be97d38e0b01 | 257 | return 0; |
andrewboyson | 4:e076884ef8bd | 258 | } |
andrewboyson | 4:e076884ef8bd | 259 | } |
andrewboyson | 4:e076884ef8bd | 260 | else |
andrewboyson | 4:e076884ef8bd | 261 | { |
andrewboyson | 6:be97d38e0b01 | 262 | busytimer.stop(); |
andrewboyson | 6:be97d38e0b01 | 263 | busytimer.reset(); |
andrewboyson | 4:e076884ef8bd | 264 | } |
andrewboyson | 4:e076884ef8bd | 265 | |
andrewboyson | 6:be97d38e0b01 | 266 | switch(state) |
andrewboyson | 4:e076884ef8bd | 267 | { |
andrewboyson | 6:be97d38e0b01 | 268 | case STATE_IDLE: |
andrewboyson | 4:e076884ef8bd | 269 | break; |
andrewboyson | 6:be97d38e0b01 | 270 | case RESET_LOW: |
andrewboyson | 6:be97d38e0b01 | 271 | if (timer.read_us() > RESET_BUS_LOW_US) readPresenceAndAwaitResetRelease(); |
andrewboyson | 6:be97d38e0b01 | 272 | break; |
andrewboyson | 6:be97d38e0b01 | 273 | case RESET_RELEASE: |
andrewboyson | 6:be97d38e0b01 | 274 | if (timer.read_us() > RESET_RELEASE_US) |
andrewboyson | 4:e076884ef8bd | 275 | { |
andrewboyson | 6:be97d38e0b01 | 276 | busfree(); |
andrewboyson | 6:be97d38e0b01 | 277 | timer.stop(); |
andrewboyson | 6:be97d38e0b01 | 278 | timer.reset(); |
andrewboyson | 6:be97d38e0b01 | 279 | if (busvalue) |
andrewboyson | 6:be97d38e0b01 | 280 | { |
andrewboyson | 6:be97d38e0b01 | 281 | LogCrLf("No 1-wire device presence detected on the bus"); |
andrewboyson | 6:be97d38e0b01 | 282 | result = ONE_WIRE_RESULT_NO_DEVICE_PRESENT; |
andrewboyson | 6:be97d38e0b01 | 283 | state = STATE_IDLE; |
andrewboyson | 6:be97d38e0b01 | 284 | } |
andrewboyson | 6:be97d38e0b01 | 285 | else |
andrewboyson | 6:be97d38e0b01 | 286 | { |
andrewboyson | 6:be97d38e0b01 | 287 | resetBitPosition(&byteindex, &bitmask); |
andrewboyson | 6:be97d38e0b01 | 288 | switch (job) |
andrewboyson | 6:be97d38e0b01 | 289 | { |
andrewboyson | 6:be97d38e0b01 | 290 | case JOB_XCHG: state = XCHG_WRITE; break; |
andrewboyson | 6:be97d38e0b01 | 291 | case JOB_SEARCH: state = SEARCH_WRITE; break; |
andrewboyson | 6:be97d38e0b01 | 292 | default: |
andrewboyson | 6:be97d38e0b01 | 293 | LogF("Unknown job in RESET_RELEASE %d\r\n", job); |
andrewboyson | 6:be97d38e0b01 | 294 | return -1; |
andrewboyson | 6:be97d38e0b01 | 295 | } |
andrewboyson | 6:be97d38e0b01 | 296 | } |
andrewboyson | 4:e076884ef8bd | 297 | } |
andrewboyson | 4:e076884ef8bd | 298 | break; |
andrewboyson | 6:be97d38e0b01 | 299 | |
andrewboyson | 4:e076884ef8bd | 300 | case XCHG_WRITE: |
andrewboyson | 4:e076884ef8bd | 301 | if (moreBitsToWrite(byteindex)) |
andrewboyson | 4:e076884ef8bd | 302 | { |
andrewboyson | 4:e076884ef8bd | 303 | int bit = getBitAtPosition(byteindex, bitmask); |
andrewboyson | 4:e076884ef8bd | 304 | incrementBitPosition(&byteindex, &bitmask); |
andrewboyson | 6:be97d38e0b01 | 305 | if (moreBitsToWrite(byteindex)) writeBit(bit); |
andrewboyson | 6:be97d38e0b01 | 306 | else writeBitWithPullUp(bit); |
andrewboyson | 4:e076884ef8bd | 307 | } |
andrewboyson | 4:e076884ef8bd | 308 | else |
andrewboyson | 4:e076884ef8bd | 309 | { |
andrewboyson | 4:e076884ef8bd | 310 | resetBitPosition(&byteindex, &bitmask); |
andrewboyson | 4:e076884ef8bd | 311 | if (moreBitsToRead(byteindex)) |
andrewboyson | 4:e076884ef8bd | 312 | { |
andrewboyson | 5:6226f3c566ef | 313 | resetCrc(); |
andrewboyson | 6:be97d38e0b01 | 314 | readBit(); |
andrewboyson | 6:be97d38e0b01 | 315 | state = XCHG_READ; |
andrewboyson | 4:e076884ef8bd | 316 | |
andrewboyson | 4:e076884ef8bd | 317 | } |
andrewboyson | 4:e076884ef8bd | 318 | else |
andrewboyson | 4:e076884ef8bd | 319 | { |
andrewboyson | 6:be97d38e0b01 | 320 | result = ONE_WIRE_RESULT_OK; |
andrewboyson | 6:be97d38e0b01 | 321 | state = STATE_IDLE; |
andrewboyson | 4:e076884ef8bd | 322 | } |
andrewboyson | 4:e076884ef8bd | 323 | } |
andrewboyson | 4:e076884ef8bd | 324 | break; |
andrewboyson | 6:be97d38e0b01 | 325 | case PULL_UP: |
andrewboyson | 6:be97d38e0b01 | 326 | if (timer.read_ms() > pullupms) |
andrewboyson | 6:be97d38e0b01 | 327 | { |
andrewboyson | 6:be97d38e0b01 | 328 | busfree(); |
andrewboyson | 6:be97d38e0b01 | 329 | switch (job) |
andrewboyson | 6:be97d38e0b01 | 330 | { |
andrewboyson | 6:be97d38e0b01 | 331 | case JOB_XCHG: state = XCHG_WRITE; break; |
andrewboyson | 6:be97d38e0b01 | 332 | default: |
andrewboyson | 6:be97d38e0b01 | 333 | LogF("Unknown job in PULL_UP %d\r\n", job); |
andrewboyson | 6:be97d38e0b01 | 334 | return -1; |
andrewboyson | 6:be97d38e0b01 | 335 | } |
andrewboyson | 6:be97d38e0b01 | 336 | } |
andrewboyson | 6:be97d38e0b01 | 337 | break; |
andrewboyson | 4:e076884ef8bd | 338 | case XCHG_READ: |
andrewboyson | 5:6226f3c566ef | 339 | addBitToCrc(busvalue); |
andrewboyson | 4:e076884ef8bd | 340 | setBitAtPosition(byteindex, bitmask, busvalue); |
andrewboyson | 4:e076884ef8bd | 341 | incrementBitPosition(&byteindex, &bitmask); |
andrewboyson | 4:e076884ef8bd | 342 | if (moreBitsToRead(byteindex)) |
andrewboyson | 4:e076884ef8bd | 343 | { |
andrewboyson | 6:be97d38e0b01 | 344 | readBit(); |
andrewboyson | 6:be97d38e0b01 | 345 | } |
andrewboyson | 6:be97d38e0b01 | 346 | else |
andrewboyson | 6:be97d38e0b01 | 347 | { |
andrewboyson | 6:be97d38e0b01 | 348 | state = STATE_IDLE; |
andrewboyson | 6:be97d38e0b01 | 349 | result = crc ? ONE_WIRE_RESULT_CRC_ERROR : ONE_WIRE_RESULT_OK; |
andrewboyson | 6:be97d38e0b01 | 350 | } |
andrewboyson | 6:be97d38e0b01 | 351 | break; |
andrewboyson | 6:be97d38e0b01 | 352 | |
andrewboyson | 6:be97d38e0b01 | 353 | case SEARCH_WRITE: |
andrewboyson | 6:be97d38e0b01 | 354 | if (moreBitsToWrite(byteindex)) |
andrewboyson | 6:be97d38e0b01 | 355 | { |
andrewboyson | 6:be97d38e0b01 | 356 | int bit = getBitAtPosition(byteindex, bitmask); |
andrewboyson | 6:be97d38e0b01 | 357 | incrementBitPosition(&byteindex, &bitmask); |
andrewboyson | 6:be97d38e0b01 | 358 | writeBit(bit); |
andrewboyson | 4:e076884ef8bd | 359 | } |
andrewboyson | 4:e076884ef8bd | 360 | else |
andrewboyson | 4:e076884ef8bd | 361 | { |
andrewboyson | 6:be97d38e0b01 | 362 | searchBitPosn = 0; |
andrewboyson | 6:be97d38e0b01 | 363 | state = SEARCH_BIT; |
andrewboyson | 6:be97d38e0b01 | 364 | } |
andrewboyson | 6:be97d38e0b01 | 365 | break; |
andrewboyson | 6:be97d38e0b01 | 366 | case SEARCH_BIT: |
andrewboyson | 6:be97d38e0b01 | 367 | readBit(); |
andrewboyson | 6:be97d38e0b01 | 368 | state = SEARCH_READ_BIT_TRUE; |
andrewboyson | 6:be97d38e0b01 | 369 | break; |
andrewboyson | 6:be97d38e0b01 | 370 | case SEARCH_READ_BIT_TRUE: |
andrewboyson | 6:be97d38e0b01 | 371 | searchBitTrue = busvalue; |
andrewboyson | 6:be97d38e0b01 | 372 | readBit(); |
andrewboyson | 6:be97d38e0b01 | 373 | state = SEARCH_READ_BIT_COMP; |
andrewboyson | 6:be97d38e0b01 | 374 | break; |
andrewboyson | 6:be97d38e0b01 | 375 | case SEARCH_READ_BIT_COMP: |
andrewboyson | 6:be97d38e0b01 | 376 | searchBitComp = busvalue; |
andrewboyson | 6:be97d38e0b01 | 377 | state = SEARCH_WRITE_BIT; |
andrewboyson | 6:be97d38e0b01 | 378 | break; |
andrewboyson | 6:be97d38e0b01 | 379 | case SEARCH_WRITE_BIT: |
andrewboyson | 7:024ace6d943c | 380 | if (DEBUG) LogF("%d%d - ", searchBitTrue, searchBitComp); |
andrewboyson | 6:be97d38e0b01 | 381 | int direction; |
andrewboyson | 6:be97d38e0b01 | 382 | direction = chooseDirectionToTake(); |
andrewboyson | 6:be97d38e0b01 | 383 | if (direction == -1) |
andrewboyson | 6:be97d38e0b01 | 384 | { |
andrewboyson | 6:be97d38e0b01 | 385 | LogCrLf("No devices have responded"); |
andrewboyson | 6:be97d38e0b01 | 386 | result = ONE_WIRE_RESULT_NO_DEVICE_PARTICIPATING; |
andrewboyson | 6:be97d38e0b01 | 387 | state = STATE_IDLE; |
andrewboyson | 6:be97d38e0b01 | 388 | } |
andrewboyson | 6:be97d38e0b01 | 389 | else |
andrewboyson | 6:be97d38e0b01 | 390 | { |
andrewboyson | 7:024ace6d943c | 391 | if (DEBUG) LogF(" %d -> %d\r\n", direction, searchBitPosn); |
andrewboyson | 6:be97d38e0b01 | 392 | setRomBit(searchBitPosn, direction); |
andrewboyson | 6:be97d38e0b01 | 393 | writeBit(direction); |
andrewboyson | 6:be97d38e0b01 | 394 | searchBitPosn++; |
andrewboyson | 6:be97d38e0b01 | 395 | if (searchBitPosn < 64) |
andrewboyson | 6:be97d38e0b01 | 396 | { |
andrewboyson | 6:be97d38e0b01 | 397 | state = SEARCH_BIT; |
andrewboyson | 6:be97d38e0b01 | 398 | } |
andrewboyson | 6:be97d38e0b01 | 399 | else |
andrewboyson | 6:be97d38e0b01 | 400 | { |
andrewboyson | 6:be97d38e0b01 | 401 | if (thisFurthestForkLeftPosn == -1) *pallfound = true; |
andrewboyson | 6:be97d38e0b01 | 402 | lastFurthestForkLeftPosn = thisFurthestForkLeftPosn; |
andrewboyson | 6:be97d38e0b01 | 403 | result = ONE_WIRE_RESULT_OK; |
andrewboyson | 6:be97d38e0b01 | 404 | state = STATE_IDLE; |
andrewboyson | 6:be97d38e0b01 | 405 | } |
andrewboyson | 4:e076884ef8bd | 406 | } |
andrewboyson | 4:e076884ef8bd | 407 | break; |
andrewboyson | 4:e076884ef8bd | 408 | default: |
andrewboyson | 6:be97d38e0b01 | 409 | LogF("Unknown state %d\r\n", state); |
andrewboyson | 4:e076884ef8bd | 410 | return -1; |
andrewboyson | 4:e076884ef8bd | 411 | } |
andrewboyson | 4:e076884ef8bd | 412 | return 0; |
andrewboyson | 4:e076884ef8bd | 413 | } |