diff --git a/LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.h b/LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.h index 13db86e699824277760532b7c00faa03855c08a4..2d8e6df1e829dd03974eddb5c79cc7ea60f820a8 100644 --- a/LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.h +++ b/LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.h @@ -56,6 +56,7 @@ #include <avr/io.h> #include <stdbool.h> #include <util/twi.h> + #include <util/delay.h> /* Enable C linkage for C++ Compilers: */ #if defined(__cplusplus) @@ -131,10 +132,11 @@ /** Begins a master mode TWI bus communication with the given slave device address. * * \param[in] SlaveAddress Address of the slave TWI device to communicate with + * \param[in] TimeoutMS Timeout period within which the slave must respond, in milliseconds * * \return Boolean true if the device is ready for data, false otherwise */ - bool TWI_StartTransmission(uint8_t SlaveAddress); + bool TWI_StartTransmission(uint8_t SlaveAddress, uint8_t TimeoutMS); /* Disable C linkage for C++ Compilers: */ #if defined(__cplusplus) diff --git a/LUFA/Drivers/Peripheral/TWI.c b/LUFA/Drivers/Peripheral/TWI.c index 6028bbae93709f78631c4c4c4ee6994a4f4690dd..eb513c454b8a26435b7a87f50cd797c130f26060 100644 --- a/LUFA/Drivers/Peripheral/TWI.c +++ b/LUFA/Drivers/Peripheral/TWI.c @@ -7,39 +7,58 @@ #include "TWI.h" -bool TWI_StartTransmission(uint8_t SlaveAddress) +bool TWI_StartTransmission(uint8_t SlaveAddress, uint8_t TimeoutMS) { for (;;) { - uint8_t IterationsRemaining = 50; - bool BusCaptured = false; + bool BusCaptured = false; + uint16_t TimeoutRemaining; - while (IterationsRemaining-- && !BusCaptured) + TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN)); + + TimeoutRemaining = (TimeoutMS * 100); + while (TimeoutRemaining-- && !BusCaptured) { - TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN)); - while (!(TWCR & (1 << TWINT))); - - switch (TWSR & TW_STATUS_MASK) + if (TWCR & (1 << TWINT)) { - case TW_START: - case TW_REP_START: - BusCaptured = true; - break; - case TW_MT_ARB_LOST: - continue; - default: - return false; + switch (TWSR & TW_STATUS_MASK) + { + case TW_START: + case TW_REP_START: + BusCaptured = true; + break; + case TW_MT_ARB_LOST: + TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN)); + continue; + default: + TWCR = (1 << TWEN); + return false; + } } + + _delay_us(10); } if (!(BusCaptured)) - return false; - + { + TWCR = (1 << TWEN); + return false; + } + TWDR = SlaveAddress; TWCR = ((1 << TWINT) | (1 << TWEN)); - while (!(TWCR & (1 << TWINT))); - GPIOR0 = (TWSR & TW_STATUS_MASK); + TimeoutRemaining = (TimeoutMS * 100); + while (TimeoutRemaining--) + { + if (TWCR & (1 << TWINT)) + break; + + _delay_us(10); + } + + if (!(TimeoutRemaining)) + return false; switch (TWSR & TW_STATUS_MASK) { @@ -49,6 +68,6 @@ bool TWI_StartTransmission(uint8_t SlaveAddress) default: TWI_StopTransmission(); break; - } + } } } diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 14f1a25471a265d97369e8339f011b979534a214..155afa0991fc2f62976354bdc82a0c7c0711ae44 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -15,9 +15,11 @@ * - AVRISP programmer project now has a more robust timeout system, allowing for a doubling of the software USART speed * for PDI and TPI programming * - Increased the speed of both software and hardware TPI/PDI programming modes of the AVRISP project + * - Added a timeout value to the TWI_StartTransmission() function, within which the addressed device must respond * * <b>Fixed:</b> * - Fixed software PDI/TPI programming mode in the AVRISP project not correctly toggling just the clock pin + * - Fixed TWI_StartTransmission() corrupting the contents of the GPIOR0 register * * \section Sec_ChangeLog100219 Version 100219 * diff --git a/LUFA/ManPages/MigrationInformation.txt b/LUFA/ManPages/MigrationInformation.txt index 26236407018c2f4cc7c05be87ff87395a4750094..8467e0019371a5386c3d08c6cabfd1a16b922282 100644 --- a/LUFA/ManPages/MigrationInformation.txt +++ b/LUFA/ManPages/MigrationInformation.txt @@ -12,8 +12,11 @@ * * \section Sec_MigrationXXXXXX Migrating from 100219 to XXXXXX * + * <b>Non-USB Library Components</b> + * - The \ref TWI_StartTransmission() function now takes in a timeout period, expressed in milliseconds, within which the addressed + * device must respond or the function will abort. + * * \section Sec_Migration100219 Migrating from 091223 to 100219 - * - (None) * * <b>Non-USB Library Components</b> * - Due to some ADC channels not being identical to their ADC MUX selection masks for single-ended conversions on some AVR models, diff --git a/Projects/TemperatureDataLogger/Lib/DS1307.c b/Projects/TemperatureDataLogger/Lib/DS1307.c index 64e03df0d72796f293658159c266e36ee0acb2f3..0c1d98f00efb97e1ec9af55b96cd72b0a86b8410 100644 --- a/Projects/TemperatureDataLogger/Lib/DS1307.c +++ b/Projects/TemperatureDataLogger/Lib/DS1307.c @@ -21,7 +21,7 @@ void DS1307_SetDate(uint8_t Day, uint8_t Month, uint8_t Year) CurrentRTCDate.Byte3.TenYear = (Year / 10); CurrentRTCDate.Byte3.Year = (Year % 10); - if (TWI_StartTransmission(DS1307_ADDRESS_WRITE)) + if (TWI_StartTransmission(DS1307_ADDRESS_WRITE, 10)) { TWI_SendByte(DS1307_DATEREG_START); TWI_SendByte(CurrentRTCDate.Byte1.IntVal); @@ -48,7 +48,7 @@ void DS1307_SetTime(uint8_t Hour, uint8_t Minute, uint8_t Second) CurrentRTCTime.Byte3.Hour = (Hour % 10); CurrentRTCTime.Byte3.TwelveHourMode = false; - if (TWI_StartTransmission(DS1307_ADDRESS_WRITE)) + if (TWI_StartTransmission(DS1307_ADDRESS_WRITE, 10)) { TWI_SendByte(DS1307_TIMEREG_START); TWI_SendByte(CurrentRTCTime.Byte1.IntVal); @@ -68,7 +68,7 @@ void DS1307_GetDate(uint8_t* Day, uint8_t* Month, uint8_t* Year) return; #endif - if (TWI_StartTransmission(DS1307_ADDRESS_WRITE)) + if (TWI_StartTransmission(DS1307_ADDRESS_WRITE, 10)) { TWI_SendByte(DS1307_DATEREG_START); @@ -77,7 +77,7 @@ void DS1307_GetDate(uint8_t* Day, uint8_t* Month, uint8_t* Year) DS1307_DateRegs_t CurrentRTCDate; - if (TWI_StartTransmission(DS1307_ADDRESS_READ)) + if (TWI_StartTransmission(DS1307_ADDRESS_READ, 10)) { TWI_ReceiveByte(&CurrentRTCDate.Byte1.IntVal, false); TWI_ReceiveByte(&CurrentRTCDate.Byte2.IntVal, false); @@ -100,7 +100,7 @@ void DS1307_GetTime(uint8_t* Hour, uint8_t* Minute, uint8_t* Second) return; #endif - if (TWI_StartTransmission(DS1307_ADDRESS_WRITE)) + if (TWI_StartTransmission(DS1307_ADDRESS_WRITE, 10)) { TWI_SendByte(DS1307_TIMEREG_START); @@ -109,7 +109,7 @@ void DS1307_GetTime(uint8_t* Hour, uint8_t* Minute, uint8_t* Second) DS1307_TimeRegs_t CurrentRTCTime; - if (TWI_StartTransmission(DS1307_ADDRESS_READ)) + if (TWI_StartTransmission(DS1307_ADDRESS_READ, 10)) { TWI_ReceiveByte(&CurrentRTCTime.Byte1.IntVal, false); TWI_ReceiveByte(&CurrentRTCTime.Byte2.IntVal, false); diff --git a/Projects/TemperatureDataLogger/makefile b/Projects/TemperatureDataLogger/makefile index 8fd2c2941ce93154314d40318240c8da14c01f03..f48e155b0dcf7eb8acd07127c1b26bd2bb45adf4 100644 --- a/Projects/TemperatureDataLogger/makefile +++ b/Projects/TemperatureDataLogger/makefile @@ -193,7 +193,7 @@ CSTANDARD = -std=gnu99 # Place -D or -U options here for C sources CDEFS = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD) $(LUFA_OPTS) -CDEFS += -DDUMMY_RTC +#CDEFS += -DDUMMY_RTC # Place -D or -U options here for ASM sources