/** * @file include/di_fw/onewire.h * @brief Onewire header file * @date August 26, 2016 * @author R.W.A. van der Heijden * @copyright 2016 Dual Inventive Technology Centre B.V. */ #ifndef _ONEWIRE_H_ #define _ONEWIRE_H_ /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ /** * @brief Enable synthetic test for 'search ROM' procedure. * @note Only for debugging/testing! */ #define ONEWIRE_SYNTH_SEARCH_TEST FALSE #define ONEWIRE_USE_SEARCH_ROM TRUE /** * @brief Aliases for 1-wire protocol. */ #define ONEWIRE_CMD_READ_ROM 0x33 #define ONEWIRE_CMD_SEARCH_ROM 0xF0 #define ONEWIRE_CMD_MATCH_ROM 0x55 #define ONEWIRE_CMD_SKIP_ROM 0xCC #define ONEWIRE_CMD_CONVERT_TEMP 0x44 #define ONEWIRE_CMD_READ_SCRATCHPAD 0xBE /** * @brief How many bits will be used for transaction length storage. */ #define ONEWIRE_REG_BYTES_WIDTH 16U /** * @brief Precalculated maximum transaction length. */ #define ONEWIRE_MAX_TRANSACTION_LEN ((1U << ONEWIRE_REG_BYTES_WIDTH) - 1U) /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ #if !HAL_USE_PWM #error "1-wire Driver requires HAL_USE_PWM" #endif #if !HAL_USE_PAL #error "1-wire Driver requires HAL_USE_PAL" #endif /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ /** * @brief Driver state machine possible states. */ typedef enum { ONEWIRE_UNINIT = 0, /**< Not initialized. */ ONEWIRE_STOP = 1, /**< Stopped. */ ONEWIRE_READY = 2, /**< Ready. */ } onewire_state_t; #if ONEWIRE_USE_SEARCH_ROM /** * @brief Search ROM procedure possible state. */ typedef enum { ONEWIRE_SEARCH_ROM_SUCCESS = 0, /**< ROM successfully discovered. */ ONEWIRE_SEARCH_ROM_LAST = 1, /**< Last ROM successfully discovered. */ ONEWIRE_SEARCH_ROM_ERROR = 2 /**< Error happened during search. */ } search_rom_result_t; /** * @brief Search ROM procedure iteration enum. */ typedef enum { ONEWIRE_SEARCH_ROM_FIRST = 0, /**< First search run. */ ONEWIRE_SEARCH_ROM_NEXT = 1 /**< Next search run. */ } search_iteration_t; #endif /* ONEWIRE_USE_SEARCH_ROM */ /** * @brief Driver configuration structure. */ typedef struct { /** * @brief Pointer to @p PWM driver used for communication. */ PWMDriver *pwmd; /** * @brief Pointer to configuration structure for underlying PWM driver. * @note It is NOT constant because 1-wire driver needs to change them * during normal functioning. */ PWMConfig *pwmcfg; /** * @brief Active logic level for master channel. * @details Just set it to @p PWM_OUTPUT_ACTIVE_LOW when 1-wire bus * connected to direct (not complementary) output of the timer. * In opposite case you need to check documentation to choose * correct value. */ pwmmode_t pwmmode; /** * @brief Number of PWM channel used as master pulse generator. */ pwmchannel_t master_channel; /** * @brief Number of PWM channel used as sample interrupt generator. */ pwmchannel_t sample_channel; /** * @brief Port Identifier. * @details This type can be a scalar or some kind of pointer, do not make * any assumption about it, use the provided macros when populating * variables of this type. */ ioportid_t port; /** * @brief Digital I/O port pad. */ ioportmask_t pad; #if defined(STM32F1XX) /** * @brief Digital I/O mode for idle bus. * @details This is a kind of workaround against F1x realization of alternate * function. Alternate function mode will be activated only * when you starts appropriate peripheral. */ iomode_t pad_mode_idle; #endif /** * @brief Digital I/O mode for active bus. */ iomode_t pad_mode_active; } onewireConfig; #if ONEWIRE_USE_SEARCH_ROM /** * @brief Search ROM registry. Contains small variables used * in 'search ROM' procedure. */ typedef struct { /** * @brief Bool flag. True when bus has single slave device. */ uint32_t single_device: 1; /** * @brief Search iteration (@p search_iteration_t enum). */ uint32_t search_iter: 1; /** * @brief Result of discovery procedure (@p search_rom_result_t enum). */ uint32_t result: 2; /** * @brief One of 3 steps of bit discovery. * @details 0 - direct, 1 - complemented, 2 - generated by master. */ uint32_t bit_step: 2; /** * @brief Values acquired during bit discovery. */ uint32_t bit_buf: 2; /** * @brief Currently processing ROM bit. * @note Must be big enough to store number 64. */ uint32_t rombit: 7; /** * @brief Total device count discovered on bus. * @note Maximum 256. */ uint32_t devices_found: 8; } search_rom_reg_t; /** * @brief Helper structure for 'search ROM' procedure */ typedef struct { /** * @brief Search ROM registry. */ search_rom_reg_t reg; /** * @brief Pointer to buffer with currently discovering ROM */ uint8_t *retbuf; /** * @brief Previously discovered ROM. */ uint8_t prev_path[8]; /** * @brief Last zero turn branch. * @note Negative values use to point out of device tree's root. */ int8_t last_zero_branch; /** * @brief Previous zero turn branch. * @note Negative values use to point out of device tree's root. */ int8_t prev_zero_branch; } onewire_search_rom_t; #endif /* ONEWIRE_USE_SEARCH_ROM */ /** * @brief Onewire registry. Some small variables combined * in single machine word to save RAM. */ typedef struct { /** * @brief Bool flag. If @p true than at least one device presence on bus. */ uint32_t slave_present: 1; /** * @brief Driver internal state (@p onewire_state_t enum). */ uint32_t state: 2; /** * @brief Bit number in currently receiving/sending byte. * @note Must be big enough to store 8. */ uint32_t bit: 4; /** * @brief Bool flag for premature timer stop prevention. */ uint32_t final_timeslot: 1; /** * @brief Bytes number to be processing in current transaction. */ uint32_t bytes: ONEWIRE_REG_BYTES_WIDTH; } onewire_reg_t; /** * @brief Structure representing an 1-wire driver. */ typedef struct { /** * @brief Onewire registry. */ onewire_reg_t reg; /** * @brief Onewire config. */ const onewireConfig *config; /** * @brief Pointer to I/O data buffer. */ uint8_t *buf; #if ONEWIRE_USE_SEARCH_ROM /** * @brief Search ROM helper structure. */ onewire_search_rom_t search_rom; #endif /* ONEWIRE_USE_SEARCH_ROM */ /** * @brief Thread waiting for I/O completion. */ thread_reference_t thread; } onewireDriver; /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ extern onewireDriver OWD1; void onewireInit(void); void onewireObjectInit(onewireDriver *owp); void onewireStart(onewireDriver *owp, const onewireConfig *config); void onewireStop(onewireDriver *owp); bool onewireReset(onewireDriver *owp); void onewireRead(onewireDriver *owp, uint8_t *rxbuf, size_t rxbytes); uint8_t onewireCRC(const uint8_t *buf, size_t len); void onewireWrite(onewireDriver *owp, uint8_t *txbuf, size_t txbytes); #if ONEWIRE_USE_SEARCH_ROM size_t onewireSearchRom(onewireDriver *owp, uint8_t *result, size_t max_rom_cnt); #endif /* ONEWIRE_USE_SEARCH_ROM */ #endif /* _ONEWIRE_H_ */ /** @} */