static void owtemp_update(void *arg) { struct owtemp_softc *sc = arg; u_int8_t data[9]; onewire_lock(sc->sc_onewire); if (onewire_reset(sc->sc_onewire) != 0) goto done; onewire_matchrom(sc->sc_onewire, sc->sc_rom); /* * Start temperature conversion. The conversion takes up to 750ms. * After sending the command, the data line must be held high for * at least 750ms to provide power during the conversion process. * As such, no other activity may take place on the 1-Wire bus for * at least this period. */ onewire_write_byte(sc->sc_onewire, DS_CMD_CONVERT); tsleep(sc, PRIBIO, "owtemp", hz); if (onewire_reset(sc->sc_onewire) != 0) goto done; onewire_matchrom(sc->sc_onewire, sc->sc_rom); /* * The result of the temperature measurement is placed in the * first two bytes of the scratchpad. */ onewire_write_byte(sc->sc_onewire, DS_CMD_READ_SCRATCHPAD); onewire_read_block(sc->sc_onewire, data, 9); #if 0 if (onewire_crc(data, 8) == data[8]) { sc->sc_sensor.value = 273150000 + (int)((u_int16_t)data[1] << 8 | data[0]) * 500000; } #endif sc->sc_sensor.value_cur = sc->sc_owtemp_decode(data); sc->sc_sensor.state = ENVSYS_SVALID; done: onewire_unlock(sc->sc_onewire); }
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); }