X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=drv%2Ftwi.c;h=0d03950f95fe22d74e5763be804c0f0abd448ff5;hb=27fef4ed34eb237817defa14242e726ccad70948;hp=e48663686f28ba8d030bd5dbc08f6589805f6f02;hpb=2c28fb48561c231a4732bb391de57c2b6864ae72;p=bertos.git diff --git a/drv/twi.c b/drv/twi.c old mode 100755 new mode 100644 index e4866368..0d03950f --- a/drv/twi.c +++ b/drv/twi.c @@ -1,8 +1,33 @@ -/*! +/** * \file * * * \brief Driver for the AVR ATMega TWI (implementation) @@ -15,6 +40,21 @@ /*#* *#* $Log$ + *#* Revision 1.8 2007/06/07 14:35:12 batt + *#* Merge from project_ks. + *#* + *#* Revision 1.7 2006/07/19 12:56:26 bernie + *#* Convert to new Doxygen style. + *#* + *#* 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. + *#* + *#* Revision 1.4 2005/04/11 19:10:28 bernie + *#* Include top-level headers from cfg/ subdir. + *#* *#* Revision 1.3 2005/03/01 23:26:00 bernie *#* Header fix. *#* @@ -27,11 +67,12 @@ *#*/ #include "twi.h" -#include "config.h" -#include -#include -#include -#include // BV() + +#include +#include +#include // BV() +#include /* CLOCK_FREQ */ +#include #include @@ -39,14 +80,10 @@ /* 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) -/*! +/** * Send START condition on the bus. * * \return true on success, false otherwise. @@ -64,15 +101,15 @@ 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 @@ -81,7 +118,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; @@ -98,18 +135,18 @@ 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; @@ -123,16 +160,36 @@ bool twi_start_r(uint8_t slave_addr) } -/*! +/** * Send STOP condition. */ 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; +} + + +/** * Send a sequence of bytes in master transmitter mode * to the selected slave device through the TWI bus. * @@ -144,21 +201,14 @@ 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; } -/*! +/** * Receive a sequence of one or more bytes from the * selected slave device in master receive mode through * the TWI bus. @@ -203,7 +253,7 @@ bool twi_recv(void *_buf, size_t count) } -/*! +/** * Initialize TWI module. */ void twi_init(void) @@ -216,12 +266,12 @@ void twi_init(void) * probably due to some unwanted interaction between the * port pin and the TWI lines. */ -#if defined(__AVR_ATmega64__) +#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281 PORTD |= BV(PD0) | BV(PD1); - DDRD |= BV(PD0) | BV(PD1); -#elif defined(__AVR_ATmega8__) + DDRD |= BV(PD0) | BV(PD1); +#elif CPU_AVR_ATMEGA8 PORTC |= BV(PC4) | BV(PC5); - DDRC |= BV(PC4) | BV(PC5); + DDRC |= BV(PC4) | BV(PC5); #else #error Unsupported architecture #endif