From 03c14d1d807783de7b8560727843802c00b19d0f Mon Sep 17 00:00:00 2001 From: batt Date: Tue, 11 Nov 2008 18:15:01 +0000 Subject: [PATCH] Add configurable option to choose at compile time which i2c backend to use. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@1926 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cfg/cfg_i2c.h | 7 ++++++ bertos/cpu/avr/drv/i2c_avr.c | 18 +++++++------- bertos/drv/i2c.h | 48 +++++++++++++++++++++++++++++++----- bertos/drv/i2c_bitbang.c | 22 ++++++++--------- 4 files changed, 69 insertions(+), 26 deletions(-) diff --git a/bertos/cfg/cfg_i2c.h b/bertos/cfg/cfg_i2c.h index 08f02b5c..23313443 100644 --- a/bertos/cfg/cfg_i2c.h +++ b/bertos/cfg/cfg_i2c.h @@ -50,6 +50,13 @@ */ #define CONFIG_I2C_START_TIMEOUT 100 +/** + * I2C driver can have 2 backends: + * I2C_BACKEND_BUILTIN: Use (if present) the builtin i2c hardware. + * I2C_BACKEND_BITBANG: Use the emulated bitbang driver. + */ +#define CONFIG_I2C_BACKEND I2C_BACKEND_BUILTIN + /// Module logging level definition. #define I2C_LOG_LEVEL LOG_LVL_INFO diff --git a/bertos/cpu/avr/drv/i2c_avr.c b/bertos/cpu/avr/drv/i2c_avr.c index 335d8330..2681bb75 100644 --- a/bertos/cpu/avr/drv/i2c_avr.c +++ b/bertos/cpu/avr/drv/i2c_avr.c @@ -67,7 +67,7 @@ * * \return true on success, false otherwise. */ -static bool i2c_start(void) +static bool i2c_builtin_start(void) { TWCR = BV(TWINT) | BV(TWSTA) | BV(TWEN); WAIT_TWI_READY; @@ -87,7 +87,7 @@ static bool i2c_start(void) * * \return true on success, false otherwise. */ -bool i2c_start_w(uint8_t id) +bool i2c_builtin_start_w(uint8_t id) { /* * Loop on the select write sequence: when the eeprom is busy @@ -96,7 +96,7 @@ bool i2c_start_w(uint8_t id) * keep trying until the eeprom responds with an ACK. */ ticks_t start = timer_clock(); - while (i2c_start()) + while (i2c_builtin_start()) { TWDR = id & ~I2C_READBIT; TWCR = BV(TWINT) | BV(TWEN); @@ -127,9 +127,9 @@ bool i2c_start_w(uint8_t id) * * \return true on success, false otherwise. */ -bool i2c_start_r(uint8_t id) +bool i2c_builtin_start_r(uint8_t id) { - if (i2c_start()) + if (i2c_builtin_start()) { TWDR = id | I2C_READBIT; TWCR = BV(TWINT) | BV(TWEN); @@ -148,7 +148,7 @@ bool i2c_start_r(uint8_t id) /** * Send STOP condition. */ -void i2c_stop(void) +void i2c_builtin_stop(void) { TWCR = BV(TWINT) | BV(TWEN) | BV(TWSTO); } @@ -160,7 +160,7 @@ void i2c_stop(void) * * \return true on success, false on error. */ -bool i2c_put(const uint8_t data) +bool i2c_builtin_put(const uint8_t data) { TWDR = data; TWCR = BV(TWINT) | BV(TWEN); @@ -181,7 +181,7 @@ bool i2c_put(const uint8_t data) * * \return the byte read if ok, EOF on errors. */ -int i2c_get(bool ack) +int i2c_builtin_get(bool ack) { TWCR = BV(TWINT) | BV(TWEN) | (ack ? BV(TWEA) : 0); WAIT_TWI_READY; @@ -212,7 +212,7 @@ MOD_DEFINE(i2c); /** * Initialize TWI module. */ -void i2c_init(void) +void i2c_builtin_init(void) { ATOMIC( /* diff --git a/bertos/drv/i2c.h b/bertos/drv/i2c.h index f09ec44f..f07c083d 100644 --- a/bertos/drv/i2c.h +++ b/bertos/drv/i2c.h @@ -38,16 +38,52 @@ #ifndef DRV_I2C_H #define DRV_I2C_H +#include "cfg/cfg_i2c.h" #include #define I2C_READBIT BV(0) -void i2c_init(void); -bool i2c_start_w(uint8_t id); -bool i2c_start_r(uint8_t id); -void i2c_stop(void); -bool i2c_put(uint8_t _data); -int i2c_get(bool ack); +/** + * I2C Backends. + * \{ + */ +#define I2C_BACKEND_BUILTIN 0 ///< Uses cpu builtin i2c driver +#define I2C_BACKEND_BITBANG 1 ///< Uses emulated bitbang driver +/*\}*/ + +void i2c_builtin_init(void); +bool i2c_builtin_start_w(uint8_t id); +bool i2c_builtin_start_r(uint8_t id); +void i2c_builtin_stop(void); +bool i2c_builtin_put(uint8_t _data); +int i2c_builtin_get(bool ack); + +void i2c_bitbang_init(void); +bool i2c_bitbang_start_w(uint8_t id); +bool i2c_bitbang_start_r(uint8_t id); +void i2c_bitbang_stop(void); +bool i2c_bitbang_put(uint8_t _data); +int i2c_bitbang_get(bool ack); + + +#if CONFIG_I2C_BACKEND == I2C_BACKEND_BUILTIN + #define i2c_init i2c_builtin_init + #define i2c_start_w i2c_builtin_start_w + #define i2c_start_r i2c_builtin_start_r + #define i2c_stop i2c_builtin_stop + #define i2c_put i2c_builtin_put + #define i2c_get i2c_builtin_get +#elif CONFIG_I2C_BACKEND == I2C_BACKEND_BITBANG + #define i2c_init i2c_bitbang_init + #define i2c_start_w i2c_bitbang_start_w + #define i2c_start_r i2c_bitbang_start_r + #define i2c_stop i2c_bitbang_stop + #define i2c_put i2c_bitbang_put + #define i2c_get i2c_bitbang_get +#else + #error Unsupported i2c backend. +#endif + bool i2c_send(const void *_buf, size_t count); bool i2c_recv(void *_buf, size_t count); diff --git a/bertos/drv/i2c_bitbang.c b/bertos/drv/i2c_bitbang.c index 1b7b7878..07dd2c04 100644 --- a/bertos/drv/i2c_bitbang.c +++ b/bertos/drv/i2c_bitbang.c @@ -51,7 +51,7 @@ #include "hw/hw_i2c_bitbang.h" -INLINE bool i2c_start(void) +INLINE bool i2c_bitbang_start(void) { SDA_HI; SCL_HI; @@ -62,7 +62,7 @@ INLINE bool i2c_start(void) return !SDA_IN; } -void i2c_stop(void) +void i2c_bitbang_stop(void) { SDA_LO; SCL_HI; @@ -70,7 +70,7 @@ void i2c_stop(void) SDA_HI; } -bool i2c_put(uint8_t _data) +bool i2c_bitbang_put(uint8_t _data) { /* Add ACK bit */ uint16_t data = (_data << 1) | 1; @@ -94,7 +94,7 @@ bool i2c_put(uint8_t _data) return ack; } -bool i2c_start_w(uint8_t id) +bool i2c_bitbang_start_w(uint8_t id) { id &= ~I2C_READBIT; /* @@ -104,9 +104,9 @@ bool i2c_start_w(uint8_t id) * keep trying until the deveice responds with an ACK. */ ticks_t start = timer_clock(); - while (i2c_start()) + while (i2c_bitbang_start()) { - if (i2c_put(id)) + if (i2c_bitbang_put(id)) return true; else if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT)) { @@ -119,12 +119,12 @@ bool i2c_start_w(uint8_t id) return false; } -bool i2c_start_r(uint8_t id) +bool i2c_bitbang_start_r(uint8_t id) { id |= I2C_READBIT; - if (i2c_start()) + if (i2c_bitbang_start()) { - if (i2c_put(id)) + if (i2c_bitbang_put(id)) return true; LOG_ERR("NACK on I2c start read\n"); @@ -133,7 +133,7 @@ bool i2c_start_r(uint8_t id) return false; } -int i2c_get(bool ack) +int i2c_bitbang_get(bool ack) { uint8_t data = 0; for (uint8_t i = 0x80; i != 0; i >>= 1) @@ -169,7 +169,7 @@ MOD_DEFINE(i2c); /** * Initialize i2c module. */ -void i2c_init(void) +void i2c_bitbang_init(void) { MOD_CHECK(timer); I2C_BITBANG_HW_INIT; -- 2.25.1