From 0c154bc0927a32f77467f32aac3cc3507baa97ca Mon Sep 17 00:00:00 2001 From: bernie Date: Mon, 20 Mar 2006 17:49:50 +0000 Subject: [PATCH] Make the TWI driver more generic to work with devices other than EEPROMS. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@569 38d2e660-2303-0410-9eaa-f027e97ec537 --- drv/eeprom.c | 27 +++++++++++++++++++------ drv/twi.c | 56 +++++++++++++++++++++++++++++++--------------------- drv/twi.h | 8 ++++++-- 3 files changed, 61 insertions(+), 30 deletions(-) diff --git a/drv/eeprom.c b/drv/eeprom.c index 8280ef2c..9eeb011a 100755 --- a/drv/eeprom.c +++ b/drv/eeprom.c @@ -16,6 +16,9 @@ /*#* *#* $Log$ + *#* Revision 1.19 2006/03/20 17:49:50 bernie + *#* Make the TWI driver more generic to work with devices other than EEPROMS. + *#* *#* Revision 1.18 2005/11/27 23:33:40 bernie *#* Use appconfig.h instead of cfg/config.h. *#* @@ -52,6 +55,18 @@ #error CONFIG_EEPROM_VERIFY must be defined to either 0 or 1 #endif +/** + * EEPROM ID code + */ +#define EEPROM_ID 0xA0 + +/** + * This macros form the correct slave address for EEPROMs + */ +#define EEPROM_ADDR(x) (EEPROM_ID | (((uint8_t)(x)) << 1)) + + + /*! * Copy \c count bytes from buffer \c buf to @@ -80,7 +95,7 @@ static bool eeprom_writeRaw(e2addr_t addr, const void *buf, size_t count) uint8_t blk_offs = (uint8_t)addr; result = - twi_start_w(blk_addr) + twi_start_w(EEPROM_ADDR(blk_addr)) && twi_send(&blk_offs, sizeof blk_offs) && twi_send(buf, size); @@ -90,7 +105,7 @@ static bool eeprom_writeRaw(e2addr_t addr, const void *buf, size_t count) uint16_t addr_be = cpu_to_be16(addr); result = - twi_start_w(0) + twi_start_w(EEPROM_ID) && twi_send((uint8_t *)&addr_be, sizeof addr_be) && twi_send(buf, size); @@ -198,9 +213,9 @@ bool eeprom_read(e2addr_t addr, void *buf, size_t count) uint8_t blk_offs = (uint8_t)addr; bool res = - twi_start_w(blk_addr) + twi_start_w(EEPROM_ADDR(blk_addr)) && twi_send(&blk_offs, sizeof blk_offs) - && twi_start_r(blk_addr) + && twi_start_r(EEPROM_ADDR(blk_addr)) && twi_recv(buf, count); #elif CONFIG_EEPROM_TYPE == EEPROM_24XX256 @@ -209,9 +224,9 @@ bool eeprom_read(e2addr_t addr, void *buf, size_t count) addr = cpu_to_be16(addr); bool res = - twi_start_w(0) + twi_start_w(EEPROM_ID) && twi_send((uint8_t *)&addr, sizeof(addr)) - && twi_start_r(0) + && twi_start_r(EEPROM_ID) && twi_recv(buf, count); #else #error Unknown device type diff --git a/drv/twi.c b/drv/twi.c index 76d4a82f..f2c73f94 100755 --- a/drv/twi.c +++ b/drv/twi.c @@ -15,6 +15,9 @@ /*#* *#* $Log$ + *#* Revision 1.6 2006/03/20 17:49:50 bernie + *#* Make the TWI driver more generic to work with devices other than EEPROMS. + *#* *#* Revision 1.5 2005/11/27 23:33:40 bernie *#* Use appconfig.h instead of cfg/config.h. *#* @@ -46,11 +49,7 @@ /* Wait for TWINT flag set: bus is ready */ #define WAIT_TWI_READY do {} while (!(TWCR & BV(TWINT))) -/*! \name EEPROM control codes */ -/*@{*/ -#define SLA_W 0xA0 -#define SLA_R 0xA1 -/*@}*/ +#define READ_BIT BV(0) /*! @@ -73,13 +72,13 @@ static bool twi_start(void) /*! * Send START condition and select slave for write. + * \c id is the device id comprehensive of address left shifted by 1. + * The LSB of \c id is ignored and reset to 0 for write operation. * * \return true on success, false otherwise. */ -bool twi_start_w(uint8_t slave_addr) +bool twi_start_w(uint8_t id) { - ASSERT(slave_addr < 8); - /* * Loop on the select write sequence: when the eeprom is busy * writing previously sent data it will reply to the SLA_W @@ -88,7 +87,7 @@ bool twi_start_w(uint8_t slave_addr) */ while (twi_start()) { - TWDR = SLA_W | (slave_addr << 1); + TWDR = id & ~READ_BIT; TWCR = BV(TWINT) | BV(TWEN); WAIT_TWI_READY; @@ -107,16 +106,16 @@ bool twi_start_w(uint8_t slave_addr) /*! * Send START condition and select slave for read. + * \c id is the device id comprehensive of address left shifted by 1. + * The LSB of \c id is ignored and set to 1 for read operation. * * \return true on success, false otherwise. */ -bool twi_start_r(uint8_t slave_addr) +bool twi_start_r(uint8_t id) { - ASSERT(slave_addr < 8); - if (twi_start()) { - TWDR = SLA_R | (slave_addr << 1); + TWDR = id | READ_BIT; TWCR = BV(TWINT) | BV(TWEN); WAIT_TWI_READY; @@ -135,7 +134,27 @@ bool twi_start_r(uint8_t slave_addr) */ void twi_stop(void) { - TWCR = BV(TWINT) | BV(TWEN) | BV(TWSTO); + TWCR = BV(TWINT) | BV(TWEN) | BV(TWSTO); +} + + +/*! + * Put a single byte in master transmitter mode + * to the selected slave device through the TWI bus. + * + * \return true on success, false on error. + */ +bool twi_put(const uint8_t data) +{ + TWDR = data; + TWCR = BV(TWINT) | BV(TWEN); + WAIT_TWI_READY; + if (TW_STATUS != TW_MT_DATA_ACK) + { + kprintf("!TW_MT_DATA_ACK: %x\n", TWSR); + return false; + } + return true; } @@ -151,16 +170,9 @@ bool twi_send(const void *_buf, size_t count) while (count--) { - TWDR = *buf++; - TWCR = BV(TWINT) | BV(TWEN); - WAIT_TWI_READY; - if (TW_STATUS != TW_MT_DATA_ACK) - { - kprintf("!TW_MT_DATA_ACK: %x\n", TWSR); + if (!twi_put(*buf++)) return false; - } } - return true; } diff --git a/drv/twi.h b/drv/twi.h index ac8c46f2..20671a46 100755 --- a/drv/twi.h +++ b/drv/twi.h @@ -15,6 +15,9 @@ /*#* *#* $Log$ + *#* Revision 1.4 2006/03/20 17:49:49 bernie + *#* Make the TWI driver more generic to work with devices other than EEPROMS. + *#* *#* Revision 1.3 2005/04/11 19:10:28 bernie *#* Include top-level headers from cfg/ subdir. *#* @@ -27,9 +30,10 @@ #include -bool twi_start_w(uint8_t slave_addr); -bool twi_start_r(uint8_t slave_addr); +bool twi_start_w(uint8_t id); +bool twi_start_r(uint8_t id); void twi_stop(void); +bool twi_put(const uint8_t data); bool twi_send(const void *_buf, size_t count); bool twi_recv(void *_buf, size_t count); void twi_init(void); -- 2.25.1