aboutsummaryrefslogtreecommitdiffstats
path: root/testhal/common
diff options
context:
space:
mode:
authorbarthess <barthess@yandex.ru>2016-10-18 12:08:34 +0300
committerbarthess <barthess@yandex.ru>2016-10-18 12:08:34 +0300
commitb7cefd6fac81a164017c4f81b8b53584e104db0b (patch)
tree9449b705425941f695a3be2a6f8d1fb2257b5ae7 /testhal/common
parent555f301da2f276cc353a8e2d0a283a488bd8eeff (diff)
downloadChibiOS-Contrib-b7cefd6fac81a164017c4f81b8b53584e104db0b.tar.gz
ChibiOS-Contrib-b7cefd6fac81a164017c4f81b8b53584e104db0b.tar.bz2
ChibiOS-Contrib-b7cefd6fac81a164017c4f81b8b53584e104db0b.zip
Testhal. Directory with hardware independant code renamed to 'common'.
Diffstat (limited to 'testhal/common')
-rw-r--r--testhal/common/onewire/real_roms.txt27
-rw-r--r--testhal/common/onewire/synth_searchrom.c370
-rw-r--r--testhal/common/onewire/testhal_onewire.c228
-rw-r--r--testhal/common/onewire/testhal_onewire.h28
4 files changed, 653 insertions, 0 deletions
diff --git a/testhal/common/onewire/real_roms.txt b/testhal/common/onewire/real_roms.txt
new file mode 100644
index 0000000..ea19c1a
--- /dev/null
+++ b/testhal/common/onewire/real_roms.txt
@@ -0,0 +1,27 @@
+rombuf[0] 0x28
+rombuf[1] 0xec
+rombuf[2] 0xf5
+rombuf[3] 0x67
+rombuf[4] 0x5
+rombuf[5] 0x0
+rombuf[6] 0x0
+rombuf[7] 0x1d
+
+rombuf[8] 0x28
+rombuf[9] 0xbd
+rombuf[10] 0x1a
+rombuf[11] 0x60
+rombuf[12] 0x5
+rombuf[13] 0x0
+rombuf[14] 0x0
+rombuf[15] 0x37
+
+rombuf[16] 0x28
+rombuf[17] 0x83
+rombuf[18] 0x7d
+rombuf[19] 0x67
+rombuf[20] 0x5
+rombuf[21] 0x0
+rombuf[22] 0x0
+rombuf[23] 0xf
+
diff --git a/testhal/common/onewire/synth_searchrom.c b/testhal/common/onewire/synth_searchrom.c
new file mode 100644
index 0000000..53d4a30
--- /dev/null
+++ b/testhal/common/onewire/synth_searchrom.c
@@ -0,0 +1,370 @@
+/*
+ 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 <stdlib.h>
+
+/*
+ ******************************************************************************
+ * DEFINES
+ ******************************************************************************
+ */
+
+/* do not set it more than 64 because of some fill_pattern functions
+ will be broken.*/
+#define SYNTH_DEVICES_MAX 64
+
+/*
+ * synthetic device
+ */
+typedef struct {
+ bool active;
+ uint64_t id;
+} OWSynthDevice;
+
+/*
+ * synthetic bus
+ */
+typedef struct {
+ OWSynthDevice devices[SYNTH_DEVICES_MAX];
+ size_t dev_present;
+ bool complement_bit;
+ ioline_t rom_bit;
+} OWSynthBus;
+
+/*
+ ******************************************************************************
+ * EXTERNS
+ ******************************************************************************
+ */
+
+/*
+ ******************************************************************************
+ * PROTOTYPES
+ ******************************************************************************
+ */
+
+/*
+ ******************************************************************************
+ * GLOBAL VARIABLES
+ ******************************************************************************
+ */
+
+static OWSynthBus synth_bus;
+
+/*
+ * local buffer for discovered ROMs
+ */
+static uint64_t detected_devices[SYNTH_DEVICES_MAX];
+
+/*
+ ******************************************************************************
+ ******************************************************************************
+ * LOCAL FUNCTIONS
+ ******************************************************************************
+ ******************************************************************************
+ */
+
+/*
+ ******************************************************************************
+ * EXPORTED FUNCTIONS
+ ******************************************************************************
+ */
+
+/*
+ *
+ */
+void _synth_ow_write_bit(onewireDriver *owp, ioline_t bit) {
+ (void)owp;
+ size_t i;
+
+ for (i=0; i<SYNTH_DEVICES_MAX; i++) {
+ if (((synth_bus.devices[i].id >> synth_bus.rom_bit) & 1U) != bit) {
+ synth_bus.devices[i].active = false;
+ }
+ }
+ synth_bus.rom_bit++;
+}
+
+/*
+ *
+ */
+ioline_t _synth_ow_read_bit(void) {
+ ioline_t ret = 0xFF;
+ size_t i;
+ ioline_t bit;
+
+ for (i=0; i<SYNTH_DEVICES_MAX; i++) {
+ if (synth_bus.devices[i].active){
+ bit = (synth_bus.devices[i].id >> synth_bus.rom_bit) & 1U;
+ if (synth_bus.complement_bit){
+ bit ^= 1U;
+ }
+ if (0xFF == ret)
+ ret = bit;
+ else
+ ret &= bit;
+ }
+ }
+ synth_bus.complement_bit = !synth_bus.complement_bit;
+ return ret;
+}
+
+/*
+ *
+ */
+static void synth_reset_pulse(void){
+ size_t i;
+
+ for (i=0; i<synth_bus.dev_present; i++){
+ synth_bus.devices[i].active = true;
+ }
+}
+
+/*
+ *
+ */
+static size_t synth_search_rom(onewireDriver *owp, uint8_t *result, size_t max_rom_cnt) {
+
+ size_t i;
+
+ search_clean_start(&owp->search_rom);
+
+ do {
+ /* initialize buffer to store result */
+ if (owp->search_rom.reg.devices_found >= max_rom_cnt)
+ owp->search_rom.retbuf = result + 8*(max_rom_cnt-1);
+ else
+ owp->search_rom.retbuf = result + 8*owp->search_rom.reg.devices_found;
+ memset(owp->search_rom.retbuf, 0, 8);
+
+ /* clean iteration state */
+ search_clean_iteration(&owp->search_rom);
+
+ /**/
+ synth_reset_pulse();
+ synth_bus.rom_bit = 0;
+ synth_bus.complement_bit = false;
+ for (i=0; i<64*3 - 1; i++){
+ ow_search_rom_cb(NULL, owp);
+ }
+
+ if (ONEWIRE_SEARCH_ROM_ERROR != owp->search_rom.reg.result) {
+ /* store cached result for usage in next iteration */
+ memcpy(owp->search_rom.prev_path, owp->search_rom.retbuf, 8);
+ }
+ }
+ while (ONEWIRE_SEARCH_ROM_SUCCESS == owp->search_rom.reg.result);
+
+ /**/
+ if (ONEWIRE_SEARCH_ROM_ERROR == owp->search_rom.reg.result)
+ return 0;
+ else
+ return owp->search_rom.reg.devices_found;
+}
+
+/*
+ *
+ */
+static void fill_pattern_real_devices(void) {
+ size_t i;
+
+ for (i=0; i<SYNTH_DEVICES_MAX; i++)
+ synth_bus.devices[i].active = false;
+
+ synth_bus.devices[0].active = true;
+ synth_bus.devices[0].id = 0x1d00000567f5ec28;
+
+ synth_bus.devices[1].active = true;
+ synth_bus.devices[1].id = 0x37000005601abd28;
+
+ synth_bus.devices[2].active = true;
+ synth_bus.devices[2].id = 0x0f000005677d8328;
+}
+
+/*
+ *
+ */
+static void fill_pattern_00(size_t devices, size_t start) {
+ size_t i;
+
+ for (i=0; i<SYNTH_DEVICES_MAX; i++)
+ synth_bus.devices[i].active = false;
+
+ for (i=0; i<devices; i++){
+ synth_bus.devices[i].active = true;
+ synth_bus.devices[i].id = (start + i);
+ }
+}
+
+/*
+ *
+ */
+static void fill_pattern_01(size_t devices) {
+ size_t i;
+
+ for (i=0; i<SYNTH_DEVICES_MAX; i++)
+ synth_bus.devices[i].active = false;
+
+ for (i=0; i<devices; i++){
+ synth_bus.devices[i].active = true;
+ synth_bus.devices[i].id = (devices - i);
+ }
+}
+
+/*
+ *
+ */
+static void fill_pattern_02(size_t devices) {
+ size_t i;
+
+ for (i=0; i<SYNTH_DEVICES_MAX; i++)
+ synth_bus.devices[i].active = false;
+
+ for (i=0; i<devices; i++){
+ synth_bus.devices[i].active = true;
+ synth_bus.devices[i].id = ((uint64_t)1 << i);
+ }
+}
+
+/*
+ *
+ */
+static void fill_pattern_03(size_t devices) {
+ size_t i;
+
+ for (i=0; i<SYNTH_DEVICES_MAX; i++)
+ synth_bus.devices[i].active = false;
+
+ for (i=0; i<devices; i++){
+ synth_bus.devices[i].active = true;
+ synth_bus.devices[i].id = ((uint64_t)0x8000000000000000 >> i);
+ }
+}
+
+/*
+ * Random pattern helper
+ */
+static bool is_id_uniq(const OWSynthDevice *dev, size_t n, uint64_t id) {
+ size_t i;
+
+ for (i=0; i<n; i++) {
+ if (dev[i].id == id)
+ return false;
+ }
+ return true;
+}
+
+/*
+ *
+ */
+static void fill_pattern_rand(size_t devices) {
+ size_t i;
+ uint64_t new_id;
+
+ for (i=0; i<SYNTH_DEVICES_MAX; i++){
+ synth_bus.devices[i].active = false;
+ synth_bus.devices[i].id = 0;
+ }
+
+ for (i=0; i<devices; i++) {
+ do {
+ new_id = rand();
+ new_id = (new_id << 32) | rand();
+ } while (true != is_id_uniq(synth_bus.devices, i, new_id));
+
+ synth_bus.devices[i].id = new_id;
+ synth_bus.devices[i].active = true;
+ }
+}
+
+/*
+ *
+ */
+static bool check_result(size_t detected) {
+
+ size_t i,j;
+ bool match = false;
+
+ for (i=0; i<detected; i++){
+ match = false;
+ for (j=0; j<detected; j++){
+ if (synth_bus.devices[i].id == detected_devices[j]){
+ match = true;
+ break;
+ }
+ }
+ if (false == match)
+ return OSAL_FAILED;
+ }
+ return OSAL_SUCCESS;
+}
+
+/*
+ *
+ */
+void synthSearchRomTest(onewireDriver *owp) {
+
+ size_t detected = 0;
+ size_t i;
+
+ synth_bus.dev_present = 3;
+ fill_pattern_real_devices();
+ detected = synth_search_rom(owp, (uint8_t *)detected_devices, SYNTH_DEVICES_MAX);
+ osalDbgCheck(synth_bus.dev_present == detected);
+ osalDbgCheck(OSAL_SUCCESS == check_result(detected));
+
+ for (i=1; i<=SYNTH_DEVICES_MAX; i++){
+ synth_bus.dev_present = i;
+
+ fill_pattern_00(synth_bus.dev_present, 0);
+ detected = synth_search_rom(owp, (uint8_t *)detected_devices, SYNTH_DEVICES_MAX);
+ osalDbgCheck(synth_bus.dev_present == detected);
+ osalDbgCheck(OSAL_SUCCESS == check_result(detected));
+
+ fill_pattern_00(synth_bus.dev_present, 1);
+ detected = synth_search_rom(owp, (uint8_t *)detected_devices, SYNTH_DEVICES_MAX);
+ osalDbgCheck(synth_bus.dev_present == detected);
+ osalDbgCheck(OSAL_SUCCESS == check_result(detected));
+
+ fill_pattern_01(synth_bus.dev_present);
+ detected = synth_search_rom(owp, (uint8_t *)detected_devices, SYNTH_DEVICES_MAX);
+ osalDbgCheck(synth_bus.dev_present == detected);
+ osalDbgCheck(OSAL_SUCCESS == check_result(detected));
+
+ fill_pattern_02(synth_bus.dev_present);
+ detected = synth_search_rom(owp, (uint8_t *)detected_devices, SYNTH_DEVICES_MAX);
+ osalDbgCheck(synth_bus.dev_present == detected);
+ osalDbgCheck(OSAL_SUCCESS == check_result(detected));
+
+ fill_pattern_03(synth_bus.dev_present);
+ detected = synth_search_rom(owp, (uint8_t *)detected_devices, SYNTH_DEVICES_MAX);
+ osalDbgCheck(synth_bus.dev_present == detected);
+ osalDbgCheck(OSAL_SUCCESS == check_result(detected));
+ }
+
+ i = 0;
+ while (i < 1000) {
+ synth_bus.dev_present = 1 + (rand() & 63);
+
+ fill_pattern_rand(synth_bus.dev_present);
+ detected = synth_search_rom(owp, (uint8_t *)detected_devices, SYNTH_DEVICES_MAX);
+ osalDbgCheck(synth_bus.dev_present == detected);
+ osalDbgCheck(OSAL_SUCCESS == check_result(detected));
+ i++;
+ }
+}
+
+
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);
+}
diff --git a/testhal/common/onewire/testhal_onewire.h b/testhal/common/onewire/testhal_onewire.h
new file mode 100644
index 0000000..181e09f
--- /dev/null
+++ b/testhal/common/onewire/testhal_onewire.h
@@ -0,0 +1,28 @@
+/*
+ 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.
+*/
+
+#ifndef TESTHAL_ONEWIRE_H_
+#define TESTHAL_ONEWIRE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void onewireTest(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TESTHAL_ONEWIRE_H_ */