diff options
Diffstat (limited to 'testhal/common/onewire/testhal_onewire.c')
-rw-r--r-- | testhal/common/onewire/testhal_onewire.c | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/testhal/common/onewire/testhal_onewire.c b/testhal/common/onewire/testhal_onewire.c new file mode 100644 index 0000000..93dcc31 --- /dev/null +++ b/testhal/common/onewire/testhal_onewire.c @@ -0,0 +1,228 @@ +/* + 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 <string.h> + +#include "hal.h" +#include "boarddef.h" + +/* + ****************************************************************************** + * ERROR CHECKS + ****************************************************************************** + */ + +#if defined(BOARD_ST_STM32F4_DISCOVERY) || \ + defined(BOARD_ST_STM32F0_DISCOVERY) || \ + defined(BOARD_ST_STM32F0308_DISCOVERY) + #if ONEWIRE_USE_STRONG_PULLUP + #error "This board has not enough voltage for this feature" + #endif +#endif + +/* + ****************************************************************************** + * DEFINES + ****************************************************************************** + */ + +/* + ****************************************************************************** + * EXTERNS + ****************************************************************************** + */ + +/* + ****************************************************************************** + * PROTOTYPES + ****************************************************************************** + */ +/* + * Forward declarations + */ +#if ONEWIRE_USE_STRONG_PULLUP +static void strong_pullup_assert(void); +static void strong_pullup_release(void); +#endif + +/* + ****************************************************************************** + * GLOBAL VARIABLES + ****************************************************************************** + */ + +static uint8_t testbuf[12]; + +/* stores 3 temperature values in millicelsius */ +static int32_t temperature[3]; + +/* + * Config for underlying PWM driver. + * Note! It is NOT constant because 1-wire driver needs to change them + * during functioning. + */ +static PWMConfig pwm_cfg = { + 0, + 0, + NULL, + { + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL} + }, + 0, +#if STM32_PWM_USE_ADVANCED + 0, +#endif + 0 +}; + +/* + * + */ +static const onewireConfig ow_cfg = { + &PWMD3, + &pwm_cfg, + PWM_OUTPUT_ACTIVE_LOW, + ONEWIRE_MASTER_CHANNEL, + ONEWIRE_SAMPLE_CHANNEL, + ONEWIRE_PORT, + ONEWIRE_PIN, +#if defined(STM32F1XX) + ONEWIRE_PAD_MODE_IDLE, +#endif + ONEWIRE_PAD_MODE_ACTIVE, +#if ONEWIRE_USE_STRONG_PULLUP + strong_pullup_assert, + strong_pullup_release +#endif +}; + +/* + ****************************************************************************** + ****************************************************************************** + * 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 */ + +/* + ****************************************************************************** + * EXPORTED FUNCTIONS + ****************************************************************************** + */ + +/* + * + */ +void onewireTest(void) { + + int16_t tmp; + uint8_t rombuf[24]; + size_t devices_on_bus = 0; + size_t i = 0; + bool presence; + + onewireObjectInit(&OWD1); + onewireStart(&OWD1, &ow_cfg); + +#if ONEWIRE_SYNTH_SEARCH_TEST + synthSearchRomTest(&OWD1); +#endif + + for (i=0; i<3; i++) + temperature[i] = -666; + + while (true) { + if (true == onewireReset(&OWD1)){ + + memset(rombuf, 0x55, sizeof(rombuf)); + search_led_on(); + devices_on_bus = onewireSearchRom(&OWD1, rombuf, 3); + search_led_off(); + osalDbgCheck(devices_on_bus <= 3); + osalDbgCheck(devices_on_bus > 0); + + if (1 == devices_on_bus){ + /* test read rom command */ + presence = onewireReset(&OWD1); + osalDbgCheck(true == presence); + testbuf[0] = ONEWIRE_CMD_READ_ROM; + onewireWrite(&OWD1, testbuf, 1, 0); + onewireRead(&OWD1, testbuf, 8); + osalDbgCheck(testbuf[7] == onewireCRC(testbuf, 7)); + osalDbgCheck(0 == memcmp(rombuf, testbuf, 8)); + } + + /* start temperature measurement on all connected devices at once */ + presence = onewireReset(&OWD1); + osalDbgCheck(true == presence); + testbuf[0] = ONEWIRE_CMD_SKIP_ROM; + testbuf[1] = ONEWIRE_CMD_CONVERT_TEMP; + +#if ONEWIRE_USE_STRONG_PULLUP + onewireWrite(&OWD1, testbuf, 2, MS2ST(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 + + for (i=0; i<devices_on_bus; i++) { + /* read temperature device by device from their scratchpads */ + presence = onewireReset(&OWD1); + osalDbgCheck(true == presence); + + testbuf[0] = ONEWIRE_CMD_MATCH_ROM; + memcpy(&testbuf[1], &rombuf[i*8], 8); + testbuf[9] = ONEWIRE_CMD_READ_SCRATCHPAD; + onewireWrite(&OWD1, testbuf, 10, 0); + + onewireRead(&OWD1, testbuf, 9); + osalDbgCheck(testbuf[8] == onewireCRC(testbuf, 8)); + memcpy(&tmp, &testbuf, 2); + temperature[i] = ((int32_t)tmp * 625) / 10; + } + } + else { + osalSysHalt("No devices found"); + } + osalThreadSleep(1); /* enforce ChibiOS's stack overflow check */ + } + + onewireStop(&OWD1); +} |