Implementation of 1-Wire with added Alarm Search Functionality
Dependents: Max32630_One_Wire_Interface
Diff: Masters/DS2480B/DS2480B.cpp
- Revision:
- 109:5c9180b4be25
- Parent:
- 104:3f48daed532b
- Child:
- 112:82eb520a644b
diff -r 01aa7b13a5f9 -r 5c9180b4be25 Masters/DS2480B/DS2480B.cpp --- a/Masters/DS2480B/DS2480B.cpp Thu Aug 04 20:20:32 2016 +0000 +++ b/Masters/DS2480B/DS2480B.cpp Fri Aug 05 15:06:47 2016 -0500 @@ -35,9 +35,6 @@ #include "Timer.h" #include "wait_api.h" -#define WRITE_FUNCTION 0 -#define READ_FUNCTION 1 - // Mode Commands #define MODE_DATA 0xE1 #define MODE_COMMAND 0xE3 @@ -165,80 +162,54 @@ #define PARMSET_PullUp3p0us 0x0C #define PARMSET_PullUp3p5us 0x0E -// Baud rate bits -#define PARMSET_9600 0x00 -#define PARMSET_19200 0x02 -#define PARMSET_57600 0x04 -#define PARMSET_115200 0x06 - // DS2480B program voltage available #define DS2480BPROG_MASK 0x20 -// mode bit flags -#define MODE_NORMAL 0x00 -#define MODE_OVERDRIVE 0x01 -#define MODE_STRONG5 0x02 -#define MODE_PROGRAM 0x04 -#define MODE_BREAK 0x08 - -#define MAX_BAUD PARMSET_115200 - using OneWire::DS2480B; using OneWire::OneWireMaster; -//********************************************************************* -DS2480B::DS2480B(mbed::Serial &p_serial) - :_p_serial(&p_serial), _serial_owner(false) -{ -} - +static uint32_t calculateBitTimeout(DS2480B::BaudRate baud) +{ + // Calculate bit timeout in microsecond. + // 10x the time needed to transmit or receive. + // Double for 115200 due to timer inaccuracies. + + uint32_t timeout = 1000000 * 10; + + switch (baud) + { + case DS2480B::Baud115200bps: + timeout = (timeout * 2) / 115200; + break; -//********************************************************************* -DS2480B::~DS2480B() -{ - if (_serial_owner) - { - delete _p_serial; + case DS2480B::Baud57600bps: + timeout /= 57600; + break; + + case DS2480B::Baud19200bps: + timeout /= 19200; + break; + + case DS2480B::Baud9600bps: + default: + timeout /= 9600; + break; } + + return timeout; } - -//********************************************************************* -void DS2480B::rx_callback(void) +DS2480B::DS2480B(PinName tx, PinName rx) + : serial(tx, rx) { - 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) - { - rx_buffer.wrap_error = true; - } + } - -//********************************************************************* OneWireMaster::CmdResult DS2480B::OWInitMaster() { - _p_serial->attach(this, &DS2480B::rx_callback, mbed::Serial::RxIrq); - - rx_buffer.w_idx = 0; - rx_buffer.r_idx = 0; - rx_buffer.rx_bytes_available = 0; - rx_buffer.wrap_error = false; - - _ULevel = OneWireMaster::NormalLevel; - _UBaud = Bps9600; - _UMode = MODSEL_COMMAND; - _USpeed = OneWireMaster::StandardSpeed; - - return DS2480B_Detect(); + return detect(); } - -//********************************************************************* OneWireMaster::CmdResult DS2480B::OWReset() { OneWireMaster::CmdResult result; @@ -251,23 +222,24 @@ if (result == OneWireMaster::Success) { // check for correct mode - if (_UMode != MODSEL_COMMAND) + if (mode != MODSEL_COMMAND) { - _UMode = MODSEL_COMMAND; + mode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // construct the command - sendpacket[sendlen++] = (uint8_t)(CMD_COMM | FUNCTSEL_RESET | _USpeed); + sendpacket[sendlen++] = (uint8_t)(CMD_COMM | FUNCTSEL_RESET | speed); - FlushCOM(); + // flush the buffers + flushCom(); // send the packet - result = WriteCOM(sendlen, sendpacket); + result = writeCom(sendlen, sendpacket); if (result == OneWireMaster::Success) { // read back the 1 byte response - result = ReadCOM(1, readbuffer); + result = readCom(1, readbuffer); if (result == OneWireMaster::Success) { // make sure this byte looks like a reset byte @@ -281,19 +253,11 @@ } } } - - if (result != OneWireMaster::Success) - { - // an error occured so re-sync with DS2480B - DS2480B_Detect(); - } } return result; } - -//********************************************************************* OneWireMaster::CmdResult DS2480B::OWTouchBitSetLevel(uint8_t & sendRecvBit, OWLevel afterLevel) { OneWireMaster::CmdResult result = OneWireMaster::OperationFailure; @@ -305,25 +269,25 @@ OWSetLevel(OneWireMaster::NormalLevel); // check for correct mode - if (_UMode != MODSEL_COMMAND) + if (mode != MODSEL_COMMAND) { - _UMode = MODSEL_COMMAND; + mode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // construct the command sendpacket[sendlen] = (sendRecvBit != 0) ? BITPOL_ONE : BITPOL_ZERO; - sendpacket[sendlen++] |= CMD_COMM | FUNCTSEL_BIT | _USpeed; + sendpacket[sendlen++] |= CMD_COMM | FUNCTSEL_BIT | speed; // flush the buffers - FlushCOM(); + flushCom(); // send the packet - result = WriteCOM(sendlen, sendpacket); + result = writeCom(sendlen, sendpacket); if (result == OneWireMaster::Success) { // read back the response - result = ReadCOM(1, readbuffer); + result = readCom(1, readbuffer); if (result == OneWireMaster::Success) { // interpret the response @@ -348,12 +312,7 @@ result = OneWireMaster::CommunicationWriteError; } - // an error occured so re-sync with DS2480B - if (result != OneWireMaster::Success) - { - DS2480B_Detect(); - } - else + if (result == OneWireMaster::Success) { result = OWSetLevel(afterLevel); } @@ -361,8 +320,6 @@ return result; } - -//********************************************************************* OneWireMaster::CmdResult DS2480B::OWWriteByteSetLevel(uint8_t sendByte, OWLevel afterLevel) { OneWireMaster::CmdResult result = OneWireMaster::OperationFailure; @@ -374,9 +331,9 @@ OWSetLevel(OneWireMaster::NormalLevel); // check for correct mode - if (_UMode != MODSEL_DATA) + if (mode != MODSEL_DATA) { - _UMode = MODSEL_DATA; + mode = MODSEL_DATA; sendpacket[sendlen++] = MODE_DATA; } @@ -390,14 +347,14 @@ } // flush the buffers - FlushCOM(); + flushCom(); // send the packet - result = WriteCOM(sendlen, sendpacket); + result = writeCom(sendlen, sendpacket); if (result == OneWireMaster::Success) { // read back the 1 byte response - result = ReadCOM(1, readbuffer); + result = readCom(1, readbuffer); if ((result == OneWireMaster::Success) && (readbuffer[0] == sendByte)) { result = OneWireMaster::Success; @@ -412,12 +369,7 @@ result = OneWireMaster::CommunicationWriteError; } - // an error occured so re-sync with DS2480B - if (result != OneWireMaster::Success) - { - DS2480B_Detect(); - } - else + if (result == OneWireMaster::Success) { result = OWSetLevel(afterLevel); } @@ -425,8 +377,6 @@ return result; } - -//********************************************************************* OneWireMaster::CmdResult DS2480B::OWReadByteSetLevel(uint8_t & recvByte, OWLevel afterLevel) { OneWireMaster::CmdResult result = OneWireMaster::OperationFailure; @@ -438,9 +388,9 @@ OWSetLevel(OneWireMaster::NormalLevel); // check for correct mode - if (_UMode != MODSEL_DATA) + if (mode != MODSEL_DATA) { - _UMode = MODSEL_DATA; + mode = MODSEL_DATA; sendpacket[sendlen++] = MODE_DATA; } @@ -448,14 +398,14 @@ sendpacket[sendlen++] = 0xFF; // flush the buffers - FlushCOM(); + flushCom(); // send the packet - result = WriteCOM(sendlen, sendpacket); + result = writeCom(sendlen, sendpacket); if (result == OneWireMaster::Success) { // read back the 1 byte response - result = ReadCOM(1, readbuffer); + result = readCom(1, readbuffer); if (result == OneWireMaster::Success) { recvByte = readbuffer[0]; @@ -472,11 +422,7 @@ } // an error occured so re-sync with DS2480B - if (result != OneWireMaster::Success) - { - DS2480B_Detect(); - } - else + if (result == OneWireMaster::Success) { result = OWSetLevel(afterLevel); } @@ -484,33 +430,31 @@ return result; } - -//********************************************************************* OneWireMaster::CmdResult DS2480B::OWSetSpeed(OWSpeed newSpeed) { - OneWireMaster::CmdResult result = OneWireMaster::OperationFailure; //uchar rt = FALSE; + OneWireMaster::CmdResult result = OneWireMaster::OperationFailure; uint8_t sendpacket[5]; uint8_t sendlen = 0; // check if change from current mode - if (((newSpeed == OneWireMaster::OverdriveSpeed) && (_USpeed != OneWireMaster::OverdriveSpeed)) || - ((newSpeed == OneWireMaster::StandardSpeed) && (_USpeed != OneWireMaster::StandardSpeed))) + if (((newSpeed == OneWireMaster::OverdriveSpeed) && (speed != SPEEDSEL_OD)) || + ((newSpeed == OneWireMaster::StandardSpeed) && (speed != SPEEDSEL_STD))) { if (newSpeed == OneWireMaster::OverdriveSpeed) { - result = DS2480B_ChangeBaud(Bps115200); + result = changeBaud(Baud115200bps); if (result == OneWireMaster::Success) { - _USpeed = SPEEDSEL_OD; + speed = SPEEDSEL_OD; } } else if (newSpeed == OneWireMaster::StandardSpeed) { - result = DS2480B_ChangeBaud(Bps9600); + result = changeBaud(Baud9600bps); if (result == OneWireMaster::Success) { - _USpeed = SPEEDSEL_STD; + speed = SPEEDSEL_STD; } } @@ -518,31 +462,23 @@ if (result == OneWireMaster::Success) { // check if correct mode - if (_UMode != MODSEL_COMMAND) + if (mode != MODSEL_COMMAND) { - _UMode = MODSEL_COMMAND; + mode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // proceed to set the DS2480 communication speed - sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_SEARCHOFF | _USpeed; + sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_SEARCHOFF | speed; // send the packet - result = WriteCOM(sendlen,sendpacket); - if (result != OneWireMaster::Success) - { - // lost communication with DS2480 then reset - DS2480B_Detect(); - } + result = writeCom(sendlen,sendpacket); } } - return result; } - -//********************************************************************* OneWireMaster::CmdResult DS2480B::OWSetLevel(OWLevel newLevel) { OneWireMaster::CmdResult result = OneWireMaster::Success; @@ -551,12 +487,12 @@ uint8_t sendlen = 0; // check if need to change level - if (newLevel != _ULevel) + if (newLevel != level) { // check for correct mode - if (_UMode != MODSEL_COMMAND) + if (mode != MODSEL_COMMAND) { - _UMode = MODSEL_COMMAND; + mode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } @@ -572,20 +508,21 @@ // stop pulse command sendpacket[sendlen++] = MODE_STOP_PULSE; - FlushCOM(); + // flush the buffers + flushCom(); // send the packet - result = WriteCOM(sendlen, sendpacket); + result = writeCom(sendlen, sendpacket); if (result == OneWireMaster::Success) { // read back the 1 byte response - result = ReadCOM(2, readbuffer); + result = readCom(2, readbuffer); if (result == OneWireMaster::Success) { // check response byte if (((readbuffer[0] & 0xE0) == 0xE0) && ((readbuffer[1] & 0xE0) == 0xE0)) { - _ULevel = OneWireMaster::NormalLevel; + level = OneWireMaster::NormalLevel; } else { @@ -602,20 +539,21 @@ // add the command to begin the pulse sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V; - FlushCOM(); + // flush the buffers + flushCom(); // send the packet - result = WriteCOM(sendlen, sendpacket); + result = writeCom(sendlen, sendpacket); if (result == OneWireMaster::Success) { // read back the 1 byte response from setting time limit - result = ReadCOM(1, readbuffer); + result = readCom(1, readbuffer); if (result == OneWireMaster::Success) { // check response byte if ((readbuffer[0] & 0x81) == 0) { - _ULevel = newLevel; + level = newLevel; } else { @@ -624,21 +562,12 @@ } } } - - // if lost communication with DS2480B then reset - if (result != OneWireMaster::Success) - { - DS2480B_Detect(); - } - } return result; } - -//********************************************************************* -OneWireMaster::CmdResult DS2480B::DS2480B_Detect(void) +OneWireMaster::CmdResult DS2480B::detect() { OneWireMaster::CmdResult result; @@ -646,24 +575,26 @@ uint8_t sendlen = 0; // reset modes - _UMode = MODSEL_COMMAND; - _UBaud = Bps9600; - _USpeed = SPEEDSEL_FLEX; + level = OneWireMaster::NormalLevel; + mode = MODSEL_COMMAND; + baud = Baud9600bps; + speed = SPEEDSEL_FLEX; // set the baud rate to 9600 - SetBaudCOM(_UBaud); + setComBaud(baud); // send a break to reset the DS2480B - BreakCOM(); + breakCom(); // delay to let line settle wait_ms(2); - FlushCOM(); + // flush the buffers + flushCom(); // send the timing byte sendpacket[0] = 0xC1; - result = WriteCOM(1, sendpacket); + result = writeCom(1, sendpacket); if (result == OneWireMaster::Success) { // delay to let line settle @@ -681,21 +612,22 @@ sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3); // also do 1 bit operation (to test 1-Wire block) - sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_BIT | _UBaud | BITPOL_ONE; + sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_BIT | baud | BITPOL_ONE; - FlushCOM(); + // flush the buffers + flushCom(); // send the packet - result = WriteCOM(sendlen, sendpacket); + result = writeCom(sendlen, sendpacket); if (result == OneWireMaster::Success) { // read back the response - result = ReadCOM(5, readbuffer); + result = readCom(5, readbuffer); if (result == OneWireMaster::Success) { // look at the baud rate and bit operation // to see if the response makes sense - if (((readbuffer[3] & 0xF1) == 0x00) && ((readbuffer[3] & 0x0E) == _UBaud) && ((readbuffer[4] & 0xF0) == 0x90) && ((readbuffer[4] & 0x0C) == _UBaud)) + if (((readbuffer[3] & 0xF1) == 0x00) && ((readbuffer[3] & 0x0E) == baud) && ((readbuffer[4] & 0xF0) == 0x90) && ((readbuffer[4] & 0x0C) == baud)) { result = OneWireMaster::Success; } @@ -710,9 +642,7 @@ return result; } - -//********************************************************************* -OneWireMaster::CmdResult DS2480B::DS2480B_ChangeBaud(Baud newBaud) +OneWireMaster::CmdResult DS2480B::changeBaud(BaudRate newBaud) { OneWireMaster::CmdResult result = OneWireMaster::Success; @@ -720,31 +650,31 @@ uint8_t sendlen = 0, sendlen2 = 0; //see if diffenent then current baud rate - if (_UBaud != newBaud) + if (baud != newBaud) { // build the command packet // check for correct mode - if (_UMode != MODSEL_COMMAND) + if (mode != MODSEL_COMMAND) { - _UMode = MODSEL_COMMAND; + mode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // build the command sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_BAUDRATE | newBaud; // flush the buffers - FlushCOM(); + flushCom(); // send the packet - result = WriteCOM(sendlen, sendpacket); + result = writeCom(sendlen, sendpacket); if (result == OneWireMaster::Success) { // make sure buffer is flushed wait_ms(5); // change our baud rate - SetBaudCOM(newBaud); - _UBaud = newBaud; + setComBaud(newBaud); + baud = newBaud; // wait for things to settle wait_ms(5); @@ -753,14 +683,14 @@ sendpacket2[sendlen2++] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3); // flush the buffers - FlushCOM(); + flushCom(); // send the packet - result = WriteCOM(sendlen2, sendpacket2); + result = writeCom(sendlen2, sendpacket2); if (result == OneWireMaster::Success) { // read back the 1 byte response - result = ReadCOM(1, readbuffer); + result = readCom(1, readbuffer); if (result == OneWireMaster::Success) { // verify correct baud @@ -789,237 +719,111 @@ } } - // if lost communication with DS2480B then reset - if (result != OneWireMaster::Success) + return result; +} + +OneWireMaster::CmdResult DS2480B::writeCom(size_t outlen, uint8_t *outbuf) +{ + OneWireMaster::CmdResult result = OneWireMaster::OperationFailure; + + mbed::Timer timer; + uint32_t timeout = calculateBitTimeout(baud) * outlen; + uint8_t idx = 0; + + timer.start(); + do { - DS2480B_Detect(); + while ((idx < outlen) && serial.writeable()) + { + serial.putc(outbuf[idx++]); + } + + } while ((idx < outlen) && (timer.read_us() < timeout)); + + if (idx == outlen) + { + result = OneWireMaster::Success; + } + else + { + result = OneWireMaster::TimeoutError; } return result; } - -//********************************************************************* -OneWireMaster::CmdResult DS2480B::WriteCOM(uint32_t outlen, uint8_t *outbuf) +OneWireMaster::CmdResult DS2480B::readCom(size_t inlen, uint8_t *inbuf) { - OneWireMaster::CmdResult result = OneWireMaster::OperationFailure; - - mbed::Timer t; - uint32_t t_val; - uint32_t timeout; - uint8_t idx = 0; + OneWireMaster::CmdResult result; + mbed::Timer timer; + uint32_t num_bytes_read = 0; + uint32_t timeout = calculateBitTimeout(baud) * inlen; - //calculate timeout, the time needed to tx 1 byte - //double for 115200 due to timer object inaccuracies - switch (_UBaud) - { - case Bps115200: - timeout = ((1000000 / 115200) * 20); - break; - - case Bps57600: - timeout = ((1000000 / 57600) * 10); - break; - - case Bps19200: - timeout = ((1000000 / 19200) * 10); - break; - - case Bps9600: - default: - timeout = ((1000000 / 9600) * 10); - break; - } - - t.start(); + timer.start(); do { - t.reset(); - do + while ((num_bytes_read < inlen) && serial.readable()) { - t_val = t.read_us(); - } while (!_p_serial->writeable() && (t_val < timeout)); - - if (t_val < timeout) - { - _p_serial->putc(outbuf[idx++]); - result = OneWireMaster::Success; - } - else - { - result = OneWireMaster::TimeoutError; + inbuf[num_bytes_read++] = serial.getc(); } - } while ((idx < outlen) && (result == OneWireMaster::Success)); - - return result; -} - - -//********************************************************************* -OneWireMaster::CmdResult DS2480B::ReadCOM(uint32_t inlen, uint8_t *inbuf) -{ - OneWireMaster::CmdResult result; - mbed::Timer t; - uint32_t num_bytes_read = 0; - uint32_t timeout; - uint32_t micro_seconds; + } while ((num_bytes_read < inlen) && (timer.read_us() < timeout)); + timer.stop(); - //calculate timeout, 10x the time needed to recieve inlen bytes - //double for 115200 due to timer object inaccuracies - switch (_UBaud) + if (num_bytes_read == inlen) { - case Bps115200: - timeout = ((1000000 / 115200) * 200) * inlen; - break; - - case Bps57600: - timeout = ((1000000 / 57600) * 100) * inlen; - break; - - case Bps19200: - timeout = ((1000000 / 19200) * 100) * inlen; - break; - - case Bps9600: - default: - timeout = ((1000000 / 9600) * 100) * inlen; - break; - } - - 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; + result = OneWireMaster::Success; } else { - t.start(); - t.reset(); - do - { - do - { - micro_seconds = t.read_us(); - } while (!rx_buffer.rx_bytes_available && (micro_seconds < timeout)); - - if (rx_buffer.rx_bytes_available) - { - 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 - { - //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; - } + result = OneWireMaster::TimeoutError; } return result; } - -//********************************************************************* -void DS2480B::BreakCOM(void) +void DS2480B::breakCom() { - while (!_p_serial->writeable()); - //for some reason send_break wouldn't work unless first sending char - _p_serial->putc(0); - _p_serial->send_break(); + // Switch to lower baud rate to ensure break is longer than 2 ms. + serial.baud(4800); + serial.send_break(); + setComBaud(baud); } - -void DS2480B::FlushCOM(void) +void DS2480B::flushCom() { - //reset soft rx_buffer - rx_buffer.w_idx = 0; - rx_buffer.r_idx = 0; - rx_buffer.wrap_error = false; - - //make sure hardware rx buffer is empty - while (_p_serial->readable()) + // Clear receive buffer. + while (serial.readable()) { - _p_serial->getc(); + 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 ); + /* No apparent way to clear transmit buffer. + * From the example in AN192 (http://pdfserv.maximintegrated.com/en/an/AN192.pdf), + * the data shouldn't be sent, just aborted and the buffer cleaned out. + * Below is what was used in AN192 example code using windows drivers: + * PurgeComm(ComID, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); + */ } - -//********************************************************************* -void DS2480B::SetBaudCOM(uint8_t new_baud) +void DS2480B::setComBaud(BaudRate new_baud) { switch (new_baud) { - case Bps115200: - _p_serial->baud(115200); + case Baud115200bps: + serial.baud(115200); break; - case Bps57600: - _p_serial->baud(57600); + case Baud57600bps: + serial.baud(57600); break; - case Bps19200: - _p_serial->baud(19200); + case Baud19200bps: + serial.baud(19200); break; - case Bps9600: + case Baud9600bps: default: - _p_serial->baud(9600); + serial.baud(9600); break; } } - - -//********************************************************************* -int32_t DS2480B::bitacc(uint32_t op, uint32_t state, uint32_t loc, uint8_t *buf) -{ - int nbyt, nbit; - - nbyt = (loc / 8); - nbit = loc - (nbyt * 8); - - if (op == WRITE_FUNCTION) - { - if (state) - { - buf[nbyt] |= (0x01 << nbit); - } - else - { - buf[nbyt] &= ~(0x01 << nbit); - } - - return 1; - } - else - { - return ((buf[nbyt] >> nbit) & 0x01); - } -}