123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- /*
- 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++;
- }
- }
|