return (int)(uint8_t)TWDR;
}
-
-MOD_DEFINE(i2c);
-
-/**
- * Initialize TWI module.
- */
-void i2c_builtin_init(void)
-{
- ATOMIC(
- /*
- * This is pretty useless according to AVR's datasheet,
- * but it helps us driving the TWI data lines on boards
- * where the bus pull-up resistors are missing. This is
- * probably due to some unwanted interaction between the
- * port pin and the TWI lines.
- */
-#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281
- PORTD |= BV(PD0) | BV(PD1);
- DDRD |= BV(PD0) | BV(PD1);
-#elif CPU_AVR_ATMEGA8
- PORTC |= BV(PC4) | BV(PC5);
- DDRC |= BV(PC4) | BV(PC5);
-#elif CPU_AVR_ATMEGA32
- PORTC |= BV(PC1) | BV(PC0);
- DDRC |= BV(PC1) | BV(PC0);
-#else
- #error Unsupported architecture
-#endif
-
- /*
- * Set speed:
- * F = CPU_FREQ / (16 + 2*TWBR * 4^TWPS)
- */
- #ifndef CONFIG_I2C_FREQ
- #warning Using default value of 300000L for CONFIG_I2C_FREQ
- #define CONFIG_I2C_FREQ 300000L /* ~300 kHz */
- #endif
- #define TWI_PRESC 1 /* 4 ^ TWPS */
-
- TWBR = (CPU_FREQ / (2 * CONFIG_I2C_FREQ * TWI_PRESC)) - (8 / TWI_PRESC);
- TWSR = 0;
- TWCR = BV(TWEN);
- );
- MOD_INIT(i2c);
-}
-
#endif /* !CONFIG_I2C_DISABLE_OLD_API */
/*
#if !CONFIG_I2C_DISABLE_OLD_API
+I2c local_i2c_old_api;
+
/**
* Send a sequence of bytes in master transmitter mode
* to the selected slave device through the I2C bus.
#endif
+/**
+ * \name I2C bitbang devices enum
+ */
+enum
+{
+ I2C_BITBANG_OLD = -1,
+ I2C_BITBANG0 = 1000,
+ I2C_BITBANG1,
+ I2C_BITBANG2,
+ I2C_BITBANG3,
+ I2C_BITBANG4,
+ I2C_BITBANG5,
+ I2C_BITBANG6,
+ I2C_BITBANG7,
+ I2C_BITBANG8,
+ I2C_BITBANG9,
+
+ I2C_BITBANG_CNT /**< Number of serial ports */
+};
+
#if !CONFIG_I2C_DISABLE_OLD_API
/**
* that you want the builtin backend.
* \{
*/
-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);
* that you want the bitbang backend.
* \{
*/
-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);
#endif
#if CONFIG_I2C_BACKEND == I2C_BACKEND_BUILTIN
- #define i2c_init_0 i2c_builtin_init
#define i2c_start_w_1 i2c_builtin_start_w
#define i2c_start_r_1 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_0 i2c_bitbang_init
#define i2c_start_w_1 i2c_bitbang_start_w
#define i2c_start_r_1 i2c_bitbang_start_r
#define i2c_stop i2c_bitbang_stop
* I2c new api
*/
-/**
- * \name I2C bitbang devices enum
+/*
+ * I2C error flags
*/
-enum
-{
- I2C_BITBANG0 = 1000,
- I2C_BITBANG1,
- I2C_BITBANG2,
- I2C_BITBANG3,
- I2C_BITBANG4,
- I2C_BITBANG5,
- I2C_BITBANG6,
- I2C_BITBANG7,
- I2C_BITBANG8,
- I2C_BITBANG9,
-
- I2C_BITBANG_CNT /**< Number of serial ports */
-};
-
- /*
- * I2C error flags
- */
#define I2C_OK 0 ///< I2C no errors flag
#define I2C_DATA_NACK BV(4) ///< I2C generic error
#define I2C_ERR BV(3) ///< I2C generic error
return err;
}
-#define i2c_init_3(i2c, dev, clock) (dev > I2C_BITBANG0) ? i2c_hw_bitbangInit(i2c, dev) : i2c_hw_init(i2c, dev, clock)
+#define i2c_init_3(i2c, dev, clock) ((((dev) > I2C_BITBANG0) | ((dev) == I2C_BITBANG_OLD)) ? \
+ i2c_hw_bitbangInit((i2c), (dev)) : i2c_hw_init((i2c), (dev), (clock)))
+
+#if !CONFIG_I2C_DISABLE_OLD_API
+
+extern I2c local_i2c_old_api;
+
+INLINE void i2c_init_0(void)
+{
+ #if CONFIG_I2C_BACKEND == I2C_BACKEND_BITBANG
+ i2c_init_3(&local_i2c_old_api, I2C_BITBANG_OLD, CONFIG_I2C_FREQ);
+ #else
+ i2c_init_3(&local_i2c_old_api, 0, CONFIG_I2C_FREQ);
+ #endif
+}
+
+#endif /* !CONFIG_I2C_DISABLE_OLD_API */
+
#endif
return (int)(uint8_t)data;
}
-MOD_DEFINE(i2c);
-
-/**
- * Initialize i2c module.
- */
-void i2c_bitbang_init(void)
-{
- MOD_CHECK(timer);
- I2C_BITBANG_HW_INIT;
- SDA_HI;
- SCL_HI;
- MOD_INIT(i2c);
-}
#endif /* !CONFIG_I2C_DISABLE_OLD_API */
/*
* New I2C API
*/
+static bool old_api = false;
#define I2C_DEV(i2c) ((int)((i2c)->hw))
static void i2c_bitbang_stop_1(struct I2c *i2c)
{
- i2c_sdaLo(I2C_DEV(i2c));
- i2c_sclHi(I2C_DEV(i2c));
- i2c_halfbitDelay(I2C_DEV(i2c));
- i2c_sdaHi(I2C_DEV(i2c));
+ if (old_api)
+ {
+ SDA_LO;
+ SCL_HI;
+ I2C_HALFBIT_DELAY();
+ SDA_HI;
+ }
+ else
+ {
+ i2c_sdaLo(I2C_DEV(i2c));
+ i2c_sclHi(I2C_DEV(i2c));
+ i2c_halfbitDelay(I2C_DEV(i2c));
+ i2c_sdaHi(I2C_DEV(i2c));
+ }
}
INLINE bool i2c_bitbang_start_1(struct I2c *i2c)
{
- i2c_sdaHi(I2C_DEV(i2c));
- i2c_sclHi(I2C_DEV(i2c));
- i2c_halfbitDelay(I2C_DEV(i2c));
- i2c_sdaLo(I2C_DEV(i2c));
- i2c_halfbitDelay(I2C_DEV(i2c));
+ bool ret;
+ if (old_api)
+ {
+ SDA_HI;
+ SCL_HI;
+ I2C_HALFBIT_DELAY();
+ SDA_LO;
+ I2C_HALFBIT_DELAY();
- return !i2c_sdaIn(I2C_DEV(i2c));
+ ret = !SDA_IN;
+ }
+ else
+ {
+ i2c_sdaHi(I2C_DEV(i2c));
+ i2c_sclHi(I2C_DEV(i2c));
+ i2c_halfbitDelay(I2C_DEV(i2c));
+ i2c_sdaLo(I2C_DEV(i2c));
+ i2c_halfbitDelay(I2C_DEV(i2c));
+ ret = !i2c_sdaIn(I2C_DEV(i2c));
+ }
+
+ return ret;
}
static uint8_t i2c_bitbang_getc(struct I2c *i2c)
{
uint8_t data = 0;
- for (uint8_t i = 0x80; i != 0; i >>= 1)
+ if (old_api)
{
- i2c_sclLo(I2C_DEV(i2c));
- i2c_halfbitDelay(I2C_DEV(i2c));
- i2c_sclHi(I2C_DEV(i2c));
- if (i2c_sdaIn(I2C_DEV(i2c)))
- data |= i;
+ for (uint8_t i = 0x80; i != 0; i >>= 1)
+ {
+ SCL_LO;
+ I2C_HALFBIT_DELAY();
+ SCL_HI;
+ if (SDA_IN)
+ data |= i;
+ else
+ data &= ~i;
+
+ I2C_HALFBIT_DELAY();
+ }
+ SCL_LO;
+
+ /* Generate ACK/NACK */
+ if (i2c->xfer_size > 1)
+ SDA_LO;
else
- data &= ~i;
+ SDA_HI;
- i2c_halfbitDelay(I2C_DEV(i2c));
+ I2C_HALFBIT_DELAY();
+ SCL_HI;
+ I2C_HALFBIT_DELAY();
+ SCL_LO;
+ SDA_HI;
}
- i2c_sclLo(I2C_DEV(i2c));
-
- /* Generate ACK/NACK */
- if (i2c->xfer_size > 1)
- i2c_sdaLo(I2C_DEV(i2c));
else
- i2c_sdaHi(I2C_DEV(i2c));
+ {
+ for (uint8_t i = 0x80; i != 0; i >>= 1)
+ {
+ i2c_sclLo(I2C_DEV(i2c));
+ i2c_halfbitDelay(I2C_DEV(i2c));
+ i2c_sclHi(I2C_DEV(i2c));
+ if (i2c_sdaIn(I2C_DEV(i2c)))
+ data |= i;
+ else
+ data &= ~i;
+
+ i2c_halfbitDelay(I2C_DEV(i2c));
+ }
+ i2c_sclLo(I2C_DEV(i2c));
+
+ /* Generate ACK/NACK */
+ if (i2c->xfer_size > 1)
+ i2c_sdaLo(I2C_DEV(i2c));
+ else
+ i2c_sdaHi(I2C_DEV(i2c));
- i2c_halfbitDelay(I2C_DEV(i2c));
- i2c_sclHi(I2C_DEV(i2c));
- i2c_halfbitDelay(I2C_DEV(i2c));
- i2c_sclLo(I2C_DEV(i2c));
- i2c_sdaHi(I2C_DEV(i2c));
+ i2c_halfbitDelay(I2C_DEV(i2c));
+ i2c_sclHi(I2C_DEV(i2c));
+ i2c_halfbitDelay(I2C_DEV(i2c));
+ i2c_sclLo(I2C_DEV(i2c));
+ i2c_sdaHi(I2C_DEV(i2c));
+ }
/* Generate stop condition (if requested) */
if ((i2c->xfer_size == 1) && (i2c->flags & I2C_STOP))
{
/* Add ACK bit */
uint16_t data = (_data << 1) | 1;
+ bool ack;
- for (uint16_t i = 0x100; i != 0; i >>= 1)
+ if (old_api)
{
- i2c_sclLo(I2C_DEV(i2c));
- if (data & i)
- i2c_sdaHi(I2C_DEV(i2c));
- else
- i2c_sdaLo(I2C_DEV(i2c));
- i2c_halfbitDelay(I2C_DEV(i2c));
+ for (uint16_t i = 0x100; i != 0; i >>= 1)
+ {
+ SCL_LO;
+ if (data & i)
+ SDA_HI;
+ else
+ SDA_LO;
+ I2C_HALFBIT_DELAY();
+
+ SCL_HI;
+ I2C_HALFBIT_DELAY();
+ }
- i2c_sclHi(I2C_DEV(i2c));
- i2c_halfbitDelay(I2C_DEV(i2c));
+ ack = !SDA_IN;
+ SCL_LO;
+ I2C_HALFBIT_DELAY();
}
+ else
+ {
+ for (uint16_t i = 0x100; i != 0; i >>= 1)
+ {
+ i2c_sclLo(I2C_DEV(i2c));
+ if (data & i)
+ i2c_sdaHi(I2C_DEV(i2c));
+ else
+ i2c_sdaLo(I2C_DEV(i2c));
+ i2c_halfbitDelay(I2C_DEV(i2c));
+
+ i2c_sclHi(I2C_DEV(i2c));
+ i2c_halfbitDelay(I2C_DEV(i2c));
+ }
- bool ack = !i2c_sdaIn(I2C_DEV(i2c));
- i2c_sclLo(I2C_DEV(i2c));
- i2c_halfbitDelay(I2C_DEV(i2c));
+ ack = !i2c_sdaIn(I2C_DEV(i2c));
+ i2c_sclLo(I2C_DEV(i2c));
+ i2c_halfbitDelay(I2C_DEV(i2c));
+ }
if (!ack)
{
void i2c_hw_bitbangInit(I2c *i2c, int dev)
{
MOD_CHECK(timer);
- i2c->hw = (struct I2cHardware *)(dev - I2C_BITBANG0);
+ if (dev == I2C_BITBANG_OLD)
+ old_api = true;
+ else
+ i2c->hw = (struct I2cHardware *)(dev - I2C_BITBANG0);
+
i2c->vt = &i2c_bitbang_vt;
- i2c_bitbangInit(I2C_DEV(i2c));
- i2c_sdaHi(I2C_DEV(i2c));
- i2c_sclHi(I2C_DEV(i2c));
+ if (old_api)
+ {
+ I2C_BITBANG_HW_INIT;
+ SDA_HI;
+ SCL_HI;
+ }
+ else
+ {
+ i2c_bitbangInit(I2C_DEV(i2c));
+ i2c_sdaHi(I2C_DEV(i2c));
+ i2c_sclHi(I2C_DEV(i2c));
+ }
}
deg_t lm75_read_1(uint8_t sens_addr)
{
- uint8_t data[2];
- int16_t degree;
- int16_t deci_degree;
-
- if( !(i2c_start_w(SELECT_ADDRESS(sens_addr))
- && i2c_put(LM75_PAD_BYTE)
- && i2c_start_r(SELECT_ADDRESS(sens_addr))) )
- {
- i2c_stop();
- return EOF;
- }
-
- if ( !i2c_recv(data, sizeof(data)) )
- {
- i2c_stop();
- return EOF;
- }
- i2c_stop();
-
- degree = (int16_t)data[0];
- deci_degree = (int16_t)(((data[1] >> 7) & 1 ) * 5);
-
- LOG_INFO("[%d.%d C]\n", degree, deci_degree);
-
- return degree * 10 + deci_degree;
-}
-
-void lm75_init_0(void)
-{
- // Check dependence
- MOD_CHECK(i2c);
- LM75_HW_INIT();
+ return lm75_read_2(&local_i2c_old_api, sens_addr);
}
#endif /* !CONFIG_I2C_DISABLE_OLD_API */
return degree * 10 + deci_degree;
}
-
-void lm75_init_1(I2c *i2c)
-{
- ASSERT(i2c);
-
- // Check dependence
- LM75_HW_INIT();
-}
#define I2C_READBIT BV(0)
#if COMPILER_C99
- #define lm75_init(...) PP_CAT(lm75_init ## _, COUNT_PARMS(__VA_ARGS__)) (__VA_ARGS__)
#define lm75_read(...) PP_CAT(lm75_read ## _, COUNT_PARMS(__VA_ARGS__)) (__VA_ARGS__)
#else
- #define lm75_init(args...) PP_CAT(lm75_init ## _, COUNT_PARMS(args)) (args)
#define lm75_read(args...) PP_CAT(lm75_read ## _, COUNT_PARMS(args)) (args)
#endif
#if !CONFIG_I2C_DISABLE_OLD_API
DEPRECATED deg_t lm75_read_1(uint8_t sens_addr);
-DEPRECATED void lm75_init_0(void);
-
#endif /* !CONFIG_I2C_DISABLE_OLD_API */
-
deg_t lm75_read_2(I2c *i2c, uint8_t sens_addr);
-void lm75_init_1(I2c *i2c);
#endif /* DRV_LM75_H */
#include <drv/i2c.h>
-#if !CONFIG_I2C_DISABLE_OLD_API
-
-INLINE int pcf8574_get_priv(Pcf8574 *pcf)
-{
- if (!i2c_start_r(PCF8574ID | ((pcf->addr << 1) & 0xF7)))
- return EOF;
-
- int data;
-
- if (!i2c_recv(&data, 1))
- data = EOF;
-
- i2c_stop();
-
- return data;
-}
-
-/**
- * Read PCF8574 \a pcf bit status.
- * \return the pins status or EOF on errors.
- */
-int pcf8574_get_1(Pcf8574 *pcf)
-{
- return pcf8574_get_priv(pcf);
-}
-
-/**
- * Write to PCF8574 \a pcf port \a data.
- * \return true if ok, false on errors.
- */
-bool pcf8574_put_2(Pcf8574 *pcf, uint8_t data)
-{
- bool res = i2c_start_w(PCF8574ID | ((pcf->addr << 1) & 0xF7)) && i2c_put(data);
- i2c_stop();
- return res;
-}
-
-/**
- * Init a PCF8574 on the bus with addr \a addr.
- * \return true if device is found, false otherwise.
- */
-bool pcf8574_init_2(Pcf8574 *pcf, pcf8574_addr addr)
-{
- MOD_CHECK(i2c);
- pcf->addr = addr;
- return pcf8574_get_priv(pcf) != EOF;
-}
-#endif /* !CONFIG_I2C_DISABLE_OLD_API */
-
-
-/*
- * New API
- */
-
/**
* Read PCF8574 \a pcf bit status.
* \return the pins status or EOF on errors.
#define PCF8574ID 0x40 ///< I2C address
+/**
+ * Read PCF8574 \a pcf bit status.
+ * \return the pins status or EOF on errors.
+ */
+int pcf8574_get_2(I2c *i2c, Pcf8574 *pcf);
+
+/**
+ * Write to PCF8574 \a pcf port \a data.
+ * \return true if ok, false on errors.
+ */
+bool pcf8574_put_3(I2c *i2c, Pcf8574 *pcf, uint8_t data);
+
+/**
+ * Init a PCF8574 on the bus with addr \a addr.
+ * \return true if device is found, false otherwise.
+ */
+bool pcf8574_init_3(I2c *i2c, Pcf8574 *pcf, pcf8574_addr addr);
+
#if !CONFIG_I2C_DISABLE_OLD_API
-DEPRECATED int pcf8574_get_1(Pcf8574 *pcf);
-DEPRECATED bool pcf8574_put_2(Pcf8574 *pcf, uint8_t data);
-DEPRECATED bool pcf8574_init_2(Pcf8574 *pcf, pcf8574_addr addr);
-#endif /* !CONFIG_I2C_DISABLE_OLD_API */
+DEPRECATED INLINE int pcf8574_get_1(Pcf8574 *pcf)
+{
+ return pcf8574_get_2(&local_i2c_old_api, pcf);
+}
+DEPRECATED INLINE bool pcf8574_put_2(Pcf8574 *pcf, uint8_t data)
+{
+ return pcf8574_put_3(&local_i2c_old_api, pcf, data);
+}
-int pcf8574_get_2(I2c *i2c, Pcf8574 *pcf);
-bool pcf8574_put_3(I2c *i2c, Pcf8574 *pcf, uint8_t data);
-bool pcf8574_init_3(I2c *i2c, Pcf8574 *pcf, pcf8574_addr addr);
+DEPRECATED INLINE bool pcf8574_init_2(Pcf8574 *pcf, pcf8574_addr addr)
+{
+ return pcf8574_init_3(&local_i2c_old_api, pcf, addr);
+}
+#endif /* !CONFIG_I2C_DISABLE_OLD_API */
#endif /* DRV_PCF8574_H */
#define CH4_VOL_REG 0x0B
-#if !CONFIG_I2C_DISABLE_OLD_API
-
-static bool tas5706a_send(tas_addr_t addr, const void *buf, size_t len)
-{
- bool ret = i2c_start_w(TAS_ADDR) && i2c_put(addr) && i2c_send(buf, len);
- i2c_stop();
- return ret;
-}
-
-INLINE bool tas5706a_put(tas_addr_t addr, uint8_t ch)
-{
- return tas5706a_send(addr, &ch, sizeof(ch));
-}
-
-static bool tas5706a_recv(tas_addr_t addr, void *buf, size_t len)
-{
- bool ret = i2c_start_w(TAS_ADDR) && i2c_put(addr) && i2c_start_r(TAS_ADDR) && i2c_recv(buf, len);
- i2c_stop();
- return ret;
-}
-
-INLINE int tas5706a_get(tas_addr_t addr)
-{
- uint8_t ch;
- if (tas5706a_recv(addr, &ch, sizeof(ch)))
- return (int)(uint8_t)ch;
- else
- return EOF;
-}
-
-void tas5706a_init_0(void)
-{
- MOD_CHECK(i2c);
- MOD_CHECK(timer);
- TAS5706A_PIN_INIT();
- timer_delay(200);
- TAS5706A_SETPOWERDOWN(false);
- TAS5706A_SETMUTE(false);
- TAS5706A_MCLK_INIT();
- timer_delay(2);
- TAS5706A_SETRESET(false);
- timer_delay(20);
- tas5706a_put(TRIM_REG, 0x00);
-
- tas5706a_put(VOLUME_REG, DB_TO_REG(CONFIG_TAS_MAX_VOL));
-
- /* Unmute */
- tas5706a_put(SYS_REG2, 0);
-}
-
-void tas5706a_setVolume_2(Tas5706aCh ch, tas5706a_vol_t vol)
+INLINE bool tas5706a_putc(I2c *i2c, tas_addr_t addr, uint8_t ch)
{
- ASSERT(ch < TAS_CNT);
- ASSERT(vol <= TAS_VOL_MAX);
-
- tas_addr_t addr1, addr2;
-
- switch(ch)
- {
- case TAS_CH1:
- addr1 = CH1_VOL_REG;
- addr2 = CH3_VOL_REG;
- break;
- case TAS_CH2:
- addr1 = CH2_VOL_REG;
- addr2 = CH4_VOL_REG;
- break;
- default:
- ASSERT(0);
- return;
- }
+ i2c_start_w(i2c, TAS_ADDR, 2, I2C_STOP);
+ i2c_putc(i2c, addr);
+ i2c_putc(i2c, ch);
- uint8_t vol_att = 0xff - ((vol * 0xff) / TAS_VOL_MAX);
+ if (i2c_error(i2c))
+ return false;
- tas5706a_put(addr1, vol_att);
- tas5706a_put(addr2, vol_att);
+ return true;
}
-void tas5706a_setLowPower_1(bool val)
+INLINE int tas5706a_getc(I2c *i2c, tas_addr_t addr)
{
- TAS5706A_SETPOWERDOWN(val);
- TAS5706A_SETMUTE(val);
-}
-#endif /* !CONFIG_I2C_DISABLE_OLD_API */
+ int ch;
-/*
- * New API
- */
-INLINE bool tas5706a_putc(I2c *i2c, tas_addr_t addr, uint8_t ch)
-{
- i2c_start_w(i2c, TAS_ADDR, 2, I2C_STOP);
+ i2c_start_w(i2c, TAS_ADDR, 2, I2C_NOSTOP);
i2c_putc(i2c, addr);
- i2c_putc(i2c, ch);
+ i2c_start_r(i2c, TAS_ADDR, 1, I2C_STOP);
+ ch = (int)(uint8_t)i2c_getc(i2c);
if (i2c_error(i2c))
- return false;
+ return EOF;
- return true;
+ return ch;
}
void tas5706a_setVolume_3(I2c *i2c, Tas5706aCh ch, tas5706a_vol_t vol)
#if !CONFIG_I2C_DISABLE_OLD_API
-DEPRECATED void tas5706a_setVolume_2(Tas5706aCh ch, tas5706a_vol_t vol);
-DEPRECATED void tas5706a_setLowPower_1(bool val);
-DEPRECATED void tas5706a_init_0(void);
+DEPRECATED INLINE void tas5706a_setVolume_2(Tas5706aCh ch, tas5706a_vol_t vol)
+{
+ tas5706a_setVolume_3(&local_i2c_old_api, ch, vol);
+}
+DEPRECATED INLINE void tas5706a_setLowPower_1(bool val)
+{
+ tas5706a_setLowPower_2(&local_i2c_old_api, val);
+}
+DEPRECATED INLINE void tas5706a_init_0(void)
+{
+ tas5706a_init_1(&local_i2c_old_api);
+}
+
#endif /* !CONFIG_I2C_DISABLE_OLD_API */
#endif /* DRV_TAS5706A_H */