X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/071e02c6b6b4837fa9cf0b6d4c749994e02638d7..0019fbd1294ccc9ecb0ac4ddb5d8c71efcf9597f:/LUFA/Drivers/Peripheral/TWI.c diff --git a/LUFA/Drivers/Peripheral/TWI.c b/LUFA/Drivers/Peripheral/TWI.c index bd6e85384..2f4e4ed42 100644 --- a/LUFA/Drivers/Peripheral/TWI.c +++ b/LUFA/Drivers/Peripheral/TWI.c @@ -1,20 +1,21 @@ /* - Copyright (C) Dean Camera, 2010. - + Copyright (C) Dean Camera, 2011. + dean [at] fourwalledcubicle [dot] com - www.fourwalledcubicle.com + www.lufa-lib.org */ #include "TWI.h" -bool TWI_StartTransmission(uint8_t SlaveAddress, uint8_t TimeoutMS) +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)); + TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN)); TimeoutRemaining = (TimeoutMS * 100); while (TimeoutRemaining-- && !(BusCaptured)) @@ -28,46 +29,115 @@ bool TWI_StartTransmission(uint8_t SlaveAddress, uint8_t TimeoutMS) BusCaptured = true; break; case TW_MT_ARB_LOST: - TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN)); + TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN)); 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; TWCR = ((1 << TWINT) | (1 << TWEN)); - + TimeoutRemaining = (TimeoutMS * 100); while (TimeoutRemaining--) { if (TWCR & (1 << TWINT)) break; - + _delay_us(10); } - + 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; +}