int8_t ow_temp_power(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 int8_t ret; if (rom == NULL) ret = ow_skip_rom(); else { if (!ow_temp_sensor(rom)) return -2; ret = ow_match_rom(rom); } if (ret < 0) return ret; /* transmit command byte */ ow_write_byte(busmask, OW_FUNC_READ_POWER); return (int8_t)(ow_read(busmask)); }
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; }
int8_t ow_temp_start_convert(ow_rom_code_t *rom, uint8_t wait) { int8_t ret; if (rom == NULL) ret = ow_skip_rom(); else { /* check for known family code */ if (!ow_temp_sensor(rom)) return -2; ret = ow_match_rom(rom); } if (ret < 0) return ret; /* transmit command byte */ ow_write_byte(ONEWIRE_BUSMASK, OW_FUNC_CONVERT); OW_CONFIG_OUTPUT(ONEWIRE_BUSMASK); OW_HIGH(ONEWIRE_BUSMASK); if (!wait) return 0; _delay_ms(800); /* The specification say, that we have to wait at least 500ms in parasite mode to wait for the end of the conversion. 800ms works more reliably */ while(!ow_read(ONEWIRE_BUSMASK)); return 1; }
/*This function will be called every 800 ms*/ void ow_periodic(void) { /*At startup we want an immediate discovery*/ static uint16_t discover_delay = 3; if (--discover_delay == 0) { discover_delay = OW_DISCOVER_DELAY; ow_discover_sensor(); #ifdef DEBUG_OW_POLLING for (uint8_t i = 0, k = 0; i < OW_SENSORS_COUNT; i++) { if (ow_sensors[i].ow_rom_code.raw != 0) { debug_printf("sensor #%d in list is: %02x %02x %02x %02x %02x %02x %02x %02x\n", ++k, ow_sensors[i].ow_rom_code.bytewise[0], ow_sensors[i].ow_rom_code.bytewise[1], ow_sensors[i].ow_rom_code.bytewise[2], ow_sensors[i].ow_rom_code.bytewise[3], ow_sensors[i].ow_rom_code.bytewise[4], ow_sensors[i].ow_rom_code.bytewise[5], ow_sensors[i].ow_rom_code.bytewise[6], ow_sensors[i].ow_rom_code.bytewise[7]); } } #endif /* DEBUG_OW_POLLING */ } for (uint8_t i = 0; i < OW_SENSORS_COUNT; i++) { if (ow_temp_sensor(&ow_sensors[i].ow_rom_code)) { if (ow_sensors[i].converted == 1) { if (ow_sensors[i].convert_delay == 1) ow_sensors[i].convert_delay = 0; else { #ifdef DEBUG_OW_POLLING debug_printf("reading temperature\n"); #endif /* DEBUG_OW_POLLING */ int8_t ret; ow_temp_scratchpad_t sp; ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ret = ow_temp_read_scratchpad(&ow_sensors[i].ow_rom_code, &sp); } if (ret != 1) { #ifdef DEBUG_OW_POLLING debug_printf("scratchpad read failed: %d\n", ret); #endif /* DEBUG_OW_POLLING */ return; } #ifdef DEBUG_OW_POLLING debug_printf("scratchpad read succeeded\n"); #endif /* DEBUG_OW_POLLING */ int16_t temp = ow_temp_normalize(&ow_sensors[i].ow_rom_code, &sp); #ifdef DEBUG_OW_POLLING debug_printf("temperature: %d.%d\n", HI8(temp), LO8(temp) > 0 ? 5 : 0); #endif /* DEBUG_OW_POLLING */ ow_sensors[i].temp = ((int8_t) HI8(temp)) * 10 + HI8(((temp & 0x00ff) * 10) + 0x80); ow_sensors[i].converted = 0; } } if (--ow_sensors[i].read_delay == 0 && ow_sensors[i].converted == 0) { ow_sensors[i].read_delay = OW_READ_DELAY; ow_temp_start_convert_nowait(&ow_sensors[i].ow_rom_code); ow_sensors[i].convert_delay = 1; ow_sensors[i].converted = 1; } } } }
static int8_t ow_discover_sensor(void) { uint8_t firstonbus = 1; int8_t ret = 0; #if ONEWIRE_BUSCOUNT > 1 ow_global.bus = 0; #endif /* ONEWIRE_BUSCOUNT */ #ifdef DEBUG_OW_POLLING debug_printf("starting discovery\n"); #endif /* DEBUG_OW_POLLING */ /*Prepare existing sensors*/ for (uint8_t i = 0; i < OW_SENSORS_COUNT; i++) ow_sensors[i].present = 0; #if ONEWIRE_BUSCOUNT > 1 do { #endif /* ONEWIRE_BUSCOUNT > 1 */ do { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { #if ONEWIRE_BUSCOUNT > 1 ret = ow_search_rom((uint8_t)(1 << (ow_global.bus + ONEWIRE_STARTPIN)), firstonbus); #else /* ONEWIRE_BUSCOUNT > 1 */ ret = ow_search_rom(ONEWIRE_BUSMASK, firstonbus); #endif /* ONEWIRE_BUSCOUNT > 1 */ } /* make sure only one conversion happens at a time */ ow_global.lock = 1; if (ret == 1) { firstonbus = 0; #ifdef DEBUG_OW_POLLING debug_printf("discovered device %02x %02x %02x %02x %02x %02x %02x %02x" #if ONEWIRE_BUSCOUNT > 1 " on bus %d" #endif /* ONEWIRE_BUSCOUNT > 1 */ "\n", ow_global.current_rom.bytewise[0], ow_global.current_rom.bytewise[1], ow_global.current_rom.bytewise[2], ow_global.current_rom.bytewise[3], ow_global.current_rom.bytewise[4], ow_global.current_rom.bytewise[5], ow_global.current_rom.bytewise[6], ow_global.current_rom.bytewise[7] #if ONEWIRE_BUSCOUNT > 1 ,ow_global.bus #endif /* ONEWIRE_BUSCOUNT > 1 */ ); #endif /* DEBUG_OW_POLLING */ if (ow_temp_sensor(&ow_global.current_rom)) { uint8_t already_in = 0; /*Determine whether this sensor is already present in our list*/ for (uint8_t i = 0; i < OW_SENSORS_COUNT; i++) { if (ow_global.current_rom.raw == ow_sensors[i].ow_rom_code.raw) { ow_sensors[i].present = 1; already_in = 1; /*We skip everything else to retain a regular update rate*/ break; } } if (already_in == 0) { uint8_t i; /*The sensor we found is not in our list, so we search for the first free sensor slot, e.g. the first slot where ow_rom_code is zero*/ for (i = 0; i < OW_SENSORS_COUNT; i++) { if (ow_sensors[i].ow_rom_code.raw == 0) { /* We found a free slot...storing*/ #ifdef DEBUG_OW_POLLING debug_printf("stored new sensor in pos %d\n", i); #endif /* DEBUG_OW_POLLING */ ow_sensors[i].ow_rom_code.raw = ow_global.current_rom.raw; ow_sensors[i].present = 1; ow_sensors[i].read_delay = 1; /*Read temperature asap - note: we will check for eeprom later*/ break; } } #ifdef DEBUG_OW_POLLING if (i == OW_SENSORS_COUNT - 1) debug_printf("number of sensors exceeds list size of %d\n", OW_SENSORS_COUNT); #endif /* DEBUG_OW_POLLING */ } #ifdef DEBUG_OW_POLLING } else { debug_printf("not a temperature sensor\n"); #endif /* DEBUG_OW_POLLING */ } } } while (ret > 0); #if ONEWIRE_BUSCOUNT > 1 ow_global.bus++; firstonbus = 1; } while (ow_global.bus < ONEWIRE_BUSCOUNT); #endif /* ONEWIRE_BUSCOUNT > 1 */ ow_global.lock = 0; /*We finished the discovery process. Now we delete all removed sensors*/ for (uint8_t i = 0; i < OW_SENSORS_COUNT; i++) { /*Mark the slot as free*/ if (ow_sensors[i].present == 0) ow_sensors[i].ow_rom_code.raw = 0; } return 0; }
int16_t parse_cmd_onewire_list(char *cmd, char *output, uint16_t len) { #ifdef ONEWIRE_DS2502_SUPPORT int8_t list_type; while (*cmd == ' ') cmd++; switch (*cmd) { case 't': list_type = OW_LIST_TYPE_TEMP_SENSOR; break; case 'e': list_type = OW_LIST_TYPE_EEPROM; break; case '\0': list_type = OW_LIST_TYPE_ALL; break; default: return ECMD_ERR_PARSE_ERROR; } cmd++; /* for static bytes */ #endif /* trick: use bytes on cmd as "connection specific static variables" */ if (cmd[0] != ECMD_STATE_MAGIC) /* indicator flag: real invocation: 0 */ { cmd[0] = ECMD_STATE_MAGIC; /* continuing call: 23 */ cmd[1] = 0; /* counter for sensors in list */ } uint8_t i = cmd[1]; /* This is a special case: the while loop below printed a sensor which was * last in the list, so we still need to send an 'OK' after the sensor id */ if (i >= OW_SENSORS_COUNT) return ECMD_FINAL_OK; int16_t ret = 0; do { if (ow_sensors[i].ow_rom_code.raw != 0) { #ifdef ONEWIRE_DS2502_SUPPORT if (list_type == OW_LIST_TYPE_ALL || (list_type == OW_LIST_TYPE_TEMP_SENSOR && ow_temp_sensor(&ow_sensors[i].ow_rom_code)) || (list_type == OW_LIST_TYPE_EEPROM && ow_eeprom(&ow_sensors[i].ow_rom_code))) { #endif #ifdef ONEWIRE_NAMING_SUPPORT const char *name = ""; if (ow_sensors[i].named) name = ow_sensors[i].name; #endif #ifdef ONEWIRE_ECMD_LIST_VALUES_SUPPORT char temperature[7]; itoa_fixedpoint(ow_sensors[i].temp.val, ow_sensors[i].temp.twodigits + 1, temperature, sizeof(temperature)); #endif ret = snprintf_P(output, len, PSTR("%02x%02x%02x%02x%02x%02x%02x%02x" #ifdef ONEWIRE_NAMING_SUPPORT "\t%s" #endif #ifdef ONEWIRE_ECMD_LIST_VALUES_SUPPORT "\t%s" #endif #ifdef ONEWIRE_ECMD_LIST_POWER_SUPPORT "\t%d" #endif ), ow_sensors[i].ow_rom_code.bytewise[0], ow_sensors[i].ow_rom_code.bytewise[1], ow_sensors[i].ow_rom_code.bytewise[2], ow_sensors[i].ow_rom_code.bytewise[3], ow_sensors[i].ow_rom_code.bytewise[4], ow_sensors[i].ow_rom_code.bytewise[5], ow_sensors[i].ow_rom_code.bytewise[6], ow_sensors[i].ow_rom_code.bytewise[7] #ifdef ONEWIRE_NAMING_SUPPORT , name #endif #ifdef ONEWIRE_ECMD_LIST_VALUES_SUPPORT , temperature #endif #ifdef ONEWIRE_ECMD_LIST_POWER_SUPPORT , ow_sensors[i].power #endif ); #ifdef ONEWIRE_DS2502_SUPPORT } #endif } i++; } while (ret == 0 && i < OW_SENSORS_COUNT); /* The while loop exited either because a sensor has been found or because * there is no sensor left, let's check for that */ if (ret == 0) { /* => i has reached OW_SENSORS_COUNT */ return ECMD_FINAL_OK; } /* else, ret is != 0 which means a sensor has been found and this functions * has to be called again to prevent a buffer overflow. save i to cmd[1] */ cmd[1] = i; return ECMD_AGAIN(ret); }
int16_t parse_cmd_onewire_list(char *cmd, char *output, uint16_t len) { uint8_t firstonbus = 0; int16_t ret; if (ow_global.lock == 0) { firstonbus = 1; #if ONEWIRE_BUSCOUNT > 1 ow_global.bus = 0; #endif OW_DEBUG_LIST("called onewire list for the first time\n"); #ifdef ONEWIRE_DS2502_SUPPORT /* parse optional parameters */ while (*cmd == ' ') cmd++; switch (*cmd) { case 't': ow_global.list_type = OW_LIST_TYPE_TEMP_SENSOR; break; case 'e': ow_global.list_type = OW_LIST_TYPE_EEPROM; break; case '\0': ow_global.list_type = OW_LIST_TYPE_ALL; break; default: return ECMD_ERR_PARSE_ERROR; } #endif } else { OW_DEBUG_LIST("called onewire list again\n"); firstonbus = 0; } #if defined ONEWIRE_DS2502_SUPPORT || ONEWIRE_BUSCOUNT > 1 list_next:; #endif #if ONEWIRE_BUSCOUNT > 1 ret = ow_search_rom((uint8_t) (1 << (ow_global.bus + ONEWIRE_STARTPIN)), firstonbus); #else ret = ow_search_rom(ONEWIRE_BUSMASK, firstonbus); #endif /* make sure only one conversion happens at a time */ ow_global.lock = 1; if (ret == 1) { #ifdef ONEWIRE_DS2502_SUPPORT if (ow_global.list_type == OW_LIST_TYPE_ALL || (ow_global.list_type == OW_LIST_TYPE_TEMP_SENSOR && ow_temp_sensor(&ow_global.current_rom)) || (ow_global.list_type == OW_LIST_TYPE_EEPROM && ow_eeprom(&ow_global.current_rom))) { /* only print device rom address if it matches the selected list type */ #endif OW_DEBUG_LIST("discovered device " #if ONEWIRE_BUSCOUNT > 1 "%02x %02x %02x %02x %02x %02x %02x %02x on bus %d\n", #else "%02x %02x %02x %02x %02x %02x %02x %02x\n", #endif ow_global.current_rom.bytewise[0], ow_global.current_rom.bytewise[1], ow_global.current_rom.bytewise[2], ow_global.current_rom.bytewise[3], ow_global.current_rom.bytewise[4], ow_global.current_rom.bytewise[5], ow_global.current_rom.bytewise[6], ow_global.current_rom.bytewise[7] #if ONEWIRE_BUSCOUNT > 1 , ow_global.bus); #else ); #endif #ifdef ONEWIRE_NAMING_SUPPORT char *name = ""; ow_sensor_t *sensor = ow_find_sensor(&ow_global.current_rom); if (sensor != NULL && sensor->named) { name = sensor->name; } #endif ret = snprintf_P(output, len, PSTR("%02x%02x%02x%02x%02x%02x%02x%02x" #ifdef ONEWIRE_NAMING_SUPPORT "\t%s" #endif ), ow_global.current_rom.bytewise[0], ow_global.current_rom.bytewise[1], ow_global.current_rom.bytewise[2], ow_global.current_rom.bytewise[3], ow_global.current_rom.bytewise[4], ow_global.current_rom.bytewise[5], ow_global.current_rom.bytewise[6], ow_global.current_rom.bytewise[7] #ifdef ONEWIRE_NAMING_SUPPORT , name #endif ); OW_DEBUG_LIST("generated %d bytes\n", ret); /* set return value that the parser has to be called again */ if (ret > 0) ret = ECMD_AGAIN(ret); OW_DEBUG_LIST("returning %d\n", ret); return ECMD_FINAL(ret); #ifdef ONEWIRE_DS2502_SUPPORT }
int16_t parse_cmd_onewire_list(char *cmd, char *output, uint16_t len) { int8_t list_type; while (*cmd == ' ') cmd++; switch (*cmd) { case 't': list_type = OW_LIST_TYPE_TEMP_SENSOR; break; case 'e': list_type = OW_LIST_TYPE_EEPROM; break; case '\0': list_type = OW_LIST_TYPE_ALL; break; default: return ECMD_ERR_PARSE_ERROR; } static uint8_t i=0; if(i>=OW_SENSORS_COUNT) { i=0; return ECMD_FINAL_OK; } int16_t ret=0; do { if(ow_sensors[i].ow_rom_code.raw != 0) { if ((list_type == OW_LIST_TYPE_ALL) || (list_type == OW_LIST_TYPE_TEMP_SENSOR && ow_temp_sensor(&ow_sensors[i].ow_rom_code)) || (list_type == OW_LIST_TYPE_EEPROM && ow_eeprom(&ow_sensors[i].ow_rom_code))) { ret = snprintf_P(output, len, PSTR("%02x%02x%02x%02x%02x%02x%02x%02x"), ow_sensors[i].ow_rom_code.bytewise[0], ow_sensors[i].ow_rom_code.bytewise[1], ow_sensors[i].ow_rom_code.bytewise[2], ow_sensors[i].ow_rom_code.bytewise[3], ow_sensors[i].ow_rom_code.bytewise[4], ow_sensors[i].ow_rom_code.bytewise[5], ow_sensors[i].ow_rom_code.bytewise[6], ow_sensors[i].ow_rom_code.bytewise[7] ); } } i++; } while(ret == 0 && i<OW_SENSORS_COUNT); return ECMD_AGAIN(ret); }