Andrew Boyson
/
iot
Backing up an unused program in case of future need
1-wire.cpp
- Committer:
- andrewboyson
- Date:
- 2016-05-31
- Revision:
- 6:be97d38e0b01
- Parent:
- 5:6226f3c566ef
- Child:
- 7:024ace6d943c
File content as of revision 6:be97d38e0b01:
#include "mbed.h" #include "log.h" #include "io.h" #include "1-wire.h" //Bus zone //======== static DigitalInOut pin(p25, PIN_INPUT, PullUp, 0); static volatile int busvalue; static Timer timer; static Timer busytimer; //Delays #define ATTACH_US 7 #define INITIAL_US 100 #define RESET_BUS_LOW_US 480 #define READ_PRESENCE_US 70 #define RESET_RELEASE_US 410 #define WRITE_0_BUS_LOW_US 60 #define WRITE_0_RELEASE_US 10 #define WRITE_1_BUS_LOW_US 6 #define WRITE_1_RELEASE_US 64 #define READ_BIT_BUS_LOW_US 6 #define READ_BIT_US 9 #define READ_BIT_RELEASE_US 55 #define BUS_TIMEOUT_MS 5000 static void buslow (void) { pin.output(); pin = 0; } static void busfree(void) { pin.input (); } static void bushigh(void) { pin.output(); pin = 1; } static void busread(void) { busvalue = pin; } //Exchange zone //============= #define STATE_IDLE 0 #define RESET_LOW 1 #define RESET_RELEASE 2 #define XCHG_WRITE 3 #define PULL_UP 4 #define XCHG_READ 5 #define SEARCH_WRITE 6 #define SEARCH_BIT 7 #define SEARCH_READ_BIT_TRUE 8 #define SEARCH_READ_BIT_COMP 9 #define SEARCH_WRITE_BIT 10 static int state = STATE_IDLE; #define JOB_NONE 0 #define JOB_XCHG 1 #define JOB_SEARCH 2 static int job = JOB_NONE; static int lensend = 0; static int lenrecv = 0; static char* psend = NULL; static char* precv = NULL; static int pullupms = 0; static void initiateResetLow(int jobtype) { buslow(); timer.stop(); timer.reset(); timer.start(); state = RESET_LOW; job = jobtype; } static void readPresenceAndAwaitResetRelease() { busfree(); wait_us(READ_PRESENCE_US); busread(); timer.stop(); timer.reset(); timer.start(); state = RESET_RELEASE; } static void writeBit(int bit) { buslow(); wait_us(bit ? WRITE_1_BUS_LOW_US : WRITE_0_BUS_LOW_US); busfree(); wait_us(bit ? WRITE_1_RELEASE_US : WRITE_0_RELEASE_US); } static void writeBitWithPullUp(int bit) { buslow(); wait_us(bit ? WRITE_1_BUS_LOW_US : WRITE_0_BUS_LOW_US); bushigh(); timer.stop(); timer.reset(); timer.start(); state = PULL_UP; } static void readBit() { buslow(); wait_us(READ_BIT_BUS_LOW_US); busfree(); wait_us(READ_BIT_US); busread(); wait_us(READ_BIT_RELEASE_US); } static char crc; static void resetCrc() { crc = 0; } static void addBitToCrc(int bit) { int feedback = !(crc & 0x80) != !bit; //Logical Exclusive Or of the msb of the shift register with the input crc <<= 1; //Move the shift register one place to the left leaving a zero in the lsb and losing the msb if (feedback) crc ^= 0x31; //Exclusive Or the shift register with polynomial X5 + X4 + 1 } 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; else precv[byteIndex] &= ~bitMask; } int moreBitsToRead(int byteIndex) { return byteIndex < lenrecv; } int moreBitsToWrite(int byteIndex) { return byteIndex < lensend; } int result = ONE_WIRE_RESULT_OK; int OneWireResult() { return result; } int OneWireInit() { busfree(); busytimer.stop(); busytimer.reset(); state = STATE_IDLE; job = JOB_NONE; return 0; } int OneWireBusy() { return state; } void OneWireExchange(int lenBytesToSend, int lenBytesToRecv, char *pBytesToSend, char *pBytesToRecv, int msToPullUp) { lensend = lenBytesToSend; lenrecv = lenBytesToRecv; psend = pBytesToSend; precv = pBytesToRecv; pullupms = msToPullUp; initiateResetLow(JOB_XCHG); } static int* pallfound; static char* prom; static void setRomBit(int position, int bit) { int bitindex = position & 0x07; int byteindex = position >> 3; int bitmask = 1 << bitindex; if (bit) *(prom + byteindex) |= bitmask; else *(prom + byteindex) &= ~bitmask; } static int getRomBit(int position) { int bitindex = position & 0x07; int byteindex = position >> 3; int bitmask = 1 << bitindex; return *(prom + byteindex) & bitmask; } static int thisFurthestForkLeftPosn; static int lastFurthestForkLeftPosn; static char searchCommand; static int searchBitPosn; static int searchBitTrue; static int searchBitComp; static int chooseDirectionToTake() { if ( searchBitTrue && searchBitComp) return -1; //No devices are participating in the search if ( searchBitTrue && !searchBitComp) return 1; //Only devices with a one at this point are participating if (!searchBitTrue && searchBitComp) return 0; //Only devices with a zero at this point are participating //Both bits are zero so devices with both 0s and 1s at this point are still participating //If we have not yet reached the furthest away point we forked left (0) last time then just do whatever we did last time if (searchBitPosn < lastFurthestForkLeftPosn) return getRomBit(searchBitPosn); //If we are at the furthest away point that we forked left (0) last time then this time fork right (1) if (searchBitPosn == lastFurthestForkLeftPosn) return 1; //We are at a new fork point further than we have been before so fork left (0) and record that we did so. thisFurthestForkLeftPosn = searchBitPosn; return 0; } void OneWireSearch(char command, char* pDeviceRom, int* pAllDevicesFound) //Specify the buffer to receive the rom for the first search and NULL thereafter. { if (pDeviceRom) { pallfound = pAllDevicesFound; *pallfound = false; lastFurthestForkLeftPosn = -1; prom = pDeviceRom; for (int i = 0; i < 8; i++) *(prom + i) = 0; } thisFurthestForkLeftPosn = -1; lensend = 1; lenrecv = 0; searchCommand = command; psend = &searchCommand; precv = NULL; pullupms = 0; initiateResetLow(JOB_SEARCH); } char OneWireCrc() { return crc; } int OneWireMain() { static int byteindex; static char bitmask; if (state) { busytimer.start(); if (busytimer.read_ms() > BUS_TIMEOUT_MS) { LogCrLf("1-wire bus timed out so protocol has been reset to idle."); OneWireInit(); result = ONE_WIRE_RESULT_TIMED_OUT; return 0; } } else { busytimer.stop(); busytimer.reset(); } switch(state) { case STATE_IDLE: break; case RESET_LOW: if (timer.read_us() > RESET_BUS_LOW_US) readPresenceAndAwaitResetRelease(); break; case RESET_RELEASE: if (timer.read_us() > RESET_RELEASE_US) { busfree(); timer.stop(); timer.reset(); if (busvalue) { LogCrLf("No 1-wire device presence detected on the bus"); result = ONE_WIRE_RESULT_NO_DEVICE_PRESENT; state = STATE_IDLE; } else { resetBitPosition(&byteindex, &bitmask); switch (job) { case JOB_XCHG: state = XCHG_WRITE; break; case JOB_SEARCH: state = SEARCH_WRITE; break; default: LogF("Unknown job in RESET_RELEASE %d\r\n", job); return -1; } } } break; case XCHG_WRITE: if (moreBitsToWrite(byteindex)) { int bit = getBitAtPosition(byteindex, bitmask); incrementBitPosition(&byteindex, &bitmask); if (moreBitsToWrite(byteindex)) writeBit(bit); else writeBitWithPullUp(bit); } else { resetBitPosition(&byteindex, &bitmask); if (moreBitsToRead(byteindex)) { resetCrc(); readBit(); state = XCHG_READ; } else { result = ONE_WIRE_RESULT_OK; state = STATE_IDLE; } } break; case PULL_UP: if (timer.read_ms() > pullupms) { busfree(); switch (job) { case JOB_XCHG: state = XCHG_WRITE; break; default: LogF("Unknown job in PULL_UP %d\r\n", job); return -1; } } break; case XCHG_READ: addBitToCrc(busvalue); setBitAtPosition(byteindex, bitmask, busvalue); incrementBitPosition(&byteindex, &bitmask); if (moreBitsToRead(byteindex)) { readBit(); } else { state = STATE_IDLE; result = crc ? ONE_WIRE_RESULT_CRC_ERROR : ONE_WIRE_RESULT_OK; } break; case SEARCH_WRITE: if (moreBitsToWrite(byteindex)) { int bit = getBitAtPosition(byteindex, bitmask); incrementBitPosition(&byteindex, &bitmask); writeBit(bit); } else { searchBitPosn = 0; state = SEARCH_BIT; } break; case SEARCH_BIT: readBit(); state = SEARCH_READ_BIT_TRUE; break; case SEARCH_READ_BIT_TRUE: searchBitTrue = busvalue; readBit(); state = SEARCH_READ_BIT_COMP; break; case SEARCH_READ_BIT_COMP: searchBitComp = busvalue; state = SEARCH_WRITE_BIT; break; case SEARCH_WRITE_BIT: LogF("%d%d - ", searchBitTrue, searchBitComp); int direction; direction = chooseDirectionToTake(); if (direction == -1) { LogCrLf("No devices have responded"); result = ONE_WIRE_RESULT_NO_DEVICE_PARTICIPATING; state = STATE_IDLE; } else { LogF(" %d -> %d\r\n", direction, searchBitPosn); setRomBit(searchBitPosn, direction); writeBit(direction); searchBitPosn++; if (searchBitPosn < 64) { state = SEARCH_BIT; } else { if (thisFurthestForkLeftPosn == -1) *pallfound = true; lastFurthestForkLeftPosn = thisFurthestForkLeftPosn; result = ONE_WIRE_RESULT_OK; state = STATE_IDLE; } } break; default: LogF("Unknown state %d\r\n", state); return -1; } return 0; }