Fixed TWI_StartTransmission() corrupting the contents of the GPIOR0 register.
#include <avr/io.h>\r
#include <stdbool.h>\r
#include <util/twi.h>\r
+ #include <util/delay.h>\r
\r
/* Enable C linkage for C++ Compilers: */\r
#if defined(__cplusplus)\r
/** Begins a master mode TWI bus communication with the given slave device address.\r
*\r
* \param[in] SlaveAddress Address of the slave TWI device to communicate with\r
+ * \param[in] TimeoutMS Timeout period within which the slave must respond, in milliseconds\r
*\r
* \return Boolean true if the device is ready for data, false otherwise\r
*/\r
- bool TWI_StartTransmission(uint8_t SlaveAddress);\r
+ bool TWI_StartTransmission(uint8_t SlaveAddress, uint8_t TimeoutMS);\r
\r
/* Disable C linkage for C++ Compilers: */\r
#if defined(__cplusplus)\r
\r
#include "TWI.h"\r
\r
-bool TWI_StartTransmission(uint8_t SlaveAddress)\r
+bool TWI_StartTransmission(uint8_t SlaveAddress, uint8_t TimeoutMS)\r
{\r
for (;;)\r
{\r
- uint8_t IterationsRemaining = 50;\r
- bool BusCaptured = false;\r
+ bool BusCaptured = false;\r
+ uint16_t TimeoutRemaining;\r
\r
- while (IterationsRemaining-- && !BusCaptured)\r
+ TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN)); \r
+\r
+ TimeoutRemaining = (TimeoutMS * 100);\r
+ while (TimeoutRemaining-- && !BusCaptured)\r
{\r
- TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN)); \r
- while (!(TWCR & (1 << TWINT)));\r
- \r
- switch (TWSR & TW_STATUS_MASK)\r
+ if (TWCR & (1 << TWINT))\r
{\r
- case TW_START:\r
- case TW_REP_START:\r
- BusCaptured = true;\r
- break;\r
- case TW_MT_ARB_LOST:\r
- continue;\r
- default:\r
- return false;\r
+ switch (TWSR & TW_STATUS_MASK)\r
+ {\r
+ case TW_START:\r
+ case TW_REP_START:\r
+ BusCaptured = true;\r
+ break;\r
+ case TW_MT_ARB_LOST:\r
+ TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN)); \r
+ continue;\r
+ default:\r
+ TWCR = (1 << TWEN);\r
+ return false;\r
+ }\r
}\r
+ \r
+ _delay_us(10);\r
}\r
\r
if (!(BusCaptured))\r
- return false;\r
- \r
+ {\r
+ TWCR = (1 << TWEN);\r
+ return false;\r
+ }\r
+ \r
TWDR = SlaveAddress;\r
TWCR = ((1 << TWINT) | (1 << TWEN));\r
- while (!(TWCR & (1 << TWINT)));\r
\r
- GPIOR0 = (TWSR & TW_STATUS_MASK);\r
+ TimeoutRemaining = (TimeoutMS * 100);\r
+ while (TimeoutRemaining--)\r
+ {\r
+ if (TWCR & (1 << TWINT))\r
+ break;\r
+ \r
+ _delay_us(10);\r
+ }\r
+ \r
+ if (!(TimeoutRemaining))\r
+ return false;\r
\r
switch (TWSR & TW_STATUS_MASK)\r
{\r
default:\r
TWI_StopTransmission();\r
break;\r
- } \r
+ }\r
}\r
}\r
* - AVRISP programmer project now has a more robust timeout system, allowing for a doubling of the software USART speed\r
* for PDI and TPI programming\r
* - Increased the speed of both software and hardware TPI/PDI programming modes of the AVRISP project\r
+ * - Added a timeout value to the TWI_StartTransmission() function, within which the addressed device must respond\r
*\r
* <b>Fixed:</b>\r
* - Fixed software PDI/TPI programming mode in the AVRISP project not correctly toggling just the clock pin\r
+ * - Fixed TWI_StartTransmission() corrupting the contents of the GPIOR0 register\r
*\r
* \section Sec_ChangeLog100219 Version 100219\r
*\r
*\r
* \section Sec_MigrationXXXXXX Migrating from 100219 to XXXXXX\r
*\r
+ * <b>Non-USB Library Components</b>\r
+ * - The \ref TWI_StartTransmission() function now takes in a timeout period, expressed in milliseconds, within which the addressed\r
+ * device must respond or the function will abort.\r
+ *\r
* \section Sec_Migration100219 Migrating from 091223 to 100219\r
- * - (None)\r
*\r
* <b>Non-USB Library Components</b>\r
* - Due to some ADC channels not being identical to their ADC MUX selection masks for single-ended conversions on some AVR models,\r
CurrentRTCDate.Byte3.TenYear = (Year / 10);\r
CurrentRTCDate.Byte3.Year = (Year % 10);\r
\r
- if (TWI_StartTransmission(DS1307_ADDRESS_WRITE))\r
+ if (TWI_StartTransmission(DS1307_ADDRESS_WRITE, 10))\r
{\r
TWI_SendByte(DS1307_DATEREG_START);\r
TWI_SendByte(CurrentRTCDate.Byte1.IntVal);\r
CurrentRTCTime.Byte3.Hour = (Hour % 10);\r
CurrentRTCTime.Byte3.TwelveHourMode = false;\r
\r
- if (TWI_StartTransmission(DS1307_ADDRESS_WRITE))\r
+ if (TWI_StartTransmission(DS1307_ADDRESS_WRITE, 10))\r
{\r
TWI_SendByte(DS1307_TIMEREG_START);\r
TWI_SendByte(CurrentRTCTime.Byte1.IntVal);\r
return;\r
#endif\r
\r
- if (TWI_StartTransmission(DS1307_ADDRESS_WRITE))\r
+ if (TWI_StartTransmission(DS1307_ADDRESS_WRITE, 10))\r
{\r
TWI_SendByte(DS1307_DATEREG_START);\r
\r
\r
DS1307_DateRegs_t CurrentRTCDate;\r
\r
- if (TWI_StartTransmission(DS1307_ADDRESS_READ))\r
+ if (TWI_StartTransmission(DS1307_ADDRESS_READ, 10))\r
{\r
TWI_ReceiveByte(&CurrentRTCDate.Byte1.IntVal, false);\r
TWI_ReceiveByte(&CurrentRTCDate.Byte2.IntVal, false);\r
return;\r
#endif\r
\r
- if (TWI_StartTransmission(DS1307_ADDRESS_WRITE))\r
+ if (TWI_StartTransmission(DS1307_ADDRESS_WRITE, 10))\r
{\r
TWI_SendByte(DS1307_TIMEREG_START);\r
\r
\r
DS1307_TimeRegs_t CurrentRTCTime;\r
\r
- if (TWI_StartTransmission(DS1307_ADDRESS_READ))\r
+ if (TWI_StartTransmission(DS1307_ADDRESS_READ, 10))\r
{\r
TWI_ReceiveByte(&CurrentRTCTime.Byte1.IntVal, false);\r
TWI_ReceiveByte(&CurrentRTCTime.Byte2.IntVal, false);\r
\r
# Place -D or -U options here for C sources\r
CDEFS = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD) $(LUFA_OPTS)\r
-CDEFS += -DDUMMY_RTC\r
+#CDEFS += -DDUMMY_RTC\r
\r
\r
# Place -D or -U options here for ASM sources\r