static int ow_send_command(device_t ndev, device_t pdev, struct ow_cmd *cmd) { int present, i, bit, tries; device_t lldev; struct ow_timing *t; lldev = device_get_parent(ndev); /* * Retry the reset a couple of times before giving up. */ tries = 4; do { OWLL_RESET_AND_PRESENCE(lldev, &timing_regular, &present); if (present == 1) device_printf(ndev, "Reset said no device on bus?.\n"); } while (present == 1 && tries-- > 0); if (present == 1) { device_printf(ndev, "Reset said the device wasn't there.\n"); return ENOENT; /* No devices acked the RESET */ } if (present == -1) { device_printf(ndev, "Reset discovered bus wired wrong.\n"); return ENOENT; } for (i = 0; i < cmd->rom_len; i++) ow_send_byte(lldev, &timing_regular, cmd->rom_cmd[i]); for (i = 0; i < cmd->rom_read_len; i++) ow_read_byte(lldev, &timing_regular, cmd->rom_read + i); if (cmd->xpt_len) { /* * Per AN937, the reset pulse and ROM level are always * done with the regular timings. Certain ROM commands * put the device into overdrive mode for the remainder * of the data transfer, which is why we have to pass the * timings here. Commands that need to be handled like this * are expected to be flagged by the client. */ t = (cmd->flags & OW_FLAG_OVERDRIVE) ? &timing_overdrive : &timing_regular; for (i = 0; i < cmd->xpt_len; i++) ow_send_byte(lldev, t, cmd->xpt_cmd[i]); if (cmd->flags & OW_FLAG_READ_BIT) { memset(cmd->xpt_read, 0, (cmd->xpt_read_len + 7) / 8); for (i = 0; i < cmd->xpt_read_len; i++) { OWLL_READ_DATA(lldev, t, &bit); cmd->xpt_read[i / 8] |= bit << (i % 8); } } else { for (i = 0; i < cmd->xpt_read_len; i++) ow_read_byte(lldev, t, cmd->xpt_read + i); } } return 0; }
int8_t ow_eeprom_read(ow_rom_code_t *rom, void *data) { #if ONEWIRE_BUSCOUNT > 1 uint8_t busmask = 1 << (ONEWIRE_STARTPIN); // FIXME: currently only on 1st bus #else uint8_t busmask = ONEWIRE_BUSMASK; #endif int8_t ret; if (rom == NULL) ret = ow_skip_rom(); else { /* check for known family code */ if (!(rom->family == OW_FAMILY_DS2502E48)) return -2; ret = ow_match_rom(rom); } if (ret < 0) return ret; /* transmit command byte */ ow_write_byte(busmask, OW_FUNC_READ_MEMORY); /* transmit address (mac address starts at offset 5 */ ow_write_byte(busmask, 5); ow_write_byte(busmask, 0); /* read back crc sum of the command */ uint8_t crc = ow_read_byte(busmask); /* check crc */ uint8_t crc2 = 0; crc2 = _crc_ibutton_update(crc2, OW_FUNC_READ_MEMORY); crc2 = _crc_ibutton_update(crc2, 5); crc2 = _crc_ibutton_update(crc2, 0); if (crc != crc2) return -2; uint8_t *p = (uint8_t *)data+5; /* read 6 byte of data */ for (uint8_t i = 0; i < 6; i++) *p-- = ow_read_byte(busmask); return 0; }
void ds18b20_read_scratch(struct ds18b20 *dev) { unsigned char i; //unsigned char data[9]; //ow_init(); ow_reset(); //ow_write_byte(0xCC); ow_write_byte(0x55); for(i=0;i<8;i++){ ow_write_byte(dev->romcode[i]); } ow_write_byte(0xBE); dev->scratchpad[0] = ow_read_byte(); dev->scratchpad[1] = ow_read_byte(); dev->scratchpad[2] = ow_read_byte(); dev->scratchpad[3] = ow_read_byte(); dev->scratchpad[4] = ow_read_byte(); dev->scratchpad[5] = ow_read_byte(); dev->scratchpad[6] = ow_read_byte(); dev->scratchpad[7] = ow_read_byte(); dev->scratchpad[8] = ow_read_byte(); //printf("data 1 = %x\r\n", dev->scratchpad[0]); //printf("data 2 = %x\r\n", dev->scratchpad[1]); //printf("data 3 = %x\r\n", dev->scratchpad[2]); //printf("data 4 = %x\r\n", dev->scratchpad[3]); //printf("data 5 = %x\r\n", dev->scratchpad[4]); //printf("data 6 = %x\r\n", dev->scratchpad[5]); //printf("data 7 = %x\r\n", dev->scratchpad[6]); //printf("data 8 = %x\r\n", dev->scratchpad[7]); //printf("data 9 = %x\r\n", dev->scratchpad[8]); dev->config = dev->scratchpad[4]; dev->crc = dev->scratchpad[8]; //printf("TempDS = %d\r\n", ((dev->scratchpad[1] << 8) | (dev->scratchpad[0] >> 4))); dev->tempi = (((0x07 & dev->scratchpad[1]) << 8) | dev->scratchpad[0]) >> 4; if(dev->scratchpad[1] & 0xF0) dev->tempi = -dev->tempi; dev->tempd = dev->scratchpad[0] & 0x0F; if( dev->tempd & 0x08 ){ dev->tempd = 5; }else if( dev->tempd & 0x04 ){ dev->tempd = 25; }else if( dev->tempd & 0x02 ){ dev->tempd = 125; }else if( dev->tempd & 0x01 ){ dev->tempd = 625; } //printf("TempDS = %d.%d\r\n", dev->tempi, dev->tempd); }
void ds18b20_read_rom(struct ds18b20 *dev) { //uint8_t romid[8]; //ow_init(); ow_reset(); ow_write_byte(0x33); dev->romcode[0] = ow_read_byte(); dev->romcode[1] = ow_read_byte(); dev->romcode[2] = ow_read_byte(); dev->romcode[3] = ow_read_byte(); dev->romcode[4] = ow_read_byte(); dev->romcode[5] = ow_read_byte(); dev->romcode[6] = ow_read_byte(); dev->romcode[7] = ow_read_byte(); //printf("id 1 = %x\r\n", dev->romcode[0]); //printf("id 2 = %x\r\n", dev->romcode[1]); //printf("id 3 = %x\r\n", dev->romcode[2]); //printf("id 4 = %x\r\n", dev->romcode[3]); //printf("id 5 = %x\r\n", dev->romcode[4]); //printf("id 6 = %x\r\n", dev->romcode[5]); //printf("id 7 = %x\r\n", dev->romcode[6]); //printf("id 8 = %x\r\n", dev->romcode[7]); //*(id) = romid[1] | romid[0]; //*(id + 1) = romid[3] | romid[2]; //dev->address[0] = ((((unsigned long)romid[3] << 8) | (unsigned long)romid[2]) << 16) | (((unsigned long)romid[1] << 8) | romid[0]); //dev->address[1] = ((((unsigned long)romid[7] << 8) | (unsigned long)romid[6]) << 16) | (((unsigned long)romid[5] << 8) | romid[4]); //printf("Address 1 = %ld\r\n", dev->address[0]); //printf("Address 2 = %ld\r\n", dev->address[1]); }
/* mid-level functions */ int8_t noinline ow_read_rom(ow_rom_code_t *rom) { #if ONEWIRE_BUSCOUNT > 1 uint8_t busmask = 1 << (ONEWIRE_STARTPIN); // FIXME: currently only on 1st bus #else uint8_t busmask = ONEWIRE_BUSMASK; #endif /* reset the bus */ if (!reset_onewire(busmask)) return -1; /* transmit command byte */ ow_write_byte(busmask, OW_ROM_READ_ROM); /* read 64bit rom code */ for (uint8_t i = 0; i < 8; i++) { /* read byte */ rom->bytewise[i] = ow_read_byte(busmask); } /* check CRC (last byte) */ if (rom->crc != crc_checksum(rom->bytewise, 7)) return -2; return 1; }
int ow_read_temperature(void) { char get[10]; char temp_lsb,temp_msb; int k; char temp_c; //char temp_f; ow_reset(); ow_write_byte(0xCC); //Skip ROM ow_write_byte(0x44); // Start Conversion delay_usec(119); //wait 120us ow_reset(); ow_write_byte(0xCC); // Skip ROM ow_write_byte(0xBE); // Read Scratch Pad for (k=0; k<9; k++) { get[k] = ow_read_byte(); } temp_msb = get[1]; // Sign byte + lsbit temp_lsb = get[0]; // Temp data plus lsb if (temp_msb <= 0x80){temp_lsb = (temp_lsb/2);} // shift to get whole degree temp_msb = temp_msb & 0x80; // mask all but the sign bit if (temp_msb >= 0x80) {temp_lsb = (~temp_lsb)+1;} // twos complement if (temp_msb >= 0x80) {temp_lsb = (temp_lsb/2);}// shift to get whole degree if (temp_msb >= 0x80) {temp_lsb = ((-1)*temp_lsb);} // add sign bit temp_c = temp_lsb; // ready for conversion to Fahrenheit //temp_f = (((int)temp_c)* 9)/5 + 32; return temp_c; }
void owchip_geteui(uint8_t* eui) { // >= 6000us uint8_t id[8]; int retry; int crc; uint8_t* byte; uint16_t oldTactl; retry = 5; memset(eui,0,8); // store current value of TACTL oldTactl = TACTL; // start timer in continuous mode at 1MHz TACTL = TASSEL_2 | ID_2 | MC_2; owpin_init(); while (retry-- > 0) { crc = 0; if(ow_reset()) { ow_write_byte(0x33); //read rom for(byte=id+7; byte>=id; byte--) { crc = crc8_byte( crc, *byte=ow_read_byte() ); } if(crc==0) { // CRC valid memcpy(eui,id,8); } } } // restore value of TACTL TACTL = oldTactl; }
int ow_read_block(int port, uint8_t *block, int len) { uint32_t i; for(i=0;i<len;i++) *block++ = ow_read_byte(port); return 0; }
uint8_t ds18b20_ping(void) { uint8_t i; uint8_t n = 0; int16_t v; if (!ow_read()) return 0; for (i = 0; i < ow_n_addrs; i++) { if (ow_addr(i)[0] == DS18B20_FAMILY_CODE) { ow_reset(); ow_match_rom(i); ow_write_byte(DS18B20_CMD_READ_SCRATCHPAD); v = ow_read_byte(); v |= ow_read_byte() << 8; if (ds18b20_temps[n]) { ds18b20_temps[n] -= ds18b20_temps[n] >> 4; ds18b20_temps[n] += v; } else { ds18b20_temps[n] = v << 4; } }
int8_t ds18x_read_serial(uint8_t *id) { uint8_t i; if(!ow_reset(0)) return -1; if(ow_write_byte(0, ROM_READ) < 0) return -1; for(i=0;i<8;i++) { *id = ow_read_byte(0); id++; } return 0; }
int8_t ow_temp_read_scratchpad(ow_rom_code_t *rom, ow_temp_scratchpad_t *scratchpad) { uint8_t busmask; int8_t ret; if (rom == NULL) ret = ow_skip_rom(); else { /* check for known family code */ if (!ow_temp_sensor(rom)) return -3; ret = ow_match_rom(rom); } if (ret < 0) return ret; /* transmit command byte */ ow_write_byte(ONEWIRE_BUSMASK, OW_FUNC_READ_SP); #if ONEWIRE_BUSCOUNT > 1 for (uint8_t bus = 0; bus < ONEWIRE_BUSCOUNT; bus++) { /* read 9 bytes from each onewire bus */ busmask = (uint8_t)(1 << (bus + ONEWIRE_STARTPIN)); #else busmask = ONEWIRE_BUSMASK; #endif for (uint8_t i = 0; i < 9; i++) { scratchpad->bytewise[i] = ow_read_byte(busmask); } /* check CRC (last byte) */ if (scratchpad->crc == crc_checksum(&scratchpad->bytewise, 8)) { /* return if we got a valid response from one device */ return 1; } #if ONEWIRE_BUSCOUNT > 1 } #endif return -2; }
//ow_ret_val_t ow_read_temperature(ow_device_t *ow_device, ow_temp_t *ow_temp) //{ // ow_scratchpad_t scrpad; // // if (ow_device == NULL || ow_temp == NULL) { // return OW_RET_FAIL; // } // // ow_reset(); // ow_write_byte(OW_CMD55_MATCH_ROM); // // for (int8_t i=0; i<OW_ROM_BYTE_LEN; i++) { // ow_write_byte(ow_device->addr[i]); // } // // ow_write_byte(OW_CMD44_CONV_TEMP); // while (ow_read_byte() == 0); // // /* TODO: Check up on this calculation. // * Especially with regards to the changed 9 bit // * value that was 12 bit earlier and make it // * generic. // */ // if (ow_read_scratchpad(ow_device, &scrpad) == OW_RET_OK) { // ow_temp->temp = ((scrpad.data[1]&0x7) << 4) & 0x7f; // ow_temp->temp |= (scrpad.data[0] & 0xF0) >> 4; // ow_temp->dec = _round((scrpad.data[0] & 0x0F) * THERM_DECIMAL_STEPS_9BIT); // return OW_RET_OK; // } // return OW_RET_FAIL; //} ow_ret_val_t get_scratch_pad_async(ow_device_t *ow_device, ow_temp_t *ow_temp) { //while(ow_read_byte() == 0) // ; if (ow_read_byte() == 0) { ow_temp->temp = 99; ow_temp->dec = 88; return OW_RET_OK; } ow_scratchpad_t scrpad; if (ow_read_scratchpad(ow_device, &scrpad) == OW_RET_OK) { ow_temp->temp = ((scrpad.data[1]&0x7) << 4) & 0x7f; ow_temp->temp |= (scrpad.data[0] & 0xF0) >> 4; ow_temp->dec = _round((scrpad.data[0] & 0x0F) * THERM_DECIMAL_STEPS_9BIT); return OW_RET_OK; }
void eui64_get(uint8_t* addressToWrite) { // >= 6000us uint8_t id[8]; int retry; int crc; uint8_t* byte; uint16_t oldTactl; return;//poipoi retry = 5; memset(addressToWrite,0,8); // store current value of TACTL oldTactl = TACTL; // start timer in continuous mode at 1MHz TACTL = TASSEL_2 | ID_2 | MC_2; owpin_init(); while (retry-- > 0) { crc = 0; if(ow_reset()) { ow_write_byte(0x33); //read rom for(byte=id+7; byte>=id; byte--) { crc = crc8_byte( crc, *byte=ow_read_byte() ); } if(crc==0) { // CRC valid *(addressToWrite+0) = 0x14; *(addressToWrite+1) = 0x15; *(addressToWrite+2) = 0x92; memcpy(addressToWrite+3,id+1,5); } } } // restore value of TACTL TACTL = oldTactl; }
int8_t ds18x_read_temp(uint8_t *id, int *temp_r) { int i, temp; uint8_t data[9]; if(ds18x_access(id) < 0) return -1; mprintf("found."); ow_write_byte(0, READ_SCRATCHPAD); for(i=0;i<9;i++) data[i] = ow_read_byte(0); temp = ((int)data[1] << 8) | ((int)data[0]); if(temp & 0x1000) temp = -0x10000 + temp; ds18x_access(id); ow_write_byte(0, CONVERT_TEMP); if(temp_r) *temp_r = temp; return 0; }
static PT_THREAD(read_temp(struct pt *pt, const ow_addr_t *addr)) { int err; uint8_t scratch[9]; uint8_t crc = 0; PT_BEGIN(pt); // Reset the bus err = ow_reset(); if (err != 1) { shell_output_P(&owtest_command, PSTR("Reset failed.\n")); PT_EXIT(pt); } // Match ROM err = ow_write_byte(0x55); if (err) { shell_output_P(&owtest_command, PSTR("Match ROM failed\n")); PT_EXIT(pt); } for (int i = 0; i < sizeof(*addr); i++) { err = ow_write_byte(addr->u[i]); if (err) { shell_output_P(&owtest_command, PSTR("Match ROM failed\n")); PT_EXIT(pt); } } // Start temperature conversion err = ow_write_byte(0x44); if (err) { shell_output_P(&owtest_command, PSTR("Convert T failed\n")); PT_EXIT(pt); } // Conversion timeout timer_set(&timeout, DS18B20_CONV_TIMEOUT); while (1) { _delay_ms(10); // for good measure // Read a bit from the bus int ret = ow_read_bit(); // Check for stop conditions if (ret == 1) { break; } else if (ret == -1) { shell_output_P(&owtest_command, PSTR("Read status failed.\n")); PT_EXIT(pt); } else if (timer_expired(&timeout)) { shell_output_P(&owtest_command, PSTR("Conversion has taken too long. Giving up.\n")); PT_EXIT(pt); } // Poll the process and yield the thread process_poll(&shell_owtest_process); PT_YIELD(pt); } // Reset and MATCH ROM again err = ow_reset(); if (err != 1) { shell_output_P(&owtest_command, PSTR("Reset failed.\n")); PT_EXIT(pt); } // Match ROM err = ow_write_byte(0x55); if (err) { shell_output_P(&owtest_command, PSTR("Match ROM failed\n")); PT_EXIT(pt); } for (int i = 0; i < sizeof(*addr); i++) { err = ow_write_byte(addr->u[i]); if (err) { shell_output_P(&owtest_command, PSTR("Match ROM failed\n")); PT_EXIT(pt); } } // Read the scratch pad err = ow_write_byte(0xBE); if (err) { shell_output_P(&owtest_command, PSTR("Read scratch pad failed\n")); PT_EXIT(pt); } for (int i = 0; i < sizeof(scratch); i++) { err = ow_read_byte(); if (err < 0) { shell_output_P(&owtest_command, PSTR("Read byte failed\n")); PT_EXIT(pt); } scratch[i] = err; crc = _crc_ibutton_update(crc, scratch[i]); } // Make sure the CRC is valid if (crc) { shell_output_P(&owtest_command, PSTR("CRC check failed!\n")); PT_EXIT(pt); } // Convert temperature to floating point int16_t rawtemp = scratch[0] | (scratch[1] << 8); float temp = (float)rawtemp * 0.0625; shell_output_P(&owtest_command, PSTR("Scratchpad: %02x%02x %02x%02x %02x %02x%02x%02x %02x\n"), scratch[0], scratch[1], // temperature scratch[2], scratch[3], // TH,TL alarm thresholds scratch[4], // config scratch[5], scratch[6], scratch[7], // reserved scratch[8]); // CRC shell_output_P(&owtest_command, PSTR("Reading: %0.2fC\n"), temp); PT_END(pt); }