static int ds18b20_read_temp(float* temp, int mask) { int res = 0; //start conversion PIOB_ODR = mask; //disable output ds18b20_reset(mask); w1_write_byte(mask, DS18B20_SKIP_ROM); w1_write_byte(mask, DS18B20_CONVERT_T); res = usleep(750000); //reading ds18b20_reset(mask); w1_write_byte(mask, DS18B20_SKIP_ROM); w1_write_byte(mask, DS18B20_READ_SCRATCHPAD); *temp = (w1_read_byte(mask) | (w1_read_byte(mask) << 8)); (*temp) /= 16; //skip reading the rest of scratchpad bytes PIOB_OER = mask; //enable output PIOB_CODR = mask; //level low return res; }
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_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; }
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; }