An experimental timer interrupt driven software based 1-Wire master interface that was created by Robert David Brinzer for a University of Glasgow Level 4 Electronic and Software Engineering Final Year project. This implementation requires mbed RTOS and does not use NOP waits. Perfect for programs that require multi-tasking. Includes the Read and Search network commands and can be easily extended to support new network and transport commands.
Interface/OneWire.cpp@0:7c6dd6bc20e4, 2013-04-15 (annotated)
- Committer:
- sroy
- Date:
- Mon Apr 15 07:02:49 2013 +0000
- Revision:
- 0:7c6dd6bc20e4
An experimental 1-Wire Master interface driven by timer interrupts rather than NOP waits created as part of a University of Glasgow Level 4 Electronic and Software Engineering final year project. Requires the use of mbed RTOS.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sroy | 0:7c6dd6bc20e4 | 1 | #include "OneWire.h" |
sroy | 0:7c6dd6bc20e4 | 2 | |
sroy | 0:7c6dd6bc20e4 | 3 | const OneWire_MicroInstruction OneWire::_OneWire_MicroProgram[10] = {&OneWire::_io_low,&OneWire::_io_high, |
sroy | 0:7c6dd6bc20e4 | 4 | &OneWire::_io_low,&OneWire::_io_high, |
sroy | 0:7c6dd6bc20e4 | 5 | &OneWire::_io_low,&OneWire::_io_high,&OneWire::_io_read, |
sroy | 0:7c6dd6bc20e4 | 6 | &OneWire::_io_low,&OneWire::_io_high,&OneWire::_io_read}; |
sroy | 0:7c6dd6bc20e4 | 7 | |
sroy | 0:7c6dd6bc20e4 | 8 | const unsigned short DEFAULT_TIMES[10] = {ONEWIRE_WRITE1LOW, ONEWIRE_TIMESLOT+ONEWIRE_RECOVER-ONEWIRE_WRITE1LOW+ONEWIRE_RECOVER, |
sroy | 0:7c6dd6bc20e4 | 9 | ONEWIRE_WRITE0LOW, ONEWIRE_TIMESLOT+ONEWIRE_RECOVER-ONEWIRE_WRITE0LOW+ONEWIRE_RECOVER, |
sroy | 0:7c6dd6bc20e4 | 10 | ONEWIRE_READLOW, ONEWIRE_READDURATION-ONEWIRE_READLOW-1, ONEWIRE_TIMESLOT-ONEWIRE_READDURATION-ONEWIRE_READLOW-1+ONEWIRE_RECOVER, |
sroy | 0:7c6dd6bc20e4 | 11 | ONEWIRE_TIMESLOT*8, ONEWIRE_PULSEHIGH+ONEWIRE_PULSELOW/2, ONEWIRE_TIMESLOT*8-(ONEWIRE_PULSEHIGH+ONEWIRE_PULSELOW/2)+ONEWIRE_RECOVER}; |
sroy | 0:7c6dd6bc20e4 | 12 | |
sroy | 0:7c6dd6bc20e4 | 13 | void OneWire::_nextmicroinst(){ |
sroy | 0:7c6dd6bc20e4 | 14 | if(_microinstn == 0){ |
sroy | 0:7c6dd6bc20e4 | 15 | _resumeinst(); |
sroy | 0:7c6dd6bc20e4 | 16 | }else{ |
sroy | 0:7c6dd6bc20e4 | 17 | _timer.attach_us(this, &OneWire::_nextmicroinst, timeing[_microinstc]); |
sroy | 0:7c6dd6bc20e4 | 18 | (this->*_OneWire_MicroProgram[_microinstc++])(); |
sroy | 0:7c6dd6bc20e4 | 19 | _microinstn-= 1; |
sroy | 0:7c6dd6bc20e4 | 20 | } |
sroy | 0:7c6dd6bc20e4 | 21 | } |
sroy | 0:7c6dd6bc20e4 | 22 | |
sroy | 0:7c6dd6bc20e4 | 23 | void OneWire::_resumeinst(){ |
sroy | 0:7c6dd6bc20e4 | 24 | unsigned char offset = _inststate & 0x0F; |
sroy | 0:7c6dd6bc20e4 | 25 | if(offset < 8){ |
sroy | 0:7c6dd6bc20e4 | 26 | if((execute.code>>offset) & 0x01) op_send1(); |
sroy | 0:7c6dd6bc20e4 | 27 | else op_send0(); |
sroy | 0:7c6dd6bc20e4 | 28 | _inststate+= 1; |
sroy | 0:7c6dd6bc20e4 | 29 | }else{ |
sroy | 0:7c6dd6bc20e4 | 30 | if(execute.inst == NULL) endInstruction(); |
sroy | 0:7c6dd6bc20e4 | 31 | else (*(execute.inst))(this); |
sroy | 0:7c6dd6bc20e4 | 32 | } |
sroy | 0:7c6dd6bc20e4 | 33 | |
sroy | 0:7c6dd6bc20e4 | 34 | } |
sroy | 0:7c6dd6bc20e4 | 35 | |
sroy | 0:7c6dd6bc20e4 | 36 | void OneWire::_nextinst(){ |
sroy | 0:7c6dd6bc20e4 | 37 | if(_instn > 0){ |
sroy | 0:7c6dd6bc20e4 | 38 | execute = (*_instruction).network; |
sroy | 0:7c6dd6bc20e4 | 39 | if(execute.inst == NULL) _inststate = 0x08; // skip network and transport command but allow reset |
sroy | 0:7c6dd6bc20e4 | 40 | else _inststate = 0x10; |
sroy | 0:7c6dd6bc20e4 | 41 | |
sroy | 0:7c6dd6bc20e4 | 42 | // send reset pulse |
sroy | 0:7c6dd6bc20e4 | 43 | readhandle = &OneWire::_presencedetect; |
sroy | 0:7c6dd6bc20e4 | 44 | op_reset(); |
sroy | 0:7c6dd6bc20e4 | 45 | }else{ |
sroy | 0:7c6dd6bc20e4 | 46 | error = SUCCESS; |
sroy | 0:7c6dd6bc20e4 | 47 | osSignalSet(_caller, 1); |
sroy | 0:7c6dd6bc20e4 | 48 | } |
sroy | 0:7c6dd6bc20e4 | 49 | } |
sroy | 0:7c6dd6bc20e4 | 50 | |
sroy | 0:7c6dd6bc20e4 | 51 | void OneWire::_presencedetect(OneWire * which, char bit){ |
sroy | 0:7c6dd6bc20e4 | 52 | if(bit) which->abort(NO_PRESENCE); // it is pointless to continue when there is no device attached |
sroy | 0:7c6dd6bc20e4 | 53 | } |
sroy | 0:7c6dd6bc20e4 | 54 | |
sroy | 0:7c6dd6bc20e4 | 55 | void OneWire::_ei_detect(){ |
sroy | 0:7c6dd6bc20e4 | 56 | if(detecthandle != NULL) (*detecthandle)(this); |
sroy | 0:7c6dd6bc20e4 | 57 | } |
sroy | 0:7c6dd6bc20e4 | 58 | |
sroy | 0:7c6dd6bc20e4 | 59 | // Private pin I/O methods |
sroy | 0:7c6dd6bc20e4 | 60 | |
sroy | 0:7c6dd6bc20e4 | 61 | void OneWire::_io_high(){ |
sroy | 0:7c6dd6bc20e4 | 62 | _pin = 1; |
sroy | 0:7c6dd6bc20e4 | 63 | } |
sroy | 0:7c6dd6bc20e4 | 64 | |
sroy | 0:7c6dd6bc20e4 | 65 | void OneWire::_io_low(){ |
sroy | 0:7c6dd6bc20e4 | 66 | _pin = 0; |
sroy | 0:7c6dd6bc20e4 | 67 | } |
sroy | 0:7c6dd6bc20e4 | 68 | |
sroy | 0:7c6dd6bc20e4 | 69 | void OneWire::_io_read(){ |
sroy | 0:7c6dd6bc20e4 | 70 | _pin.input(); |
sroy | 0:7c6dd6bc20e4 | 71 | (*readhandle)(this, _pin); |
sroy | 0:7c6dd6bc20e4 | 72 | _pin.output(); |
sroy | 0:7c6dd6bc20e4 | 73 | } |
sroy | 0:7c6dd6bc20e4 | 74 | |
sroy | 0:7c6dd6bc20e4 | 75 | // Public utility methods |
sroy | 0:7c6dd6bc20e4 | 76 | |
sroy | 0:7c6dd6bc20e4 | 77 | OneWire::OneWire(PinName pin) : _pin(pin), _detect(pin){ |
sroy | 0:7c6dd6bc20e4 | 78 | _pin.output(); |
sroy | 0:7c6dd6bc20e4 | 79 | _pin = 1; // turn on devices to allow them to start working |
sroy | 0:7c6dd6bc20e4 | 80 | _pin.mode(PullUp); |
sroy | 0:7c6dd6bc20e4 | 81 | _detect.mode(PullUp); |
sroy | 0:7c6dd6bc20e4 | 82 | _detect.fall(this, &OneWire::_ei_detect); |
sroy | 0:7c6dd6bc20e4 | 83 | timeing = DEFAULT_TIMES; |
sroy | 0:7c6dd6bc20e4 | 84 | detecthandle = NULL; |
sroy | 0:7c6dd6bc20e4 | 85 | } |
sroy | 0:7c6dd6bc20e4 | 86 | |
sroy | 0:7c6dd6bc20e4 | 87 | int OneWire::send(OneWire_Instruction * inst, unsigned char instnum){ |
sroy | 0:7c6dd6bc20e4 | 88 | _detect.fall(NULL); |
sroy | 0:7c6dd6bc20e4 | 89 | _instruction = inst; |
sroy | 0:7c6dd6bc20e4 | 90 | _instn = instnum; |
sroy | 0:7c6dd6bc20e4 | 91 | _nextinst(); |
sroy | 0:7c6dd6bc20e4 | 92 | _caller = Thread::gettid(); |
sroy | 0:7c6dd6bc20e4 | 93 | Thread::signal_wait(0); |
sroy | 0:7c6dd6bc20e4 | 94 | osSignalSet(_caller, 0); |
sroy | 0:7c6dd6bc20e4 | 95 | _detect.fall(this, &OneWire::_ei_detect); |
sroy | 0:7c6dd6bc20e4 | 96 | return error != SUCCESS; |
sroy | 0:7c6dd6bc20e4 | 97 | } |
sroy | 0:7c6dd6bc20e4 | 98 | |
sroy | 0:7c6dd6bc20e4 | 99 | void OneWire::endInstruction(){ |
sroy | 0:7c6dd6bc20e4 | 100 | if(_inststate>>4 && _instruction->transport.inst != NULL){ |
sroy | 0:7c6dd6bc20e4 | 101 | execute = _instruction->transport; |
sroy | 0:7c6dd6bc20e4 | 102 | _inststate = 0x00; |
sroy | 0:7c6dd6bc20e4 | 103 | _timer.attach_us(this, &OneWire::_resumeinst, 1); // MAKE TIMING CONFIGURABLE |
sroy | 0:7c6dd6bc20e4 | 104 | }else{ |
sroy | 0:7c6dd6bc20e4 | 105 | _instruction+= 1; |
sroy | 0:7c6dd6bc20e4 | 106 | _instn-= 1; |
sroy | 0:7c6dd6bc20e4 | 107 | _timer.attach_us(this, &OneWire::_nextinst, 1); // MAKE TIMING CONFIGURABLE |
sroy | 0:7c6dd6bc20e4 | 108 | } |
sroy | 0:7c6dd6bc20e4 | 109 | } |
sroy | 0:7c6dd6bc20e4 | 110 | |
sroy | 0:7c6dd6bc20e4 | 111 | // depricated, use at own risk |
sroy | 0:7c6dd6bc20e4 | 112 | void OneWire::repeatInstruction(){ |
sroy | 0:7c6dd6bc20e4 | 113 | execute = (*_instruction).network; |
sroy | 0:7c6dd6bc20e4 | 114 | _inststate = 0x10; |
sroy | 0:7c6dd6bc20e4 | 115 | // send reset pulse |
sroy | 0:7c6dd6bc20e4 | 116 | readhandle = &OneWire::_presencedetect; |
sroy | 0:7c6dd6bc20e4 | 117 | op_reset(); |
sroy | 0:7c6dd6bc20e4 | 118 | } |
sroy | 0:7c6dd6bc20e4 | 119 | |
sroy | 0:7c6dd6bc20e4 | 120 | void OneWire::abort(OneWire_Error err){ |
sroy | 0:7c6dd6bc20e4 | 121 | _timer.detach(); |
sroy | 0:7c6dd6bc20e4 | 122 | error = err; |
sroy | 0:7c6dd6bc20e4 | 123 | osSignalSet(_caller, 1); |
sroy | 0:7c6dd6bc20e4 | 124 | } |
sroy | 0:7c6dd6bc20e4 | 125 | |
sroy | 0:7c6dd6bc20e4 | 126 | // Public IO methods |
sroy | 0:7c6dd6bc20e4 | 127 | |
sroy | 0:7c6dd6bc20e4 | 128 | void OneWire::op_send1(){ |
sroy | 0:7c6dd6bc20e4 | 129 | _microinstn = 2; |
sroy | 0:7c6dd6bc20e4 | 130 | _microinstc = 0; |
sroy | 0:7c6dd6bc20e4 | 131 | _nextmicroinst(); |
sroy | 0:7c6dd6bc20e4 | 132 | } |
sroy | 0:7c6dd6bc20e4 | 133 | |
sroy | 0:7c6dd6bc20e4 | 134 | void OneWire::op_send0(){ |
sroy | 0:7c6dd6bc20e4 | 135 | _microinstn = 2; |
sroy | 0:7c6dd6bc20e4 | 136 | _microinstc = 2; |
sroy | 0:7c6dd6bc20e4 | 137 | _nextmicroinst(); |
sroy | 0:7c6dd6bc20e4 | 138 | } |
sroy | 0:7c6dd6bc20e4 | 139 | |
sroy | 0:7c6dd6bc20e4 | 140 | void OneWire::op_read(){ |
sroy | 0:7c6dd6bc20e4 | 141 | _microinstn = 3; |
sroy | 0:7c6dd6bc20e4 | 142 | _microinstc = 4; |
sroy | 0:7c6dd6bc20e4 | 143 | _nextmicroinst(); |
sroy | 0:7c6dd6bc20e4 | 144 | } |
sroy | 0:7c6dd6bc20e4 | 145 | |
sroy | 0:7c6dd6bc20e4 | 146 | void OneWire::op_reset(){ |
sroy | 0:7c6dd6bc20e4 | 147 | _microinstn = 3; |
sroy | 0:7c6dd6bc20e4 | 148 | _microinstc = 7; |
sroy | 0:7c6dd6bc20e4 | 149 | _nextmicroinst(); |
sroy | 0:7c6dd6bc20e4 | 150 | } |