aboutsummaryrefslogtreecommitdiffstats
path: root/ChibiOS_16.1.5/community/os/hal/src/hal_onewire.c
diff options
context:
space:
mode:
Diffstat (limited to 'ChibiOS_16.1.5/community/os/hal/src/hal_onewire.c')
-rw-r--r--ChibiOS_16.1.5/community/os/hal/src/hal_onewire.c890
1 files changed, 0 insertions, 890 deletions
diff --git a/ChibiOS_16.1.5/community/os/hal/src/hal_onewire.c b/ChibiOS_16.1.5/community/os/hal/src/hal_onewire.c
deleted file mode 100644
index a93eec0..0000000
--- a/ChibiOS_16.1.5/community/os/hal/src/hal_onewire.c
+++ /dev/null
@@ -1,890 +0,0 @@
-/*
- 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.
-*/
-
-/*===========================================================================*/
-/* Main ideas: */
-/*===========================================================================
-
-1) switch PWM output pin to open drain mode.
-2) start 2 channels _simultaneously_. First (master channel) generates
- pulses (read time slots) second (sample channel) generates interrupts
- from where read pin function will be called.
-
-- --------------------------------------- master channel generates pulses
- | / .
- --............................. <---------- slave (not)pulls down bus here
-- -------------------------------- sample channel reads pad state
- | |
- -------------
- ^
- | read interrupt fires here
-
-For data write it is only master channel needed. Data bit width updates
-on every timer overflow event.
-*/
-
-/*===========================================================================*/
-/* General recommendations for strong pull usage */
-/*===========================================================================
- * 1) Use separate power rail instead of strong pull up whenever possible.
- * Driver's strong pull up feature is very sensible to interrupt jitter.
- * 2) Use specialized 1-wire bus master (DS2484 for example) if you are
- * forced to handle bus requiring strong pull up feature.
- */
-
-/**
- * @file onewire.c
- * @brief 1-wire Driver code.
- *
- * @addtogroup onewire
- * @{
- */
-
-#include "hal.h"
-
-#if (HAL_USE_ONEWIRE == TRUE) || defined(__DOXYGEN__)
-
-#include <string.h>
-#include <limits.h>
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-/**
- * @brief 1MHz clock for PWM driver.
- */
-#define ONEWIRE_PWM_FREQUENCY 1000000
-
-/**
- * @brief Pulse width constants in microseconds.
- * @details Inspired by Microchip's AN1199
- * "1-Wire® Communication with PIC® Microcontroller"
- */
-#define ONEWIRE_ZERO_WIDTH 60
-#define ONEWIRE_ONE_WIDTH 6
-#define ONEWIRE_SAMPLE_WIDTH 15
-#define ONEWIRE_RECOVERY_WIDTH 10
-#define ONEWIRE_RESET_LOW_WIDTH 480
-#define ONEWIRE_RESET_SAMPLE_WIDTH 550
-#define ONEWIRE_RESET_TOTAL_WIDTH 960
-
-/**
- * @brief Local function declarations.
- */
-static void ow_reset_cb(PWMDriver *pwmp, onewireDriver *owp);
-static void pwm_reset_cb(PWMDriver *pwmp);
-static void ow_read_bit_cb(PWMDriver *pwmp, onewireDriver *owp);
-static void pwm_read_bit_cb(PWMDriver *pwmp);
-static void ow_write_bit_cb(PWMDriver *pwmp, onewireDriver *owp);
-static void pwm_write_bit_cb(PWMDriver *pwmp);
-#if ONEWIRE_USE_SEARCH_ROM
-static void ow_search_rom_cb(PWMDriver *pwmp, onewireDriver *owp);
-static void pwm_search_rom_cb(PWMDriver *pwmp);
-#endif
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-/**
- * @brief 1-wire driver identifier.
- */
-onewireDriver OWD1;
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-/**
- * @brief Look up table for fast 1-wire CRC calculation
- */
-static const uint8_t onewire_crc_table[256] = {
- 0x0, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,
- 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41,
- 0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e,
- 0x5f, 0x1, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc,
- 0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0,
- 0xe1, 0xbf, 0x5d, 0x3, 0x80, 0xde, 0x3c, 0x62,
- 0xbe, 0xe0, 0x2, 0x5c, 0xdf, 0x81, 0x63, 0x3d,
- 0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff,
- 0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5,
- 0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x7,
- 0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x6, 0x58,
- 0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,
- 0x65, 0x3b, 0xd9, 0x87, 0x4, 0x5a, 0xb8, 0xe6,
- 0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24,
- 0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b,
- 0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x5, 0xe7, 0xb9,
- 0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0xf,
- 0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,
- 0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92,
- 0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0xe, 0x50,
- 0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c,
- 0x6d, 0x33, 0xd1, 0x8f, 0xc, 0x52, 0xb0, 0xee,
- 0x32, 0x6c, 0x8e, 0xd0, 0x53, 0xd, 0xef, 0xb1,
- 0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73,
- 0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49,
- 0x8, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b,
- 0x57, 0x9, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4,
- 0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16,
- 0xe9, 0xb7, 0x55, 0xb, 0x88, 0xd6, 0x34, 0x6a,
- 0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8,
- 0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7,
- 0xb6, 0xe8, 0xa, 0x54, 0xd7, 0x89, 0x6b, 0x35
-};
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-/**
- * @brief Put bus in idle mode.
- */
-static void ow_bus_idle(onewireDriver *owp) {
-#if defined(STM32F1XX)
- palSetPadMode(owp->config->port, owp->config->pad,
- owp->config->pad_mode_idle);
-#endif
- pwmStop(owp->config->pwmd);
-}
-
-/**
- * @brief Put bus in active mode.
- */
-static void ow_bus_active(onewireDriver *owp) {
- pwmStart(owp->config->pwmd, owp->config->pwmcfg);
-#if defined(STM32F1XX)
- palSetPadMode(owp->config->port, owp->config->pad,
- owp->config->pad_mode_active);
-#endif
-}
-
-/**
- * @brief Function performing read of single bit.
- * @note It must be callable from any context.
- */
-static ioline_t ow_read_bit(onewireDriver *owp) {
-#if ONEWIRE_SYNTH_SEARCH_TEST
- (void)owp;
- return _synth_ow_read_bit();
-#else
- return palReadPad(owp->config->port, owp->config->pad);
-#endif
-}
-
-/**
- * @brief PWM adapter
- */
-static void pwm_reset_cb(PWMDriver *pwmp) {
- ow_reset_cb(pwmp, &OWD1);
-}
-
-/**
- * @brief PWM adapter
- */
-static void pwm_read_bit_cb(PWMDriver *pwmp) {
- ow_read_bit_cb(pwmp, &OWD1);
-}
-
-/**
- * @brief PWM adapter
- */
-static void pwm_write_bit_cb(PWMDriver *pwmp) {
- ow_write_bit_cb(pwmp, &OWD1);
-}
-
-#if ONEWIRE_USE_SEARCH_ROM
-/**
- * @brief PWM adapter
- */
-static void pwm_search_rom_cb(PWMDriver *pwmp) {
- ow_search_rom_cb(pwmp, &OWD1);
-}
-#endif /* ONEWIRE_USE_SEARCH_ROM */
-
-/**
- * @brief Write bit routine.
- * @details Switch PWM channel to 'width' or 'narrow' pulse depending
- * on value of bit need to be transmitted.
- *
- * @param[in] owp pointer to the @p onewireDriver object
- * @param[in] bit value to be written
- *
- * @notapi
- */
-static void ow_write_bit_I(onewireDriver *owp, ioline_t bit) {
-#if ONEWIRE_SYNTH_SEARCH_TEST
- _synth_ow_write_bit(owp, bit);
-#else
- osalSysLockFromISR();
- if (0 == bit) {
- pwmEnableChannelI(owp->config->pwmd, owp->config->master_channel,
- ONEWIRE_ZERO_WIDTH);
- }
- else {
- pwmEnableChannelI(owp->config->pwmd, owp->config->master_channel,
- ONEWIRE_ONE_WIDTH);
- }
- osalSysUnlockFromISR();
-#endif
-}
-
-/**
- * @brief 1-wire reset pulse callback.
- * @note Must be called from PWM's ISR.
- *
- * @param[in] pwmp pointer to the @p PWMDriver object
- * @param[in] owp pointer to the @p onewireDriver object
- *
- * @notapi
- */
-static void ow_reset_cb(PWMDriver *pwmp, onewireDriver *owp) {
-
- owp->reg.slave_present = (PAL_LOW == ow_read_bit(owp));
-
- osalSysLockFromISR();
- pwmDisableChannelI(pwmp, owp->config->sample_channel);
- osalThreadResumeI(&owp->thread, MSG_OK);
- osalSysUnlockFromISR();
-}
-
-/**
- * @brief 1-wire read bit callback.
- * @note Must be called from PWM's ISR.
- *
- * @param[in] pwmp pointer to the @p PWMDriver object
- * @param[in] owp pointer to the @p onewireDriver object
- *
- * @notapi
- */
-static void ow_read_bit_cb(PWMDriver *pwmp, onewireDriver *owp) {
-
- if (true == owp->reg.final_timeslot) {
- osalSysLockFromISR();
- pwmDisableChannelI(pwmp, owp->config->sample_channel);
- osalThreadResumeI(&owp->thread, MSG_OK);
- osalSysUnlockFromISR();
- return;
- }
- else {
- *owp->buf |= ow_read_bit(owp) << owp->reg.bit;
- owp->reg.bit++;
- if (8 == owp->reg.bit) {
- owp->reg.bit = 0;
- owp->buf++;
- owp->reg.bytes--;
- if (0 == owp->reg.bytes) {
- owp->reg.final_timeslot = true;
- osalSysLockFromISR();
- /* Only master channel must be stopped here.
- Sample channel will be stopped in next ISR call.
- It is still needed to generate final interrupt. */
- pwmDisableChannelI(pwmp, owp->config->master_channel);
- osalSysUnlockFromISR();
- }
- }
- }
-}
-
-/**
- * @brief 1-wire bit transmission callback.
- * @note Must be called from PWM's ISR.
- *
- * @param[in] pwmp pointer to the @p PWMDriver object
- * @param[in] owp pointer to the @p onewireDriver object
- *
- * @notapi
- */
-static void ow_write_bit_cb(PWMDriver *pwmp, onewireDriver *owp) {
-
- if (8 == owp->reg.bit) {
- owp->buf++;
- owp->reg.bit = 0;
- owp->reg.bytes--;
-
- if (0 == owp->reg.bytes) {
- osalSysLockFromISR();
- pwmDisableChannelI(pwmp, owp->config->master_channel);
- osalSysUnlockFromISR();
- /* used to prevent premature timer stop from userspace */
- owp->reg.final_timeslot = true;
- return;
- }
- }
-
- /* wait until timer generate last pulse */
- if (true == owp->reg.final_timeslot) {
- #if ONEWIRE_USE_STRONG_PULLUP
- if (owp->reg.need_pullup) {
- owp->reg.state = ONEWIRE_PULL_UP;
- owp->config->pullup_assert();
- owp->reg.need_pullup = false;
- }
- #endif
-
- osalSysLockFromISR();
- osalThreadResumeI(&owp->thread, MSG_OK);
- osalSysUnlockFromISR();
- return;
- }
-
- ow_write_bit_I(owp, (*owp->buf >> owp->reg.bit) & 1);
- owp->reg.bit++;
-}
-
-#if ONEWIRE_USE_SEARCH_ROM
-/**
- * @brief Helper function for collision handler
- *
- * @param[in] sr pointer to the @p onewire_search_rom_t helper structure
- * @param[in] bit discovered bit to be stored in helper structure
- */
-static void store_bit(onewire_search_rom_t *sr, uint8_t bit) {
-
- size_t rb = sr->reg.rombit;
-
- sr->retbuf[rb / CHAR_BIT] |= bit << (rb % CHAR_BIT);
- sr->reg.rombit++;
-}
-
-/**
- * @brief Helper function for collision handler
- * @details Extract bit from previous search path.
- *
- * @param[in] path pointer to the array with previous path stored in
- * 'search ROM' helper structure
- * @param[in] bit number of bit [0..63]
- */
-static uint8_t extract_path_bit(const uint8_t *path, size_t bit) {
-
- return (path[bit / CHAR_BIT] >> (bit % CHAR_BIT)) & 1;
-}
-
-/**
- * @brief Collision handler for 'search ROM' procedure.
- * @details You can find algorithm details in APPNOTE 187
- * "1-Wire Search Algorithm" from Maxim
- *
- * @param[in,out] sr pointer to the @p onewire_search_rom_t helper structure
- */
-static uint8_t collision_handler(onewire_search_rom_t *sr) {
-
- uint8_t bit;
-
- switch(sr->reg.search_iter) {
- case ONEWIRE_SEARCH_ROM_NEXT:
- if ((int)sr->reg.rombit < sr->last_zero_branch) {
- bit = extract_path_bit(sr->prev_path, sr->reg.rombit);
- if (0 == bit) {
- sr->prev_zero_branch = sr->reg.rombit;
- sr->reg.result = ONEWIRE_SEARCH_ROM_SUCCESS;
- }
- store_bit(sr, bit);
- return bit;
- }
- else if ((int)sr->reg.rombit == sr->last_zero_branch) {
- sr->last_zero_branch = sr->prev_zero_branch;
- store_bit(sr, 1);
- return 1;
- }
- else {
- /* found next branch some levels deeper */
- sr->prev_zero_branch = sr->last_zero_branch;
- sr->last_zero_branch = sr->reg.rombit;
- store_bit(sr, 0);
- sr->reg.result = ONEWIRE_SEARCH_ROM_SUCCESS;
- return 0;
- }
- break;
-
- case ONEWIRE_SEARCH_ROM_FIRST:
- /* always take 0-branch */
- sr->prev_zero_branch = sr->last_zero_branch;
- sr->last_zero_branch = sr->reg.rombit;
- store_bit(sr, 0);
- sr->reg.result = ONEWIRE_SEARCH_ROM_SUCCESS;
- return 0;
- break;
-
- default:
- osalSysHalt("Unhandled case");
- return 0; /* warning supressor */
- break;
- }
-}
-
-/**
- * @brief 1-wire search ROM callback.
- * @note Must be called from PWM's ISR.
- *
- * @param[in] pwmp pointer to the @p PWMDriver object
- * @param[in] owp pointer to the @p onewireDriver object
- *
- * @notapi
- */
-static void ow_search_rom_cb(PWMDriver *pwmp, onewireDriver *owp) {
-
- onewire_search_rom_t *sr = &owp->search_rom;
-
- if (0 == sr->reg.bit_step) { /* read direct bit */
- sr->reg.bit_buf |= ow_read_bit(owp);
- sr->reg.bit_step++;
- }
- else if (1 == sr->reg.bit_step) { /* read complement bit */
- sr->reg.bit_buf |= ow_read_bit(owp) << 1;
- sr->reg.bit_step++;
- switch(sr->reg.bit_buf){
- case 0b11:
- /* no one device on bus or any other fail happened */
- sr->reg.result = ONEWIRE_SEARCH_ROM_ERROR;
- goto THE_END;
- break;
- case 0b01:
- /* all slaves have 1 in this position */
- store_bit(sr, 1);
- ow_write_bit_I(owp, 1);
- break;
- case 0b10:
- /* all slaves have 0 in this position */
- store_bit(sr, 0);
- ow_write_bit_I(owp, 0);
- break;
- case 0b00:
- /* collision */
- sr->reg.single_device = false;
- ow_write_bit_I(owp, collision_handler(sr));
- break;
- }
- }
- else { /* start next step */
- #if !ONEWIRE_SYNTH_SEARCH_TEST
- ow_write_bit_I(owp, 1);
- #endif
- sr->reg.bit_step = 0;
- sr->reg.bit_buf = 0;
- }
-
- /* one ROM successfully discovered */
- if (64 == sr->reg.rombit) {
- sr->reg.devices_found++;
- sr->reg.search_iter = ONEWIRE_SEARCH_ROM_NEXT;
- if (true == sr->reg.single_device)
- sr->reg.result = ONEWIRE_SEARCH_ROM_LAST;
- goto THE_END;
- }
- return; /* next search bit iteration */
-
-THE_END:
-#if ONEWIRE_SYNTH_SEARCH_TEST
- (void)pwmp;
- return;
-#else
- osalSysLockFromISR();
- pwmDisableChannelI(pwmp, owp->config->master_channel);
- pwmDisableChannelI(pwmp, owp->config->sample_channel);
- osalThreadResumeI(&(owp)->thread, MSG_OK);
- osalSysUnlockFromISR();
-#endif
-}
-
-/**
- * @brief Helper function. Initialize structures required by 'search ROM'.
- * @details Early reset. Call it once before 'search ROM' routine.
- *
- * @param[in] sr pointer to the @p onewire_search_rom_t helper structure
- */
-static void search_clean_start(onewire_search_rom_t *sr) {
-
- sr->reg.single_device = true; /* presume simplest way at beginning */
- sr->reg.result = ONEWIRE_SEARCH_ROM_LAST;
- sr->reg.search_iter = ONEWIRE_SEARCH_ROM_FIRST;
- sr->retbuf = NULL;
- sr->reg.devices_found = 0;
- memset(sr->prev_path, 0, 8);
-
- sr->reg.rombit = 0;
- sr->reg.bit_step = 0;
- sr->reg.bit_buf = 0;
- sr->last_zero_branch = -1;
- sr->prev_zero_branch = -1;
-}
-
-/**
- * @brief Helper function. Prepare structures required by 'search ROM'.
- *
- * @param[in] sr pointer to the @p onewire_search_rom_t helper structure
- */
-static void search_clean_iteration(onewire_search_rom_t *sr) {
-
- sr->reg.rombit = 0;
- sr->reg.bit_step = 0;
- sr->reg.bit_buf = 0;
- sr->reg.result = ONEWIRE_SEARCH_ROM_LAST;
-}
-#endif /* ONEWIRE_USE_SEARCH_ROM */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Calculates 1-wire CRC.
- *
- * @param[in] buf pointer to the data buffer
- * @param[in] len lenght of data buffer
- *
- * @init
- */
-uint8_t onewireCRC(const uint8_t *buf, size_t len) {
- uint8_t ret = 0;
- size_t i;
-
- for (i=0; i<len; i++)
- ret = onewire_crc_table[ret ^ buf[i]];
-
- return ret;
-}
-
-/**
- * @brief Initializes @p onewireDriver structure.
- *
- * @param[out] owp pointer to the @p onewireDriver object
- *
- * @init
- */
-void onewireObjectInit(onewireDriver *owp) {
-
- osalDbgCheck(NULL != owp);
-
- owp->config = NULL;
- owp->reg.slave_present = false;
- owp->reg.state = ONEWIRE_STOP;
- owp->thread = NULL;
-
- owp->reg.bytes = 0;
- owp->reg.bit = 0;
- owp->reg.final_timeslot = false;
- owp->buf = NULL;
-
-#if ONEWIRE_USE_STRONG_PULLUP
- owp->reg.need_pullup = false;
-#endif
-}
-
-/**
- * @brief Configures and activates the 1-wire driver.
- *
- * @param[in] owp pointer to the @p onewireDriver object
- * @param[in] config pointer to the @p onewireConfig object
- *
- * @api
- */
-void onewireStart(onewireDriver *owp, const onewireConfig *config) {
-
- osalDbgCheck((NULL != owp) && (NULL != config));
- osalDbgAssert(PWM_STOP == config->pwmd->state,
- "PWM will be started by onewire driver internally");
- osalDbgAssert(ONEWIRE_STOP == owp->reg.state, "Invalid state");
-#if ONEWIRE_USE_STRONG_PULLUP
- osalDbgCheck((NULL != config->pullup_assert) &&
- (NULL != config->pullup_release));
-#endif
-
- owp->config = config;
- owp->config->pwmcfg->frequency = ONEWIRE_PWM_FREQUENCY;
- owp->config->pwmcfg->period = ONEWIRE_RESET_TOTAL_WIDTH;
-
-#if !defined(STM32F1XX)
- palSetPadMode(owp->config->port, owp->config->pad,
- owp->config->pad_mode_active);
-#endif
- ow_bus_idle(owp);
- owp->reg.state = ONEWIRE_READY;
-}
-
-/**
- * @brief Deactivates the UART peripheral.
- *
- * @param[in] owp pointer to the @p onewireDriver object
- *
- * @api
- */
-void onewireStop(onewireDriver *owp) {
- osalDbgCheck(NULL != owp);
-#if ONEWIRE_USE_STRONG_PULLUP
- owp->config->pullup_release();
-#endif
- ow_bus_idle(owp);
- pwmStop(owp->config->pwmd);
- owp->config = NULL;
- owp->reg.state = ONEWIRE_STOP;
-}
-
-/**
- * @brief Generate reset pulse on bus.
- *
- * @param[in] owp pointer to the @p onewireDriver object
- *
- * @return Bool flag denoting device presence.
- * @retval true There is at least one device on bus.
- */
-bool onewireReset(onewireDriver *owp) {
- PWMDriver *pwmd;
- PWMConfig *pwmcfg;
- size_t mch, sch;
-
- osalDbgCheck(NULL != owp);
- osalDbgAssert(owp->reg.state == ONEWIRE_READY, "Invalid state");
-
- /* short circuit on bus or any other device transmit data */
- if (PAL_LOW == ow_read_bit(owp))
- return false;
-
- pwmd = owp->config->pwmd;
- pwmcfg = owp->config->pwmcfg;
- mch = owp->config->master_channel;
- sch = owp->config->sample_channel;
-
-
- pwmcfg->period = ONEWIRE_RESET_LOW_WIDTH + ONEWIRE_RESET_SAMPLE_WIDTH;
- pwmcfg->callback = NULL;
- pwmcfg->channels[mch].callback = NULL;
- pwmcfg->channels[mch].mode = owp->config->pwmmode;
- pwmcfg->channels[sch].callback = pwm_reset_cb;
- pwmcfg->channels[sch].mode = PWM_OUTPUT_ACTIVE_LOW;
-
- ow_bus_active(owp);
-
- osalSysLock();
- pwmEnableChannelI(pwmd, mch, ONEWIRE_RESET_LOW_WIDTH);
- pwmEnableChannelI(pwmd, sch, ONEWIRE_RESET_SAMPLE_WIDTH);
- pwmEnableChannelNotificationI(pwmd, sch);
- osalThreadSuspendS(&owp->thread);
- osalSysUnlock();
-
- ow_bus_idle(owp);
-
- /* wait until slave release bus to discriminate short circuit condition */
- osalThreadSleepMicroseconds(500);
- return (PAL_HIGH == ow_read_bit(owp)) && (true == owp->reg.slave_present);
-}
-
-/**
- * @brief Read some bites from slave device.
- *
- * @param[in] owp pointer to the @p onewireDriver object
- * @param[out] rxbuf pointer to the buffer for read data
- * @param[in] rxbytes amount of data to be received
- */
-void onewireRead(onewireDriver *owp, uint8_t *rxbuf, size_t rxbytes) {
- PWMDriver *pwmd;
- PWMConfig *pwmcfg;
- size_t mch, sch;
-
- osalDbgCheck((NULL != owp) && (NULL != rxbuf));
- osalDbgCheck((rxbytes > 0) && (rxbytes <= ONEWIRE_MAX_TRANSACTION_LEN));
- osalDbgAssert(owp->reg.state == ONEWIRE_READY, "Invalid state");
-
- /* Buffer zeroing. This is important because of driver collects
- bits using |= operation.*/
- memset(rxbuf, 0, rxbytes);
-
- pwmd = owp->config->pwmd;
- pwmcfg = owp->config->pwmcfg;
- mch = owp->config->master_channel;
- sch = owp->config->sample_channel;
-
- owp->reg.bit = 0;
- owp->reg.final_timeslot = false;
- owp->buf = rxbuf;
- owp->reg.bytes = rxbytes;
-
- pwmcfg->period = ONEWIRE_ZERO_WIDTH + ONEWIRE_RECOVERY_WIDTH;
- pwmcfg->callback = NULL;
- pwmcfg->channels[mch].callback = NULL;
- pwmcfg->channels[mch].mode = owp->config->pwmmode;
- pwmcfg->channels[sch].callback = pwm_read_bit_cb;
- pwmcfg->channels[sch].mode = PWM_OUTPUT_ACTIVE_LOW;
-
- ow_bus_active(owp);
- osalSysLock();
- pwmEnableChannelI(pwmd, mch, ONEWIRE_ONE_WIDTH);
- pwmEnableChannelI(pwmd, sch, ONEWIRE_SAMPLE_WIDTH);
- pwmEnableChannelNotificationI(pwmd, sch);
- osalThreadSuspendS(&owp->thread);
- osalSysUnlock();
-
- ow_bus_idle(owp);
-}
-
-/**
- * @brief Read some bites from slave device.
- *
- * @param[in] owp pointer to the @p onewireDriver object
- * @param[in] txbuf pointer to the buffer with data to be written
- * @param[in] txbytes amount of data to be written
- * @param[in] pullup_time how long strong pull up must be activated. Set
- * it to 0 if not needed.
- */
-void onewireWrite(onewireDriver *owp, uint8_t *txbuf,
- size_t txbytes, systime_t pullup_time) {
- PWMDriver *pwmd;
- PWMConfig *pwmcfg;
- size_t mch, sch;
-
- osalDbgCheck((NULL != owp) && (NULL != txbuf));
- osalDbgCheck((txbytes > 0) && (txbytes <= ONEWIRE_MAX_TRANSACTION_LEN));
- osalDbgAssert(owp->reg.state == ONEWIRE_READY, "Invalid state");
-#if !ONEWIRE_USE_STRONG_PULLUP
- osalDbgAssert(0 == pullup_time,
- "Non zero time is valid only when strong pull enabled");
-#endif
-
- pwmd = owp->config->pwmd;
- pwmcfg = owp->config->pwmcfg;
- mch = owp->config->master_channel;
- sch = owp->config->sample_channel;
-
- owp->buf = txbuf;
- owp->reg.bit = 0;
- owp->reg.final_timeslot = false;
- owp->reg.bytes = txbytes;
-
- pwmcfg->period = ONEWIRE_ZERO_WIDTH + ONEWIRE_RECOVERY_WIDTH;
- pwmcfg->callback = pwm_write_bit_cb;
- pwmcfg->channels[mch].callback = NULL;
- pwmcfg->channels[mch].mode = owp->config->pwmmode;
- pwmcfg->channels[sch].callback = NULL;
- pwmcfg->channels[sch].mode = PWM_OUTPUT_DISABLED;
-
-#if ONEWIRE_USE_STRONG_PULLUP
- if (pullup_time > 0) {
- owp->reg.state = ONEWIRE_PULL_UP;
- owp->reg.need_pullup = true;
- }
-#endif
-
- ow_bus_active(owp);
- osalSysLock();
- pwmEnablePeriodicNotificationI(pwmd);
- osalThreadSuspendS(&owp->thread);
- osalSysUnlock();
-
- pwmDisablePeriodicNotification(pwmd);
- ow_bus_idle(owp);
-
-#if ONEWIRE_USE_STRONG_PULLUP
- if (pullup_time > 0) {
- osalThreadSleep(pullup_time);
- owp->config->pullup_release();
- owp->reg.state = ONEWIRE_READY;
- }
-#endif
-}
-
-#if ONEWIRE_USE_SEARCH_ROM
-/**
- * @brief Performs tree search on bus.
- * @note This function does internal 1-wire reset calls every search
- * iteration.
- *
- * @param[in] owp pointer to a @p OWDriver object
- * @param[out] result pointer to buffer for discovered ROMs
- * @param[in] max_rom_cnt buffer size in ROMs count for overflow prevention
- *
- * @return Count of discovered ROMs. May be more than max_rom_cnt.
- * @retval 0 no ROMs found or communication error occurred.
- */
-size_t onewireSearchRom(onewireDriver *owp, uint8_t *result,
- size_t max_rom_cnt) {
- PWMDriver *pwmd;
- PWMConfig *pwmcfg;
- uint8_t cmd;
- size_t mch, sch;
-
- osalDbgCheck(NULL != owp);
- osalDbgAssert(ONEWIRE_READY == owp->reg.state, "Invalid state");
- osalDbgCheck((max_rom_cnt <= 256) && (max_rom_cnt > 0));
-
- pwmd = owp->config->pwmd;
- pwmcfg = owp->config->pwmcfg;
- cmd = ONEWIRE_CMD_SEARCH_ROM;
- mch = owp->config->master_channel;
- sch = owp->config->sample_channel;
-
- search_clean_start(&owp->search_rom);
-
- do {
- /* every search must be started from reset pulse */
- if (false == onewireReset(owp))
- return 0;
-
- /* 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);
-
- /**/
- onewireWrite(&OWD1, &cmd, 1, 0);
-
- /* Reconfiguration always needed because of previous call onewireWrite.*/
- pwmcfg->period = ONEWIRE_ZERO_WIDTH + ONEWIRE_RECOVERY_WIDTH;
- pwmcfg->callback = NULL;
- pwmcfg->channels[mch].callback = NULL;
- pwmcfg->channels[mch].mode = owp->config->pwmmode;
- pwmcfg->channels[sch].callback = pwm_search_rom_cb;
- pwmcfg->channels[sch].mode = PWM_OUTPUT_ACTIVE_LOW;
-
- ow_bus_active(owp);
- osalSysLock();
- pwmEnableChannelI(pwmd, mch, ONEWIRE_ONE_WIDTH);
- pwmEnableChannelI(pwmd, sch, ONEWIRE_SAMPLE_WIDTH);
- pwmEnableChannelNotificationI(pwmd, sch);
- osalThreadSuspendS(&owp->thread);
- osalSysUnlock();
-
- ow_bus_idle(owp);
-
- if (ONEWIRE_SEARCH_ROM_ERROR != owp->search_rom.reg.result) {
- /* check CRC and return 0 (0 == error) if mismatch */
- if (owp->search_rom.retbuf[7] != onewireCRC(owp->search_rom.retbuf, 7))
- return 0;
- /* 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;
-}
-#endif /* ONEWIRE_USE_SEARCH_ROM */
-
-/*
- * Include test code (if enabled).
- */
-#if ONEWIRE_SYNTH_SEARCH_TEST
-#include "search_rom_synth.c"
-#endif
-
-#endif /* HAL_USE_ONEWIRE */
-
-/** @} */