Scott Roy / OneWire
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers OneWire.cpp Source File

OneWire.cpp

00001 #include "OneWire.h"
00002 
00003 const OneWire_MicroInstruction OneWire::_OneWire_MicroProgram[10] = {&OneWire::_io_low,&OneWire::_io_high,
00004                                                                     &OneWire::_io_low,&OneWire::_io_high,
00005                                                                     &OneWire::_io_low,&OneWire::_io_high,&OneWire::_io_read,
00006                                                                     &OneWire::_io_low,&OneWire::_io_high,&OneWire::_io_read};
00007                                                                     
00008 const unsigned short DEFAULT_TIMES[10] = {ONEWIRE_WRITE1LOW, ONEWIRE_TIMESLOT+ONEWIRE_RECOVER-ONEWIRE_WRITE1LOW+ONEWIRE_RECOVER,
00009                                                 ONEWIRE_WRITE0LOW, ONEWIRE_TIMESLOT+ONEWIRE_RECOVER-ONEWIRE_WRITE0LOW+ONEWIRE_RECOVER,
00010                                                 ONEWIRE_READLOW, ONEWIRE_READDURATION-ONEWIRE_READLOW-1, ONEWIRE_TIMESLOT-ONEWIRE_READDURATION-ONEWIRE_READLOW-1+ONEWIRE_RECOVER,
00011                                                 ONEWIRE_TIMESLOT*8, ONEWIRE_PULSEHIGH+ONEWIRE_PULSELOW/2, ONEWIRE_TIMESLOT*8-(ONEWIRE_PULSEHIGH+ONEWIRE_PULSELOW/2)+ONEWIRE_RECOVER};
00012 
00013 void OneWire::_nextmicroinst(){
00014     if(_microinstn == 0){
00015         _resumeinst();
00016     }else{
00017         _timer.attach_us(this, &OneWire::_nextmicroinst, timeing[_microinstc]);
00018         (this->*_OneWire_MicroProgram[_microinstc++])();
00019         _microinstn-= 1;
00020     }
00021 }
00022 
00023 void OneWire::_resumeinst(){
00024     unsigned char offset = _inststate & 0x0F;
00025     if(offset < 8){
00026         if((execute.code>>offset) & 0x01) op_send1();
00027         else op_send0();
00028         _inststate+= 1;
00029     }else{
00030         if(execute.inst == NULL) endInstruction();
00031         else (*(execute.inst))(this);
00032     }
00033     
00034 }
00035 
00036 void OneWire::_nextinst(){
00037     if(_instn > 0){
00038         execute = (*_instruction).network;
00039         if(execute.inst == NULL) _inststate = 0x08; // skip network and transport command but allow reset
00040         else _inststate = 0x10;
00041         
00042         // send reset pulse
00043         readhandle = &OneWire::_presencedetect;
00044         op_reset();
00045     }else{
00046         error = SUCCESS;
00047         osSignalSet(_caller, 1);
00048     }
00049 }
00050 
00051 void OneWire::_presencedetect(OneWire * which, char bit){
00052     if(bit) which->abort(NO_PRESENCE); // it is pointless to continue when there is no device attached
00053 }
00054 
00055 void OneWire::_ei_detect(){
00056     if(detecthandle != NULL) (*detecthandle)(this);
00057 }
00058 
00059 // Private pin I/O methods
00060 
00061 void OneWire::_io_high(){
00062     _pin = 1;
00063 }
00064 
00065 void OneWire::_io_low(){
00066     _pin = 0;
00067 }
00068 
00069 void OneWire::_io_read(){
00070     _pin.input();
00071     (*readhandle)(this, _pin);
00072     _pin.output();
00073 }
00074 
00075 // Public utility methods
00076 
00077 OneWire::OneWire(PinName pin) : _pin(pin), _detect(pin){
00078     _pin.output();
00079     _pin = 1; // turn on devices to allow them to start working
00080     _pin.mode(PullUp); 
00081     _detect.mode(PullUp);
00082     _detect.fall(this, &OneWire::_ei_detect);
00083     timeing = DEFAULT_TIMES;
00084     detecthandle = NULL;
00085 }
00086 
00087 int OneWire::send(OneWire_Instruction * inst, unsigned char instnum){
00088     _detect.fall(NULL);
00089     _instruction = inst;
00090     _instn = instnum;
00091     _nextinst();
00092     _caller = Thread::gettid();
00093     Thread::signal_wait(0);
00094     osSignalSet(_caller, 0);
00095     _detect.fall(this, &OneWire::_ei_detect);
00096     return error != SUCCESS;
00097 }
00098 
00099 void OneWire::endInstruction(){
00100     if(_inststate>>4 && _instruction->transport.inst != NULL){
00101         execute = _instruction->transport;
00102         _inststate = 0x00;
00103         _timer.attach_us(this, &OneWire::_resumeinst, 1); // MAKE TIMING CONFIGURABLE
00104     }else{
00105         _instruction+= 1;
00106         _instn-= 1;
00107         _timer.attach_us(this, &OneWire::_nextinst, 1); // MAKE TIMING CONFIGURABLE
00108     }
00109 }
00110 
00111 // depricated, use at own risk
00112 void OneWire::repeatInstruction(){
00113     execute = (*_instruction).network;
00114     _inststate = 0x10;
00115     // send reset pulse
00116     readhandle = &OneWire::_presencedetect;
00117     op_reset();
00118 }
00119 
00120 void OneWire::abort(OneWire_Error err){
00121     _timer.detach();
00122     error = err;
00123     osSignalSet(_caller, 1);
00124 }
00125 
00126 // Public IO methods
00127 
00128 void OneWire::op_send1(){
00129     _microinstn = 2;
00130     _microinstc = 0;
00131     _nextmicroinst();
00132 }
00133 
00134 void OneWire::op_send0(){
00135     _microinstn = 2;
00136     _microinstc = 2;
00137     _nextmicroinst();
00138 }
00139 
00140 void OneWire::op_read(){
00141     _microinstn = 3;
00142     _microinstc = 4;
00143     _nextmicroinst();
00144 }
00145 
00146 void OneWire::op_reset(){
00147     _microinstn = 3;
00148     _microinstc = 7;
00149     _nextmicroinst();
00150 }