Пример #1
0
// 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;
}
Пример #2
0
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);
}