Andrew Boyson
/
iot
Backing up an unused program in case of future need
1-wire.cpp@4:e076884ef8bd, 2016-05-03 (annotated)
- Committer:
- andrewboyson
- Date:
- Tue May 03 09:23:26 2016 +0000
- Revision:
- 4:e076884ef8bd
- Child:
- 5:6226f3c566ef
Added 1-wire
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 4:e076884ef8bd | 1 | #include "mbed.h" |
andrewboyson | 4:e076884ef8bd | 2 | #include "log.h" |
andrewboyson | 4:e076884ef8bd | 3 | #include "io.h" |
andrewboyson | 4:e076884ef8bd | 4 | |
andrewboyson | 4:e076884ef8bd | 5 | //Bus zone |
andrewboyson | 4:e076884ef8bd | 6 | //======== |
andrewboyson | 4:e076884ef8bd | 7 | static DigitalInOut pin(p25, PIN_INPUT, PullUp, 0); |
andrewboyson | 4:e076884ef8bd | 8 | |
andrewboyson | 4:e076884ef8bd | 9 | |
andrewboyson | 4:e076884ef8bd | 10 | static int busvalue; |
andrewboyson | 4:e076884ef8bd | 11 | |
andrewboyson | 4:e076884ef8bd | 12 | //Delays |
andrewboyson | 4:e076884ef8bd | 13 | #define ATTACH_DELAY 7 |
andrewboyson | 4:e076884ef8bd | 14 | #define INITIAL_DELAY 100 |
andrewboyson | 4:e076884ef8bd | 15 | #define RESET_BUS_LOW_DELAY 480 |
andrewboyson | 4:e076884ef8bd | 16 | #define READ_PRESENCE_DELAY 70 |
andrewboyson | 4:e076884ef8bd | 17 | #define RESET_RELEASE_DELAY 410 |
andrewboyson | 4:e076884ef8bd | 18 | #define WRITE_0_BUS_LOW_DELAY 60 |
andrewboyson | 4:e076884ef8bd | 19 | #define WRITE_0_RELEASE_DELAY 10 |
andrewboyson | 4:e076884ef8bd | 20 | #define WRITE_1_BUS_LOW_DELAY 6 |
andrewboyson | 4:e076884ef8bd | 21 | #define WRITE_1_RELEASE_DELAY 64 |
andrewboyson | 4:e076884ef8bd | 22 | #define READ_BIT_BUS_LOW_DELAY 6 |
andrewboyson | 4:e076884ef8bd | 23 | #define READ_BIT_DELAY 9 |
andrewboyson | 4:e076884ef8bd | 24 | #define READ_BIT_RELEASE_DELAY 55 |
andrewboyson | 4:e076884ef8bd | 25 | #define BUS_TIMEOUT_MS 1000 |
andrewboyson | 4:e076884ef8bd | 26 | |
andrewboyson | 4:e076884ef8bd | 27 | static int busbusy = false; //Set whenever an operation starts; reset by finishbus interrupt; |
andrewboyson | 4:e076884ef8bd | 28 | static Timer busbusytimer; |
andrewboyson | 4:e076884ef8bd | 29 | |
andrewboyson | 4:e076884ef8bd | 30 | static void buslow (void) { pin = 0; pin.output(); } |
andrewboyson | 4:e076884ef8bd | 31 | static Timeout startbuslow; |
andrewboyson | 4:e076884ef8bd | 32 | static void busfree(void) { pin.input (); } |
andrewboyson | 4:e076884ef8bd | 33 | static Timeout startbusfree; |
andrewboyson | 4:e076884ef8bd | 34 | static void bushigh(void) { pin = 1; pin.output(); } |
andrewboyson | 4:e076884ef8bd | 35 | static Timeout startbushigh; |
andrewboyson | 4:e076884ef8bd | 36 | static void busread(void) { busvalue = pin; } |
andrewboyson | 4:e076884ef8bd | 37 | static Timeout startbusread; |
andrewboyson | 4:e076884ef8bd | 38 | static void busidle(void) { pin.input (); busbusy = false; } |
andrewboyson | 4:e076884ef8bd | 39 | static Timeout startbusidle; |
andrewboyson | 4:e076884ef8bd | 40 | |
andrewboyson | 4:e076884ef8bd | 41 | static void reset() |
andrewboyson | 4:e076884ef8bd | 42 | { |
andrewboyson | 4:e076884ef8bd | 43 | busbusy = true; |
andrewboyson | 4:e076884ef8bd | 44 | int delay = INITIAL_DELAY - ATTACH_DELAY; startbuslow.attach_us(&buslow, delay); |
andrewboyson | 4:e076884ef8bd | 45 | delay += RESET_BUS_LOW_DELAY - ATTACH_DELAY; startbusfree.attach_us(&busfree, delay); |
andrewboyson | 4:e076884ef8bd | 46 | delay += READ_PRESENCE_DELAY - ATTACH_DELAY; startbusread.attach_us(&busread, delay); |
andrewboyson | 4:e076884ef8bd | 47 | delay += RESET_RELEASE_DELAY - ATTACH_DELAY; startbusidle.attach_us(&busidle, delay); |
andrewboyson | 4:e076884ef8bd | 48 | } |
andrewboyson | 4:e076884ef8bd | 49 | static void writebit(int bit, int msToPullUp) |
andrewboyson | 4:e076884ef8bd | 50 | { |
andrewboyson | 4:e076884ef8bd | 51 | busbusy = true; |
andrewboyson | 4:e076884ef8bd | 52 | int delay = INITIAL_DELAY - ATTACH_DELAY; |
andrewboyson | 4:e076884ef8bd | 53 | startbuslow.attach_us(&buslow, delay); |
andrewboyson | 4:e076884ef8bd | 54 | delay += bit ? WRITE_1_BUS_LOW_DELAY : WRITE_0_BUS_LOW_DELAY; |
andrewboyson | 4:e076884ef8bd | 55 | delay -= ATTACH_DELAY; |
andrewboyson | 4:e076884ef8bd | 56 | if (msToPullUp) |
andrewboyson | 4:e076884ef8bd | 57 | { |
andrewboyson | 4:e076884ef8bd | 58 | startbushigh.attach_us(&bushigh, delay); |
andrewboyson | 4:e076884ef8bd | 59 | delay += msToPullUp * 1000 - ATTACH_DELAY; |
andrewboyson | 4:e076884ef8bd | 60 | } |
andrewboyson | 4:e076884ef8bd | 61 | else |
andrewboyson | 4:e076884ef8bd | 62 | { |
andrewboyson | 4:e076884ef8bd | 63 | startbusfree.attach_us(&busfree, delay); |
andrewboyson | 4:e076884ef8bd | 64 | delay += bit ? WRITE_1_RELEASE_DELAY : WRITE_0_RELEASE_DELAY; |
andrewboyson | 4:e076884ef8bd | 65 | delay -= ATTACH_DELAY; |
andrewboyson | 4:e076884ef8bd | 66 | } |
andrewboyson | 4:e076884ef8bd | 67 | startbusidle.attach_us(&busidle, delay); |
andrewboyson | 4:e076884ef8bd | 68 | } |
andrewboyson | 4:e076884ef8bd | 69 | static void initiatebitread() |
andrewboyson | 4:e076884ef8bd | 70 | { |
andrewboyson | 4:e076884ef8bd | 71 | busbusy = true; |
andrewboyson | 4:e076884ef8bd | 72 | int delay = INITIAL_DELAY - ATTACH_DELAY; startbuslow.attach_us(&buslow, delay); |
andrewboyson | 4:e076884ef8bd | 73 | delay += READ_BIT_BUS_LOW_DELAY - ATTACH_DELAY; startbusfree.attach_us(&busfree, delay); |
andrewboyson | 4:e076884ef8bd | 74 | delay += READ_BIT_DELAY - ATTACH_DELAY; startbusread.attach_us(&busread, delay); |
andrewboyson | 4:e076884ef8bd | 75 | delay += READ_BIT_RELEASE_DELAY - ATTACH_DELAY; startbusidle.attach_us(&busidle, delay); |
andrewboyson | 4:e076884ef8bd | 76 | } |
andrewboyson | 4:e076884ef8bd | 77 | |
andrewboyson | 4:e076884ef8bd | 78 | //Exchange zone |
andrewboyson | 4:e076884ef8bd | 79 | //============= |
andrewboyson | 4:e076884ef8bd | 80 | #define XCHG_IDLE 0 |
andrewboyson | 4:e076884ef8bd | 81 | #define XCHG_RESET 1 |
andrewboyson | 4:e076884ef8bd | 82 | #define XCHG_WRITE 2 |
andrewboyson | 4:e076884ef8bd | 83 | #define XCHG_READ 3 |
andrewboyson | 4:e076884ef8bd | 84 | #define XCHG_PULLUP 4 |
andrewboyson | 4:e076884ef8bd | 85 | static int xchgstate = XCHG_IDLE; |
andrewboyson | 4:e076884ef8bd | 86 | |
andrewboyson | 4:e076884ef8bd | 87 | static int lensend = 0; |
andrewboyson | 4:e076884ef8bd | 88 | static int lenrecv = 0; |
andrewboyson | 4:e076884ef8bd | 89 | static char* psend = NULL; |
andrewboyson | 4:e076884ef8bd | 90 | static char* precv = NULL; |
andrewboyson | 4:e076884ef8bd | 91 | static int pullupms = 0; |
andrewboyson | 4:e076884ef8bd | 92 | |
andrewboyson | 4:e076884ef8bd | 93 | static void resetBitPosition(int* pByteIndex, char* pBitMask) |
andrewboyson | 4:e076884ef8bd | 94 | { |
andrewboyson | 4:e076884ef8bd | 95 | *pBitMask = 1; |
andrewboyson | 4:e076884ef8bd | 96 | *pByteIndex = 0; |
andrewboyson | 4:e076884ef8bd | 97 | } |
andrewboyson | 4:e076884ef8bd | 98 | static void incrementBitPosition(int* pByteIndex, char* pBitMask) |
andrewboyson | 4:e076884ef8bd | 99 | { |
andrewboyson | 4:e076884ef8bd | 100 | *pBitMask <<= 1; |
andrewboyson | 4:e076884ef8bd | 101 | if (!*pBitMask) |
andrewboyson | 4:e076884ef8bd | 102 | { |
andrewboyson | 4:e076884ef8bd | 103 | *pBitMask = 1; |
andrewboyson | 4:e076884ef8bd | 104 | *pByteIndex += 1; |
andrewboyson | 4:e076884ef8bd | 105 | } |
andrewboyson | 4:e076884ef8bd | 106 | } |
andrewboyson | 4:e076884ef8bd | 107 | |
andrewboyson | 4:e076884ef8bd | 108 | int getBitAtPosition(int byteIndex, char bitMask) |
andrewboyson | 4:e076884ef8bd | 109 | { |
andrewboyson | 4:e076884ef8bd | 110 | return psend[byteIndex] & bitMask; |
andrewboyson | 4:e076884ef8bd | 111 | } |
andrewboyson | 4:e076884ef8bd | 112 | void setBitAtPosition(int byteIndex, char bitMask, int bit) |
andrewboyson | 4:e076884ef8bd | 113 | { |
andrewboyson | 4:e076884ef8bd | 114 | if (bit) precv[byteIndex] |= bitMask; |
andrewboyson | 4:e076884ef8bd | 115 | } |
andrewboyson | 4:e076884ef8bd | 116 | int moreBitsToRead(int byteIndex) |
andrewboyson | 4:e076884ef8bd | 117 | { |
andrewboyson | 4:e076884ef8bd | 118 | return byteIndex < lenrecv; |
andrewboyson | 4:e076884ef8bd | 119 | } |
andrewboyson | 4:e076884ef8bd | 120 | int moreBitsToWrite(int byteIndex) |
andrewboyson | 4:e076884ef8bd | 121 | { |
andrewboyson | 4:e076884ef8bd | 122 | return byteIndex < lensend; |
andrewboyson | 4:e076884ef8bd | 123 | } |
andrewboyson | 4:e076884ef8bd | 124 | int OneWireInit() |
andrewboyson | 4:e076884ef8bd | 125 | { |
andrewboyson | 4:e076884ef8bd | 126 | startbuslow.detach(); |
andrewboyson | 4:e076884ef8bd | 127 | startbushigh.detach(); |
andrewboyson | 4:e076884ef8bd | 128 | startbusfree.detach(); |
andrewboyson | 4:e076884ef8bd | 129 | startbusread.detach(); |
andrewboyson | 4:e076884ef8bd | 130 | startbusidle.detach(); |
andrewboyson | 4:e076884ef8bd | 131 | busidle(); |
andrewboyson | 4:e076884ef8bd | 132 | xchgstate = XCHG_IDLE; |
andrewboyson | 4:e076884ef8bd | 133 | busbusytimer.stop(); |
andrewboyson | 4:e076884ef8bd | 134 | busbusytimer.reset(); |
andrewboyson | 4:e076884ef8bd | 135 | return 0; |
andrewboyson | 4:e076884ef8bd | 136 | } |
andrewboyson | 4:e076884ef8bd | 137 | int OneWireBusy() |
andrewboyson | 4:e076884ef8bd | 138 | { |
andrewboyson | 4:e076884ef8bd | 139 | return xchgstate; |
andrewboyson | 4:e076884ef8bd | 140 | } |
andrewboyson | 4:e076884ef8bd | 141 | void OneWireExchange(int lenBytesToSend, int lenBytesToRecv, char *pBytesToSend, char *pBytesToRecv, int msToPullUp) |
andrewboyson | 4:e076884ef8bd | 142 | { |
andrewboyson | 4:e076884ef8bd | 143 | lensend = lenBytesToSend; |
andrewboyson | 4:e076884ef8bd | 144 | lenrecv = lenBytesToRecv; |
andrewboyson | 4:e076884ef8bd | 145 | psend = pBytesToSend; |
andrewboyson | 4:e076884ef8bd | 146 | precv = pBytesToRecv; |
andrewboyson | 4:e076884ef8bd | 147 | pullupms = msToPullUp; |
andrewboyson | 4:e076884ef8bd | 148 | xchgstate = XCHG_RESET; |
andrewboyson | 4:e076884ef8bd | 149 | reset(); |
andrewboyson | 4:e076884ef8bd | 150 | } |
andrewboyson | 4:e076884ef8bd | 151 | int OneWireMain() |
andrewboyson | 4:e076884ef8bd | 152 | { |
andrewboyson | 4:e076884ef8bd | 153 | static int byteindex; |
andrewboyson | 4:e076884ef8bd | 154 | static char bitmask; |
andrewboyson | 4:e076884ef8bd | 155 | |
andrewboyson | 4:e076884ef8bd | 156 | if (busbusy) |
andrewboyson | 4:e076884ef8bd | 157 | { |
andrewboyson | 4:e076884ef8bd | 158 | busbusytimer.start(); |
andrewboyson | 4:e076884ef8bd | 159 | if (busbusytimer.read_ms() > BUS_TIMEOUT_MS) |
andrewboyson | 4:e076884ef8bd | 160 | { |
andrewboyson | 4:e076884ef8bd | 161 | LogCrLf("1-wire bus timed out so protocol has been reset to idle."); |
andrewboyson | 4:e076884ef8bd | 162 | OneWireInit(); |
andrewboyson | 4:e076884ef8bd | 163 | } |
andrewboyson | 4:e076884ef8bd | 164 | return 0; |
andrewboyson | 4:e076884ef8bd | 165 | } |
andrewboyson | 4:e076884ef8bd | 166 | else |
andrewboyson | 4:e076884ef8bd | 167 | { |
andrewboyson | 4:e076884ef8bd | 168 | busbusytimer.stop(); |
andrewboyson | 4:e076884ef8bd | 169 | busbusytimer.reset(); |
andrewboyson | 4:e076884ef8bd | 170 | } |
andrewboyson | 4:e076884ef8bd | 171 | |
andrewboyson | 4:e076884ef8bd | 172 | switch(xchgstate) |
andrewboyson | 4:e076884ef8bd | 173 | { |
andrewboyson | 4:e076884ef8bd | 174 | case XCHG_IDLE: |
andrewboyson | 4:e076884ef8bd | 175 | break; |
andrewboyson | 4:e076884ef8bd | 176 | case XCHG_RESET: |
andrewboyson | 4:e076884ef8bd | 177 | if (busvalue) |
andrewboyson | 4:e076884ef8bd | 178 | { |
andrewboyson | 4:e076884ef8bd | 179 | LogCrLf("No 1-wire device presence detected on the bus"); |
andrewboyson | 4:e076884ef8bd | 180 | xchgstate = XCHG_IDLE; |
andrewboyson | 4:e076884ef8bd | 181 | } |
andrewboyson | 4:e076884ef8bd | 182 | else |
andrewboyson | 4:e076884ef8bd | 183 | { |
andrewboyson | 4:e076884ef8bd | 184 | resetBitPosition(&byteindex, &bitmask); |
andrewboyson | 4:e076884ef8bd | 185 | xchgstate = XCHG_WRITE; |
andrewboyson | 4:e076884ef8bd | 186 | } |
andrewboyson | 4:e076884ef8bd | 187 | break; |
andrewboyson | 4:e076884ef8bd | 188 | case XCHG_WRITE: |
andrewboyson | 4:e076884ef8bd | 189 | if (moreBitsToWrite(byteindex)) |
andrewboyson | 4:e076884ef8bd | 190 | { |
andrewboyson | 4:e076884ef8bd | 191 | int bit = getBitAtPosition(byteindex, bitmask); |
andrewboyson | 4:e076884ef8bd | 192 | incrementBitPosition(&byteindex, &bitmask); |
andrewboyson | 4:e076884ef8bd | 193 | if (moreBitsToWrite(byteindex)) writebit(bit, 0); |
andrewboyson | 4:e076884ef8bd | 194 | else writebit(bit, pullupms); |
andrewboyson | 4:e076884ef8bd | 195 | } |
andrewboyson | 4:e076884ef8bd | 196 | else |
andrewboyson | 4:e076884ef8bd | 197 | { |
andrewboyson | 4:e076884ef8bd | 198 | resetBitPosition(&byteindex, &bitmask); |
andrewboyson | 4:e076884ef8bd | 199 | if (moreBitsToRead(byteindex)) |
andrewboyson | 4:e076884ef8bd | 200 | { |
andrewboyson | 4:e076884ef8bd | 201 | initiatebitread(); |
andrewboyson | 4:e076884ef8bd | 202 | xchgstate = XCHG_READ; |
andrewboyson | 4:e076884ef8bd | 203 | |
andrewboyson | 4:e076884ef8bd | 204 | } |
andrewboyson | 4:e076884ef8bd | 205 | else |
andrewboyson | 4:e076884ef8bd | 206 | { |
andrewboyson | 4:e076884ef8bd | 207 | xchgstate = XCHG_IDLE; |
andrewboyson | 4:e076884ef8bd | 208 | } |
andrewboyson | 4:e076884ef8bd | 209 | } |
andrewboyson | 4:e076884ef8bd | 210 | break; |
andrewboyson | 4:e076884ef8bd | 211 | case XCHG_READ: |
andrewboyson | 4:e076884ef8bd | 212 | setBitAtPosition(byteindex, bitmask, busvalue); |
andrewboyson | 4:e076884ef8bd | 213 | incrementBitPosition(&byteindex, &bitmask); |
andrewboyson | 4:e076884ef8bd | 214 | if (moreBitsToRead(byteindex)) |
andrewboyson | 4:e076884ef8bd | 215 | { |
andrewboyson | 4:e076884ef8bd | 216 | initiatebitread(); |
andrewboyson | 4:e076884ef8bd | 217 | } |
andrewboyson | 4:e076884ef8bd | 218 | else |
andrewboyson | 4:e076884ef8bd | 219 | { |
andrewboyson | 4:e076884ef8bd | 220 | xchgstate = XCHG_IDLE; |
andrewboyson | 4:e076884ef8bd | 221 | } |
andrewboyson | 4:e076884ef8bd | 222 | break; |
andrewboyson | 4:e076884ef8bd | 223 | default: |
andrewboyson | 4:e076884ef8bd | 224 | LogF("Unknown xchgstate %d\r\n", xchgstate); |
andrewboyson | 4:e076884ef8bd | 225 | return -1; |
andrewboyson | 4:e076884ef8bd | 226 | } |
andrewboyson | 4:e076884ef8bd | 227 | return 0; |
andrewboyson | 4:e076884ef8bd | 228 | } |