/*#*
*#* $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.
*#*
#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
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);
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);
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
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
/*#*
*#* $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.
*#*
/* 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 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
*/
while (twi_start())
{
- TWDR = SLA_W | (slave_addr << 1);
+ TWDR = id & ~READ_BIT;
TWCR = BV(TWINT) | BV(TWEN);
WAIT_TWI_READY;
/*!
* 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;
*/
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;
}
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;
}
/*#*
*#* $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.
*#*
#include <cfg/compiler.h>
-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);