/* ChibiOS/RT - Copyright (C) 2014 Uladzimir Pylinsky aka barthess Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include #include "hal.h" #include "onewire.h" /* * Forward declarations */ #if ONEWIRE_USE_STRONG_PULLUP static void strong_pullup_assert(void); static void strong_pullup_release(void); #endif /* * VARIABLES */ static uint8_t testbuf[12]; /* ****************************************************************************** ****************************************************************************** * LOCAL FUNCTIONS ****************************************************************************** ****************************************************************************** */ #if ONEWIRE_USE_STRONG_PULLUP /** * */ static void strong_pullup_assert(void) { palSetPadMode(ONEWIRE_PORT, ONEWIRE_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL); } /** * */ static void strong_pullup_release(void) { palSetPadMode(ONEWIRE_PORT, ONEWIRE_PIN, PAL_MODE_STM32_ALTERNATE_OPENDRAIN); } #endif /* ONEWIRE_USE_STRONG_PULLUP */ /* * */ void onewireMeasure(onewired_t * ow) { int16_t tmp; uint8_t rombuf[24]; bool presence; onewireObjectInit(&OWD1); onewireStart(&OWD1, ow->ow_cfg); #if ONEWIRE_SYNTH_SEARCH_TEST synthSearchRomTest(&OWD1); #endif ow->temperature = -666000; if (true == onewireReset(&OWD1)){ memset(rombuf, 0x55, sizeof(rombuf)); ow->dev_on_bus = onewireSearchRom(&OWD1, rombuf, 3); if (ow->dev_on_bus == 0) { ow->err_code = onewire_No_Dev; return; } if (1 == ow->dev_on_bus){ /* test read rom command */ presence = onewireReset(&OWD1); if (true != presence) { ow->err_code = onewire_Dev_Lost; return; } testbuf[0] = ONEWIRE_CMD_READ_ROM; onewireWrite(&OWD1, testbuf, 1, 0); onewireRead(&OWD1, testbuf, 8); if (testbuf[7] != onewireCRC(testbuf, 7)) { ow->err_code = onewire_CRC_Err; return; } if (0 != memcmp(rombuf, testbuf, 8)) { ow->err_code = onewire_MemCmp_Err; return; } } /* start temperature measurement on all connected devices at once */ presence = onewireReset(&OWD1); if (true != presence) { ow->err_code = onewire_Dev_Lost; return; } testbuf[0] = ONEWIRE_CMD_SKIP_ROM; testbuf[1] = ONEWIRE_CMD_CONVERT_TEMP; #if ONEWIRE_USE_STRONG_PULLUP onewireWrite(&OWD1, testbuf, 2, TIME_MS2I(750)); #else onewireWrite(&OWD1, testbuf, 2, 0); /* poll bus waiting ready signal from all connected devices */ testbuf[0] = 0; while (testbuf[0] == 0){ osalThreadSleepMilliseconds(50); onewireRead(&OWD1, testbuf, 1); } #endif /* read temperature device by device from their scratchpads */ presence = onewireReset(&OWD1); if (true != presence) { ow->err_code = onewire_Dev_Lost; return; } testbuf[0] = ONEWIRE_CMD_MATCH_ROM; memcpy(&testbuf[1], &rombuf[8], 8); testbuf[9] = ONEWIRE_CMD_READ_SCRATCHPAD; onewireWrite(&OWD1, testbuf, 10, 0); onewireRead(&OWD1, testbuf, 9); if (testbuf[8] != onewireCRC(testbuf, 8)) { ow->err_code = onewire_CRC_Err; return; } memcpy(&tmp, &testbuf, 2); ow->temperature = ((int32_t)tmp * 625) / 10; } else { ow->dev_on_bus = 0; } osalThreadSleep(1); /* enforce ChibiOS's stack overflow check */ onewireStop(&OWD1); } onewire_error_t onewireGetErrorCode(onewired_t * ow) { return ow->err_code; } uint8_t onewireGetDevicesNum(onewired_t * ow) { return (uint8_t)ow->dev_on_bus; } int32_t onewireGetTemperature(onewired_t * ow) { if (ow->err_code == onewire_OK) { return ow->temperature; } else { return -333000; } }