aboutsummaryrefslogtreecommitdiffstats
path: root/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2011-02-20 18:21:04 +0000
committerDean Camera <dean@fourwalledcubicle.com>2011-02-20 18:21:04 +0000
commitb6a3c78fa3e46fea1dd6f4b93352686837983dfd (patch)
tree146ab396b543ebbcd521a932763b5e0217e75edc /LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c
parentcad5e9ffca70f4f5d3b486049088fd77dfa8f0ca (diff)
downloadlufa-b6a3c78fa3e46fea1dd6f4b93352686837983dfd.tar.gz
lufa-b6a3c78fa3e46fea1dd6f4b93352686837983dfd.tar.bz2
lufa-b6a3c78fa3e46fea1dd6f4b93352686837983dfd.zip
Rename architecture specific driver files, to make them appear with uniquely identifying filenames in the documentation.
Diffstat (limited to 'LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c')
-rw-r--r--LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c b/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c
new file mode 100644
index 000000000..b5f258dd3
--- /dev/null
+++ b/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c
@@ -0,0 +1,144 @@
+/*
+ Copyright (C) Dean Camera, 2011.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+#define __INCLUDE_FROM_TWI_C
+#include "TWI.h"
+
+uint8_t TWI_StartTransmission(const uint8_t SlaveAddress,
+ const uint8_t TimeoutMS)
+{
+ for (;;)
+ {
+ bool BusCaptured = false;
+ uint16_t TimeoutRemaining;
+
+ TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN));
+
+ TimeoutRemaining = (TimeoutMS * 100);
+ while (TimeoutRemaining-- && !(BusCaptured))
+ {
+ if (TWCR & (1 << TWINT))
+ {
+ 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 TWI_ERROR_BusFault;
+ }
+ }
+
+ _delay_us(10);
+ }
+
+ if (!(TimeoutRemaining))
+ {
+ TWCR = (1 << TWEN);
+ return TWI_ERROR_BusCaptureTimeout;
+ }
+
+ TWDR = SlaveAddress;
+ TWCR = ((1 << TWINT) | (1 << TWEN));
+
+ TimeoutRemaining = (TimeoutMS * 100);
+ while (TimeoutRemaining--)
+ {
+ if (TWCR & (1 << TWINT))
+ break;
+
+ _delay_us(10);
+ }
+
+ if (!(TimeoutRemaining))
+ return TWI_ERROR_SlaveResponseTimeout;
+
+ switch (TWSR & TW_STATUS_MASK)
+ {
+ case TW_MT_SLA_ACK:
+ case TW_MR_SLA_ACK:
+ return TWI_ERROR_NoError;
+ default:
+ TWCR = ((1 << TWINT) | (1 << TWSTO) | (1 << TWEN));
+ 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;
+}