// uint16_t onewire_crc16(const uint8_t* input, uint16_t len, uint16_t crc); // Lua: r = ow.crc16( buf, crc ) static int ow_crc16( lua_State *L ) { size_t datalen; const uint8_t *pdata = luaL_checklstring( L, 1, &datalen ); if(datalen > 65535) return luaL_error( L, "wrong arg range" ); int crc = 0; if(lua_isnumber(L, 2)) crc = lua_tointeger(L, 2); if(crc > 65535) return luaL_error( L, "wrong arg range" ); lua_pushinteger( L, onewire_crc16(pdata, (uint16_t)datalen, (uint16_t)crc) ); return 1; }
void owctr_update_counter(void *arg, int bank) { struct owctr_softc *sc = arg; u_int32_t counter; u_int16_t crc; u_int8_t *buf; rw_enter_write(&sc->sc_lock); onewire_lock(sc->sc_onewire, 0); if (onewire_reset(sc->sc_onewire) != 0) goto done; buf = malloc(DS2423_COUNTER_BUFSZ, M_DEVBUF, M_NOWAIT); if (buf == NULL) { printf("%s: malloc() failed\n", sc->sc_dev.dv_xname); goto done; } onewire_matchrom(sc->sc_onewire, sc->sc_rom); buf[0] = DSCTR_CMD_READ_MEMCOUNTER; buf[1] = bank; buf[2] = bank >> 8; onewire_write_byte(sc->sc_onewire, buf[0]); onewire_write_byte(sc->sc_onewire, buf[1]); onewire_write_byte(sc->sc_onewire, buf[2]); onewire_read_block(sc->sc_onewire, &buf[3], DS2423_COUNTER_BUFSZ-3); crc = onewire_crc16(buf, DS2423_COUNTER_BUFSZ-2); crc ^= buf[DS2423_COUNTER_BUF_CRC] | (buf[DS2423_COUNTER_BUF_CRC+1] << 8); if ( crc != 0xffff) { printf("%s: invalid CRC\n", sc->sc_dev.dv_xname); if (bank == DS2423_COUNTER_BANK_A) { sc->sc_counterA.value = 0; sc->sc_counterA.status = SENSOR_S_UNKNOWN; sc->sc_counterA.flags |= SENSOR_FUNKNOWN; } else { sc->sc_counterB.value = 0; sc->sc_counterB.status = SENSOR_S_UNKNOWN; sc->sc_counterB.flags |= SENSOR_FUNKNOWN; } } else { counter = buf[DS2423_COUNTER_BUF_COUNTER] | (buf[DS2423_COUNTER_BUF_COUNTER+1] << 8) | (buf[DS2423_COUNTER_BUF_COUNTER+2] << 16) | (buf[DS2423_COUNTER_BUF_COUNTER+3] << 24); if (bank == DS2423_COUNTER_BANK_A) { sc->sc_counterA.value = counter; sc->sc_counterA.status = SENSOR_S_UNSPEC; sc->sc_counterA.flags &= ~SENSOR_FUNKNOWN; } else { sc->sc_counterB.value = counter; sc->sc_counterB.status = SENSOR_S_UNSPEC; sc->sc_counterB.flags &= ~SENSOR_FUNKNOWN; } } onewire_reset(sc->sc_onewire); free(buf, M_DEVBUF); done: onewire_unlock(sc->sc_onewire); rw_exit_write(&sc->sc_lock); }