1-Wire® library for mbed. Complete 1-Wire library that supports our silicon masters along with a bit-bang master on the MAX32600MBED platform with one common interface for mbed. Slave support has also been included and more slaves will be added as time permits.
Dependents: MAXREFDES131_Qt_Demo MAX32630FTHR_iButton_uSD_Logger MAX32630FTHR_DS18B20_uSD_Logger MAXREFDES130_131_Demo ... more
Superseded by MaximInterface.
Diff: OneWire_Masters/DS2480B/ds2480b.cpp
- Revision:
- 65:a28ac52ca127
- Parent:
- 63:422be898443a
- Child:
- 67:76776130aec9
diff -r 08384e63ee40 -r a28ac52ca127 OneWire_Masters/DS2480B/ds2480b.cpp --- a/OneWire_Masters/DS2480B/ds2480b.cpp Tue Apr 19 21:56:03 2016 +0000 +++ b/OneWire_Masters/DS2480B/ds2480b.cpp Wed Apr 20 21:47:42 2016 +0000 @@ -210,7 +210,11 @@ //********************************************************************* void Ds2480b::rx_callback(void) { - rx_buffer.buff[rx_buffer.w_idx++] = _p_serial->getc(); + while(_p_serial->readable()) + { + rx_buffer.buff[rx_buffer.w_idx++] = _p_serial->getc(); + rx_buffer.rx_bytes_available++; + } if(rx_buffer.w_idx == rx_buffer.r_idx) { @@ -233,6 +237,7 @@ rx_buffer.w_idx = 0; rx_buffer.r_idx = 0; + rx_buffer.rx_bytes_available = 0; rx_buffer.wrap_error = false; _ULevel = OneWireMaster::LEVEL_NORMAL; @@ -706,72 +711,88 @@ //********************************************************************* OneWireMaster::CmdResult Ds2480b::DS2480B_ChangeBaud(DS2480B_BPS newbaud) { - OneWireMaster::CmdResult result = OneWireMaster::OperationFailure; - - uint8_t rt=0; - uint8_t readbuffer[5],sendpacket[5],sendpacket2[5]; - uint8_t sendlen=0,sendlen2=0; + OneWireMaster::CmdResult result = OneWireMaster::Success; + + uint8_t readbuffer[5],sendpacket[5],sendpacket2[5]; + uint8_t sendlen=0,sendlen2=0; + + //see if diffenent then current baud rate + if(_UBaud != newbaud) + { + // build the command packet + // check for correct mode + if(_UMode != MODSEL_COMMAND) + { + _UMode = MODSEL_COMMAND; + sendpacket[sendlen++] = MODE_COMMAND; + } + // build the command + sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_BAUDRATE | newbaud; - // see if diffenent then current baud rate - if (_UBaud == newbaud) - { - //return _UBaud; - } - else - { - // build the command packet - // check for correct mode - if (_UMode != MODSEL_COMMAND) - { - _UMode = MODSEL_COMMAND; - sendpacket[sendlen++] = MODE_COMMAND; - } - // build the command - sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_BAUDRATE | newbaud; + // flush the buffers + FlushCOM(); + + // send the packet + result = WriteCOM(sendlen,sendpacket); + if(result == OneWireMaster::Success) + { + // make sure buffer is flushed + wait_ms(5); - // flush the buffers - FlushCOM(); + // change our baud rate + SetBaudCOM(newbaud); + _UBaud = newbaud; + + // wait for things to settle + wait_ms(5); + + // build a command packet to read back baud rate + sendpacket2[sendlen2++] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3); + + // flush the buffers + FlushCOM(); - // send the packet - if (!WriteCOM(sendlen,sendpacket)) - rt = 0; - else - { - // make sure buffer is flushed - wait_ms(5); - - // change our baud rate - SetBaudCOM(newbaud); - _UBaud = newbaud; - - // wait for things to settle - wait_ms(5); - - // build a command packet to read back baud rate - sendpacket2[sendlen2++] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3); - - // flush the buffers - FlushCOM(); - - // send the packet - if(WriteCOM(sendlen2,sendpacket2)) - { - // read back the 1 byte response - if (ReadCOM(1,readbuffer) == 1) + // send the packet + result = WriteCOM(sendlen2,sendpacket2); + if(result == OneWireMaster::Success) { - // verify correct baud - if (((readbuffer[0] & 0x0E) == (sendpacket[sendlen-1] & 0x0E))) - rt = 1; + // read back the 1 byte response + result = ReadCOM(1,readbuffer); + if(result == OneWireMaster::Success) + { + // verify correct baud + if((readbuffer[0] & 0x0E) == (sendpacket[sendlen-1] & 0x0E)) + { + result = OneWireMaster::Success; + } + else + { + result = OneWireMaster::OperationFailure; + } + } + else + { + result = OneWireMaster::CommunicationReadError; + } } - } - } - } - - // if lost communication with DS2480B then reset - if (rt != 1) - DS2480B_Detect(); - - return result; + else + { + result = OneWireMaster::CommunicationWriteError; + } + } + else + { + result = OneWireMaster::CommunicationWriteError; + } + } + + // if lost communication with DS2480B then reset + if(result != OneWireMaster::Success) + { + DS2480B_Detect(); + } + + return result; } @@ -786,10 +807,11 @@ uint8_t idx = 0; //calculate timeout, the time needed to tx 1 byte + //double for 115200 due to timer object inaccuracies switch(_UBaud) { case BPS_115200: - timeout = ((1000000/115200)*10); + timeout = ((1000000/115200)*20); break; case BPS_57600: @@ -836,64 +858,81 @@ OneWireMaster::CmdResult Ds2480b::ReadCOM(uint32_t inlen, uint8_t *inbuf) { OneWireMaster::CmdResult result; + Timer t; uint32_t num_bytes_read= 0; uint32_t timeout; + uint32_t micro_seconds; - //calculate timeout, 5x the time needed to recieve inlen bytes + //calculate timeout, 10x the time needed to recieve inlen bytes + //double for 115200 due to timer object inaccuracies switch(_UBaud) { case BPS_115200: - timeout = ((1000000/115200)*50)*inlen; + timeout = ((1000000/115200)*200)*inlen; break; case BPS_57600: - timeout = ((1000000/57600)*50)*inlen; + timeout = ((1000000/57600)*100)*inlen; break; case BPS_19200: - timeout = ((1000000/19200)*50)*inlen; + timeout = ((1000000/19200)*100)*inlen; break; case BPS_9600: default: - timeout = ((1000000/9600)*50)*inlen; + timeout = ((1000000/9600)*100)*inlen; break; } - wait_us(timeout); - if(rx_buffer.wrap_error) { //reset rx buffer, error, and return failure rx_buffer.w_idx = 0; rx_buffer.r_idx = 0; + rx_buffer.rx_bytes_available = 0; rx_buffer.wrap_error = false; result = OneWireMaster::OperationFailure; } else { - if(rx_buffer.w_idx != rx_buffer.r_idx) + t.start(); + t.reset(); + do { do { - inbuf[num_bytes_read++] = rx_buffer.buff[rx_buffer.r_idx++]; + micro_seconds = t.read_us(); } - while((num_bytes_read < inlen) && (rx_buffer.w_idx != rx_buffer.r_idx)); + while(!rx_buffer.rx_bytes_available && (micro_seconds < timeout)); - if(num_bytes_read == inlen) + if(rx_buffer.rx_bytes_available) { - result = OneWireMaster::Success; - } - else - { - result = OneWireMaster::CommunicationReadError; - } + inbuf[num_bytes_read++] = rx_buffer.buff[rx_buffer.r_idx++]; + rx_buffer.rx_bytes_available--; + } + } + while((num_bytes_read < inlen) && (micro_seconds < timeout) && !rx_buffer.wrap_error); + t.stop(); + + if(num_bytes_read == inlen) + { + result = OneWireMaster::Success; + } + else if(micro_seconds > timeout) + { + result = OneWireMaster::TimeoutError; } else { - //buffer empty - result = OneWireMaster::OperationFailure; + //reset rx buffer, error, and return failure + rx_buffer.w_idx = 0; + rx_buffer.r_idx = 0; + rx_buffer.rx_bytes_available = 0; + rx_buffer.wrap_error = false; + + result = OneWireMaster::CommunicationReadError; } } @@ -923,6 +962,14 @@ { _p_serial->getc(); } + + /*Not sure how to flush tx buffer without sending data out on the bus. + from the example in AN192, the data shouldn't be sent, just aborted + and the buffer cleaned out, http://pdfserv.maximintegrated.com/en/an/AN192.pdf + Below is what was used in AN192 example code using windows drivers + */ + + //PurgeComm(ComID, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); } @@ -954,20 +1001,26 @@ //********************************************************************* int32_t Ds2480b::bitacc(uint32_t op, uint32_t state, uint32_t loc, uint8_t *buf) { - int nbyt,nbit; + int nbyt,nbit; - nbyt = (loc / 8); - nbit = loc - (nbyt * 8); + nbyt = (loc / 8); + nbit = loc - (nbyt * 8); - if (op == WRITE_FUNCTION) - { - if (state) - buf[nbyt] |= (0x01 << nbit); - else - buf[nbyt] &= ~(0x01 << nbit); + if(op == WRITE_FUNCTION) + { + if (state) + { + buf[nbyt] |= (0x01 << nbit); + } + else + { + buf[nbyt] &= ~(0x01 << nbit); + } - return 1; - } - else - return ((buf[nbyt] >> nbit) & 0x01); + return 1; + } + else + { + return ((buf[nbyt] >> nbit) & 0x01); + } } \ No newline at end of file