int32_t w1_read_temp(struct w1_dev *dev, unsigned long flags) { static uint8_t scratchpad[8]; int class = w1_class(dev); int32_t res; int16_t cval; int i; /* The caller is expected to have checked the class. but still... */ switch(class) { case 0x10: case 0x28: case 0x42: break; /* Supported, at least for temperature input */ default: return 1l<<31; /* very negative */ } /* If so asked, jump over start-conversion and only collect result */ if (flags & W1_FLAG_COLLECT) goto collect; w1_match_rom(dev); w1_write_byte(dev->bus, W1_CMDT_CONVERT); /* If so asked, don't wait for the conversion to be over */ if (flags & W1_FLAG_NOWAIT) return 0; while(bathos_w1_ops.read_bit(dev->bus) == 0) ; collect: w1_match_rom(dev); w1_write_byte(dev->bus, W1_CMDT_R_SPAD); for (i = 0; i < sizeof(scratchpad); i++) scratchpad[i] = w1_read_byte(dev->bus); res = 0; cval = scratchpad[1] << 8 | scratchpad[0]; switch(class) { case 0x10: /* 18S20: two bytes plus "count remain" value */ res = (int32_t)cval << 15; /* 1 decimal points */ res -= 0x4000; /* - 0.25 degrees */ res |= scratchpad[6] << 12; /* 1/16th of degree each */ break; case 0x28: case 0x42: /* 18B20 and DS28EA00: only the two bytes */ res = (int32_t)cval << 12; /* 4 decimal points */ break; } return res; }
int w1_write_eeprom(struct w1_dev *dev, int offset, const uint8_t *buffer, int blen) { int i; int read_data; w1_match_rom(dev); w1_write_byte(dev->bus, W1_CMDR_W_SPAD); /* write of target addr */ w1_write_byte(dev->bus, LSB_ADDR(offset)); w1_write_byte(dev->bus, MSB_ADDR(offset)); /* write to scratchpad */ for (i = 0; i < blen; i++) w1_write_byte(dev->bus, buffer[i]); for (; i < 32; i++) w1_write_byte(dev->bus, '\0'); /*padding */ w1_match_rom(dev); w1_write_byte(dev->bus, W1_CMDR_C_SPAD); /* copy to memory */ w1_write_byte(dev->bus, LSB_ADDR(offset)); w1_write_byte(dev->bus, MSB_ADDR(offset)); /* ending offset/data status byte */ w1_write_byte(dev->bus, 0x1f); usleep(10000); /* check final status byte */ read_data = w1_read_byte(dev->bus); if (read_data != 0xaa) return -1; return 0; }
int w1_read_eeprom(struct w1_dev *dev, int offset, uint8_t *buffer, int blen) { int i; w1_match_rom(dev); w1_write_byte(dev->bus, W1_CMDR_R_MEMORY); /* read of target addr */ w1_write_byte(dev->bus, LSB_ADDR(offset)); w1_write_byte(dev->bus, MSB_ADDR(offset)); for (i = 0; i < blen; i++) buffer[i] = w1_read_byte(dev->bus); return 0; }
static int handle_1w(const char *line) { if (strncmp(line, "read", 4) == 0 && line[4] != '_') { int n = 1; if (line[4] == ' ') n = undec(line+5); if (n < 1) { printf("\nERROR:arguments\n"); return 0; } printf("1WIRE DATA"); while (n--) { int r = w1_read(w1); if (r < 0) { printf("\nERROR:%i\n", r); return 0; } printf(" %02x", r); } printf("\nOK\n"); } else if (strncmp(line, "write ", 6) == 0) { line += 5; int written = 0; while (line[0] == ' ') { int data = unhex8(line+1); if (data < 0) break; int r = w1_write(w1, data); if (r < 0) { printf("ERROR:%i\n", r); return 0; } line += 3; written++; } printf("OK:%i\n", written); } else if (strncmp(line, "read_rom", 8) == 0) { w1_addr_t addr; int r = w1_read_rom(w1, &addr); if (r < 0) { printf("ERROR:%i\n", r); return 0; } u8 *b = addr.bytes; printf("OK:%02x%02x%02x%02x%02x%02x%02x%02x\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); } else if (strncmp(line, "match_rom ", 10) == 0) { w1_addr_t addr; w1_unpack(&addr, line+10); int r = w1_match_rom(w1, addr); if (r < 0) { printf("ERROR:%i\n", r); return 0; } printf("OK\n"); } else if (strncmp(line, "skip_rom", 8) == 0) { int r = w1_skip_rom(w1); if (r < 0) { printf("ERROR:%i\n", r); return 0; } printf("OK\n"); } else if (strcmp(line, "scan") == 0) { w1_addr_t addrs[5]; int n = w1_scan(w1, addrs, 5); if (n <= 0) { printf("ERROR:%i\n", n); return 0; } printf("OK:%i 1-wire devices:\n", n); int i; for (i=0; i<n; i++) { u8 *b = addrs[i].bytes; printf("1WIRE DEV %02x%02x%02x%02x%02x%02x%02x%02x\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); } } else if (strcmp(line, "scan_read") == 0) { w1_addr_t addrs[5]; int n = w1_scan(w1, addrs, 5); if (n <= 0) { printf("ERROR:%i\n", n); return 0; } printf("OK:%i 1-wire devices:\n", n); int i; for (i=0; i<n; i++) { u8 *b = addrs[i].bytes; if (addrs[i].bytes[0] == FAMILY_DS18B20) { s16 temp; u8 tmp[9]; w1_match_rom(w1, addrs[i]); w1_write(w1, 0x44); /* conversion */ mdelay(750); /* 750ms conversion time */ w1_match_rom(w1, addrs[i]); w1_write(w1, 0xbe); /* read */ int j; for (j=0; j<9; j++) tmp[j] = w1_read(w1); if (crc8r(tmp, 9) != 0) continue; temp = tmp[1]<<8 | tmp[0]; printf("1WIRE DS18B20 %02x%02x%02x%02x%02x%02x%02x%02x ", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); if (temp < 0) { printf("-"); temp = -temp; } printf("%i.%02i\n", temp>>4, 100*(temp&0xf)/16); } else {