aboutsummaryrefslogtreecommitdiffstats
path: root/LUFA/Drivers/Peripheral
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2011-08-31 07:17:33 +0000
committerDean Camera <dean@fourwalledcubicle.com>2011-08-31 07:17:33 +0000
commit88d022a75245e7492ecd11a5e1ea5c553acf0b2c (patch)
treeafc2c8b9321a04d1bb66cb47389ad249ec50e54e /LUFA/Drivers/Peripheral
parentdc9133ad21e1661abdcc549a274b0cb464b0ac9e (diff)
downloadlufa-88d022a75245e7492ecd11a5e1ea5c553acf0b2c.tar.gz
lufa-88d022a75245e7492ecd11a5e1ea5c553acf0b2c.tar.bz2
lufa-88d022a75245e7492ecd11a5e1ea5c553acf0b2c.zip
Make TWI_ReadPacket() use a repeated start condition rather than a full bus release/recapture after the read address has been sent.
Fix TWI_ReadPacket() not releasing the bus correctly after all data transferred. Make TWI_SendByte() and TWI_ReceiveByte() non-inline to reduce compiled binary size.
Diffstat (limited to 'LUFA/Drivers/Peripheral')
-rw-r--r--LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c63
-rw-r--r--LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h57
2 files changed, 69 insertions, 51 deletions
diff --git a/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c b/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c
index d4f594f3b..d6db37d6e 100644
--- a/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c
+++ b/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c
@@ -97,34 +97,69 @@ uint8_t TWI_StartTransmission(const uint8_t SlaveAddress,
}
}
+bool TWI_SendByte(const uint8_t Byte)
+{
+ TWDR = Byte;
+ TWCR = ((1 << TWINT) | (1 << TWEN));
+ while (!(TWCR & (1 << TWINT)));
+
+ return ((TWSR & TW_STATUS_MASK) == TW_MT_DATA_ACK);
+}
+
+bool TWI_ReceiveByte(uint8_t* const Byte,
+ const bool LastByte)
+{
+ uint8_t TWCRMask;
+
+ if (LastByte)
+ TWCRMask = ((1 << TWINT) | (1 << TWEN));
+ else
+ TWCRMask = ((1 << TWINT) | (1 << TWEN) | (1 << TWEA));
+
+ TWCR = TWCRMask;
+ while (!(TWCR & (1 << TWINT)));
+ *Byte = TWDR;
+
+ uint8_t Status = (TWSR & TW_STATUS_MASK);
+
+ return ((LastByte) ? (Status == TW_MR_DATA_NACK) : (Status == TW_MR_DATA_ACK));
+}
+
uint8_t TWI_ReadPacket(const uint8_t SlaveAddress,
const uint8_t TimeoutMS,
const uint8_t* InternalAddress,
- const uint8_t InternalAddressLen,
+ 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)
+ if ((ErrorCode = TWI_StartTransmission((SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_WRITE,
+ TimeoutMS)) == TWI_ERROR_NoError)
{
- while (Length--)
+ while (InternalAddressLen--)
{
- if (!(TWI_ReceiveByte(Buffer++, (Length == 1))))
- {
+ if (!(TWI_SendByte(*(InternalAddress++))))
+ {
ErrorCode = TWI_ERROR_SlaveNAK;
break;
}
}
- TWI_StopTransmission();
+ 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;
@@ -145,7 +180,7 @@ uint8_t TWI_WritePacket(const uint8_t SlaveAddress,
while (InternalAddressLen--)
{
if (!(TWI_SendByte(*(InternalAddress++))))
- {
+ {
ErrorCode = TWI_ERROR_SlaveNAK;
break;
}
diff --git a/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h b/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h
index 63b9f03c6..705ef530c 100644
--- a/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h
+++ b/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h
@@ -99,14 +99,14 @@
* uint8_t WritePacket[3] = {0x01, 0x02, 0x03};
*
* TWI_WritePacket(0xA0, 10, &InternalWriteAddress, sizeof(InternalWriteAddress),
- * WritePacket, sizeof(WritePacket);
+ * &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);
+ * &ReadPacket, sizeof(ReadPacket);
* \endcode
*
* @{
@@ -215,20 +215,24 @@
TWCR = ((1 << TWINT) | (1 << TWSTO) | (1 << TWEN));
}
+ /* Function Prototypes: */
+ /** 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 A value from the \ref TWI_ErrorCodes_t enum.
+ */
+ uint8_t TWI_StartTransmission(const uint8_t SlaveAddress,
+ const uint8_t TimeoutMS);
+
/** Sends a byte to the currently addressed device on the TWI bus.
*
* \param[in] Byte Byte to send to the currently addressed device
*
* \return Boolean \c true if the recipient ACKed the byte, \c false otherwise
*/
- static inline bool TWI_SendByte(const uint8_t Byte)
- {
- TWDR = Byte;
- TWCR = ((1 << TWINT) | (1 << TWEN));
- while (!(TWCR & (1 << TWINT)));
-
- return ((TWSR & TW_STATUS_MASK) == TW_MT_DATA_ACK);
- }
+ bool TWI_SendByte(const uint8_t Byte);
/** Receives a byte from the currently addressed device on the TWI bus.
*
@@ -237,32 +241,11 @@
*
* \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)
- {
- uint8_t TWCRMask = ((1 << TWINT) | (1 << TWEN));
-
- if (!(LastByte))
- TWCRMask |= (1 << TWEA);
-
- TWCR = TWCRMask;
- while (!(TWCR & (1 << TWINT)));
- *Byte = TWDR;
-
- return ((TWSR & TW_STATUS_MASK) == TW_MR_DATA_ACK);
- }
-
- /* Function Prototypes: */
- /** 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 A value from the \ref TWI_ErrorCodes_t enum.
- */
- uint8_t TWI_StartTransmission(const uint8_t SlaveAddress,
- const uint8_t TimeoutMS);
-
+ bool TWI_ReceiveByte(uint8_t* const Byte,
+ const bool LastByte) ATTR_NON_NULL_PTR_ARG(1);
+ bool TWI_ReceiveByte(uint8_t* const Byte,
+ const bool LastByte);
+
/** High level function to perform a complete packet transfer over the TWI bus to the specified
* device.
*
@@ -278,7 +261,7 @@
uint8_t TWI_ReadPacket(const uint8_t SlaveAddress,
const uint8_t TimeoutMS,
const uint8_t* InternalAddress,
- const uint8_t InternalAddressLen,
+ uint8_t InternalAddressLen,
uint8_t* Buffer,
uint8_t Length) ATTR_NON_NULL_PTR_ARG(3);