Andrew Boyson
/
iot
Backing up an unused program in case of future need
Diff: 1-wire.cpp
- Revision:
- 4:e076884ef8bd
- Child:
- 5:6226f3c566ef
diff -r accba7e07a0d -r e076884ef8bd 1-wire.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/1-wire.cpp Tue May 03 09:23:26 2016 +0000 @@ -0,0 +1,228 @@ +#include "mbed.h" +#include "log.h" +#include "io.h" + +//Bus zone +//======== +static DigitalInOut pin(p25, PIN_INPUT, PullUp, 0); + + +static int busvalue; + +//Delays +#define ATTACH_DELAY 7 +#define INITIAL_DELAY 100 +#define RESET_BUS_LOW_DELAY 480 +#define READ_PRESENCE_DELAY 70 +#define RESET_RELEASE_DELAY 410 +#define WRITE_0_BUS_LOW_DELAY 60 +#define WRITE_0_RELEASE_DELAY 10 +#define WRITE_1_BUS_LOW_DELAY 6 +#define WRITE_1_RELEASE_DELAY 64 +#define READ_BIT_BUS_LOW_DELAY 6 +#define READ_BIT_DELAY 9 +#define READ_BIT_RELEASE_DELAY 55 +#define BUS_TIMEOUT_MS 1000 + +static int busbusy = false; //Set whenever an operation starts; reset by finishbus interrupt; +static Timer busbusytimer; + +static void buslow (void) { pin = 0; pin.output(); } +static Timeout startbuslow; +static void busfree(void) { pin.input (); } +static Timeout startbusfree; +static void bushigh(void) { pin = 1; pin.output(); } +static Timeout startbushigh; +static void busread(void) { busvalue = pin; } +static Timeout startbusread; +static void busidle(void) { pin.input (); busbusy = false; } +static Timeout startbusidle; + +static void reset() +{ + busbusy = true; + int delay = INITIAL_DELAY - ATTACH_DELAY; startbuslow.attach_us(&buslow, delay); + delay += RESET_BUS_LOW_DELAY - ATTACH_DELAY; startbusfree.attach_us(&busfree, delay); + delay += READ_PRESENCE_DELAY - ATTACH_DELAY; startbusread.attach_us(&busread, delay); + delay += RESET_RELEASE_DELAY - ATTACH_DELAY; startbusidle.attach_us(&busidle, delay); +} +static void writebit(int bit, int msToPullUp) +{ + busbusy = true; + int delay = INITIAL_DELAY - ATTACH_DELAY; + startbuslow.attach_us(&buslow, delay); + delay += bit ? WRITE_1_BUS_LOW_DELAY : WRITE_0_BUS_LOW_DELAY; + delay -= ATTACH_DELAY; + if (msToPullUp) + { + startbushigh.attach_us(&bushigh, delay); + delay += msToPullUp * 1000 - ATTACH_DELAY; + } + else + { + startbusfree.attach_us(&busfree, delay); + delay += bit ? WRITE_1_RELEASE_DELAY : WRITE_0_RELEASE_DELAY; + delay -= ATTACH_DELAY; + } + startbusidle.attach_us(&busidle, delay); +} +static void initiatebitread() +{ + busbusy = true; + int delay = INITIAL_DELAY - ATTACH_DELAY; startbuslow.attach_us(&buslow, delay); + delay += READ_BIT_BUS_LOW_DELAY - ATTACH_DELAY; startbusfree.attach_us(&busfree, delay); + delay += READ_BIT_DELAY - ATTACH_DELAY; startbusread.attach_us(&busread, delay); + delay += READ_BIT_RELEASE_DELAY - ATTACH_DELAY; startbusidle.attach_us(&busidle, delay); +} + +//Exchange zone +//============= +#define XCHG_IDLE 0 +#define XCHG_RESET 1 +#define XCHG_WRITE 2 +#define XCHG_READ 3 +#define XCHG_PULLUP 4 +static int xchgstate = XCHG_IDLE; + +static int lensend = 0; +static int lenrecv = 0; +static char* psend = NULL; +static char* precv = NULL; +static int pullupms = 0; + +static void resetBitPosition(int* pByteIndex, char* pBitMask) +{ + *pBitMask = 1; + *pByteIndex = 0; +} +static void incrementBitPosition(int* pByteIndex, char* pBitMask) +{ + *pBitMask <<= 1; + if (!*pBitMask) + { + *pBitMask = 1; + *pByteIndex += 1; + } +} + +int getBitAtPosition(int byteIndex, char bitMask) +{ + return psend[byteIndex] & bitMask; +} +void setBitAtPosition(int byteIndex, char bitMask, int bit) +{ + if (bit) precv[byteIndex] |= bitMask; +} +int moreBitsToRead(int byteIndex) +{ + return byteIndex < lenrecv; +} +int moreBitsToWrite(int byteIndex) +{ + return byteIndex < lensend; +} +int OneWireInit() +{ + startbuslow.detach(); + startbushigh.detach(); + startbusfree.detach(); + startbusread.detach(); + startbusidle.detach(); + busidle(); + xchgstate = XCHG_IDLE; + busbusytimer.stop(); + busbusytimer.reset(); + return 0; +} +int OneWireBusy() +{ + return xchgstate; +} +void OneWireExchange(int lenBytesToSend, int lenBytesToRecv, char *pBytesToSend, char *pBytesToRecv, int msToPullUp) +{ + lensend = lenBytesToSend; + lenrecv = lenBytesToRecv; + psend = pBytesToSend; + precv = pBytesToRecv; + pullupms = msToPullUp; + xchgstate = XCHG_RESET; + reset(); +} +int OneWireMain() +{ + static int byteindex; + static char bitmask; + + if (busbusy) + { + busbusytimer.start(); + if (busbusytimer.read_ms() > BUS_TIMEOUT_MS) + { + LogCrLf("1-wire bus timed out so protocol has been reset to idle."); + OneWireInit(); + } + return 0; + } + else + { + busbusytimer.stop(); + busbusytimer.reset(); + } + + switch(xchgstate) + { + case XCHG_IDLE: + break; + case XCHG_RESET: + if (busvalue) + { + LogCrLf("No 1-wire device presence detected on the bus"); + xchgstate = XCHG_IDLE; + } + else + { + resetBitPosition(&byteindex, &bitmask); + xchgstate = XCHG_WRITE; + } + break; + case XCHG_WRITE: + if (moreBitsToWrite(byteindex)) + { + int bit = getBitAtPosition(byteindex, bitmask); + incrementBitPosition(&byteindex, &bitmask); + if (moreBitsToWrite(byteindex)) writebit(bit, 0); + else writebit(bit, pullupms); + } + else + { + resetBitPosition(&byteindex, &bitmask); + if (moreBitsToRead(byteindex)) + { + initiatebitread(); + xchgstate = XCHG_READ; + + } + else + { + xchgstate = XCHG_IDLE; + } + } + break; + case XCHG_READ: + setBitAtPosition(byteindex, bitmask, busvalue); + incrementBitPosition(&byteindex, &bitmask); + if (moreBitsToRead(byteindex)) + { + initiatebitread(); + } + else + { + xchgstate = XCHG_IDLE; + } + break; + default: + LogF("Unknown xchgstate %d\r\n", xchgstate); + return -1; + } + return 0; +}