orgua / OneWireHub

OneWire slave device emulator
GNU General Public License v3.0
343 stars 86 forks source link

DS2413 device communication protocol not implemented correctly #79

Open thomasesr opened 5 years ago

thomasesr commented 5 years ago

Ack Success (0xAA) and Ack Failure(0xFF) Bytes are not implemented correctly on the DS2413 emulated device. The proper protocol should be Master: Reset Slave: Presence Pulse Master: Select ROM Master: 0x5A - Access Write Master: 0xFE - Turn on Latch A Master: 0x01 - Inverse of previous Byte for integrity check Slave: 0xAA - if Success 0xFF - if Failure slave: 0x3C - Access Read byte with PIO and Latch states Master: Reset pulse

orgua commented 4 years ago

Yeah, you could be right! Also there seems to be an endless loop for more latching after that. Don't know how i could miss that! Will look into it

lindenaar commented 4 years ago

I fixed this in my local install in this way, in src/DS2413.cpp I replaced

void DS2413::duty(OneWireHub * const hub)
{
    uint8_t cmd, data, check;

    if (hub->recv(&cmd)) return;

    switch (cmd)
    {
        case 0x5A:      // PIO ACCESS WRITE

            if (hub->recv(&data)) return;
            data = ~data; // Write inverse

            if (hub->send(&data)) return; // send inverted form for safety
            setPinLatch(0, (data & static_cast<uint8_t>(0x01)) != 0);// A
            setPinLatch(1, (data & static_cast<uint8_t>(0x02)) != 0);// B

            break;

        case 0xF5:      // PIO ACCESS READ

            data = 0;

with

void DS2413::duty(OneWireHub * const hub)
{
    uint8_t cmd, data, check;

    if (hub->recv(&cmd)) return;

    switch (cmd)
    {
        case 0x5A:      // PIO ACCESS WRITE

            if (hub->recv(&data)) return;
            data = ~data; // Write inverse

            if (hub->recv(&check)) return;
            if (data == check) {
                    setPinLatch(0, (data & static_cast<uint8_t>(0x01)) != 0);// A
                    setPinLatch(1, (data & static_cast<uint8_t>(0x02)) != 0);// B
                    hub->send(0xAA);
                    goto sendstatus;
            } else {
                    hub->send(0xFF);
            }

            break;

        case 0xF5:      // PIO ACCESS READ
sendstatus:
            data = 0;

Which seems in line with the datasheet and stops my Raspberry Pi giving read errors on the device.

Koxx3 commented 3 years ago

I confirm ;)