aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/include/onewire.h41
-rw-r--r--os/hal/src/onewire.c92
2 files changed, 74 insertions, 59 deletions
diff --git a/os/hal/include/onewire.h b/os/hal/include/onewire.h
index fac0b54..2d27f48 100644
--- a/os/hal/include/onewire.h
+++ b/os/hal/include/onewire.h
@@ -46,6 +46,16 @@
#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. */
/*===========================================================================*/
@@ -116,6 +126,20 @@ 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.
*/
@@ -167,7 +191,7 @@ typedef struct {
*/
typedef struct {
/**
- * @brief Bool flag. If @p true than only bus has only one slave device.
+ * @brief Bool flag. True when bus has single slave device.
*/
uint32_t single_device: 1;
/**
@@ -260,7 +284,7 @@ typedef struct {
/**
* @brief Bytes number to be processing in current transaction.
*/
- uint32_t bytes: 16;
+ uint32_t bytes: ONEWIRE_REG_BYTES_WIDTH;
} onewire_reg_t;
/**
@@ -276,10 +300,6 @@ typedef struct {
*/
const onewireConfig *config;
/**
- * @brief Config for underlying PWM driver.
- */
- PWMConfig pwmcfg;
- /**
* @brief Pointer to I/O data buffer.
*/
uint8_t *buf;
@@ -315,14 +335,11 @@ extern "C" {
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,
- systime_t pullup_time);
+ void onewireWrite(onewireDriver *owp, uint8_t *txbuf,
+ size_t txbytes, systime_t pullup_time);
#if ONEWIRE_USE_SEARCH_ROM
size_t onewireSearchRom(onewireDriver *owp,
- uint8_t *result,
- size_t max_rom_cnt);
+ uint8_t *result, size_t max_rom_cnt);
#endif /* ONEWIRE_USE_SEARCH_ROM */
#if ONEWIRE_SYNTH_SEARCH_TEST
void _synth_ow_write_bit(onewireDriver *owp, uint8_t bit);
diff --git a/os/hal/src/onewire.c b/os/hal/src/onewire.c
index 8c92434..d11196c 100644
--- a/os/hal/src/onewire.c
+++ b/os/hal/src/onewire.c
@@ -63,7 +63,12 @@ on every timer overflow event.
/* Driver local definitions. */
/*===========================================================================*/
/**
- * @brief Pulse width constants.
+ * @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"
*/
@@ -101,23 +106,6 @@ onewireDriver OWD1;
/* Driver local variables and types. */
/*===========================================================================*/
/**
- * @brief Config for fast initialization of all config's fields
- */
-static const PWMConfig pwm_default_cfg = {
- 1000000,
- ONEWIRE_RESET_TOTAL_WIDTH,
- NULL,
- {
- {PWM_OUTPUT_DISABLED, NULL},
- {PWM_OUTPUT_DISABLED, NULL},
- {PWM_OUTPUT_DISABLED, NULL},
- {PWM_OUTPUT_DISABLED, NULL}
- },
- 0,
- 0
-};
-
-/**
* @brief Look up table for fast 1-wire CRC calculation
*/
static const uint8_t onewire_crc_table[256] = {
@@ -173,7 +161,7 @@ static void ow_bus_idle(onewireDriver *owp) {
* @brief Put bus in active mode.
*/
static void ow_bus_active(onewireDriver *owp) {
- pwmStart(owp->config->pwmd, &owp->pwmcfg);
+ pwmStart(owp->config->pwmd, owp->config->pwmcfg);
#if defined(STM32F1XX)
palSetPadMode(owp->config->port, owp->config->pad,
owp->config->pad_mode_active);
@@ -588,8 +576,6 @@ void onewireObjectInit(onewireDriver *owp) {
owp->reg.final_timeslot = false;
owp->buf = NULL;
- owp->pwmcfg = pwm_default_cfg;
-
#if ONEWIRE_USE_STRONG_PULLUP
owp->reg.need_pullup = false;
#endif
@@ -615,6 +601,9 @@ void onewireStart(onewireDriver *owp, const onewireConfig *config) {
#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);
@@ -651,6 +640,7 @@ void onewireStop(onewireDriver *owp) {
*/
bool onewireReset(onewireDriver *owp) {
PWMDriver *pwmd;
+ PWMConfig *pwmcfg;
size_t mch, sch;
osalDbgCheck(NULL != owp);
@@ -661,15 +651,17 @@ bool onewireReset(onewireDriver *owp) {
return false;
pwmd = owp->config->pwmd;
+ pwmcfg = owp->config->pwmcfg;
mch = owp->config->master_channel;
sch = owp->config->sample_channel;
- owp->pwmcfg.period = ONEWIRE_RESET_LOW_WIDTH + ONEWIRE_RESET_SAMPLE_WIDTH;
- owp->pwmcfg.callback = NULL;
- owp->pwmcfg.channels[mch].callback = NULL;
- owp->pwmcfg.channels[mch].mode = PWM_OUTPUT_ACTIVE_LOW;
- owp->pwmcfg.channels[sch].callback = pwm_reset_cb;
- owp->pwmcfg.channels[sch].mode = PWM_OUTPUT_ACTIVE_LOW;
+
+ 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);
pwmEnableChannel(pwmd, mch, ONEWIRE_RESET_LOW_WIDTH);
@@ -696,10 +688,11 @@ bool onewireReset(onewireDriver *owp) {
*/
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 < 65536));
+ 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
@@ -707,6 +700,7 @@ void onewireRead(onewireDriver *owp, uint8_t *rxbuf, size_t rxbytes) {
memset(rxbuf, 0, rxbytes);
pwmd = owp->config->pwmd;
+ pwmcfg = owp->config->pwmcfg;
mch = owp->config->master_channel;
sch = owp->config->sample_channel;
@@ -715,12 +709,12 @@ void onewireRead(onewireDriver *owp, uint8_t *rxbuf, size_t rxbytes) {
owp->buf = rxbuf;
owp->reg.bytes = rxbytes;
- owp->pwmcfg.period = ONEWIRE_ZERO_WIDTH + ONEWIRE_RECOVERY_WIDTH;
- owp->pwmcfg.callback = NULL;
- owp->pwmcfg.channels[mch].callback = NULL;
- owp->pwmcfg.channels[mch].mode = PWM_OUTPUT_ACTIVE_LOW;
- owp->pwmcfg.channels[sch].callback = pwm_read_bit_cb;
- owp->pwmcfg.channels[sch].mode = PWM_OUTPUT_ACTIVE_LOW;
+ 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);
pwmEnableChannel(pwmd, mch, ONEWIRE_ONE_WIDTH);
@@ -746,10 +740,11 @@ void onewireRead(onewireDriver *owp, uint8_t *rxbuf, size_t rxbytes) {
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 < 65536));
+ 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,
@@ -757,6 +752,7 @@ void onewireWrite(onewireDriver *owp, uint8_t *txbuf,
#endif
pwmd = owp->config->pwmd;
+ pwmcfg = owp->config->pwmcfg;
mch = owp->config->master_channel;
sch = owp->config->sample_channel;
@@ -765,12 +761,12 @@ void onewireWrite(onewireDriver *owp, uint8_t *txbuf,
owp->reg.final_timeslot = false;
owp->reg.bytes = txbytes;
- owp->pwmcfg.period = ONEWIRE_ZERO_WIDTH + ONEWIRE_RECOVERY_WIDTH;
- owp->pwmcfg.callback = pwm_write_bit_cb;
- owp->pwmcfg.channels[mch].callback = NULL;
- owp->pwmcfg.channels[mch].mode = PWM_OUTPUT_ACTIVE_LOW;
- owp->pwmcfg.channels[sch].callback = NULL;
- owp->pwmcfg.channels[sch].mode = PWM_OUTPUT_DISABLED;
+ 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) {
@@ -814,6 +810,7 @@ void onewireWrite(onewireDriver *owp, uint8_t *txbuf,
size_t onewireSearchRom(onewireDriver *owp, uint8_t *result,
size_t max_rom_cnt) {
PWMDriver *pwmd;
+ PWMConfig *pwmcfg;
uint8_t cmd;
size_t mch, sch;
@@ -822,6 +819,7 @@ size_t onewireSearchRom(onewireDriver *owp, uint8_t *result,
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;
@@ -847,12 +845,12 @@ size_t onewireSearchRom(onewireDriver *owp, uint8_t *result,
onewireWrite(&OWD1, &cmd, 1, 0);
/* Reconfiguration always needed because of previous call onewireWrite.*/
- owp->pwmcfg.period = ONEWIRE_ZERO_WIDTH + ONEWIRE_RECOVERY_WIDTH;
- owp->pwmcfg.callback = NULL;
- owp->pwmcfg.channels[mch].callback = NULL;
- owp->pwmcfg.channels[mch].mode = PWM_OUTPUT_ACTIVE_LOW;
- owp->pwmcfg.channels[sch].callback = pwm_search_rom_cb;
- owp->pwmcfg.channels[sch].mode = PWM_OUTPUT_ACTIVE_LOW;
+ 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);
pwmEnableChannel(pwmd, mch, ONEWIRE_ONE_WIDTH);