From 70d55f6e0ca1f262bd8811ad8d4149e33125819a Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Thu, 13 Jan 2011 22:56:49 +0000
Subject: [PATCH] Added new high level TWI packet read/write commands, altered
 behaviour of the TWI_StartTransmission() function.

Spell check source code files.
---
 .../TestAndMeasurement/TestAndMeasurement.c   |   2 +-
 LUFA/Drivers/Board/Dataflash.h                |   4 +-
 LUFA/Drivers/Board/Temperature.h              |   2 +-
 LUFA/Drivers/Misc/RingBuffer.h                |   8 +-
 LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.h       | 115 +++++++++++++++---
 LUFA/Drivers/Peripheral/TWI.c                 |  84 +++++++++++--
 LUFA/Drivers/USB/Class/Common/CDC.h           |   6 +-
 LUFA/Drivers/USB/LowLevel/Host.h              |   4 +-
 LUFA/Drivers/USB/LowLevel/USBController.h     |   2 +-
 LUFA/ManPages/ChangeLog.txt                   |  11 +-
 LUFA/ManPages/MigrationInformation.txt        |  10 +-
 Projects/TempDataLogger/Lib/DS1307.c          |  60 +++------
 Projects/TempDataLogger/Lib/DS1307.h          |   7 +-
 13 files changed, 224 insertions(+), 91 deletions(-)

diff --git a/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.c b/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.c
index 3c5cf47d5..a2f3cca86 100644
--- a/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.c
+++ b/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.c
@@ -64,7 +64,7 @@ bool IsTMCBulkOUTReset = false;
 /** Last used tag value for data transfers */
 uint8_t CurrentTransferTag = 0;
 
-/** Length of last data transfer, for reporting to the host in case an in-progress tranfer is aborted */
+/** Length of last data transfer, for reporting to the host in case an in-progress transfer is aborted */
 uint32_t LastTransferLength = 0;
 
 /** Main program entry point. This routine contains the overall program flow, including initial
diff --git a/LUFA/Drivers/Board/Dataflash.h b/LUFA/Drivers/Board/Dataflash.h
index 69ffdcb82..852d81977 100644
--- a/LUFA/Drivers/Board/Dataflash.h
+++ b/LUFA/Drivers/Board/Dataflash.h
@@ -87,13 +87,13 @@
  *      for (uint16_t i = 0; i < DATAFLASH_PAGE_SIZE; i++)
  *        Dataflash_SendByte(WriteBuffer[i]);
  *
- *      // Commit the Dataflash's first memory buffer to the non-voltatile FLASH memory
+ *      // Commit the Dataflash's first memory buffer to the non-volatile FLASH memory
  *      printf("Committing page to non-volatile memory page index 5:\r\n");
  *      Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE);
  *      Dataflash_SendAddressBytes(5, 0);
  *      Dataflash_WaitWhileBusy();
  *
- *      // Read the page from non-voltatile FLASH memory into the Dataflash's second memory buffer
+ *      // Read the page from non-volatile FLASH memory into the Dataflash's second memory buffer
  *      printf("Reading data into second dataflash buffer:\r\n");
  *      Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF2);
  *      Dataflash_SendAddressBytes(5, 0);
diff --git a/LUFA/Drivers/Board/Temperature.h b/LUFA/Drivers/Board/Temperature.h
index 29775b4af..a87327571 100644
--- a/LUFA/Drivers/Board/Temperature.h
+++ b/LUFA/Drivers/Board/Temperature.h
@@ -56,7 +56,7 @@
  *      ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_128);
  *      Temperature_Init();
  *
- *      // Display converted temperature in degrees Celcius
+ *      // Display converted temperature in degrees Celsius
  *      printf("Current Temperature: %d Degrees\r\n", Temperature_GetTemperature());
  *  \endcode
  * 
diff --git a/LUFA/Drivers/Misc/RingBuffer.h b/LUFA/Drivers/Misc/RingBuffer.h
index 4b2b9b22c..37e8a1ba5 100644
--- a/LUFA/Drivers/Misc/RingBuffer.h
+++ b/LUFA/Drivers/Misc/RingBuffer.h
@@ -35,9 +35,9 @@
  *  different sizes to suit different needs.
  *
  *  Note that for each buffer, insertion and removal operations may occur at the same time (via
- *  a multithreaded ISR based system) however the same kind of operation (two or more insertions
+ *  a multi-threaded ISR based system) however the same kind of operation (two or more insertions
  *  or deletions) must not overlap. If there is possibility of two or more of the same kind of
- *  operating occuring at the same point in time, atomic (mutex) locking should be used.
+ *  operating occurring at the same point in time, atomic (mutex) locking should be used.
  */
  
 /** \ingroup Group_MiscDrivers
@@ -52,9 +52,9 @@
  *  different sizes to suit different needs.
  *
  *  Note that for each buffer, insertion and removal operations may occur at the same time (via
- *  a multithreaded ISR based system) however the same kind of operation (two or more insertions
+ *  a multi-threaded ISR based system) however the same kind of operation (two or more insertions
  *  or deletions) must not overlap. If there is possibility of two or more of the same kind of
- *  operating occuring at the same point in time, atomic (mutex) locking should be used.
+ *  operating occurring at the same point in time, atomic (mutex) locking should be used.
  *
  *  \section Sec_ExampleUsage Example Usage
  *  The following snippet is an example of how this module may be used within a typical
diff --git a/LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.h b/LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.h
index 2408ad15f..499fc4d99 100644
--- a/LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.h
+++ b/LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.h
@@ -49,13 +49,16 @@
  *  The following snippet is an example of how this module may be used within a typical
  *  application.
  *
+ *  <b>Low Level API Example:</b>
  *  \code
  *      // Initialise the TWI driver before first use
  *      TWI_Init();
  *
- *      // Start a write session to device at address 0xA0 with a 10ms timeout
+ *      // Start a write session to device at device address 0xA0, internal address 0xDC with a 10ms timeout
  *      if (TWI_StartTransmission(0xA0 | TWI_ADDRESS_WRITE, 10))
  *      {
+ *          TWI_SendByte(0xDC);
+ *
  *          TWI_SendByte(0x01);
  *          TWI_SendByte(0x02);
  *          TWI_SendByte(0x03);
@@ -64,21 +67,47 @@
  *          TWI_StopTransmission();
  *      }
  *
- *      // Start a read session to device at address 0xA0 with a 10ms timeout
- *      if (TWI_StartTransmission(0xA0 | TWI_ADDRESS_READ, 10))
+ *      // Start a read session to device at address 0xA0, internal address 0xDC with a 10ms timeout
+ *      if (TWI_StartTransmission(0xA0 | TWI_ADDRESS_WRITE, 10))
  *      {
- *          uint8_t Byte1, Byte2, Byte3;
+ *          TWI_SendByte(0xDC);
+ *          TWI_StopTransmission();
  *
- *          // Read three bytes, acknowledge after the third byte is received
- *          TWI_ReceiveByte(&Byte1, false);
- *          TWI_ReceiveByte(&Byte2, false);
- *          TWI_ReceiveByte(&Byte3, true);
+ *          if (TWI_StartTransmission(0xA0 | TWI_ADDRESS_READ, 10))
+ *          {
+ *              uint8_t Byte1, Byte2, Byte3;
  *
- *          // Must stop transmission afterwards to release the bus
- *          TWI_StopTransmission();
+ *              // Read three bytes, acknowledge after the third byte is received
+ *              TWI_ReceiveByte(&Byte1, false);
+ *              TWI_ReceiveByte(&Byte2, false);
+ *              TWI_ReceiveByte(&Byte3, true);
+ *
+ *              // Must stop transmission afterwards to release the bus
+ *              TWI_StopTransmission();
+ *          }
  *      }
  *  \endcode
  * 
+ *  <b>High Level API Example:</b>
+ *  \code
+ *      // Initialise the TWI driver before first use
+ *      TWI_Init();
+ *
+ *      // Start a write session to device at device address 0xA0, internal address 0xDC with a 10ms timeout
+ *      uint8_t InternalWriteAddress = 0xDC;
+ *      uint8_t WritePacket[3] = {0x01, 0x02, 0x03};
+ *
+ *      TWI_WritePacket(0xA0, 10, &InternalWriteAddress, sizeof(InternalWriteAddress),
+ *                      &WritePacket, sizeof(WritePacket);
+ *
+ *      // Start a read session to device at address 0xA0, internal address 0xDC with a 10ms timeout
+ *      uint8_t InternalReadAddress = 0xDC;
+ *      uint8_t ReadPacket[3];
+ *
+ *      TWI_ReadPacket(0xA0, 10, &InternalReadAddress, sizeof(InternalReadAddress),
+ *                     &ReadPacket, sizeof(ReadPacket);
+ *  \endcode
+ *
  *  @{
  */
 
@@ -90,6 +119,7 @@
 
 		#include <avr/io.h>
 		#include <stdbool.h>
+		#include <stdio.h>
 		#include <util/twi.h>
 		#include <util/delay.h>
 
@@ -108,12 +138,29 @@
 			/** TWI slave device address mask for a read session. Mask with a slave device base address to obtain
 			 *  the correct TWI bus address for the slave device when reading data from it.
 			 */
-			#define TWI_ADDRESS_READ        0x00
+			#define TWI_ADDRESS_READ         0x00
 
 			/** TWI slave device address mask for a write session. Mask with a slave device base address to obtain
 			 *  the correct TWI bus address for the slave device when writing data to it.
 			 */
-			#define TWI_ADDRESS_WRITE       0x01
+			#define TWI_ADDRESS_WRITE        0x01
+
+			/** Mask to retrieve the base address for a TWI device, which can then be ORed with \ref TWI_ADDRESS_READ
+			 *  or \ref TWI_ADDRESS_WRITE to obtain the device's read and write address respectively.
+			 */
+			#define TWI_DEVICE_ADDRESS_MASK  0xFE
+			
+		/* Enums: */
+			/** Enum for the possible return codes of the TWI transfer start routine and other dependant TWI functions. */
+			enum TWI_ErrorCodes_t
+			{
+				TWI_ERROR_NoError              = 0, /**< Indicates that the command completed sucessfully. */
+				TWI_ERROR_BusFault             = 1, /**< A TWI bus fault occurred while attempting to capture the bus. */
+				TWI_ERROR_BusCaptureTimeout    = 2, /**< A timeout occurred whilst waiting for the bus to be ready. */
+				TWI_ERROR_SlaveResponseTimeout = 3, /**< No ACK received at the nominated slave address within the timeout period. */
+				TWI_ERROR_SlaveNotReady        = 4, /**< Slave NAKed the TWI bus START condition. */
+				TWI_ERROR_SlaveNAK             = 5, /**< Slave NAKed whilst attempting to send data to the device. */
+			};
 	
 		/* Inline Functions: */
 			/** Initialises the TWI hardware into master mode, ready for data transmission and reception. This must be
@@ -163,8 +210,8 @@
 			 *
 			 *  \return Boolean \c true if the byte reception successfully completed, \c false otherwise
 			 */
-			static inline bool TWI_ReceiveByte(uint8_t* const Byte,
-			                                   const bool LastByte)
+			static inline uint8_t TWI_ReceiveByte(uint8_t* const Byte,
+			                                      const bool LastByte)
 			{
 				uint8_t TWCRMask = ((1 << TWINT) | (1 << TWEN));
 
@@ -184,10 +231,44 @@
 			 *  \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 \c true if the device is ready for data, \c false otherwise
+			 *  \return A value from the \ref TWI_ErrorCodes_t enum
+			 */
+			uint8_t TWI_StartTransmission(const uint8_t SlaveAddress,
+			                              const uint8_t TimeoutMS);
+
+			/** High level function to perform a complete packet transfer over the TWI bus to the specified
+			 *  device.
+			 *
+			 *  \param[in] SlaveAddress        Base address of the TWI slave device to communicate with
+			 *  \param[in] TimeoutMS           Timeout for bus capture and slave START ACK, in milliseconds
+			 *  \param[in] InternalAddress     Pointer to a location where the internal slave read start address is stored
+			 *  \param[in] InternalAddressLen  Size of the internal device address, in bytes
+			 *  \param[in] Buffer              Pointer to a buffer where the read packet data is to be stored
+			 *  \param[in] Length              Size of the packet to read, in bytes
+			 */
+			uint8_t TWI_ReadPacket(const uint8_t SlaveAddress,
+			                       const uint8_t TimeoutMS,
+			                       const uint8_t* InternalAddress,
+			                       uint8_t InternalAddressLen,
+			                       uint8_t* Buffer,
+			                       uint8_t Length);
+
+			/** High level function to perform a complete packet transfer over the TWI bus from the specified
+			 *  device.
+			 *
+			 *  \param[in] SlaveAddress        Base address of the TWI slave device to communicate with
+			 *  \param[in] TimeoutMS           Timeout for bus capture and slave START ACK, in milliseconds
+			 *  \param[in] InternalAddress     Pointer to a location where the internal slave write start address is stored
+			 *  \param[in] InternalAddressLen  Size of the internal device address, in bytes
+			 *  \param[in] Buffer              Pointer to a buffer where the packet data to send is stored
+			 *  \param[in] Length              Size of the packet to send, in bytes
 			 */
-			bool TWI_StartTransmission(const uint8_t SlaveAddress,
-			                           const uint8_t TimeoutMS);
+			uint8_t TWI_WritePacket(const uint8_t SlaveAddress,
+			                        const uint8_t TimeoutMS,
+			                        const uint8_t* InternalAddress,
+			                        uint8_t InternalAddressLen,
+			                        const uint8_t* Buffer,
+			                        uint8_t Length);
 
 	/* Disable C linkage for C++ Compilers: */
 		#if defined(__cplusplus)
diff --git a/LUFA/Drivers/Peripheral/TWI.c b/LUFA/Drivers/Peripheral/TWI.c
index 6aaf19219..2f4e4ed42 100644
--- a/LUFA/Drivers/Peripheral/TWI.c
+++ b/LUFA/Drivers/Peripheral/TWI.c
@@ -7,8 +7,8 @@
 
 #include "TWI.h"
 
-bool TWI_StartTransmission(const uint8_t SlaveAddress,
-                           const uint8_t TimeoutMS)
+uint8_t TWI_StartTransmission(const uint8_t SlaveAddress,
+                              const uint8_t TimeoutMS)
 {
 	for (;;)
 	{
@@ -33,17 +33,17 @@ bool TWI_StartTransmission(const uint8_t SlaveAddress,
 						continue;
 					default:
 						TWCR = (1 << TWEN);
-						return false;
+						return TWI_ERROR_BusFault;
 				}
 			}
 
 			_delay_us(10);
 		}
 
-		if (!(BusCaptured))
+		if (!(TimeoutRemaining))
 		{
 			TWCR = (1 << TWEN);
-			return false;
+			return TWI_ERROR_BusCaptureTimeout;
 		}
 
 		TWDR = SlaveAddress;
@@ -59,17 +59,85 @@ bool TWI_StartTransmission(const uint8_t SlaveAddress,
 		}
 
 		if (!(TimeoutRemaining))
-		  return false;
+		  return TWI_ERROR_SlaveResponseTimeout;
 
 		switch (TWSR & TW_STATUS_MASK)
 		{
 			case TW_MT_SLA_ACK:
 			case TW_MR_SLA_ACK:
-				return true;
+				return TWI_ERROR_NoError;
 			default:
 				TWCR = ((1 << TWINT) | (1 << TWSTO) | (1 << TWEN));
-				return false;
+				return TWI_ERROR_SlaveNotReady;
+		}
+	}
+}
+
+uint8_t TWI_ReadPacket(const uint8_t SlaveAddress,
+                       const uint8_t TimeoutMS,
+                       const uint8_t* InternalAddress,
+                       uint8_t InternalAddressLen,
+                       uint8_t* Buffer,
+                       uint8_t Length)
+{
+	uint8_t ErrorCode;
+	
+	if ((ErrorCode = TWI_WritePacket(SlaveAddress, TimeoutMS, InternalAddress, InternalAddressLen,
+	                                 NULL, 0)) != TWI_ERROR_NoError)
+	{
+		return ErrorCode;
+	}
+
+	if ((ErrorCode = TWI_StartTransmission((SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_READ,
+										   TimeoutMS)) == TWI_ERROR_NoError)
+	{
+		while (Length--)
+		{
+			if (!(TWI_ReceiveByte(Buffer++, (Length == 0))))
+			{
+				ErrorCode = TWI_ERROR_SlaveNAK;
+				break;
+			}
 		}
+		
+		TWI_StopTransmission();
 	}
+	
+	return ErrorCode;
 }
 
+uint8_t TWI_WritePacket(const uint8_t SlaveAddress,
+                        const uint8_t TimeoutMS,
+                        const uint8_t* InternalAddress,
+                        uint8_t InternalAddressLen,
+                        const uint8_t* Buffer,
+                        uint8_t Length)
+{
+	uint8_t ErrorCode;
+
+	if ((ErrorCode = TWI_StartTransmission((SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_WRITE,
+	                                       TimeoutMS)) == TWI_ERROR_NoError)
+	{
+		while (InternalAddressLen--)
+		{
+			if (!(TWI_SendByte(*(InternalAddress++))))
+			{
+				ErrorCode = TWI_ERROR_SlaveNAK;
+				break;
+			}
+		}
+
+		while (Length--)
+		{
+			if (!(TWI_SendByte(*(Buffer++))))
+			{
+				ErrorCode = TWI_ERROR_SlaveNAK;
+				break;
+			}
+		}
+		
+		TWI_StopTransmission();
+	}
+	
+	return ErrorCode;
+}
diff --git a/LUFA/Drivers/USB/Class/Common/CDC.h b/LUFA/Drivers/USB/Class/Common/CDC.h
index 06efb51d4..52107d6a8 100644
--- a/LUFA/Drivers/USB/Class/Common/CDC.h
+++ b/LUFA/Drivers/USB/Class/Common/CDC.h
@@ -189,7 +189,7 @@
 		enum CDC_DescriptorSubtypes_t
 		{
 			CDC_DSUBTYPE_CSInterface_Header           = 0x00, /**< CDC class-specific Header functional descriptor. */
-			CDC_DSUBTYPE_CSInterface_CallManagement   = 0x01, /**< CDC class-specific Call Managment functional descriptor. */
+			CDC_DSUBTYPE_CSInterface_CallManagement   = 0x01, /**< CDC class-specific Call Management functional descriptor. */
 			CDC_DSUBTYPE_CSInterface_ACM              = 0x02, /**< CDC class-specific Abstract Control Model functional descriptor. */
 			CDC_DSUBTYPE_CSInterface_DirectLine       = 0x03, /**< CDC class-specific Direct Line functional descriptor. */
 			CDC_DSUBTYPE_CSInterface_TelephoneRinger  = 0x04, /**< CDC class-specific Telephone Ringer functional descriptor. */
@@ -280,7 +280,7 @@
 			                                  *   must be \ref CDC_DSUBTYPE_CSInterface_ACM.
 			                                  */
 			uint8_t                 Capabilities; /**< Capabilities of the ACM interface, given as a bit mask. For most devices,
-			                                       *   this should be set to a fixed value of 0x06 - for other capabiltiies, refer
+			                                       *   this should be set to a fixed value of 0x06 - for other capabilities, refer
 			                                       *   to the CDC ACM specification.
 			                                       */
 		} USB_CDC_Descriptor_FunctionalACM_t;
@@ -303,7 +303,7 @@
 			                             *   must be \ref CDC_DSUBTYPE_CSInterface_ACM.
 			                             */
 			uint8_t bmCapabilities; /**< Capabilities of the ACM interface, given as a bit mask. For most devices,
-			                         *   this should be set to a fixed value of 0x06 - for other capabiltiies, refer
+			                         *   this should be set to a fixed value of 0x06 - for other capabilities, refer
 			                         *   to the CDC ACM specification.
 			                         */
 		} USB_CDC_StdDescriptor_FunctionalACM_t;
diff --git a/LUFA/Drivers/USB/LowLevel/Host.h b/LUFA/Drivers/USB/LowLevel/Host.h
index 48d7926f3..92a4cb9c5 100644
--- a/LUFA/Drivers/USB/LowLevel/Host.h
+++ b/LUFA/Drivers/USB/LowLevel/Host.h
@@ -95,8 +95,8 @@
 				 *  after connection before the enumeration process can start or incorrect operation will
 				 *  occur.
 				 *
-				 *  The default delay value may be overridden in the user project makefile by definining the
-				 *  \c HOST_DEVICE_SETTLE_DELAY_MS token to tbe required delay in milliseconds, and passed to the
+				 *  The default delay value may be overridden in the user project makefile by defining the
+				 *  \c HOST_DEVICE_SETTLE_DELAY_MS token to the required delay in milliseconds, and passed to the
 				 *  compiler using the -D switch.
 				 */
 				#define HOST_DEVICE_SETTLE_DELAY_MS        1000
diff --git a/LUFA/Drivers/USB/LowLevel/USBController.h b/LUFA/Drivers/USB/LowLevel/USBController.h
index ea3d8fa99..5511fa573 100644
--- a/LUFA/Drivers/USB/LowLevel/USBController.h
+++ b/LUFA/Drivers/USB/LowLevel/USBController.h
@@ -308,7 +308,7 @@
 				 *        changed in value.
 				 *        \n\n
 				 *
-				 *  \note When the controller is initialized into UID autodetection mode, this variable will hold the
+				 *  \note When the controller is initialized into UID auto-detection mode, this variable will hold the
 				 *        currently selected USB mode (i.e. \ref USB_MODE_Device or \ref USB_MODE_Host). If the controller
 				 *        is fixed into a specific mode (either through the \c USB_DEVICE_ONLY or \c USB_HOST_ONLY compile time
 				 *        options, or a limitation of the USB controller in the chosen device model) this will evaluate to
diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index b7a7aad99..edf354c55 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -37,6 +37,7 @@
   *   - Combined page and word ISP programming mode code in the AVRISP-MKII clone project to reduce compiled size and
   *     increase maintainability of the code
   *   - Changed over library projects to use the new general ring buffer library driver module
+  *   - Added new high level TWI packet read/write commands, altered behaviour of the TWI_StartTransmission() function
   *   - Changed TempDataLogger project's DS1307 driver to simplify the function interface and prevent a possible race condition
   *
   *  <b>Fixed:</b>
@@ -106,7 +107,7 @@
   *    - Renamed ENDPOINT_DOUBLEBANK_SUPPORTED() to ENDPOINT_BANKS_SUPPORTED() and changed it to return the maximum number of supported banks for
   *      the given endpoint
   *    - Better algorithm to extract and convert the internal device serial number into a string descriptor (if present)
-  *    - All USB class drivers are now automatically included when LUFA/Drivers/USB.h is included, and no longer need to be seperately included
+  *    - All USB class drivers are now automatically included when LUFA/Drivers/USB.h is included, and no longer need to be separately included
   *    - The MIDI class drivers now automatically flushes the MIDI interface when the MIDI class driver's USBTask() function is called
   *    - Renamed the EVENT_USB_Device_UnhandledControlRequest() event to EVENT_USB_Device_ControlRequest() as it is now fired before the library
   *      request handlers, not afterwards
@@ -117,7 +118,7 @@
   *    - Added compile time error to the AVRISP-MKII project when built for the U4 chips, as the default VTARGET detection ADC channel
   *      does not exist on these chips (thanks to Marco)
   *    - Changed all Device mode LowLevel demos and Device Class drivers so that the control request is acknowledged and any data
-  *      transferred as quickly as possible without any processing inbetween sections, so that long callbacks or event handlers will
+  *      transferred as quickly as possible without any processing in between sections, so that long callbacks or event handlers will
   *      not break communications with the host by exceeding the maximum control request stage timeout period
   *    - Changed over all demos, drivers and internal functions to use the current frame number over the Start of Frame flag where possible
   *      to free up the Start of Frame flag for interrupt use in the user application
@@ -127,8 +128,8 @@
   *    - All LowLevel demos changed to use the constants and types defined in the USB class drivers
   *    - Changed AudioInput and AudioOutput demos to reload the next sample via an interrupt rather than polling the sample timer
   *    - Rescue clock of the AVRISP-MKII moved to the AVR's OCR1A pin, so that the clock can be generated at all times
-  *    - Changed ClassDriver MIDI demos to process all incomming events in a loop until the bank becomes empty rather than one at a time
-  *    - Changed LowLevel MIDI demos to only clear the incomming event bank once it has become empty to support packed event packets
+  *    - Changed ClassDriver MIDI demos to process all incoming events in a loop until the bank becomes empty rather than one at a time
+  *    - Changed LowLevel MIDI demos to only clear the incoming event bank once it has become empty to support packed event packets
   *
   *  <b>Fixed:</b>
   *  - Core:
@@ -599,7 +600,7 @@
   *    of device configurations can be defined statically
   *  - Removed VBUS events, as they are already exposed to the user application via the regular device connection and disconnection events
   *  - Renamed and altered existing events to properly separate out Host and Device mode events
-  *  - All demos switched over from GNU99 standards mode to C99 standards mode, to reduce the dependancies on GCC-only language extensions
+  *  - All demos switched over from GNU99 standards mode to C99 standards mode, to reduce the dependencies on GCC-only language extensions
   *
   *  <b>Fixed:</b>
   *  - Changed bootloaders to use FLASHEND rather than the existence of RAMPZ to determine if far FLASH pointers are needed to fix
diff --git a/LUFA/ManPages/MigrationInformation.txt b/LUFA/ManPages/MigrationInformation.txt
index 489e91a21..8f8fbcd29 100644
--- a/LUFA/ManPages/MigrationInformation.txt
+++ b/LUFA/ManPages/MigrationInformation.txt
@@ -11,6 +11,12 @@
  *  areas relevant to making older projects compatible with the API changes of each new release.
  *
  *  \section Sec_MigrationXXXXXX Migrating from 101122 to XXXXXX
+ *  <b>Non-USB Library Components</b>
+ *    - The TWI driver \ref TWI_StartTransmission() function return type has now changed, so that the function returns an
+ *      error code from the \ref TWI_ErrorCodes_t enum instead of a boolean success flag. Existing code must now check
+ *      against the \ref TWI_ERROR_NoError return value for success instead of a boolean true value, or it will not function
+ *      correctly.
+ *
  *  <b>USB Core</b>
  *    - By default, unordered Endpoint and Pipe configuration is now allowed once again, via the previous workaround of
  *      reconfiguring all Endpoints/Pipes in order each time a new Endpoint/Pipe is created. To minimise the compiled program
@@ -43,7 +49,7 @@
  *    - The USB mode specifier constants have been moved into a new enum and renamed. Existing projects should use the equivalent
  *      value in the new \ref USB_Modes_t enum.
  *    - All class driver headers are now included as part of the standard LUFA/Drivers/USB/USB.h master dispatch header, and should
- *      no longer be included seperately. Class driver module source files must still be added as a seperate module in the project's
+ *      no longer be included separately. Class driver module source files must still be added as a separate module in the project's
  *      makefile if used.
  *
  *  <b>Device Mode</b>
@@ -57,7 +63,7 @@
  *      for each class driver for the new class specific descriptor type names.
  *    - The ENDPOINT_DOUBLEBANK_SUPPORTED() macro is has been renamed \ref ENDPOINT_BANKS_SUPPORTED() and now returns the total number of
  *      banks supported by the given endpoint. Existing code should switch to the new naming scheme, and test that the return value of the
- *      macro is equal to or greated than 2 to regain the previous functionality.
+ *      macro is equal to or greater than 2 to regain the previous functionality.
  *    - The EVENT_USB_Device_UnhandledControlRequest() event is now named \ref EVENT_USB_Device_ControlRequest() and fires before (not after)
  *      the internal library event handlers. Existing code should rename the event handlers in the user application to match the new event
  *      name, and should ensure that the new execution order does not affect the application's operation.
diff --git a/Projects/TempDataLogger/Lib/DS1307.c b/Projects/TempDataLogger/Lib/DS1307.c
index 40aba3204..2f84a18cf 100644
--- a/Projects/TempDataLogger/Lib/DS1307.c
+++ b/Projects/TempDataLogger/Lib/DS1307.c
@@ -7,13 +7,14 @@
 
 #include "DS1307.h"
 
-void DS1307_SetTimeDate(const TimeDate_t* NewTimeDate)
+bool DS1307_SetTimeDate(const TimeDate_t* NewTimeDate)
 {
 #if defined(DUMMY_RTC)
-	return;
+	return true;
 #endif
 
 	DS1307_DateTimeRegs_t NewRegValues;
+	const uint8_t         WriteAddress = 0;
 
 	// Convert new time data to the DS1307's time register layout
 	NewRegValues.Byte1.Fields.TenSec    = (NewTimeDate->Second / 10);
@@ -34,27 +35,17 @@ void DS1307_SetTimeDate(const TimeDate_t* NewTimeDate)
 	NewRegValues.Byte7.Fields.TenYear   = (NewTimeDate->Year / 10);
 	NewRegValues.Byte7.Fields.Year      = (NewTimeDate->Year % 10);
 	
-	if (TWI_StartTransmission(DS1307_ADDRESS_WRITE, 10))
+	// Write the new Time and Date into the DS1307
+	if (TWI_WritePacket(DS1307_ADDRESS, 10, &WriteAddress, sizeof(WriteAddress),
+	                   (uint8_t*)&NewRegValues, sizeof(DS1307_DateTimeRegs_t)) != TWI_ERROR_NoError)
 	{
-		// Must start writing to the first address within the device		
-		TWI_SendByte(0);
-
-		// Write time data to the first set of device registers
-		TWI_SendByte(NewRegValues.Byte1.IntVal);
-		TWI_SendByte(NewRegValues.Byte2.IntVal);
-		TWI_SendByte(NewRegValues.Byte3.IntVal);
-
-		// Write date data to the second set of device registers
-		TWI_SendByte(NewRegValues.Byte4.IntVal);
-		TWI_SendByte(NewRegValues.Byte5.IntVal);
-		TWI_SendByte(NewRegValues.Byte6.IntVal);
-		TWI_SendByte(NewRegValues.Byte7.IntVal);
-		
-		TWI_StopTransmission();
+		return false;
 	}
+
+	return true;
 }
 
-void DS1307_GetTimeDate(TimeDate_t* const TimeDate)
+bool DS1307_GetTimeDate(TimeDate_t* const TimeDate)
 {
 #if defined(DUMMY_RTC)
 	TimeDate->Hour   = 1;
@@ -65,34 +56,19 @@ void DS1307_GetTimeDate(TimeDate_t* const TimeDate)
 	TimeDate->Month  = 1;
 	TimeDate->Year   = 1;
 	
-	return;
+	return true;
 #endif
 
-	if (TWI_StartTransmission(DS1307_ADDRESS_WRITE, 10))
-	{
-		// Must start reading from the first address within the device
-		TWI_SendByte(0);
-		TWI_StopTransmission();
-	}
-
 	DS1307_DateTimeRegs_t CurrentRegValues;
+	const uint8_t         ReadAddress = 0;
 	
-	if (TWI_StartTransmission(DS1307_ADDRESS_READ, 10))
+	// Read in the stored Time and Date from the DS1307
+	if (TWI_ReadPacket(DS1307_ADDRESS, 10, &ReadAddress, sizeof(ReadAddress),
+	                   (uint8_t*)&CurrentRegValues, sizeof(DS1307_DateTimeRegs_t)) != TWI_ERROR_NoError)
 	{
-		// First set of registers store the current time
-		TWI_ReceiveByte(&CurrentRegValues.Byte1.IntVal, false);
-		TWI_ReceiveByte(&CurrentRegValues.Byte2.IntVal, false);
-		TWI_ReceiveByte(&CurrentRegValues.Byte3.IntVal, false);
-
-		// Second set of registers store the current date
-		TWI_ReceiveByte(&CurrentRegValues.Byte4.IntVal, false);
-		TWI_ReceiveByte(&CurrentRegValues.Byte5.IntVal, false);
-		TWI_ReceiveByte(&CurrentRegValues.Byte6.IntVal, false);
-		TWI_ReceiveByte(&CurrentRegValues.Byte7.IntVal, true);
-		
-		TWI_StopTransmission();
+		return false;
 	}
-
+	
 	// Convert stored time value into decimal
 	TimeDate->Second  = (CurrentRegValues.Byte1.Fields.TenSec  * 10) + CurrentRegValues.Byte1.Fields.Sec;
 	TimeDate->Minute  = (CurrentRegValues.Byte2.Fields.TenMin  * 10) + CurrentRegValues.Byte2.Fields.Min;
@@ -102,5 +78,7 @@ void DS1307_GetTimeDate(TimeDate_t* const TimeDate)
 	TimeDate->Day    = (CurrentRegValues.Byte5.Fields.TenDay   * 10) + CurrentRegValues.Byte5.Fields.Day;
 	TimeDate->Month  = (CurrentRegValues.Byte6.Fields.TenMonth * 10) + CurrentRegValues.Byte6.Fields.Month;
 	TimeDate->Year   = (CurrentRegValues.Byte7.Fields.TenYear  * 10) + CurrentRegValues.Byte7.Fields.Year;
+
+	return true;
 }
 
diff --git a/Projects/TempDataLogger/Lib/DS1307.h b/Projects/TempDataLogger/Lib/DS1307.h
index 6269bb235..5181c3e87 100644
--- a/Projects/TempDataLogger/Lib/DS1307.h
+++ b/Projects/TempDataLogger/Lib/DS1307.h
@@ -111,12 +111,11 @@
 		} DS1307_DateTimeRegs_t;
 
 	/* Macros: */
-		#define DS1307_ADDRESS_READ   (0xD0 | TWI_ADDRESS_READ)
-		#define DS1307_ADDRESS_WRITE  (0xD0 | TWI_ADDRESS_WRITE)
+		#define DS1307_ADDRESS       0xD0
 
 	/* Function Prototypes: */
-		void DS1307_SetTimeDate(const TimeDate_t* NewTimeDate);
-		void DS1307_GetTimeDate(TimeDate_t* const TimeDate);
+		bool DS1307_SetTimeDate(const TimeDate_t* NewTimeDate);
+		bool DS1307_GetTimeDate(TimeDate_t* const TimeDate);
 
 #endif
 
-- 
GitLab