From 27461546523862a3a76ee41f615f7ec2eed2195f Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Tue, 19 Jan 2010 00:25:26 +0000 Subject: Added master mode hardware TWI driver. Fixed a bug in the incomplete Webserver project, where the packet data was not being written to and read from the correct buffer address. --- LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.c | 54 ++++++++++++ LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.h | 141 ++++++++++++++++++++++++++++++++ LUFA/Drivers/Peripheral/TWI.h | 70 ++++++++++++++++ 3 files changed, 265 insertions(+) create mode 100644 LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.c create mode 100644 LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.h create mode 100644 LUFA/Drivers/Peripheral/TWI.h (limited to 'LUFA/Drivers/Peripheral') diff --git a/LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.c b/LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.c new file mode 100644 index 000000000..6028bbae9 --- /dev/null +++ b/LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.c @@ -0,0 +1,54 @@ +/* + Copyright (C) Dean Camera, 2010. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +#include "TWI.h" + +bool TWI_StartTransmission(uint8_t SlaveAddress) +{ + for (;;) + { + uint8_t IterationsRemaining = 50; + bool BusCaptured = false; + + while (IterationsRemaining-- && !BusCaptured) + { + TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN)); + while (!(TWCR & (1 << TWINT))); + + switch (TWSR & TW_STATUS_MASK) + { + case TW_START: + case TW_REP_START: + BusCaptured = true; + break; + case TW_MT_ARB_LOST: + continue; + default: + return false; + } + } + + if (!(BusCaptured)) + return false; + + TWDR = SlaveAddress; + TWCR = ((1 << TWINT) | (1 << TWEN)); + while (!(TWCR & (1 << TWINT))); + + GPIOR0 = (TWSR & TW_STATUS_MASK); + + switch (TWSR & TW_STATUS_MASK) + { + case TW_MT_SLA_ACK: + case TW_MR_SLA_ACK: + return true; + default: + TWI_StopTransmission(); + break; + } + } +} diff --git a/LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.h b/LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.h new file mode 100644 index 000000000..0247668dc --- /dev/null +++ b/LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.h @@ -0,0 +1,141 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2010. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +/* + Copyright 2010 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 + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Master mode TWI driver for the AT90USB1287, AT90USB1286, AT90USB647, AT90USB646, ATMEGA16U4 and ATMEGA32U4 AVRs. + * + * \note This file should not be included directly. It is automatically included as needed by the TWI driver + * dispatch header located in LUFA/Drivers/Peripheral/TWI.h. + */ + +/** \ingroup Group_TWI + * @defgroup Group_TWI_AVRU4U6U7 Series U4, U6 and U7 Model TWI Driver + * + * @{ + */ + +#ifndef __TWI_AVRU4U6U7_H__ +#define __TWI_AVRU4U6U7_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + + #include + #include + #include + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(INCLUDE_FROM_TWI_H) + #error Do not include this file directly. Include LUFA/Drivers/Peripheral/TWI.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Pseudo-Function Macros: */ + #if defined(__DOXYGEN__) + /** Initializes the TWI hardware into master mode, ready for data transmission and reception. This must be + * before any other TWI operations. + */ + static inline void TWI_Init(void); + + /** Turns off the TWI driver hardware. If this is called, any further TWI operations will require a call to + * \ref TWI_Init() before the TWI can be used again. + */ + static inline void TWI_ShutDown(void); + #else + #define TWI_Init() MACROS{ TWCR |= (1 << TWEN); }MACROE + #define TWI_ShutDown() MACROS{ TWCR &= ~(1 << TWEN); }MACROE + #endif + + /* Inline Functions: */ + /** Sends a TWI STOP onto the TWI bus, terminating communication with the currently addressed device. */ + static inline void TWI_StopTransmission(void) + { + TWCR = ((1 << TWINT) | (1 << TWSTO) | (1 << TWEN)); + } + + /** Sends a byte to the currently addressed device on the TWI bus. + * + * \param Byte Byte to send to the currently addressed device + * + * \return Boolean true if the recipient ACKed the byte, false otherwise + */ + static inline bool TWI_SendByte(uint8_t Byte) + { + TWDR = Byte; + TWCR = ((1 << TWINT) | (1 << TWEN)); + while (!(TWCR & (1 << TWINT))); + + return ((TWSR & TW_STATUS_MASK) == TW_MT_DATA_ACK); + } + + /** Receives a byte from the currently addressed device on the TWI bus. + * + * \param Byte Location where the read byte is to be stored + * \param LastByte Indicates if the byte should be ACKed if false, NAKed if true + * + * \return Boolean true if the byte reception sucessfully completed, false otherwise + */ + static inline bool TWI_ReceiveByte(uint8_t* Byte, 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 SlaveAddress Address of the slave TWI device to communicate with + * + * \return Boolean true if the device is ready for data, false otherwise + */ + bool TWI_StartTransmission(uint8_t SlaveAddress); + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ diff --git a/LUFA/Drivers/Peripheral/TWI.h b/LUFA/Drivers/Peripheral/TWI.h new file mode 100644 index 000000000..2a97e1899 --- /dev/null +++ b/LUFA/Drivers/Peripheral/TWI.h @@ -0,0 +1,70 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2010. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +/* + Copyright 2010 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 + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * This file is the master dispatch header file for the device-specific ADC driver, for AVRs containing an ADC. + * + * User code should include this file, which will in turn include the correct ADC driver header file for the + * currently selected AVR model. + */ + +/** \ingroup Group_PeripheralDrivers + * @defgroup Group_TWI TWI Driver - LUFA/Drivers/Peripheral/TWI.h + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/Peripheral/AVRU4U6U7/TWI.c (for U4, U6 and U7 AVR models) + * + * \section Module Description + * Master Mode Hardware TWI driver. This module provides an easy to use driver for the hardware + * TWI present on many AVR models, for the transmission and reception of data on a TWI bus. + */ + +#ifndef __TWI_H__ +#define __TWI_H__ + + /* Macros: */ + #if !defined(__DOXYGEN__) + #define INCLUDE_FROM_TWI_H + #define INCLUDE_FROM_CHIP_DRIVER + #endif + + /* Includes: */ + #if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || \ + defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__) || \ + defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || \ + defined(__AVR_ATmega32U6__)) + #include "AVRU4U6U7/TWI.h" + #else + #error "TWI is not available for the currently selected AVR model." + #endif + +#endif -- cgit v1.2.3