X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/bad956bace05c603e9d6e63718f40ae173f5052f..e1803e3adb7754ad612a0251f0772f3e37d805aa:/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h diff --git a/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h b/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h index 8ff38a16f..38ad1f3e3 100644 --- a/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h +++ b/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h @@ -1,13 +1,13 @@ /* LUFA Library - Copyright (C) Dean Camera, 2011. + Copyright (C) Dean Camera, 2012. dean [at] fourwalledcubicle [dot] com www.lufa-lib.org */ /* - Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted @@ -52,59 +52,59 @@ * * Low Level API Example: * \code - * // Initialize the TWI driver before first use - * TWI_Init(TWI_BIT_PRESCALE_1, 10); - * + * // Initialize the TWI driver before first use at 200KHz + * TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 200000)); + * * // 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_ERROR_NoError) * { * TWI_SendByte(0xDC); - * + * * TWI_SendByte(0x01); * TWI_SendByte(0x02); * TWI_SendByte(0x03); - * + * * // Must stop transmission afterwards to release the bus * TWI_StopTransmission(); * } - * + * * // Start a read session to device at address 0xA0, internal address 0xDC with a 10ms timeout * if (TWI_StartTransmission(0xA0 | TWI_ADDRESS_WRITE, 10) == TWI_ERROR_NoError) * { * TWI_SendByte(0xDC); * TWI_StopTransmission(); - * + * * if (TWI_StartTransmission(0xA0 | TWI_ADDRESS_READ, 10) == TWI_ERROR_NoError) * { * uint8_t Byte1, Byte2, Byte3; - * + * * // 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 - * + * * High Level API Example: * \code - * // Initialize the TWI driver before first use - * TWI_Init(TWI_BIT_PRESCALE_1, 10); - * + * // Initialize the TWI driver before first use at 200KHz + * TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 200000)); + * * // 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 @@ -143,21 +143,21 @@ /** 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 0x01 /** 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 0x00 /** 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 - + /** Bit length prescaler for \ref TWI_Init(). This mask multiplies the TWI bit length prescaler by 1. */ #define TWI_BIT_PRESCALE_1 ((0 << TWPS1) | (0 << TWPS0)) - + /** Bit length prescaler for \ref TWI_Init(). This mask multiplies the TWI bit length prescaler by 4. */ #define TWI_BIT_PRESCALE_4 ((0 << TWPS1) | (1 << TWPS0)) @@ -166,7 +166,18 @@ /** Bit length prescaler for \ref TWI_Init(). This mask multiplies the TWI bit length prescaler by 64. */ #define TWI_BIT_PRESCALE_64 ((1 << TWPS1) | (1 << TWPS0)) - + + /** Calculates the length of each bit on the TWI bus for a given target frequency. This may be used with + * the \ref TWI_Init() function to convert a bus frequency to a number of clocks for the \c BitLength + * parameter. + * + * \param[in] Prescale Prescaler set on the TWI bus. + * \param[in] Frequency Desired TWI bus frequency in Hz. + * + * \return Bit length in clocks for the given TWI bus frequency at the given prescaler value. + */ + #define TWI_BITLENGTH_FROM_FREQ(Prescale, Frequency) ((((F_CPU / (Prescale)) / (Frequency)) - 16) / 2) + /* Enums: */ /** Enum for the possible return codes of the TWI transfer start routine and other dependant TWI functions. */ enum TWI_ErrorCodes_t @@ -178,15 +189,15 @@ 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: */ /** Initializes the TWI hardware into master mode, ready for data transmission and reception. This must be * before any other TWI operations. * * The generated SCL frequency will be according to the formula
F_CPU / (16 + 2 * BitLength + 4 ^ Prescale). * - * \note The value of the \c BitLength parameter should not be set below 10 or invalid bus conditions may - * occur, as indicated in the AVR8 microcontroller datasheet. + * \attention The value of the \c BitLength parameter should not be set below 10 or invalid bus conditions may + * occur, as indicated in the AVR8 microcontroller datasheet. * * \param[in] Prescale Prescaler to use when determining the bus frequency, a \c TWI_BIT_PRESCALE_* value. * \param[in] BitLength Length of the bits sent on the bus. @@ -215,70 +226,53 @@ TWCR = ((1 << TWINT) | (1 << TWSTO) | (1 << TWEN)); } - /** Sends a byte to the currently addressed device on the TWI bus. + /* Function Prototypes: */ + /** Begins a master mode TWI bus communication with the given slave device address. * - * \param[in] Byte Byte to send to the currently addressed device + * \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 recipient ACKed the byte, \c false otherwise + * \return A value from the \ref TWI_ErrorCodes_t enum. */ - 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); - } + uint8_t TWI_StartTransmission(const uint8_t SlaveAddress, + const uint8_t TimeoutMS); - /** Receives a byte from the currently addressed device on the TWI bus. + /** Sends a byte to the currently addressed device on the TWI bus. * - * \param[in] Byte Location where the read byte is to be stored - * \param[in] LastByte Indicates if the byte should be ACKed if false, NAKed if true + * \param[in] Byte Byte to send to the currently addressed device * - * \return Boolean \c true if the byte reception successfully completed, \c false otherwise + * \return Boolean \c true if the recipient ACKed the byte, \c false otherwise */ - static inline uint8_t 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; + bool TWI_SendByte(const uint8_t Byte); - return ((TWSR & TW_STATUS_MASK) == TW_MR_DATA_ACK); - } - - /* Function Prototypes: */ - /** Begins a master mode TWI bus communication with the given slave device address. + /** Receives a byte from the currently addressed device on the TWI bus. * - * \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 + * \param[in] Byte Location where the read byte is to be stored. + * \param[in] LastByte Indicates if the byte should be ACKed if false, NAKed if true. * - * \return A value from the \ref TWI_ErrorCodes_t enum + * \return Boolean \c true if the byte reception successfully completed, \c false otherwise. */ - 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); /** 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 + * \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. + * + * \return A value from the \ref TWI_ErrorCodes_t enum. */ 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 Length) ATTR_NON_NULL_PTR_ARG(3); /** High level function to perform a complete packet transfer over the TWI bus from the specified * device. @@ -289,13 +283,15 @@ * \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 + * + * \return A value from the \ref TWI_ErrorCodes_t enum. */ 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 Length) ATTR_NON_NULL_PTR_ARG(3); /* Disable C linkage for C++ Compilers: */ #if defined(__cplusplus)