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.

Revision:
0:7c6dd6bc20e4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Interface/OneWire.cpp	Mon Apr 15 07:02:49 2013 +0000
@@ -0,0 +1,150 @@
+#include "OneWire.h"
+
+const OneWire_MicroInstruction OneWire::_OneWire_MicroProgram[10] = {&OneWire::_io_low,&OneWire::_io_high,
+                                                                    &OneWire::_io_low,&OneWire::_io_high,
+                                                                    &OneWire::_io_low,&OneWire::_io_high,&OneWire::_io_read,
+                                                                    &OneWire::_io_low,&OneWire::_io_high,&OneWire::_io_read};
+                                                                    
+const unsigned short DEFAULT_TIMES[10] = {ONEWIRE_WRITE1LOW, ONEWIRE_TIMESLOT+ONEWIRE_RECOVER-ONEWIRE_WRITE1LOW+ONEWIRE_RECOVER,
+                                                ONEWIRE_WRITE0LOW, ONEWIRE_TIMESLOT+ONEWIRE_RECOVER-ONEWIRE_WRITE0LOW+ONEWIRE_RECOVER,
+                                                ONEWIRE_READLOW, ONEWIRE_READDURATION-ONEWIRE_READLOW-1, ONEWIRE_TIMESLOT-ONEWIRE_READDURATION-ONEWIRE_READLOW-1+ONEWIRE_RECOVER,
+                                                ONEWIRE_TIMESLOT*8, ONEWIRE_PULSEHIGH+ONEWIRE_PULSELOW/2, ONEWIRE_TIMESLOT*8-(ONEWIRE_PULSEHIGH+ONEWIRE_PULSELOW/2)+ONEWIRE_RECOVER};
+
+void OneWire::_nextmicroinst(){
+    if(_microinstn == 0){
+        _resumeinst();
+    }else{
+        _timer.attach_us(this, &OneWire::_nextmicroinst, timeing[_microinstc]);
+        (this->*_OneWire_MicroProgram[_microinstc++])();
+        _microinstn-= 1;
+    }
+}
+
+void OneWire::_resumeinst(){
+    unsigned char offset = _inststate & 0x0F;
+    if(offset < 8){
+        if((execute.code>>offset) & 0x01) op_send1();
+        else op_send0();
+        _inststate+= 1;
+    }else{
+        if(execute.inst == NULL) endInstruction();
+        else (*(execute.inst))(this);
+    }
+    
+}
+
+void OneWire::_nextinst(){
+    if(_instn > 0){
+        execute = (*_instruction).network;
+        if(execute.inst == NULL) _inststate = 0x08; // skip network and transport command but allow reset
+        else _inststate = 0x10;
+        
+        // send reset pulse
+        readhandle = &OneWire::_presencedetect;
+        op_reset();
+    }else{
+        error = SUCCESS;
+        osSignalSet(_caller, 1);
+    }
+}
+
+void OneWire::_presencedetect(OneWire * which, char bit){
+    if(bit) which->abort(NO_PRESENCE); // it is pointless to continue when there is no device attached
+}
+
+void OneWire::_ei_detect(){
+    if(detecthandle != NULL) (*detecthandle)(this);
+}
+
+// Private pin I/O methods
+
+void OneWire::_io_high(){
+    _pin = 1;
+}
+
+void OneWire::_io_low(){
+    _pin = 0;
+}
+
+void OneWire::_io_read(){
+    _pin.input();
+    (*readhandle)(this, _pin);
+    _pin.output();
+}
+
+// Public utility methods
+
+OneWire::OneWire(PinName pin) : _pin(pin), _detect(pin){
+    _pin.output();
+    _pin = 1; // turn on devices to allow them to start working
+    _pin.mode(PullUp); 
+    _detect.mode(PullUp);
+    _detect.fall(this, &OneWire::_ei_detect);
+    timeing = DEFAULT_TIMES;
+    detecthandle = NULL;
+}
+
+int OneWire::send(OneWire_Instruction * inst, unsigned char instnum){
+    _detect.fall(NULL);
+    _instruction = inst;
+    _instn = instnum;
+    _nextinst();
+    _caller = Thread::gettid();
+    Thread::signal_wait(0);
+    osSignalSet(_caller, 0);
+    _detect.fall(this, &OneWire::_ei_detect);
+    return error != SUCCESS;
+}
+
+void OneWire::endInstruction(){
+    if(_inststate>>4 && _instruction->transport.inst != NULL){
+        execute = _instruction->transport;
+        _inststate = 0x00;
+        _timer.attach_us(this, &OneWire::_resumeinst, 1); // MAKE TIMING CONFIGURABLE
+    }else{
+        _instruction+= 1;
+        _instn-= 1;
+        _timer.attach_us(this, &OneWire::_nextinst, 1); // MAKE TIMING CONFIGURABLE
+    }
+}
+
+// depricated, use at own risk
+void OneWire::repeatInstruction(){
+    execute = (*_instruction).network;
+    _inststate = 0x10;
+    // send reset pulse
+    readhandle = &OneWire::_presencedetect;
+    op_reset();
+}
+
+void OneWire::abort(OneWire_Error err){
+    _timer.detach();
+    error = err;
+    osSignalSet(_caller, 1);
+}
+
+// Public IO methods
+
+void OneWire::op_send1(){
+    _microinstn = 2;
+    _microinstc = 0;
+    _nextmicroinst();
+}
+
+void OneWire::op_send0(){
+    _microinstn = 2;
+    _microinstc = 2;
+    _nextmicroinst();
+}
+
+void OneWire::op_read(){
+    _microinstn = 3;
+    _microinstc = 4;
+    _nextmicroinst();
+}
+
+void OneWire::op_reset(){
+    _microinstn = 3;
+    _microinstc = 7;
+    _nextmicroinst();
+}
\ No newline at end of file